|
@@ -24,6 +24,8 @@ import { countStudents, getPackages, getStudents } from "@/api/api";
|
|
import { httpApp } from "@/plugins/axiosApp";
|
|
import { httpApp } from "@/plugins/axiosApp";
|
|
import mustache from "mustache";
|
|
import mustache from "mustache";
|
|
|
|
|
|
|
|
+let statisticTime = 0;
|
|
|
|
+
|
|
async function getImageDim(
|
|
async function getImageDim(
|
|
blob: Blob
|
|
blob: Blob
|
|
): Promise<[width: number, height: number]> {
|
|
): Promise<[width: number, height: number]> {
|
|
@@ -80,15 +82,216 @@ let students = [];
|
|
|
|
|
|
const config = store.pageInputs["/image-download"];
|
|
const config = store.pageInputs["/image-download"];
|
|
// console.log("config::", config);
|
|
// console.log("config::", config);
|
|
|
|
+const storePassedToNodeJs = JSON.parse(JSON.stringify(store));
|
|
|
|
+const color = storePassedToNodeJs.config.watermark.color;
|
|
|
|
+const nextColor = storePassedToNodeJs.config.watermark.nextColor || "#0000ff";
|
|
|
|
+// const otherColor = storePassedToNodeJs.config.watermark.otherColor;
|
|
|
|
+const otherColor = "#ddd";
|
|
|
|
+
|
|
|
|
+const studentHandler = async (student: any, urls: any) => {
|
|
|
|
+ try {
|
|
|
|
+ let allTags = Object.values(student.tags || {})
|
|
|
|
+ .filter((x) => !!x)
|
|
|
|
+ .flat()
|
|
|
|
+ .filter((v: any) => v.userId != 0);
|
|
|
|
+ allTags.forEach((item: any) => {
|
|
|
|
+ if (
|
|
|
|
+ allTags.find((v: any) => {
|
|
|
|
+ return v.groupNumber == item.groupNumber && v.userId != item.userId;
|
|
|
|
+ })
|
|
|
|
+ ) {
|
|
|
|
+ item.hide = true;
|
|
|
|
+ } else {
|
|
|
|
+ item.hide = false;
|
|
|
|
+ }
|
|
|
|
+ if (
|
|
|
|
+ allTags.find((v: any) => {
|
|
|
|
+ return (
|
|
|
|
+ v.groupNumber == item.groupNumber &&
|
|
|
|
+ v.userRole &&
|
|
|
|
+ v.userRole !== "MARKER" &&
|
|
|
|
+ (item.userRole === "MARKER" || !item.userRole)
|
|
|
|
+ );
|
|
|
|
+ })
|
|
|
|
+ ) {
|
|
|
|
+ item.forceHide = true;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // allTags.sort((a: any, b: any) => {
|
|
|
|
+ // return a.userId - b.userId;
|
|
|
|
+ // });
|
|
|
|
+ let colorMap: any = {};
|
|
|
|
+ let headerColorMap: any = {};
|
|
|
|
+ for (let i = 0; i < allTags.length; i++) {
|
|
|
|
+ const tag: any = allTags[i];
|
|
|
|
+ const { groupNumber } = tag;
|
|
|
|
+ if (tag.userRole && tag.userRole !== "MARKER") {
|
|
|
|
+ if (!headerColorMap[groupNumber + ""]) {
|
|
|
|
+ headerColorMap[groupNumber + ""] = {};
|
|
|
|
+ headerColorMap[groupNumber + ""][tag.userId + ""] = "#008000";
|
|
|
|
+ continue;
|
|
|
|
+ } else {
|
|
|
|
+ headerColorMap[groupNumber + ""][tag.userId + ""] = "#008000";
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (!colorMap[groupNumber + ""]) {
|
|
|
|
+ colorMap[groupNumber + ""] = {};
|
|
|
|
+ colorMap[groupNumber + ""][tag.userId + ""] = color;
|
|
|
|
+ } else {
|
|
|
|
+ let targetGroupObjKeys = Object.keys(colorMap[groupNumber + ""]);
|
|
|
|
+ const len = targetGroupObjKeys.length;
|
|
|
|
+ if (len == 1) {
|
|
|
|
+ if (!targetGroupObjKeys.includes(tag.userId + "")) {
|
|
|
|
+ colorMap[groupNumber + ""][tag.userId + ""] = nextColor;
|
|
|
|
+ } else {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ } else if (len > 1) {
|
|
|
|
+ if (!targetGroupObjKeys.includes(tag.userId + "")) {
|
|
|
|
+ colorMap[groupNumber + ""][tag.userId + ""] = otherColor;
|
|
|
|
+ } else {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // let c = len === 1 ? nextColor : otherColor;
|
|
|
|
+ // colorMap[groupNumber + ""][tag.userId + ""] = c;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // console.log("allTags:", allTags);
|
|
|
|
+ // console.log("colorMap:", colorMap);
|
|
|
|
+ let resultImgList: any[] = [];
|
|
|
|
+ let sheetUrlsLength = (student.sheetUrls || []).length;
|
|
|
|
+ for (const sheetUrl of student.sheetUrls) {
|
|
|
|
+ if (stopSignal) return;
|
|
|
|
+ try {
|
|
|
|
+ const index = student.sheetUrls.indexOf(sheetUrl);
|
|
|
|
+ student.index = index + 1;
|
|
|
|
+ student.examId = store.env.examId;
|
|
|
|
+ // const filePath = window.electron.join(
|
|
|
|
+ // config.dir,
|
|
|
|
+ // mustache.render(config.template, student)
|
|
|
|
+ // );
|
|
|
|
+ const filePath = [
|
|
|
|
+ config.dir,
|
|
|
|
+ mustache.render(config.template, student),
|
|
|
|
+ ];
|
|
|
|
+ if (config.append && window.electron.existsImage(filePath)) {
|
|
|
|
+ console.log(filePath + " already exists");
|
|
|
|
+ // 执行到这里时,可能图片已经cache了
|
|
|
|
+ urls.splice(urls.indexOf(sheetUrl), 1);
|
|
|
|
+ // console.log(urls);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ console.debug("start ", sheetUrl);
|
|
|
|
+ const imageDownloadStartTime = Date.now();
|
|
|
|
+ const imageRes = await httpApp.get(sheetUrl, {
|
|
|
|
+ responseType: "blob",
|
|
|
|
+ headers: {
|
|
|
|
+ "Cache-Control": "no-cache",
|
|
|
|
+ },
|
|
|
|
+ });
|
|
|
|
+ // totalImageDownloadTime += Date.now() - imageDownloadStartTime;
|
|
|
|
+
|
|
|
|
+ const [width, height] = await getImageDim(imageRes.data);
|
|
|
|
+ const arrayBuffer = await imageRes.data.arrayBuffer();
|
|
|
|
+
|
|
|
|
+ // console.log(imageRes.data);
|
|
|
|
+ // console.log(await imageRes.data.arrayBuffer());
|
|
|
|
+ // console.log(new Uint8Array(await imageRes.data.arrayBuffer()));
|
|
|
|
+ let onlyUsePdf = config.pdf == "2";
|
|
|
|
+ // console.log("colorMap:", colorMap);
|
|
|
|
+ let fileLocation = await window.electron.addWatermark(
|
|
|
|
+ storePassedToNodeJs,
|
|
|
|
+ arrayBuffer,
|
|
|
|
+ width,
|
|
|
|
+ height,
|
|
|
|
+ filePath,
|
|
|
|
+ student,
|
|
|
|
+ index + 1,
|
|
|
|
+ config.trackMode,
|
|
|
|
+ config.x,
|
|
|
|
+ config.y,
|
|
|
|
+ colorMap,
|
|
|
|
+ headerColorMap,
|
|
|
|
+ onlyUsePdf
|
|
|
|
+ );
|
|
|
|
+ resultImgList.push(fileLocation);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ window.electron.errorLogger(student, sheetUrl, error);
|
|
|
|
+ errorCount.value += 1;
|
|
|
|
+ if (config.failover) {
|
|
|
|
+ throw error;
|
|
|
|
+ } else {
|
|
|
|
+ console.log(student, error);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 下载完一个学生
|
|
|
|
+ finishedCount.value += 1;
|
|
|
|
+ if (finishedCount.value == totalCount.value) {
|
|
|
|
+ console.log(
|
|
|
|
+ `${finishedCount.value}个学生的图片下载完成,总耗时${
|
|
|
|
+ Date.now() - statisticTime
|
|
|
|
+ }ms`
|
|
|
|
+ );
|
|
|
|
+ const modal = Modal.success({});
|
|
|
|
+ modal.update({
|
|
|
|
+ title: "图片下载完成",
|
|
|
|
+ content: "完成",
|
|
|
|
+ onOk: () => router.back(),
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ if (
|
|
|
|
+ resultImgList.length === sheetUrlsLength &&
|
|
|
|
+ (config.pdf == "2" || config.pdf == "3")
|
|
|
|
+ ) {
|
|
|
|
+ let imgName = "";
|
|
|
|
+ if (config.template.lastIndexOf("/") > -1) {
|
|
|
|
+ imgName = config.template.slice(config.template.lastIndexOf("/") + 1);
|
|
|
|
+ } else {
|
|
|
|
+ imgName = config.template;
|
|
|
|
+ }
|
|
|
|
+ let n = imgName.slice(0, imgName.lastIndexOf("."));
|
|
|
|
+ let pdfName = n
|
|
|
|
+ .match(/{{.*?}}/g)
|
|
|
|
+ ?.map((item: any) => {
|
|
|
|
+ return item.replace("{{", "").replace("}}", "");
|
|
|
|
+ })
|
|
|
|
+ .filter((v) => !!v)
|
|
|
|
+ .map((item: any) => {
|
|
|
|
+ return item === "index" ? "" : student[item];
|
|
|
|
+ })
|
|
|
|
+ .filter((v) => !!v)
|
|
|
|
+ .join("-");
|
|
|
|
+
|
|
|
|
+ window.electron.saveToPDF(resultImgList, [
|
|
|
|
+ config.dir,
|
|
|
|
+ `/pdfs/${store.env.examId}/${student.subjectCode}/${pdfName}.pdf`,
|
|
|
|
+ ]);
|
|
|
|
+ }
|
|
|
|
+ } catch (error) {
|
|
|
|
+ const modal = Modal.error({});
|
|
|
|
+ console.log(error);
|
|
|
|
+ modal.update({
|
|
|
|
+ title: "考生图片下载出错",
|
|
|
|
+ content: error.message || error,
|
|
|
|
+ onOk: () => router.back(),
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
- const storePassedToNodeJs = JSON.parse(JSON.stringify(store));
|
|
|
|
- const color = storePassedToNodeJs.config.watermark.color;
|
|
|
|
- const nextColor = storePassedToNodeJs.config.watermark.nextColor || "#0000ff";
|
|
|
|
- // const otherColor = storePassedToNodeJs.config.watermark.otherColor;
|
|
|
|
- const otherColor = "#ddd";
|
|
|
|
|
|
+ // const storePassedToNodeJs = JSON.parse(JSON.stringify(store));
|
|
|
|
+ // const color = storePassedToNodeJs.config.watermark.color;
|
|
|
|
+ // const nextColor = storePassedToNodeJs.config.watermark.nextColor || "#0000ff";
|
|
|
|
+ // // const otherColor = storePassedToNodeJs.config.watermark.otherColor;
|
|
|
|
+ // const otherColor = "#ddd";
|
|
try {
|
|
try {
|
|
if (config.type === "1") {
|
|
if (config.type === "1") {
|
|
- console.log("download start ", Date.now());
|
|
|
|
|
|
+ // console.log("download start ", Date.now());
|
|
const res = await countStudents(store.env.examId, {
|
|
const res = await countStudents(store.env.examId, {
|
|
upload: true,
|
|
upload: true,
|
|
withSheetUrl: true,
|
|
withSheetUrl: true,
|
|
@@ -99,7 +302,9 @@ onMounted(async () => {
|
|
subjectCodeIn: config.subjectCode ?? "",
|
|
subjectCodeIn: config.subjectCode ?? "",
|
|
});
|
|
});
|
|
totalCount.value = res.data;
|
|
totalCount.value = res.data;
|
|
- let totalImageDownloadTime = 0;
|
|
|
|
|
|
+ console.log(`一共${totalCount.value}个考生`);
|
|
|
|
+ // let totalImageDownloadTime = 0;
|
|
|
|
+ statisticTime = Date.now();
|
|
for (
|
|
for (
|
|
let pageNumber = 0;
|
|
let pageNumber = 0;
|
|
pageNumber * 10 < totalCount.value;
|
|
pageNumber * 10 < totalCount.value;
|
|
@@ -128,198 +333,23 @@ onMounted(async () => {
|
|
);
|
|
);
|
|
// cacheImages(urls);
|
|
// cacheImages(urls);
|
|
|
|
|
|
- for (const student of students) {
|
|
|
|
- let allTags = Object.values(student.tags || {})
|
|
|
|
- .filter((x) => !!x)
|
|
|
|
- .flat()
|
|
|
|
- .filter((v: any) => v.userId != 0);
|
|
|
|
- allTags.forEach((item: any) => {
|
|
|
|
- if (
|
|
|
|
- allTags.find((v: any) => {
|
|
|
|
- return (
|
|
|
|
- v.groupNumber == item.groupNumber && v.userId != item.userId
|
|
|
|
- );
|
|
|
|
- })
|
|
|
|
- ) {
|
|
|
|
- item.hide = true;
|
|
|
|
- } else {
|
|
|
|
- item.hide = false;
|
|
|
|
- }
|
|
|
|
- if (
|
|
|
|
- allTags.find((v: any) => {
|
|
|
|
- return (
|
|
|
|
- v.groupNumber == item.groupNumber &&
|
|
|
|
- v.userRole &&
|
|
|
|
- v.userRole !== "MARKER" &&
|
|
|
|
- (item.userRole === "MARKER" || !item.userRole)
|
|
|
|
- );
|
|
|
|
- })
|
|
|
|
- ) {
|
|
|
|
- item.forceHide = true;
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- // allTags.sort((a: any, b: any) => {
|
|
|
|
- // return a.userId - b.userId;
|
|
|
|
- // });
|
|
|
|
- let colorMap: any = {};
|
|
|
|
- let headerColorMap: any = {};
|
|
|
|
- for (let i = 0; i < allTags.length; i++) {
|
|
|
|
- const tag: any = allTags[i];
|
|
|
|
- const { groupNumber } = tag;
|
|
|
|
- if (tag.userRole && tag.userRole !== "MARKER") {
|
|
|
|
- if (!headerColorMap[groupNumber + ""]) {
|
|
|
|
- headerColorMap[groupNumber + ""] = {};
|
|
|
|
- headerColorMap[groupNumber + ""][tag.userId + ""] = "#008000";
|
|
|
|
- continue;
|
|
|
|
- } else {
|
|
|
|
- headerColorMap[groupNumber + ""][tag.userId + ""] = "#008000";
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (!colorMap[groupNumber + ""]) {
|
|
|
|
- colorMap[groupNumber + ""] = {};
|
|
|
|
- colorMap[groupNumber + ""][tag.userId + ""] = color;
|
|
|
|
- } else {
|
|
|
|
- let targetGroupObjKeys = Object.keys(colorMap[groupNumber + ""]);
|
|
|
|
- const len = targetGroupObjKeys.length;
|
|
|
|
- if (len == 1) {
|
|
|
|
- if (!targetGroupObjKeys.includes(tag.userId + "")) {
|
|
|
|
- colorMap[groupNumber + ""][tag.userId + ""] = nextColor;
|
|
|
|
- } else {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- } else if (len > 1) {
|
|
|
|
- if (!targetGroupObjKeys.includes(tag.userId + "")) {
|
|
|
|
- colorMap[groupNumber + ""][tag.userId + ""] = otherColor;
|
|
|
|
- } else {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // let c = len === 1 ? nextColor : otherColor;
|
|
|
|
- // colorMap[groupNumber + ""][tag.userId + ""] = c;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- console.log("allTags:", allTags);
|
|
|
|
- // console.log("colorMap:", colorMap);
|
|
|
|
- let resultImgList: any[] = [];
|
|
|
|
- let sheetUrlsLength = (student.sheetUrls || []).length;
|
|
|
|
- for (const sheetUrl of student.sheetUrls) {
|
|
|
|
- if (stopSignal) return;
|
|
|
|
- try {
|
|
|
|
- const index = student.sheetUrls.indexOf(sheetUrl);
|
|
|
|
- student.index = index + 1;
|
|
|
|
- student.examId = store.env.examId;
|
|
|
|
- // const filePath = window.electron.join(
|
|
|
|
- // config.dir,
|
|
|
|
- // mustache.render(config.template, student)
|
|
|
|
- // );
|
|
|
|
- const filePath = [
|
|
|
|
- config.dir,
|
|
|
|
- mustache.render(config.template, student),
|
|
|
|
- ];
|
|
|
|
- if (config.append && window.electron.existsImage(filePath)) {
|
|
|
|
- console.log(filePath + " already exists");
|
|
|
|
- // 执行到这里时,可能图片已经cache了
|
|
|
|
- urls.splice(urls.indexOf(sheetUrl), 1);
|
|
|
|
- // console.log(urls);
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- console.debug("start ", sheetUrl);
|
|
|
|
- const imageDownloadStartTime = Date.now();
|
|
|
|
- const imageRes = await httpApp.get(sheetUrl, {
|
|
|
|
- responseType: "blob",
|
|
|
|
- headers: {
|
|
|
|
- "Cache-Control": "no-cache",
|
|
|
|
- },
|
|
|
|
- });
|
|
|
|
- totalImageDownloadTime += Date.now() - imageDownloadStartTime;
|
|
|
|
-
|
|
|
|
- const [width, height] = await getImageDim(imageRes.data);
|
|
|
|
- const arrayBuffer = await imageRes.data.arrayBuffer();
|
|
|
|
|
|
+ // for (const student of students) {
|
|
|
|
|
|
- // console.log(imageRes.data);
|
|
|
|
- // console.log(await imageRes.data.arrayBuffer());
|
|
|
|
- // console.log(new Uint8Array(await imageRes.data.arrayBuffer()));
|
|
|
|
- let onlyUsePdf = config.pdf == "2";
|
|
|
|
- console.log("colorMap:", colorMap);
|
|
|
|
- let fileLocation = await window.electron.addWatermark(
|
|
|
|
- storePassedToNodeJs,
|
|
|
|
- arrayBuffer,
|
|
|
|
- width,
|
|
|
|
- height,
|
|
|
|
- filePath,
|
|
|
|
- student,
|
|
|
|
- index + 1,
|
|
|
|
- config.trackMode,
|
|
|
|
- config.x,
|
|
|
|
- config.y,
|
|
|
|
- colorMap,
|
|
|
|
- headerColorMap,
|
|
|
|
- onlyUsePdf
|
|
|
|
- );
|
|
|
|
- resultImgList.push(fileLocation);
|
|
|
|
- } catch (error) {
|
|
|
|
- window.electron.errorLogger(student, sheetUrl, error);
|
|
|
|
- errorCount.value += 1;
|
|
|
|
- if (config.failover) {
|
|
|
|
- throw error;
|
|
|
|
- } else {
|
|
|
|
- console.log(student, error);
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // 下载完一个学生
|
|
|
|
- finishedCount.value += 1;
|
|
|
|
- if (
|
|
|
|
- resultImgList.length === sheetUrlsLength &&
|
|
|
|
- (config.pdf == "2" || config.pdf == "3")
|
|
|
|
- ) {
|
|
|
|
- let imgName = "";
|
|
|
|
- if (config.template.lastIndexOf("/") > -1) {
|
|
|
|
- imgName = config.template.slice(
|
|
|
|
- config.template.lastIndexOf("/") + 1
|
|
|
|
- );
|
|
|
|
- } else {
|
|
|
|
- imgName = config.template;
|
|
|
|
- }
|
|
|
|
- let n = imgName.slice(0, imgName.lastIndexOf("."));
|
|
|
|
- let pdfName = n
|
|
|
|
- .match(/{{.*?}}/g)
|
|
|
|
- ?.map((item: any) => {
|
|
|
|
- return item.replace("{{", "").replace("}}", "");
|
|
|
|
- })
|
|
|
|
- .filter((v) => !!v)
|
|
|
|
- .map((item: any) => {
|
|
|
|
- return item === "index" ? "" : student[item];
|
|
|
|
- })
|
|
|
|
- .filter((v) => !!v)
|
|
|
|
- .join("-");
|
|
|
|
-
|
|
|
|
- window.electron.saveToPDF(resultImgList, [
|
|
|
|
- config.dir,
|
|
|
|
- `/pdfs/${store.env.examId}/${student.subjectCode}/${pdfName}.pdf`,
|
|
|
|
- ]);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ // }
|
|
|
|
+ students.forEach((student: any) => {
|
|
|
|
+ studentHandler(student, urls);
|
|
|
|
+ });
|
|
}
|
|
}
|
|
- console.log(
|
|
|
|
- "all end at ",
|
|
|
|
- Date.now(),
|
|
|
|
- " totalImageDownloadTime: ",
|
|
|
|
- totalImageDownloadTime
|
|
|
|
- );
|
|
|
|
} else if (config.type === "2") {
|
|
} else if (config.type === "2") {
|
|
await processPackage();
|
|
await processPackage();
|
|
}
|
|
}
|
|
|
|
|
|
- const modal = Modal.success({});
|
|
|
|
- modal.update({
|
|
|
|
- title: "图片下载完成",
|
|
|
|
- content: "完成",
|
|
|
|
- onOk: () => router.back(),
|
|
|
|
- });
|
|
|
|
|
|
+ // const modal = Modal.success({});
|
|
|
|
+ // modal.update({
|
|
|
|
+ // title: "图片下载完成",
|
|
|
|
+ // content: "完成",
|
|
|
|
+ // onOk: () => router.back(),
|
|
|
|
+ // });
|
|
} catch (error) {
|
|
} catch (error) {
|
|
const modal = Modal.error({});
|
|
const modal = Modal.error({});
|
|
console.log(error);
|
|
console.log(error);
|
|
@@ -374,6 +404,14 @@ async function processPackage() {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
finishedCount.value += 1;
|
|
finishedCount.value += 1;
|
|
|
|
+ if (finishedCount.value == totalCount.value) {
|
|
|
|
+ const modal = Modal.success({});
|
|
|
|
+ modal.update({
|
|
|
|
+ title: "图片下载完成",
|
|
|
|
+ content: "完成",
|
|
|
|
+ onOk: () => router.back(),
|
|
|
|
+ });
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|