|
|
|
@ -4,7 +4,7 @@ import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
|
|
|
import { getVersion } from "@tauri-apps/api/app";
|
|
|
|
import { getVersion } from "@tauri-apps/api/app";
|
|
|
|
import { writeText } from "@tauri-apps/api/clipboard";
|
|
|
|
import { writeText } from "@tauri-apps/api/clipboard";
|
|
|
|
import { invoke } from "@tauri-apps/api/tauri";
|
|
|
|
import { invoke } from "@tauri-apps/api/tauri";
|
|
|
|
import { computed, onMounted, onUnmounted, ref } from "vue";
|
|
|
|
import { computed, onMounted, onUnmounted, reactive, ref } from "vue";
|
|
|
|
import { api } from "../api";
|
|
|
|
import { api } from "../api";
|
|
|
|
import { getAllConfig, mergeConfig } from "../host/config";
|
|
|
|
import { getAllConfig, mergeConfig } from "../host/config";
|
|
|
|
import { log } from "../host/logger";
|
|
|
|
import { log } from "../host/logger";
|
|
|
|
@ -17,8 +17,11 @@ import {
|
|
|
|
startWindowDragging,
|
|
|
|
startWindowDragging,
|
|
|
|
} from "../host/window";
|
|
|
|
} from "../host/window";
|
|
|
|
|
|
|
|
|
|
|
|
const username = ref("admin");
|
|
|
|
/** el-form 需要稳定引用,勿使用每次渲染新建的 `{ username, password }` 对象 */
|
|
|
|
const password = ref("admin");
|
|
|
|
const loginForm = reactive({
|
|
|
|
|
|
|
|
username: "admin",
|
|
|
|
|
|
|
|
password: "admin",
|
|
|
|
|
|
|
|
});
|
|
|
|
const loginType = ref("NSFW");
|
|
|
|
const loginType = ref("NSFW");
|
|
|
|
const isLoading = ref(false);
|
|
|
|
const isLoading = ref(false);
|
|
|
|
const formRef = ref<InstanceType<typeof ElForm>>();
|
|
|
|
const formRef = ref<InstanceType<typeof ElForm>>();
|
|
|
|
@ -58,7 +61,7 @@ const rules = {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const isFormValid = computed(
|
|
|
|
const isFormValid = computed(
|
|
|
|
() => username.value.trim() !== "" && password.value !== "",
|
|
|
|
() => loginForm.username.trim() !== "" && loginForm.password.trim() !== "",
|
|
|
|
);
|
|
|
|
);
|
|
|
|
const isWindowSelected = computed(() => selectedWin.value !== "");
|
|
|
|
const isWindowSelected = computed(() => selectedWin.value !== "");
|
|
|
|
|
|
|
|
|
|
|
|
@ -78,6 +81,13 @@ function showMessage(
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 从窗口选择返回账号登录步骤。
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
function backToUserForm(): void {
|
|
|
|
|
|
|
|
isLoginSuccessed.value = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 处理账号登录。
|
|
|
|
* 处理账号登录。
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
@ -87,26 +97,32 @@ async function handleLogin(): Promise<void> {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await formRef.value?.validate(async (valid) => {
|
|
|
|
const form = formRef.value;
|
|
|
|
if (!valid) {
|
|
|
|
if (!form) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
isLoading.value = true;
|
|
|
|
isLoading.value = true;
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
await form.validate();
|
|
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
|
|
isLoading.value = false;
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const loginRes = await api.user.login({
|
|
|
|
const loginRes = await api.user.login({
|
|
|
|
loginMode: loginType.value,
|
|
|
|
loginMode: loginType.value,
|
|
|
|
clientType: "CALLER",
|
|
|
|
clientType: "CALLER",
|
|
|
|
username: username.value,
|
|
|
|
username: loginForm.username,
|
|
|
|
password: password.value,
|
|
|
|
password: loginForm.password,
|
|
|
|
hallRegNum: "",
|
|
|
|
hallRegNum: "",
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!loginRes?.queueToken) {
|
|
|
|
if (!loginRes?.queueToken) {
|
|
|
|
await log(
|
|
|
|
await log(
|
|
|
|
"warn",
|
|
|
|
"warn",
|
|
|
|
`登录失败: 接口未返回有效 queueToken, user=${username.value}`,
|
|
|
|
`登录失败: 接口未返回有效 queueToken, user=${loginForm.username}`,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -133,54 +149,61 @@ async function handleLogin(): Promise<void> {
|
|
|
|
selectedWin.value = cachedWinKey.value;
|
|
|
|
selectedWin.value = cachedWinKey.value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const initWindowUid =
|
|
|
|
|
|
|
|
selectedWin.value.trim() !== ""
|
|
|
|
|
|
|
|
? Number.parseInt(selectedWin.value, 10)
|
|
|
|
|
|
|
|
: Number(sessionState.winUid ?? 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const initRes = await api.action.init({
|
|
|
|
|
|
|
|
empUid: Number(sessionState.empUid ?? -1),
|
|
|
|
|
|
|
|
windowUid: Number.isFinite(initWindowUid) ? initWindowUid : 0,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const initSuccess =
|
|
|
|
|
|
|
|
((initRes as { data?: { success?: boolean } }).data?.success ??
|
|
|
|
|
|
|
|
(initRes as { success?: boolean }).success) === true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!initSuccess) {
|
|
|
|
|
|
|
|
await log("warn", "初始化接口调用完成,但返回 success=false");
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
sessionState.empUid = Number(sessionState.empUid ?? loginRes.operatorProfile.empUid);
|
|
|
|
|
|
|
|
sessionState.winUid = Number.isFinite(initWindowUid) ? initWindowUid : Number(sessionState.winUid ?? 0);
|
|
|
|
|
|
|
|
await setSession(sessionState);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
isLoginSuccessed.value = true;
|
|
|
|
isLoginSuccessed.value = true;
|
|
|
|
await log(
|
|
|
|
await log(
|
|
|
|
"info",
|
|
|
|
"info",
|
|
|
|
`登录成功: user=${username.value}, empUid=${sessionState.empUid}`,
|
|
|
|
`登录成功: user=${loginForm.username}, empUid=${sessionState.empUid}`,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
const message = error instanceof Error ? error.message : String(error);
|
|
|
|
const message = error instanceof Error ? error.message : String(error);
|
|
|
|
await log("error", `登录失败: user=${username.value}, ${message}`);
|
|
|
|
await log("error", `登录失败: user=${loginForm.username}, ${message}`);
|
|
|
|
} finally {
|
|
|
|
} finally {
|
|
|
|
isLoading.value = false;
|
|
|
|
isLoading.value = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 处理窗口登录确认。
|
|
|
|
* 处理窗口登录确认。
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
async function handleWindowLogin(): Promise<void> {
|
|
|
|
async function handleWindowLogin(): Promise<void> {
|
|
|
|
|
|
|
|
isLoading.value = true;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const winUid = Number.parseInt(selectedWin.value, 10);
|
|
|
|
const winUid = Number.parseInt(selectedWin.value, 10);
|
|
|
|
|
|
|
|
if (!Number.isFinite(winUid) || winUid <= 0) {
|
|
|
|
|
|
|
|
showMessage("warning", "请选择有效窗口");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const selected = options.value.find(
|
|
|
|
const selected = options.value.find(
|
|
|
|
(item) => item.value === selectedWin.value,
|
|
|
|
(item) => item.value === selectedWin.value,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const initRes = await api.action.init({
|
|
|
|
|
|
|
|
empUid: Number(sessionState.empUid ?? -1),
|
|
|
|
|
|
|
|
windowUid: winUid,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const initSuccess =
|
|
|
|
|
|
|
|
((initRes as { data?: { success?: boolean } }).data?.success ??
|
|
|
|
|
|
|
|
(initRes as { success?: boolean }).success) === true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!initSuccess) {
|
|
|
|
|
|
|
|
const initData = (initRes as { data?: { message?: string } }).data;
|
|
|
|
|
|
|
|
const msg =
|
|
|
|
|
|
|
|
(typeof initData?.message === "string" && initData.message.trim() !== ""
|
|
|
|
|
|
|
|
? initData.message
|
|
|
|
|
|
|
|
: null) ??
|
|
|
|
|
|
|
|
(typeof (initRes as { message?: string }).message === "string"
|
|
|
|
|
|
|
|
? (initRes as { message?: string }).message
|
|
|
|
|
|
|
|
: null) ??
|
|
|
|
|
|
|
|
"窗口初始化失败,请重试或更换窗口";
|
|
|
|
|
|
|
|
showMessage("error", String(msg));
|
|
|
|
|
|
|
|
await log("warn", `call-terminal/init 未成功: windowUid=${winUid}`);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await mergeConfig({
|
|
|
|
await mergeConfig({
|
|
|
|
last_username: username.value.trim(),
|
|
|
|
last_username: loginForm.username.trim(),
|
|
|
|
selected_win_key: selectedWin.value,
|
|
|
|
selected_win_key: selectedWin.value,
|
|
|
|
selected_win_value: selected?.label ?? "",
|
|
|
|
selected_win_value: selected?.label ?? "",
|
|
|
|
selected_win_uid: winUid,
|
|
|
|
selected_win_uid: winUid,
|
|
|
|
@ -226,6 +249,8 @@ async function handleWindowLogin(): Promise<void> {
|
|
|
|
const message = error instanceof Error ? error.message : String(error);
|
|
|
|
const message = error instanceof Error ? error.message : String(error);
|
|
|
|
showMessage("error", message || "打开主窗口失败");
|
|
|
|
showMessage("error", message || "打开主窗口失败");
|
|
|
|
await log("error", `打开主窗口失败: ${message}`);
|
|
|
|
await log("error", `打开主窗口失败: ${message}`);
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
isLoading.value = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -380,7 +405,7 @@ onMounted(async () => {
|
|
|
|
|
|
|
|
|
|
|
|
const config = await getAllConfig();
|
|
|
|
const config = await getAllConfig();
|
|
|
|
if (typeof config.last_username === "string" && config.last_username.trim()) {
|
|
|
|
if (typeof config.last_username === "string" && config.last_username.trim()) {
|
|
|
|
username.value = config.last_username;
|
|
|
|
loginForm.username = config.last_username;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (
|
|
|
|
if (
|
|
|
|
typeof config.selected_win_key === "string" &&
|
|
|
|
typeof config.selected_win_key === "string" &&
|
|
|
|
@ -465,7 +490,7 @@ onUnmounted(() => {
|
|
|
|
|
|
|
|
|
|
|
|
<el-form
|
|
|
|
<el-form
|
|
|
|
ref="formRef"
|
|
|
|
ref="formRef"
|
|
|
|
:model="{ username, password }"
|
|
|
|
:model="loginForm"
|
|
|
|
:rules="rules"
|
|
|
|
:rules="rules"
|
|
|
|
class="login-form"
|
|
|
|
class="login-form"
|
|
|
|
label-position="top"
|
|
|
|
label-position="top"
|
|
|
|
@ -473,7 +498,7 @@ onUnmounted(() => {
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<el-form-item label="账号" prop="username">
|
|
|
|
<el-form-item label="账号" prop="username">
|
|
|
|
<el-input
|
|
|
|
<el-input
|
|
|
|
v-model="username"
|
|
|
|
v-model="loginForm.username"
|
|
|
|
:prefix-icon="User"
|
|
|
|
:prefix-icon="User"
|
|
|
|
placeholder="请输入用户名/手机号"
|
|
|
|
placeholder="请输入用户名/手机号"
|
|
|
|
size="large"
|
|
|
|
size="large"
|
|
|
|
@ -483,7 +508,7 @@ onUnmounted(() => {
|
|
|
|
|
|
|
|
|
|
|
|
<el-form-item label="密码" prop="password">
|
|
|
|
<el-form-item label="密码" prop="password">
|
|
|
|
<el-input
|
|
|
|
<el-input
|
|
|
|
v-model="password"
|
|
|
|
v-model="loginForm.password"
|
|
|
|
:prefix-icon="Lock"
|
|
|
|
:prefix-icon="Lock"
|
|
|
|
type="password"
|
|
|
|
type="password"
|
|
|
|
placeholder="请输入登录密码"
|
|
|
|
placeholder="请输入登录密码"
|
|
|
|
@ -544,7 +569,7 @@ onUnmounted(() => {
|
|
|
|
type="primary"
|
|
|
|
type="primary"
|
|
|
|
size="large"
|
|
|
|
size="large"
|
|
|
|
class="login-button"
|
|
|
|
class="login-button"
|
|
|
|
@click="isLoginSuccessed = false"
|
|
|
|
@click="backToUserForm"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
返回
|
|
|
|
返回
|
|
|
|
</el-button>
|
|
|
|
</el-button>
|
|
|
|
|