ソースを参照

feat: 下载优化

zhangjie 11 ヶ月 前
コミット
fbe5de757d

+ 36 - 5
electron/preload/api.ts

@@ -50,6 +50,9 @@ function drawTrack(
   outpath: string
 ): Promise<string> {
   return new Promise((resolve, reject) => {
+    const bname = path.basename(outpath);
+    log.info(`开始绘制:${bname}`);
+
     const gmObj = gmInst(imgPath);
 
     makeDirSync(path.dirname(outpath));
@@ -95,6 +98,8 @@ function drawTrack(
     });
 
     gmObj.write(outpath, (err) => {
+      log.info(`绘制完成:${bname}`);
+
       if (!err) {
         return resolve(outpath);
       }
@@ -103,6 +108,36 @@ function drawTrack(
   });
 }
 
+interface ImageItem {
+  url: string;
+  width: number;
+  height: number;
+}
+interface TaskItem {
+  imgItem: ImageItem;
+  outpath: string;
+  drawTrackList: DrawTrackItem[];
+}
+async function drawTracks(taskList: TaskItem[]): Promise<ImageItem[]> {
+  const downloads = taskList.map((item) =>
+    drawTrack(item.imgItem.url, item.drawTrackList, item.outpath)
+  );
+  const images = await Promise.all(downloads).catch((error) => {
+    console.log(error);
+  });
+  if (!images) {
+    return Promise.reject(new Error('绘制轨迹错误'));
+  }
+  const result = taskList.map((item, index) => {
+    return {
+      url: images[index],
+      width: item.imgItem.width,
+      height: item.imgItem.height,
+    };
+  });
+  return result;
+}
+
 async function downloadFile(url: string, outputPath: string): Promise<string> {
   return new Promise((resolve, reject) => {
     axios({
@@ -136,11 +171,6 @@ function joinPath(paths: string[]) {
   return path.join(...paths);
 }
 
-interface ImageItem {
-  url: string;
-  width: number;
-  height: number;
-}
 async function imagesToPdf(
   images: ImageItem[],
   outpath: string
@@ -180,6 +210,7 @@ function logger(content: string, type?: 'info' | 'error') {
 const commonApi = {
   cropImage,
   drawTrack,
+  drawTracks,
   joinPath,
   downloadImage,
   imagesToPdf,

+ 0 - 0
src/views/base/track-export/usePQueue.ts → src/hooks/p-queue.ts


+ 6 - 0
src/views/base/track-export/readme.md

@@ -5,3 +5,9 @@
 - 开启多窗口执行任务。
 - 单个窗口获取当前任务配置,获取细分任务的完整数据,执行任务。
 - 主窗口轮询任务进度。一旦结束,广播任务结束事件,关闭所有隐藏窗口。
+
+# 下载优化策略
+
+- 生成轨迹图放主进程。
+- 单个窗口开始多任务。
+- 多页答题纸轨迹图开启多任务执行。

+ 10 - 0
src/views/base/track-export/taskProgress.vue

@@ -180,6 +180,16 @@
     total.value = await window.db.getTrackTaskDetailCount({
       trackTaskId: res.id,
     });
+    if (total.value === 0) {
+      await window.db.updateTrackTaskStatus({
+        id: task.value.id,
+        status: 'FINISH',
+      });
+      Message.warning('当前无可执行任务!');
+      close();
+      return;
+    }
+
     updateProgress();
 
     // 开启导出进程

+ 44 - 33
src/views/base/track-export/useDraw.ts

@@ -182,6 +182,7 @@ export default function useDraw(winId: number) {
       if (isOnlyOrigin) {
         return true;
       }
+      addLog(`[${curStudentId}] 02-1-图片下载成功`);
 
       await parseDrawList();
       addLog(`[${curStudentId}] 03-解析绘制数据成功`);
@@ -225,32 +226,40 @@ export default function useDraw(winId: number) {
   }
 
   async function getTaskData(studentId: string) {
-    rawTask = await getSingleStudentTaskOfStudentTrack(studentId);
-    if (!rawTask) return;
+    const funcs = [
+      async () => {
+        rawTask = await getSingleStudentTaskOfStudentTrack(studentId);
+        if (!rawTask.sheetUrls) rawTask.sheetUrls = [];
+      },
+    ];
 
-    if (!rawTask.sheetUrls) rawTask.sheetUrls = [];
+    if (!isOnlyOrigin) {
+      funcs.push(async () => {
+        // 获取客观题选项信息
+        const objectiveData = await studentObjectiveConfirmData(studentId);
+        objectiveData.answers.forEach((item) => {
+          answerMap[`${item.mainNumber}_${item.subNumber}`] = {
+            answer: item.answer,
+            totalScore: item.totalScore,
+            score: item.score,
+            isRight: item.answer === item.standardAnswer,
+          };
+        });
+        recogDatas = objectiveData.sheetUrls.map((item) => item.recogData);
+      });
 
-    if (isOnlyOrigin) return;
+      funcs.push(async () => {
+        // 获取题卡数据
+        const cardRes = await getSingleStudentCardData(studentId);
+        const cardContent =
+          cardRes && cardRes.content
+            ? (JSON.parse(cardRes.content) as CardContentType)
+            : { pages: [] };
+        cardData = cardContent.pages;
+      });
+    }
 
-    // 获取客观题选项信息
-    const objectiveData = await studentObjectiveConfirmData(studentId);
-    objectiveData.answers.forEach((item) => {
-      answerMap[`${item.mainNumber}_${item.subNumber}`] = {
-        answer: item.answer,
-        totalScore: item.totalScore,
-        score: item.score,
-        isRight: item.answer === item.standardAnswer,
-      };
-    });
-    recogDatas = objectiveData.sheetUrls.map((item) => item.recogData);
-
-    // 获取题卡数据
-    const cardRes = await getSingleStudentCardData(studentId);
-    const cardContent =
-      cardRes && cardRes.content
-        ? (JSON.parse(cardRes.content) as CardContentType)
-        : { pages: [] };
-    cardData = cardContent.pages;
+    await Promise.all(funcs.map((func) => func()));
   }
 
   /**
@@ -348,19 +357,21 @@ export default function useDraw(winId: number) {
   async function drawTask(): Promise<ImageItem[]> {
     if (!trackData.length) return [];
 
-    const draw = async (item: TrackItemType, index: number) => {
+    const tasks = trackData.map((item, index) => {
       const outpath = getOutputPath('track', index);
 
-      const url = await window.api.drawTrack(
-        item.url,
-        item.drawTrackList,
-        outpath
-      );
-      return { url, width: item.width, height: item.height };
-    };
-    const tasks = trackData.map((item, index) => draw(item, index + 1));
+      return {
+        imgItem: {
+          url: item.url,
+          width: item.width,
+          height: item.height,
+        },
+        outpath,
+        drawTrackList: item.drawTrackList,
+      };
+    });
 
-    const res = await Promise.all(tasks).catch((error) => {
+    const res = await window.api.drawTracks(tasks).catch((error) => {
       console.log(error);
     });
     if (!res) {

+ 0 - 146
src/views/base/track-export/useTask.pall.ts

@@ -1,146 +0,0 @@
-import { ref } from 'vue';
-import { trackExportDetailListPage, trackExportListPage } from '@/api/task';
-import {
-  TrackExportDetailItem,
-  TrackExportDetailListFilter,
-  TrackExportDetailListParams,
-  TrackExportItem,
-  TrackExportListFilter,
-  TrackExportListPageRes,
-} from '@/api/types/task';
-import {
-  TRACK_TASK_DETAIL_STATUS,
-  TRACK_TASK_STATUS,
-} from '../../../../electron/db/enumerate';
-import { TrackTaskCreationAttributes } from '../../../../electron/db/models/trackTask';
-
-export default function useTask() {
-  const pageSize = 20;
-  const trackTaskId = ref(0);
-
-  async function createTrackTask(data: TrackTaskCreationAttributes) {
-    const res = await window.db.createTrackTask(
-      { ...data, status: TRACK_TASK_STATUS.INIT },
-      []
-    );
-    trackTaskId.value = res.id;
-  }
-  async function updateTrackTaskReady() {
-    await window.db.updateTrackTaskStatus({
-      id: trackTaskId.value,
-      status: 'READY',
-    });
-  }
-
-  async function getTrackExportList(params: TrackExportListFilter) {
-    const trackExportList: TrackExportItem[] = [];
-    const res = await trackExportListPage({
-      ...params,
-      pageNumber: 1,
-      pageSize,
-    });
-    trackExportList.push(...res.records);
-
-    if (res.pages > 1) {
-      const fetchFunc: Promise<TrackExportListPageRes>[] = [];
-      for (let i = 2; i <= res.pages; i++) {
-        fetchFunc.push(
-          trackExportListPage({
-            ...params,
-            pageNumber: i,
-            pageSize,
-          })
-        );
-      }
-
-      const fetchResult = await Promise.all(fetchFunc);
-      fetchResult.forEach((item) => {
-        trackExportList.push(...item.records);
-      });
-    }
-
-    // get details
-    const detailFetchFunc = trackExportList.map((item) =>
-      getTrackExportDetailList({
-        examId: item.examId,
-        paperNumber: item.paperNumber,
-      })
-    );
-    await Promise.all(detailFetchFunc);
-  }
-
-  async function getTrackExportDetailList(params: TrackExportDetailListFilter) {
-    const filterData = {
-      ...params,
-      pageSize,
-    };
-    const res = await createTrackTaskDetails({
-      ...filterData,
-      pageNumber: 1,
-    });
-
-    if (res.pages <= 1) return;
-
-    const fetchFunc: Promise<any>[] = [];
-    for (let i = 2; i <= res.pages; i++) {
-      fetchFunc.push(
-        createTrackTaskDetails({
-          ...filterData,
-          pageNumber: i,
-        })
-      );
-    }
-
-    await Promise.all(fetchFunc);
-  }
-
-  async function createTrackTaskDetails(params: TrackExportDetailListParams) {
-    const res = await trackExportDetailListPage(params);
-    const details = res.records
-      .filter((item) => item.sheetUrls)
-      .map((item) => {
-        return {
-          trackTaskId: trackTaskId.value,
-          studentId: item.studentId,
-          studentName: item.studentName,
-          studentCode: item.studentCode,
-          className: item.className,
-          status: TRACK_TASK_DETAIL_STATUS.INIT,
-        };
-      });
-    await window.db.createTrackTaskDetails(details);
-
-    return {
-      total: res.total,
-      pages: res.pages,
-      pageNumber: params.pageNumber,
-    };
-  }
-
-  async function createTrackTaskDetailsFromStudents(
-    datas: TrackExportDetailItem[]
-  ) {
-    const details = datas
-      .filter((item) => item.sheetUrls)
-      .map((item) => {
-        return {
-          trackTaskId: trackTaskId.value,
-          studentId: item.studentId,
-          studentName: item.studentName,
-          studentCode: item.studentCode,
-          className: item.className,
-          status: TRACK_TASK_DETAIL_STATUS.INIT,
-        };
-      });
-    await window.db.createTrackTaskDetails(details);
-  }
-
-  return {
-    trackTaskId,
-    createTrackTask,
-    updateTrackTaskReady,
-    getTrackExportList,
-    getTrackExportDetailList,
-    createTrackTaskDetailsFromStudents,
-  };
-}

+ 1 - 1
src/views/base/track-export/useTask.ts

@@ -8,12 +8,12 @@ import {
   TrackExportListFilter,
   TrackExportListPageRes,
 } from '@/api/types/task';
+import { usePQueue } from '@/hooks/p-queue';
 import {
   TRACK_TASK_DETAIL_STATUS,
   TRACK_TASK_STATUS,
 } from '../../../../electron/db/enumerate';
 import { TrackTaskCreationAttributes } from '../../../../electron/db/models/trackTask';
-import { usePQueue } from './usePQueue';
 
 export default function useTask() {
   const pageSize = 20;