刘洋 11 сар өмнө
parent
commit
8e2a2022a1

+ 105 - 30
src/features/ImageDownload/ImageDownload.vue

@@ -8,8 +8,10 @@
       <a-progress :percent="Math.round((finishedCount / totalCount) * 100)" />
     </div>
     <p>
-      已下载图片:<b>{{ finishedCount }}</b> / 错误图片:<b>{{ errorCount }}</b>
-      / 全部图片:<b>{{ totalCount }}</b>
+      已下载图片考生数:<b>{{ finishedCount }}</b> / 错误图片数:<b>{{
+        errorCount
+      }}</b>
+      / 全部考生数:<b>{{ totalCount }}</b>
     </p>
   </div>
 </template>
@@ -35,6 +37,7 @@ function millisecondsToHMS(milliseconds: number) {
     "秒"
   );
 }
+let requestStack: any = [];
 let stopSignal = false;
 let statisticTime = 0;
 let downloadFailStatus = ref(false);
@@ -111,10 +114,7 @@ const nextColor = storePassedToNodeJs.config.watermark.nextColor || "#0000ff";
 // const otherColor = storePassedToNodeJs.config.watermark.otherColor;
 const otherColor = "#ddd";
 
-const studentHandler = async (student: any, urls: any) => {
-  if (downloadFailStatus.value || stopSignal) {
-    return;
-  }
+const studentHandler = async (student: any, obj: any) => {
   try {
     let allTags = Object.values(student.tags || {})
       .filter((x) => !!x)
@@ -190,7 +190,11 @@ const studentHandler = async (student: any, urls: any) => {
     let resultImgList: any[] = [];
     let sheetUrlsLength = (student.sheetUrls || []).length;
     for (const sheetUrl of student.sheetUrls) {
-      if (stopSignal || downloadFailStatus.value) return;
+      if (stopSignal) {
+        obj.curTasksLength = -1;
+        obj.id = student.id;
+        return;
+      }
       try {
         const index = student.sheetUrls.indexOf(sheetUrl);
         student.index = index + 1;
@@ -204,13 +208,13 @@ const studentHandler = async (student: any, urls: any) => {
           mustache.render(config.template, student),
         ];
         if (config.append && window.electron.existsImage(filePath)) {
-          console.log(filePath + " already exists");
+          // console.log(filePath + " already exists");
           // 执行到这里时,可能图片已经cache了
-          urls.splice(urls.indexOf(sheetUrl), 1);
+          // urls.splice(urls.indexOf(sheetUrl), 1);
           // console.log(urls);
           continue;
         }
-        console.debug("start ", sheetUrl);
+        // console.debug("start ", sheetUrl);
         const imageDownloadStartTime = Date.now();
         const imageRes = await httpApp.get(sheetUrl, {
           responseType: "blob",
@@ -251,21 +255,16 @@ const studentHandler = async (student: any, urls: any) => {
           downloadFailStatus.value = true;
           throw error;
         } else {
-          console.log(student, error);
+          console.log(
+            `某张图片${sheetUrl}下载出错,但是配置为“不终止继续下载操作”,学生信息:`,
+            student,
+            error
+          );
           continue;
         }
       }
     }
-    // 下载完一个学生
-    finishedCount.value += 1;
-    if (finishedCount.value == totalCount.value) {
-      console.log(
-        `${finishedCount.value}个学生的图片下载完成,总耗时${
-          Date.now() - statisticTime
-        }ms`
-      );
-      openSuccessDialog();
-    }
+
     if (
       resultImgList.length === sheetUrlsLength &&
       (config.pdf == "2" || config.pdf == "3")
@@ -294,17 +293,91 @@ const studentHandler = async (student: any, urls: any) => {
         `/pdfs/${store.env.examId}/${student.subjectCode}/${pdfName}.pdf`,
       ]);
     }
+
+    // 下载完一个学生
+    obj.curTasksLength--;
+    obj.id = student.id;
+    finishedCount.value += 1;
+    if (finishedCount.value == totalCount.value) {
+      console.log(
+        `${finishedCount.value}个学生的图片下载完成,总耗时${
+          Date.now() - statisticTime
+        }ms`
+      );
+      openSuccessDialog();
+    }
   } catch (error: any) {
+    obj.curTasksLength--;
+    obj.id = student.id;
     const modal = Modal.error({});
-    console.log(error);
+    console.log(
+      "studentHandler方法执行某个学生数据出错,该学生信息:",
+      student,
+      error
+    );
     modal.update({
       title: "考生图片下载出错",
       content: error.message || error,
       onOk: () => router.back(),
     });
+    if (config.failover) {
+      downloadFailStatus.value = true;
+    }
   }
 };
 
+//10个学生的任务一起执行,但是做一下限制,这10个学生的所有图片执行完了,才继续请求下一波的10个学生,防止服务器的吞吐量不行,进入并发队列地狱,导致图片请求超时
+const doneTenStudents = () => {
+  let record = { curTasksLength: requestStack.length, id: "" };
+  let recordManager = new Proxy(record, {
+    get: function (obj: any, prop) {
+      return obj[prop];
+    },
+    set: function (obj, prop, value) {
+      if (prop === "id") {
+        let index = requestStack.findIndex((stu: any) => stu.id == value);
+        requestStack.splice(index, 1);
+      }
+      obj[prop] = value;
+      return true;
+    },
+  });
+
+  let timer: any = null;
+  const cleanTimer = () => {
+    if (timer) {
+      clearTimeout(timer);
+      timer = null;
+    }
+  };
+
+  requestStack.forEach((student: any) => {
+    studentHandler(student, recordManager);
+  });
+  return new Promise((rs, rj) => {
+    const func = (rs: any) => {
+      if (recordManager.curTasksLength <= 0) {
+        if (requestStack.length > 0) {
+          let cloneCurRequestStack = JSON.stringify(requestStack);
+          console.warn(
+            `这一轮的10个学生中,居然还有某些学生任务未完成!,按道理这应该不可能发生:`,
+            cloneCurRequestStack
+          );
+        }
+        //等于-1时,说明离开页面了,需要停止任务。
+        cleanTimer();
+        rs();
+      } else {
+        cleanTimer();
+        timer = setTimeout(() => {
+          func(rs);
+        }, 100);
+      }
+    };
+    func(rs);
+  });
+};
+
 onMounted(async () => {
   downloadFailStatus.value = false;
   // const storePassedToNodeJs = JSON.parse(JSON.stringify(store));
@@ -357,18 +430,20 @@ onMounted(async () => {
         );
         students = resStudents.data;
 
-        const urls = students.reduce(
-          (accumulator, stu) => accumulator.concat(stu.sheetUrls),
-          []
-        );
+        // const urls = students.reduce(
+        //   (accumulator, stu) => accumulator.concat(stu.sheetUrls),
+        //   []
+        // );
         // cacheImages(urls);
 
         // for (const student of students) {
 
         // }
-        students.forEach((student: any) => {
-          studentHandler(student, urls);
-        });
+
+        for (const student of students) {
+          requestStack.push(student);
+        }
+        await doneTenStudents();
       }
     } else if (config.type === "2") {
       await processPackage();
@@ -382,7 +457,7 @@ onMounted(async () => {
     // });
   } catch (error: any) {
     const modal = Modal.error({});
-    console.log(error);
+    console.log("图片下载出错", error);
     modal.update({
       title: "图片下载出错",
       content: error?.message || error,

+ 1 - 1
src/plugins/axiosApp.ts

@@ -9,7 +9,7 @@ import { store } from "@/store";
 
 const config = {
   // baseURL: store.env.server || "",
-  timeout: 1 * 60 * 1000, // Timeout
+  timeout: 2 * 60 * 1000, // Timeout
   withCredentials: true, // Check cross-site Access-Control
 };