Explorar el Código

feat: 主流程调试通

zhangjie hace 1 año
padre
commit
abf6643396

+ 1 - 0
.gitignore

@@ -1,6 +1,7 @@
 node_modules
 database
 store
+logs
 .DS_Store
 dist
 out

+ 4 - 1
electron/db/modelApi/trackTask.ts

@@ -95,7 +95,10 @@ export async function getTrackTaskDetailCount(data: {
   status?: TrackTaskDetailStatusKey;
 }) {
   const count = await TrackTaskDetail.count({
-    where: data,
+    where: {
+      trackTaskId: data.trackTaskId,
+      ...(data.status ? { status: TRACK_TASK_DETAIL_STATUS[data.status] } : {}),
+    },
   });
   return count;
 }

+ 1 - 0
electron/main/logger.ts

@@ -2,6 +2,7 @@ import log from 'electron-log/main';
 import path from 'node:path';
 import { getRootDir } from '../preload/utils';
 
+log.initialize();
 log.transports.console.level = false;
 log.transports.file.resolvePathFn = () =>
   path.join(getRootDir(), 'logs/main.log');

+ 5 - 3
electron/main/useWinProcess.ts

@@ -28,6 +28,8 @@ async function buildChildWindow(
   loadPageUrl: string
 ) {
   const childWin = new BrowserWindow({
+    // width: 1428,
+    // height: 700,
     width: 400,
     height: 400,
     show: false,
@@ -35,14 +37,14 @@ async function buildChildWindow(
     webPreferences: {
       preload: join(__dirname, '../preload/index.js'),
       sandbox: false,
+      webSecurity: false,
     },
   });
-  // const exportPdfHash = '#/export-track-pdf';
 
   const pageUrl = `${loadPageUrl}&winId=${childWin.id}`;
-  if (process.env.WEBPACK_DEV_SERVER_URL) {
+  if (process.env.ELECTRON_RENDERER_URL) {
     // Load the url of the dev server if in development mode
-    await childWin.loadURL(process.env.WEBPACK_DEV_SERVER_URL + pageUrl);
+    await childWin.loadURL(process.env.ELECTRON_RENDERER_URL + pageUrl);
     // childWin.webContents.openDevTools();
   } else {
     // Load the index.html when not in development

+ 26 - 16
electron/preload/api.ts

@@ -6,7 +6,12 @@ import fs from 'node:fs';
 import PDFDocument from 'pdfkit';
 import log from 'electron-log/renderer';
 
-import { getImagicPath, getTempPath } from './utils';
+import {
+  getImagicPath,
+  getTempPath,
+  makeDirSync,
+  getGmFontPath,
+} from './utils';
 
 import {
   DrawTrackItem,
@@ -46,8 +51,11 @@ function drawTrack(
   return new Promise((resolve, reject) => {
     const gmObj = gmInst(imgPath);
 
+    makeDirSync(path.dirname(outpath));
+
     const defaultColor = '#f53f3f';
-    const defaultFontSize = 14;
+    const defaultFontSize = 22;
+    gmObj.font(getGmFontPath());
 
     drawTrackList.forEach((track) => {
       // text
@@ -83,24 +91,25 @@ function drawTrack(
   });
 }
 
-async function downloadFile(url: string, outputPath: string) {
-  const writer = fs.createWriteStream(outputPath);
-
-  const response = await axios({
-    url,
-    method: 'GET',
-    responseType: 'stream',
-  });
-
-  response.data.pipe(writer);
-
+async function downloadFile(url: string, outputPath: string): Promise<string> {
   return new Promise((resolve, reject) => {
-    writer.on('finish', resolve);
-    writer.on('error', reject);
+    axios({
+      url,
+      method: 'GET',
+      responseType: 'arraybuffer',
+    })
+      .then((response) => {
+        fs.writeFileSync(outputPath, Buffer.from(response.data, 'binary'));
+        resolve(outputPath);
+      })
+      .catch(() => {
+        reject();
+      });
   });
 }
 
 async function downloadImage(url: string, outputPath: string) {
+  makeDirSync(path.dirname(outputPath));
   await downloadFile(url, outputPath);
   const size = sizeOf(outputPath);
 
@@ -125,8 +134,9 @@ async function imagesToPdf(
   outpath: string
 ): Promise<string> {
   return new Promise((resolve, reject) => {
-    const doc = new PDFDocument();
+    const doc = new PDFDocument({ autoFirstPage: false });
 
+    makeDirSync(path.dirname(outpath));
     const steam = fs.createWriteStream(outpath);
     doc.pipe(steam);
 

+ 4 - 0
electron/preload/utils.ts

@@ -32,6 +32,10 @@ export function getImagicPath() {
   return path.join(getResourcesDir(), './imagemagick-7.1.1-11/');
 }
 
+export function getGmFontPath() {
+  return path.join(getResourcesDir(), './font/simsun.ttf');
+}
+
 export function makeDirSync(pathContent: string) {
   const mkPathList: string[] = [];
   let curPath = pathContent;

BIN
resources/font/simsun.ttf


+ 0 - 9
src/store/modules/user/index.ts

@@ -1,5 +1,4 @@
 import { defineStore } from 'pinia';
-import ls from '@/utils/storage';
 import { removeRouteListener } from '@/utils/route-listener';
 import { userLogout } from '@/api/user';
 import { UserState } from './types';
@@ -50,14 +49,6 @@ const useUserStore = defineStore('user', {
       await userLogout().catch(() => {});
       this.resetInfo();
       removeRouteListener();
-
-      const returnUrl = ls.get('returnUrl');
-      if (returnUrl) {
-        window.location.href = returnUrl;
-        return;
-      }
-
-      ls.clear();
       window.location.reload();
     },
   },

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

@@ -254,7 +254,7 @@
 
     await updateTrackTaskReady();
     detailBuildStop.value = true;
-    // taskProgressRef.value?.open();
+    taskProgressRef.value?.open();
   }
 
   // 单个课程下载
@@ -298,6 +298,7 @@
     setLoading(false);
 
     if (!tRes) {
+      detailBuildStop.value = true;
       Message.error('创建任务详情错误!');
       return;
     }

+ 24 - 5
src/views/base/track-export/taskProgress.vue

@@ -7,6 +7,7 @@
     :align-center="false"
     :mask-closable="false"
     :esc-to-close="false"
+    :closable="false"
     @before-open="modalBeforeOpen"
   >
     <template #title> 任务进度 </template>
@@ -14,8 +15,8 @@
     <a-descriptions
       :data="taskInfo"
       title="任务详情"
-      layout="inline-horizontal"
       :align="{ label: 'right' }"
+      :column="1"
     />
 
     <a-descriptions title="进度">
@@ -25,7 +26,10 @@
     </a-descriptions>
 
     <template #footer>
-      <a-button @click="close">取消</a-button>
+      <a-button v-if="progressNum >= 1" type="primary" @click="close"
+        >确定</a-button
+      >
+      <a-button v-else @click="toCancel">取消</a-button>
     </template>
   </a-modal>
 </template>
@@ -38,6 +42,7 @@
   import { PICTURE_TYPE, PictureTypeEnum } from '@/constants/enumerate';
   import { useUserStore } from '@/store';
 
+  import { modalConfirm } from '../../../utils/arco';
   import { TrackTaskData } from '../../../../electron/db/models/trackTask';
 
   defineOptions({
@@ -62,12 +67,13 @@
   async function updateProgress() {
     clearSetTimeout(PROGRESS_KEY);
     finishCount.value = await window.db.getTrackTaskDetailCount({
-      trackTaskId: task.value?.id as number,
+      trackTaskId: task.value.id,
       status: 'FINISH',
     });
     progressNum.value = !total.value
       ? 0
       : Math.floor((10000 * finishCount.value) / total.value) / 10000;
+    // console.log(total.value, finishCount.value, progressNum.value);
 
     if (finishCount.value === total.value) {
       await window.db.updateTrackTaskStatus({
@@ -83,7 +89,9 @@
 
   function getExportUrl() {
     const page = '#/track-task-export';
-    const user = window.btoa(JSON.stringify(userStore.userInfo));
+    const user = window.btoa(
+      encodeURIComponent(JSON.stringify(userStore.$state))
+    );
     return `${page}?user=${user}`;
   }
 
@@ -141,6 +149,17 @@
     });
     updateProgress();
 
-    window.electron.startWinProcess(2, getExportUrl());
+    window.electron.startWinProcess(3, getExportUrl());
+  }
+
+  async function toCancel() {
+    const confirmRes = await modalConfirm(
+      '提示',
+      `确定要停止正在执行的任务吗?`
+    ).catch(() => false);
+    if (confirmRes !== 'confirm') return;
+
+    window.electron.stopWinProcess();
+    close();
   }
 </script>

+ 2 - 2
src/views/base/track-export/trackTaskExport.vue

@@ -20,7 +20,7 @@
 
   const winId = Number(route.query.winId);
   const userInfo = JSON.parse(
-    window.atob(route.query.user as string)
+    decodeURIComponent(window.atob(route.query.user as string))
   ) as UserState;
   const userStore = useUserStore();
   userStore.setInfo(userInfo);
@@ -51,7 +51,7 @@
 
     const status = result ? 'FINISH' : 'INIT';
     await window.db.updateTrackTaskDetailStatus({
-      id: res.trackTaskId,
+      id: res.id,
       status,
     });
     addLog(`[${res.studentId}] 09-任务结束`);

+ 3 - 3
src/views/base/track-export/useDraw.ts

@@ -223,7 +223,7 @@ export default function useDraw(winId: number) {
       task.value.examName,
       `${rawTask.courseName}(${rawTask.courseCode})`,
       rawTask.paperNumber,
-      type === 'pdf' ? '' : type,
+      type,
       filename,
     ];
     return window.api.joinPath(paths);
@@ -517,7 +517,7 @@ export default function useDraw(winId: number) {
           x: area.x + area.w - Math.ceil(tContLen * 20),
           y: area.y,
           text: tCont,
-          fontSize: 20,
+          fontSize: 30,
         },
       });
     });
@@ -573,7 +573,7 @@ export default function useDraw(winId: number) {
           x: area.x + area.w - Math.ceil(tContLen * 20),
           y: area.y,
           text: tCont,
-          fontSize: 20,
+          fontSize: 30,
         },
       });
     });

+ 10 - 0
src/views/login/test-page/index.vue

@@ -2,6 +2,7 @@
   <div>
     <h1>TestPage1</h1>
     <a-button type="primary" @click="toOpenFile">打开文件</a-button>
+    <a-button type="primary" @click="toDownloadFile">下载文件</a-button>
     <br />
     <img v-if="originImg" :src="originImg" alt="原图" />
     <br />
@@ -38,4 +39,13 @@
     if (!info) return;
     cropImg.value = `local://${info}`;
   }
+
+  async function toDownloadFile() {
+    const url =
+      'https://oss-file.qmth.com.cn/teachcloud-dps-dev-private/sheet/506931097515331584/511142910851289088/2024000001/1-1.jpg?Expires=1717638293&OSSAccessKeyId=key&Signature=UYsoE6XTZ3KR8cng7liDN1zmwj0%3D';
+    const outpath =
+      '/Users/chulin/develop/workspace/tcs/teachcloud-mark-tool/store/temp/111.jpg';
+    const res = await window.api.downloadImage(url, outpath);
+    console.log(res);
+  }
 </script>