|
@@ -1,20 +1,22 @@
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
import {
|
|
import {
|
|
- loginApi,
|
|
|
|
getStudentInfoBySessionApi,
|
|
getStudentInfoBySessionApi,
|
|
getStudentSpecialtyNameListApi,
|
|
getStudentSpecialtyNameListApi,
|
|
|
|
+ loginApi,
|
|
} from "@/api/login";
|
|
} from "@/api/login";
|
|
|
|
+import { DOMAIN, VITE_GIT_REPO_VERSION } from "@/constants/constants";
|
|
|
|
+import { useTimers } from "@/setups/useTimers";
|
|
import { store } from "@/store/store";
|
|
import { store } from "@/store/store";
|
|
import { createUserDetailLog } from "@/utils/logger";
|
|
import { createUserDetailLog } from "@/utils/logger";
|
|
-import { useRouter } from "vue-router";
|
|
|
|
-import { getElectronConfig } from "./useElectronConfig";
|
|
|
|
-import { getGeeTestConfig } from "./useGeeTestConfig";
|
|
|
|
-import { DOMAIN, VITE_GIT_REPO_VERSION } from "@/constants/constants";
|
|
|
|
|
|
+import { CloseCircleOutline, LockClosed, Person } from "@vicons/ionicons5";
|
|
|
|
+import { FormItemInst, FormRules } from "naive-ui";
|
|
import { onMounted, onUnmounted, watch } from "vue";
|
|
import { onMounted, onUnmounted, watch } from "vue";
|
|
-import { Person, LockClosed, CloseCircleOutline } from "@vicons/ionicons5";
|
|
|
|
-import { FormRules, FormItemInst } from "naive-ui";
|
|
|
|
|
|
+import { useRouter } from "vue-router";
|
|
import GeeTest from "./GeeTest.vue";
|
|
import GeeTest from "./GeeTest.vue";
|
|
import GlobalNotice from "./GlobalNotice.vue";
|
|
import GlobalNotice from "./GlobalNotice.vue";
|
|
|
|
+import { getElectronConfig } from "./useElectronConfig";
|
|
|
|
+import { getGeeTestConfig } from "./useGeeTestConfig";
|
|
|
|
+import { limitLogin } from "./useLimitLogin";
|
|
|
|
|
|
logger({
|
|
logger({
|
|
cnl: ["console", "local", "server"],
|
|
cnl: ["console", "local", "server"],
|
|
@@ -22,6 +24,8 @@ logger({
|
|
act: "首次渲染",
|
|
act: "首次渲染",
|
|
});
|
|
});
|
|
|
|
|
|
|
|
+const { addTimeout } = useTimers();
|
|
|
|
+
|
|
//#region service worker通知是否有版本更新
|
|
//#region service worker通知是否有版本更新
|
|
let newVersionAvailable = $ref(false);
|
|
let newVersionAvailable = $ref(false);
|
|
const checkNewVersionListener = () => {
|
|
const checkNewVersionListener = () => {
|
|
@@ -63,7 +67,7 @@ const productName = $computed(
|
|
const allowLoginType = $computed(() => QECSConfig.LOGIN_TYPE ?? []);
|
|
const allowLoginType = $computed(() => QECSConfig.LOGIN_TYPE ?? []);
|
|
|
|
|
|
let disableLoginBtn = $computed(
|
|
let disableLoginBtn = $computed(
|
|
- () => false
|
|
|
|
|
|
+ () => disableLoginBtnBecauseNotTimeout
|
|
// (isElectron() &&
|
|
// (isElectron() &&
|
|
// (this.disableLoginBtnBecauseRemoteApp ||
|
|
// (this.disableLoginBtnBecauseRemoteApp ||
|
|
// this.disableLoginBtnBecauseVCam)) ||
|
|
// this.disableLoginBtnBecauseVCam)) ||
|
|
@@ -72,8 +76,6 @@ let disableLoginBtn = $computed(
|
|
// this.disableLoginBtnBecauseNotAllowedNative
|
|
// this.disableLoginBtnBecauseNotAllowedNative
|
|
);
|
|
);
|
|
|
|
|
|
-let loginBtnLoading = $ref(false);
|
|
|
|
-
|
|
|
|
//#region form校验
|
|
//#region form校验
|
|
const domain = DOMAIN;
|
|
const domain = DOMAIN;
|
|
type FormModel = {
|
|
type FormModel = {
|
|
@@ -132,19 +134,74 @@ watch(
|
|
);
|
|
);
|
|
//#endregion
|
|
//#endregion
|
|
|
|
|
|
|
|
+/** 有版本更新返回true,函数内部处理;没版本更新则返回false */
|
|
|
|
+async function checkNewVersion(): Promise<boolean> {
|
|
|
|
+ let myHeaders = new Headers();
|
|
|
|
+ myHeaders.append("Content-Type", "application/javascript");
|
|
|
|
+ myHeaders.append("Cache-Control", "no-cache");
|
|
|
|
+ const response = await fetch(
|
|
|
|
+ [...document.scripts].at(-1)?.src + "?x" + Date.now(),
|
|
|
|
+ {
|
|
|
|
+ method: import.meta.env.DEV ? "GET" : "HEAD",
|
|
|
|
+ headers: myHeaders,
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ if (!response.ok || newVersionAvailable) {
|
|
|
|
+ if (
|
|
|
|
+ response.ok &&
|
|
|
|
+ newVersionAvailable &&
|
|
|
|
+ localStorage.getItem("__swReload")
|
|
|
|
+ ) {
|
|
|
|
+ logger({
|
|
|
|
+ cnl: ["local", "server"],
|
|
|
|
+ pgu: "AUTO",
|
|
|
|
+ dtl: "service worker刷新失败",
|
|
|
|
+ });
|
|
|
|
+ $message.info("请重新打开程序。", { duration: 2 * 24 * 60 * 60 });
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ logger({
|
|
|
|
+ cnl: ["local", "server"],
|
|
|
|
+ pgu: "AUTO",
|
|
|
|
+ dtl: "新版本发布后,客户端自动刷新",
|
|
|
|
+ });
|
|
|
|
+ $message.info("正在获取新版本...");
|
|
|
|
+ localStorage.setItem("__swReload", "anything");
|
|
|
|
+ // disableLoginBtnBecauseRefreshServiceWorker = true;
|
|
|
|
+ await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
|
|
+ location.reload();
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
const router = useRouter();
|
|
const router = useRouter();
|
|
|
|
|
|
|
|
+let loginBtnLoading = $ref(false);
|
|
|
|
+let disableLoginBtnBecauseNotTimeout = $ref(false);
|
|
async function loginForuser() {
|
|
async function loginForuser() {
|
|
|
|
+ if (await checkNewVersion()) return;
|
|
|
|
+
|
|
if (await formRef.validate().catch(() => true)) return;
|
|
if (await formRef.validate().catch(() => true)) return;
|
|
|
|
|
|
if (isGeeTestEnabled) {
|
|
if (isGeeTestEnabled) {
|
|
if (!captchaObj?.getValidate()) {
|
|
if (!captchaObj?.getValidate()) {
|
|
$message.error("请完成验证");
|
|
$message.error("请完成验证");
|
|
- loginBtnLoading = false;
|
|
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ loginBtnLoading = true;
|
|
|
|
+ // 登录接口调一次必然间隔10秒以上
|
|
|
|
+ disableLoginBtnBecauseNotTimeout = true;
|
|
|
|
+ addTimeout(() => (disableLoginBtnBecauseNotTimeout = false), 10 * 1000);
|
|
|
|
+
|
|
|
|
+ if (await limitLogin()) {
|
|
|
|
+ loginBtnLoading = false;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
logger({
|
|
logger({
|
|
pgn: "登录页面",
|
|
pgn: "登录页面",
|
|
cnl: ["local", "server"],
|
|
cnl: ["local", "server"],
|
|
@@ -165,39 +222,49 @@ async function loginForuser() {
|
|
seccode: geeRes.geetest_seccode, // geeForm[2].value,
|
|
seccode: geeRes.geetest_seccode, // geeForm[2].value,
|
|
};
|
|
};
|
|
}
|
|
}
|
|
- const res = await loginApi(
|
|
|
|
- formValue.accountType,
|
|
|
|
- formValue.accountValue,
|
|
|
|
- formValue.password,
|
|
|
|
- domain,
|
|
|
|
- QECSConfig.ROOT_ORG_ID,
|
|
|
|
- geeParams
|
|
|
|
- );
|
|
|
|
|
|
|
|
- if (res.data.code === "200") {
|
|
|
|
- errorInfo = "";
|
|
|
|
- // 准备下面的登录token
|
|
|
|
- store.user = res.data.content;
|
|
|
|
- } else {
|
|
|
|
- errorInfo = res.data.desc;
|
|
|
|
- captchaObj.destroy();
|
|
|
|
- resetGeeTime = Date.now();
|
|
|
|
- logger({
|
|
|
|
- pgu: "AUTO",
|
|
|
|
- act: "点击登录-res-error",
|
|
|
|
- stk: res.data.code + res.data.desc,
|
|
|
|
- cnl: ["console", "server"],
|
|
|
|
- });
|
|
|
|
- return;
|
|
|
|
|
|
+ try {
|
|
|
|
+ const res = await loginApi(
|
|
|
|
+ formValue.accountType,
|
|
|
|
+ formValue.accountValue,
|
|
|
|
+ formValue.password,
|
|
|
|
+ domain,
|
|
|
|
+ QECSConfig.ROOT_ORG_ID,
|
|
|
|
+ geeParams
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ if (res.data.code === "200") {
|
|
|
|
+ errorInfo = "";
|
|
|
|
+ // 准备下面的登录token
|
|
|
|
+ store.user = res.data.content;
|
|
|
|
+ } else {
|
|
|
|
+ errorInfo = res.data.desc;
|
|
|
|
+ captchaObj?.destroy();
|
|
|
|
+ resetGeeTime = Date.now();
|
|
|
|
+ logger({
|
|
|
|
+ pgu: "AUTO",
|
|
|
|
+ act: "点击登录-res-error",
|
|
|
|
+ stk: res.data.code + res.data.desc,
|
|
|
|
+ cnl: ["console", "server"],
|
|
|
|
+ });
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ await afterLogin(res);
|
|
|
|
+ } finally {
|
|
|
|
+ loginBtnLoading = false;
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
|
|
+/** 登录成功后,取学生信息和跳转 */
|
|
|
|
+async function afterLogin(loginRes: any) {
|
|
try {
|
|
try {
|
|
const [{ data: student }, { data: specialty }] = await Promise.all([
|
|
const [{ data: student }, { data: specialty }] = await Promise.all([
|
|
getStudentInfoBySessionApi(),
|
|
getStudentInfoBySessionApi(),
|
|
getStudentSpecialtyNameListApi(),
|
|
getStudentSpecialtyNameListApi(),
|
|
]);
|
|
]);
|
|
const user = {
|
|
const user = {
|
|
- ...res.data.content,
|
|
|
|
|
|
+ ...loginRes.data.content,
|
|
...student,
|
|
...student,
|
|
specialty: specialty.join(),
|
|
specialty: specialty.join(),
|
|
schoolDomain: domain,
|
|
schoolDomain: domain,
|
|
@@ -211,7 +278,7 @@ async function loginForuser() {
|
|
logger({
|
|
logger({
|
|
cnl: ["local", "server"],
|
|
cnl: ["local", "server"],
|
|
act: "登录失败",
|
|
act: "登录失败",
|
|
- dtl: "getStudentInfoBySession失败",
|
|
|
|
|
|
+ dtl: "getStudentInfoBySession/getStudentSpecialtyNameListApi失败",
|
|
});
|
|
});
|
|
$message.error("获取学生信息失败,请重试!", {
|
|
$message.error("获取学生信息失败,请重试!", {
|
|
duration: 15,
|
|
duration: 15,
|