Selaa lähdekoodia

feat: 静默登录

zhangjie 6 kuukautta sitten
vanhempi
commit
f3ff6018c8

+ 5 - 5
electron/main/index.ts

@@ -11,11 +11,11 @@ import log from './logger';
 function silenceAuthorityHandle(mainWindow) {
   const arg = process.argv;
   log.info(`process.argv:${JSON.stringify(arg)}`);
-  // mainWindow.webContents.send('silence-authority', arg[1]);
-  mainWindow.webContents.send(
-    'silence-authority',
-    'zgiOtrHS2nq9q3SOr0iOYAW1JJsG2w1lrqdv0PB2IrT9ijPBsKxT7I7u2077RaKAPbwfEj+9f/zr+RHzOZFsaYZo5GuoJLMdJPKvvOnpG/3jk6GsdPFlMooCjs5LzJKutFiFOj/xsXoOGdxqIYXWWH6sROZQAKhvBIu2Mfem6+fZhy66baK/s0ihec59gOTQ8lsjyJzf8To2K0EyapRWGVpFwljAmaQ1HfhfUUoRIYTIHW89wqRU3KYjB5oJQRQnVYLA7v0H9kK0smmX3N3Kbc0V9LtHUIiU/teGvWaa6ty43SAJqci9IRZEh35xzM9IjtzvR/9LHQWZqTLuVSZ+JmCwfKKGFV39ewYjrjmFk34tIW5yvmQ9oUugpi2T3xhdMA7aeNkkoK0tgm3hwqri3KdziGcqdEdkqhfW2vapwPDy4m5g/JH7ulNLI0nfDmPpTNsWgWXjUnmAQNWAp4In1oH8TMRNHImMbsxz4RhcBz/z/YCWl89zk/vA4TOtQDV99s66+8kVhTQEjDXffz6z2T5hZTGaPMv/lSCo1Fo01VM='
-  );
+  mainWindow.webContents.send('silence-authority', arg[1]);
+  // mainWindow.webContents.send(
+  //   'silence-authority',
+  //   'zgiOtrHS2nq9q3SOr0iOYAW1JJsG2w1lrqdv0PB2IrT9ijPBsKxT7I7u2077RaKAPbwfEj+9f/zr+RHzOZFsaYZo5GuoJLMdJPKvvOnpG/3jk6GsdPFlMooCjs5LzJKutFiFOj/xsXoOGdxqIYXWWH6sROZQAKhvBIu2Mfem6+fZhy66baK/s0ihec59gOTQ8lsjyJzf8To2K0EyapRWGVpFwljAmaQ1HfhfUUoRIYTIHW89wqRU3KYjB5oJQRQnVYLA7v0H9kK0smmX3N3Kbc0V9LtHUIiU/teGvWaa6ty43SAJqci9IRZEh35xzM9IjtzvR/9LHQWZqTLuVSZ+JmCwfKKGFV39ewYjrjmFk34tIW5yvmQ9oUugpi2T3xhdMA7aeNkkoK0tgm3hwqri3KdziGcqdEdkqhfW2vapwPDy4m5g/JH7ulNLI0nfDmPpTNsWgWXjUnmAQNWAp4In1oH8TMRNHImMbsxz4RhcBz/z/YCWl89zk/vA4TOtQDV99s66+8kVhTQEjDXffz6z2T5hZTGaPMv/lSCo1Fo01VM='
+  // );
 }
 
 function createWindow(): void {

+ 89 - 18
src/App.vue

@@ -8,55 +8,126 @@
 </template>
 
 <script lang="ts" setup>
-  import { useRouter } from 'vue-router';
+  import { useRoute, useRouter } from 'vue-router';
   import { Message } from '@arco-design/web-vue';
   import { sysMenu } from '@/api/user';
 
   import { AESDecode } from './utils/crypto';
   import { UserState } from './store/modules/user/types';
+  import { AppState } from './store/modules/app/types';
   import { useUserStore, useAppStore } from './store';
 
   const router = useRouter();
+  const route = useRoute();
   const appStore = useAppStore();
   const userStore = useUserStore();
 
   registSilenceAuthEvent();
 
-  interface AuthKey {
+  function registSilenceAuthEvent() {
+    window.electron.onSilenceAuthority(silenceAuthorityHandle);
+  }
+
+  function silenceAuthorityHandle(authKey: string) {
+    if (!authKey) return;
+
+    if (authKey.startsWith('trd://launcher')) {
+      silenceLauncher();
+      return;
+    }
+
+    if (authKey.startsWith('trd://download')) {
+      silenceDownload(authKey);
+      return;
+    }
+
+    window.api.logger(`error authKey data`, 'error');
+  }
+  // 打开工具登录界面
+  function silenceLauncher() {
+    if (route.name === 'Login') return;
+
+    router.push({ name: 'Login' });
+  }
+
+  interface AuthData {
     user: Partial<UserState>;
     apiUrl: string;
+    actionSession: AppState['actionSession'];
+    downloadSet: AppState['downloadSet'];
   }
 
-  function registSilenceAuthEvent() {
-    window.electron.onSilenceAuthority((authKey: string) =>
-      silenceLogin(authKey)
-    );
-  }
+  // 静默登录下载
+  async function silenceDownload(authKey: string) {
+    const paramData = authKey.replace('trd://download?q=', '');
+    const authData: AuthData = JSON.parse(AESDecode(paramData));
+    window.api.logger(`authData: ${JSON.stringify(authData)}`);
 
-  async function silenceLogin(authKey: string) {
-    if (!authKey) return;
-    const authKeyData: AuthKey = JSON.parse(AESDecode(authKey));
-    console.log(authKeyData.user);
+    // 防止重复执行
+    if (authData.actionSession === appStore.actionSession) {
+      window.api.logger(`[warning] 重复的actionSession!`);
+      return;
+    }
+    // 有任务在进行,不做任何处理
+    if (appStore.downloadTaskRunning) {
+      window.api.logger(`[warning] 当前有任务正在进行!`);
+      return;
+    }
+
+    // console.log(authData);
+    const user = authData.user;
+    if (!user || !user.accessToken) return;
+
+    // 登录人切换警告
+    if (userStore.id && userStore.id !== user.id) {
+      Message.warning('登录人信息改变!');
+      window.api.logger(`[warning] 登录人信息改变!`);
+    }
 
-    const data = authKeyData.user;
-    if (!data.accessToken) return;
+    appStore.setInfo({
+      domain: authData.apiUrl,
+      actionSession: authData.actionSession || '',
+      downloadSet: authData.downloadSet || null,
+    });
 
-    appStore.setInfo({ domain: authKeyData.apiUrl });
+    user.privilegeId = '';
+    userStore.setInfo(user);
 
-    data.privilegeId = '';
-    userStore.setInfo(data);
     const menuRes = await sysMenu();
     const validMenu = menuRes.privileges.find(
       (item) => item.url === 'ScoreManage'
     );
     if (!validMenu) {
       userStore.resetInfo();
+      appStore.setInfo({
+        actionSession: '',
+        downloadSet: null,
+      });
+      recoverSystemDomain();
       Message.error('您没有权限!');
       return;
     }
-    data.privilegeId = validMenu.id;
-    userStore.setInfo(data);
+    userStore.setInfo({ privilegeId: validMenu.id });
+    updateSystemDomain(appStore.domain);
+
+    if (route.name === 'TrackExport') {
+      window.api.logger(`TrackExport 页面刷新`);
+      window.location.reload();
+      return;
+    }
 
+    window.api.logger(`进入 TrackExport 页面`);
     router.push({ name: 'TrackExport' });
   }
+
+  async function updateSystemDomain(domain: string) {
+    await window.db.updateDict({ key: 'domain', val: domain });
+  }
+
+  async function recoverSystemDomain() {
+    const domain = await window.db.getDict('domain');
+    appStore.setInfo({
+      domain,
+    });
+  }
 </script>

+ 4 - 0
src/store/modules/app/index.ts

@@ -14,6 +14,10 @@ const useAppStore = defineStore('app', {
       trackColorType: 'DEFAULT',
       studentFileRule: 'CODE',
     },
+    downloadTaskRunning: false,
+    // auto download task
+    actionSession: '',
+    downloadSet: null,
   }),
 
   getters: {

+ 12 - 0
src/store/modules/app/types.ts

@@ -13,9 +13,21 @@ export interface TrackConfigType {
   studentFileRule: StudentFileRuleEnum;
 }
 
+export interface DownloadSetType {
+  trackExport: {
+    semesterId: string;
+    examId: string;
+    courseId: string;
+  };
+}
+
 export interface AppState {
   version: string;
   domain: string;
   device: string;
   trackConfig: TrackConfigType;
+  downloadTaskRunning: boolean;
+  // auto download task
+  actionSession: string;
+  downloadSet: DownloadSetType | null;
 }

+ 6 - 2
src/views/base/track-export/taskProgress.vue

@@ -61,7 +61,7 @@
   import useModal from '@/hooks/modal';
   import useTimeout from '@/hooks/timout';
   import { PICTURE_TYPE } from '@/constants/enumerate';
-  import { useUserStore } from '@/store';
+  import { useAppStore, useUserStore } from '@/store';
   import { TrackConfigType } from '@/store/modules/app/types';
   import { TrackExportDetailListFilter } from '@/api/types/task';
   import { objTypeOf } from '@/utils/utils';
@@ -72,7 +72,7 @@
   type FilterDataType = TrackExportDetailListFilter | string[];
 
   defineOptions({
-    name: 'ModifySet',
+    name: 'TaskProgress',
   });
 
   /* modal */
@@ -81,6 +81,7 @@
 
   const { addSetTimeout, clearSetTimeout } = useTimeout();
   const userStore = useUserStore();
+  const appStore = useAppStore();
 
   const PROGRESS_KEY = 'progress';
 
@@ -108,6 +109,7 @@
         status: 'FINISH',
       });
       window.electron.stopWinProcess();
+      appStore.setInfo({ downloadTaskRunning: false });
       return;
     }
 
@@ -198,6 +200,7 @@
       appConfig.downloadProcessCount,
       getExportUrl()
     );
+    appStore.setInfo({ downloadTaskRunning: true });
     // window.electron.startWinProcess(2, getExportUrl());
   }
 
@@ -279,6 +282,7 @@
     if (confirmRes !== 'confirm') return;
 
     window.electron.stopWinProcess();
+    appStore.setInfo({ downloadTaskRunning: false });
     close();
   }
 </script>

+ 6 - 5
src/views/login/login/index.vue

@@ -62,15 +62,16 @@
   import { ref, reactive, onMounted } from 'vue';
   import { useRouter } from 'vue-router';
   import type { FormInstance } from '@arco-design/web-vue/es/form';
+  import { Message } from '@arco-design/web-vue';
   import useLoading from '@/hooks/loading';
   import { login, schoolList, sysMenu } from '@/api/user';
-  import { getBase64 } from '@/utils/crypto';
+  import { AESEncode } from '@/utils/crypto';
   import { useAppStore, useUserStore } from '@/store';
   import { UserSchoolInfoType } from '@/store/modules/user/types';
   import type { LoginData } from '@/api/types/user';
   import { FormRules, OptionListItem } from '@/types/global';
   import { objAssign } from '@/utils/utils';
-  import { Message } from '@arco-design/web-vue';
+  import { DEVICE_ID, PLATFORM } from '@/constants/app';
 
   defineOptions({
     name: 'Login',
@@ -134,7 +135,7 @@
 
     setLoading(true);
     const datas = objAssign(formData, {});
-    datas.password = getBase64(formData.password);
+    datas.password = AESEncode(formData.password);
     const data = await login(datas).catch(() => {});
     setLoading(false);
     if (!data) return;
@@ -146,7 +147,7 @@
       data.curSchoolInfo = curSchool || ({} as UserSchoolInfoType);
     }
 
-    userStore.setInfo(data);
+    userStore.setInfo({ ...data, deviceId: DEVICE_ID, platform: PLATFORM });
 
     const menuRes = await sysMenu();
     const validMenu = menuRes.privileges.find(
@@ -158,7 +159,7 @@
       return;
     }
     data.privilegeId = validMenu.id;
-    userStore.setInfo(data);
+    userStore.setInfo({ ...data, deviceId: DEVICE_ID, platform: PLATFORM });
 
     router.push({
       name: 'TrackExport',