zhangjie hai 6 meses
pai
achega
3672ed0639
Modificáronse 6 ficheiros con 104 adicións e 10 borrados
  1. 6 1
      electron/main/index.ts
  2. 10 1
      electron/preload/apiElectron.ts
  3. 1 1
      index.html
  4. 53 1
      src/App.vue
  5. 8 1
      src/api/interceptor.ts
  6. 26 5
      src/utils/crypto.ts

+ 6 - 1
electron/main/index.ts

@@ -5,7 +5,7 @@ import { electronApp, optimizer, is } from '@electron-toolkit/utils';
 import icon from '../../resources/icon.png?asset';
 import icon from '../../resources/icon.png?asset';
 import useElectron from './useElectron';
 import useElectron from './useElectron';
 import useWinProcess from './useWinProcess';
 import useWinProcess from './useWinProcess';
-import './logger';
+// import log from './logger';
 
 
 function createWindow(): void {
 function createWindow(): void {
   // Create the browser window.
   // Create the browser window.
@@ -32,6 +32,11 @@ function createWindow(): void {
     return { action: 'deny' };
     return { action: 'deny' };
   });
   });
 
 
+  // TODO:方案要改
+  // const arg = process.argv;
+  // log.info(`process.argv:${JSON.stringify(arg)}`);
+  // mainWindow.webContents.send('silence-authority', arg[1]);
+
   // HMR for renderer base on electron-vite cli.
   // HMR for renderer base on electron-vite cli.
   // Load the remote URL for development or the local html file for production.
   // Load the remote URL for development or the local html file for production.
   if (is.dev && process.env.ELECTRON_RENDERER_URL) {
   if (is.dev && process.env.ELECTRON_RENDERER_URL) {

+ 10 - 1
electron/preload/apiElectron.ts

@@ -23,7 +23,15 @@ function closeProcessWindow(winId: number) {
   return ipcRenderer.send('close-process-window', winId);
   return ipcRenderer.send('close-process-window', winId);
 }
 }
 function onStopRunning(callback: () => void) {
 function onStopRunning(callback: () => void) {
-  return ipcRenderer.on('stop-running', callback);
+  // return ipcRenderer.on('stop-running', callback);
+  return ipcRenderer.on('stop-running', () => callback());
+}
+
+function onSilenceAuthority(callback: (authKey: string) => void) {
+  return ipcRenderer.on(
+    'silence-authority',
+    (event: Electron.IpcRendererEvent, authKey: string) => callback(authKey)
+  );
 }
 }
 
 
 const electronApi = {
 const electronApi = {
@@ -34,6 +42,7 @@ const electronApi = {
   stopWinProcess,
   stopWinProcess,
   closeProcessWindow,
   closeProcessWindow,
   onStopRunning,
   onStopRunning,
+  onSilenceAuthority,
 };
 };
 
 
 export type ElectronApi = typeof electronApi;
 export type ElectronApi = typeof electronApi;

+ 1 - 1
index.html

@@ -7,7 +7,7 @@
   <meta http-equiv="Content-Security-Policy"
   <meta http-equiv="Content-Security-Policy"
     content="script-src 'self'; style-src 'self' 'unsafe-inline';" />
     content="script-src 'self'; style-src 'self' 'unsafe-inline';" />
   <title>
   <title>
-    知学知考-图片导出工具
+    知学知考-图片导出工具-1.0.3
   </title>
   </title>
 </head>
 </head>
 
 

+ 53 - 1
src/App.vue

@@ -7,4 +7,56 @@
   </a-config-provider>
   </a-config-provider>
 </template>
 </template>
 
 
-<script lang="ts" setup></script>
+<script lang="ts" setup>
+  import { 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 { useUserStore, useAppStore } from './store';
+
+  const router = useRouter();
+  const appStore = useAppStore();
+  const userStore = useUserStore();
+
+  registSilenceAuthEvent();
+
+  interface AuthKey {
+    user: Partial<UserState>;
+    domain: string;
+  }
+
+  function registSilenceAuthEvent() {
+    window.electron.onSilenceAuthority((authKey: string) =>
+      silenceLogin(authKey)
+    );
+  }
+
+  async function silenceLogin(authKey: string) {
+    if (!authKey) return;
+    const authKeyData: AuthKey = JSON.parse(AESDecode(authKey));
+    console.log(authKeyData.user);
+
+    const data = authKeyData.user;
+    if (!data.accessToken) return;
+
+    appStore.setInfo({ domain: authKeyData.domain });
+
+    data.privilegeId = '';
+    userStore.setInfo(data);
+    const menuRes = await sysMenu();
+    const validMenu = menuRes.privileges.find(
+      (item) => item.url === 'ScoreManage'
+    );
+    if (!validMenu) {
+      userStore.resetInfo();
+      Message.error('您没有权限!');
+      return;
+    }
+    data.privilegeId = validMenu.id;
+    userStore.setInfo(data);
+
+    router.push({ name: 'TrackExport' });
+  }
+</script>

+ 8 - 1
src/api/interceptor.ts

@@ -3,6 +3,7 @@ import type {
   AxiosRequestConfig,
   AxiosRequestConfig,
   AxiosResponse,
   AxiosResponse,
   AxiosRequestHeaders,
   AxiosRequestHeaders,
+  AxiosError,
 } from 'axios';
 } from 'axios';
 import {
 import {
   Message,
   Message,
@@ -18,6 +19,8 @@ import { useUserStore, useAppStore } from '../store';
 
 
 axios.defaults.timeout = 2 * 60 * 1000;
 axios.defaults.timeout = 2 * 60 * 1000;
 
 
+const unNoticeUrls = ['api/admin/common/logout'];
+
 let load: MessageReturn | null = null;
 let load: MessageReturn | null = null;
 // 同一时间有多个请求时,会形成队列。在第一个请求创建loading,在最后一个响应关闭loading
 // 同一时间有多个请求时,会形成队列。在第一个请求创建loading,在最后一个响应关闭loading
 const queue: Array<string | undefined> = [];
 const queue: Array<string | undefined> = [];
@@ -105,7 +108,7 @@ axios.interceptors.response.use(
 
 
     return response.data.data;
     return response.data.data;
   },
   },
-  (error) => {
+  (error: AxiosError) => {
     // 关闭loading提示
     // 关闭loading提示
     setTimeout(() => {
     setTimeout(() => {
       queue.shift();
       queue.shift();
@@ -129,6 +132,10 @@ axios.interceptors.response.use(
     const { response } = error;
     const { response } = error;
     initSyncTime(new Date(response.headers.date).getTime());
     initSyncTime(new Date(response.headers.date).getTime());
 
 
+    if (unNoticeUrls.some((url) => (response.config.url || '').includes(url))) {
+      return Promise.reject(error);
+    }
+
     if (objTypeOf(response.data) === 'blob')
     if (objTypeOf(response.data) === 'blob')
       return Promise.reject(error.response.data);
       return Promise.reject(error.response.data);
 
 

+ 26 - 5
src/utils/crypto.ts

@@ -2,6 +2,8 @@ import Base64 from 'crypto-js/enc-base64';
 import Utf8 from 'crypto-js/enc-utf8';
 import Utf8 from 'crypto-js/enc-utf8';
 import AES from 'crypto-js/aes';
 import AES from 'crypto-js/aes';
 import SHA1 from 'crypto-js/sha1';
 import SHA1 from 'crypto-js/sha1';
+import ECB from 'crypto-js/mode-ecb';
+import Pkcs7 from 'crypto-js/pad-pkcs7';
 
 
 export const getBase64 = (content: string): string => {
 export const getBase64 = (content: string): string => {
   const words = Utf8.parse(content);
   const words = Utf8.parse(content);
@@ -10,16 +12,35 @@ export const getBase64 = (content: string): string => {
   return base64Str;
   return base64Str;
 };
 };
 
 
-export const getAES = (content: string): string => {
-  const KEY = '1234567890123456';
-  const IV = '1234567890123456';
+export const AESEncode = (content: string): string => {
+  const KEY = 'Qmth87863577qmth';
+  // const IV = '1234567890123456';
 
 
   const key = Utf8.parse(KEY);
   const key = Utf8.parse(KEY);
-  const iv = Utf8.parse(IV);
-  const encrypted = AES.encrypt(content, key, { iv });
+  // const iv = Utf8.parse(IV);
+  const encrypted = AES.encrypt(content, key, {
+    // iv,
+    mode: ECB,
+    padding: Pkcs7,
+  });
   return encrypted.toString();
   return encrypted.toString();
 };
 };
 
 
+export const AESDecode = (content: string): string => {
+  const KEY = 'Qmth87863577qmth';
+  // const IV = "1234567890123456";
+
+  const key = Utf8.parse(KEY);
+
+  // const iv = Utf8.parse(IV);
+  const decrypted = AES.decrypt(content, key, {
+    // iv: iv,
+    mode: ECB,
+    padding: Pkcs7,
+  });
+  return decrypted.toString(Utf8);
+};
+
 type AuthType = 'token' | 'secret';
 type AuthType = 'token' | 'secret';
 interface AuthInfo {
 interface AuthInfo {
   uri: string;
   uri: string;