zhangjie 1 жил өмнө
parent
commit
fcd57ee9d3

+ 15 - 0
electron/db/enumerate.ts

@@ -0,0 +1,15 @@
+// 任务状态:
+// INIT:未开始,RUNNING:运行中,FINISH:已完成
+export const TRACK_TASK_STATUS = {
+  INIT: 0,
+  RUNNING: 1,
+  FINISH: 9,
+};
+// 细分任务状态:
+// INIT:未开始,READY:数据已完整,RUNNING:运行中,FINISH:已完成
+export const TRACK_TASK_DETAIL_STATUS = {
+  INIT: 0,
+  READY: 1,
+  RUNNING: 2,
+  FINISH: 9,
+};

+ 19 - 5
electron/db/models/trackTask.ts

@@ -6,6 +6,7 @@ import {
   InferCreationAttributes,
 } from 'sequelize';
 import sequelize from '../sequelizeInstance';
+import { TRACK_TASK_STATUS } from '../enumerate';
 
 class TrackTask extends Model<
   // eslint-disable-next-line no-use-before-define
@@ -21,7 +22,11 @@ class TrackTask extends Model<
 
   declare examId: string;
 
-  declare pathRule: string;
+  declare extType: string;
+
+  declare pictureType: string;
+
+  declare outputDir: string;
 
   declare status: number;
 
@@ -49,16 +54,25 @@ TrackTask.init(
       type: DataTypes.STRING,
       allowNull: false,
     },
-    pathRule: {
+    extType: {
+      type: DataTypes.STRING,
+      allowNull: false,
+      comment: '文件类型',
+    },
+    pictureType: {
+      type: DataTypes.STRING,
+      allowNull: false,
+      comment: '图片类型',
+    },
+    outputDir: {
       type: DataTypes.STRING,
       allowNull: false,
-      comment: '保存路径规则',
+      comment: '保存目录',
     },
     status: {
       type: DataTypes.INTEGER,
       allowNull: false,
-      defaultValue: 0,
-      // 任务状态:0:未开始,1:运行中,2:已完成
+      defaultValue: TRACK_TASK_STATUS.INIT,
     },
     createdAt: DataTypes.DATE,
     updatedAt: DataTypes.DATE,

+ 2 - 2
electron/db/models/trackTaskDetail.ts

@@ -7,6 +7,7 @@ import {
 } from 'sequelize';
 import sequelize from '../sequelizeInstance';
 import TrackTask from './trackTask';
+import { TRACK_TASK_DETAIL_STATUS } from '../enumerate';
 
 class TrackTaskDetail extends Model<
   // eslint-disable-next-line no-use-before-define
@@ -65,8 +66,7 @@ TrackTaskDetail.init(
     status: {
       type: DataTypes.INTEGER,
       allowNull: false,
-      defaultValue: 0,
-      // 任务状态:0:未开始,1:运行中,2:已完成
+      defaultValue: TRACK_TASK_DETAIL_STATUS.INIT,
     },
     error: {
       type: DataTypes.TEXT,

+ 2 - 0
electron/main/index.ts

@@ -4,6 +4,7 @@ import url from 'url';
 import { electronApp, optimizer, is } from '@electron-toolkit/utils';
 import icon from '../../resources/icon.png?asset';
 import useElectron from './useElectron';
+import useWinProcess from './useWinProcess';
 
 function createWindow(): void {
   // Create the browser window.
@@ -55,6 +56,7 @@ app.whenReady().then(() => {
 
   // use electron
   useElectron();
+  useWinProcess();
 
   createWindow();
 

+ 74 - 0
electron/main/useWinProcess.ts

@@ -0,0 +1,74 @@
+import { ipcMain, BrowserWindow } from 'electron';
+import { join } from 'path';
+
+// export
+let childrenWindows: BrowserWindow[] = [];
+async function handleStartWinProcess(
+  event: Electron.IpcMainEvent,
+  processCount: number,
+  loadPageUrl: string
+) {
+  if (childrenWindows.length) {
+    childrenWindows.forEach((win) => win && win.close());
+    childrenWindows = [] as BrowserWindow[];
+  }
+
+  const parentWindow = BrowserWindow.getFocusedWindow();
+  if (!parentWindow) return;
+
+  const createWins = [] as Promise<BrowserWindow>[];
+  for (let i = 0; i < processCount; i++) {
+    createWins.push(buildChildWindow(parentWindow, loadPageUrl));
+  }
+  childrenWindows = await Promise.all(createWins);
+}
+
+async function buildChildWindow(
+  parentWindow: BrowserWindow,
+  loadPageUrl: string
+) {
+  const childWin = new BrowserWindow({
+    width: 400,
+    height: 400,
+    show: false,
+    parent: parentWindow,
+    webPreferences: {
+      preload: join(__dirname, '../preload/index.js'),
+      sandbox: false,
+    },
+  });
+  // const exportPdfHash = '#/export-track-pdf';
+
+  if (process.env.WEBPACK_DEV_SERVER_URL) {
+    // Load the url of the dev server if in development mode
+    await childWin.loadURL(process.env.WEBPACK_DEV_SERVER_URL + loadPageUrl);
+    // childWin.webContents.openDevTools();
+  } else {
+    // Load the index.html when not in development
+    await childWin.loadURL(`app://./index.html${loadPageUrl}`);
+  }
+  return childWin;
+}
+
+function handleStopWinProcess() {
+  if (!childrenWindows.length) return;
+  childrenWindows.forEach((cwin) => {
+    cwin.webContents.send('stop-running');
+  });
+}
+
+function handleCloseProcessWindow(event: Electron.IpcMainEvent, winId: number) {
+  if (!childrenWindows.length) return;
+
+  const pos = childrenWindows.findIndex((item) => item.id === winId);
+  if (pos !== -1) {
+    childrenWindows[pos].close();
+    childrenWindows.splice(pos, 1);
+  }
+}
+
+export default function useWinProcess() {
+  ipcMain.on('start-win-process', handleStartWinProcess);
+  ipcMain.on('stop-win-process', handleStopWinProcess);
+  ipcMain.on('close-process-window', handleCloseProcessWindow);
+}

+ 19 - 0
electron/preload/apiElectron.ts

@@ -12,9 +12,28 @@ function dialogSaveFile(
   return ipcRenderer.invoke('dialog:saveFile', config);
 }
 
+// win prcess
+function startWinProcess(processCount: number, loadPageUrl: string) {
+  return ipcRenderer.send('start-win-process', processCount, loadPageUrl);
+}
+function stopWinProcess() {
+  return ipcRenderer.send('stop-win-process');
+}
+function closeProcessWindow(winId: number) {
+  return ipcRenderer.send('close-process-window', winId);
+}
+function onStopRunning(callback: () => void) {
+  return ipcRenderer.on('stop-running', callback);
+}
+
 const electronApi = {
   dialogSelectFile,
   dialogSaveFile,
+  // win prcess
+  startWinProcess,
+  stopWinProcess,
+  closeProcessWindow,
+  onStopRunning,
 };
 
 export type ElectronApi = typeof electronApi;

+ 1 - 0
src/views/base/track-export/index.vue

@@ -31,6 +31,7 @@
         <a-input-search
           v-model.trim="formData.outputDir"
           :style="{ width: '400px' }"
+          readonly
           search-button
           button-text="选择"
           @search="toSelectDir"

+ 10 - 1
src/views/base/track-export/readme.md

@@ -3,7 +3,16 @@
 - sqlite3 -ok-
 - model/db -ok-
 - api
-- page view set
+- page view set -ok-
 - gm-imagemagic -ok-
 - task build -ok-
 - process manange
+
+## 轨迹图导出执行流程
+
+- 设置任务参数,保存数据。
+- 获取任务列表详情数据,保存数据。
+  - 此过程如果耗时过长,会触发 token 更新机制。
+- 开启多窗口执行任务。
+- 单个窗口获取当前任务配置,获取数据完整的细分任务,执行任务。
+- 主窗口轮询任务进度。一旦结束,广播任务结束事件,关闭所有隐藏窗口。