123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- <template>
- <div class="title title_grey cl">
- <h2>图片下载中 …</h2>
- </div>
- <div class="progress-box">
- <h3>正在下载图片,请耐心等候 ~</h3>
- <div class="progress">
- <a-progress :percent="Math.round((finishedCount / totalCount) * 100)" />
- </div>
- <p>
- 已下载图片:<b>{{ finishedCount }}</b> / 错误图片:<b>{{ errorCount }}</b>
- / 全部图片:<b>{{ totalCount }}</b>
- </p>
- </div>
- </template>
- <script setup lang="ts">
- import { store } from "@/store";
- import { onMounted, ref, watch } from "vue";
- import { Modal } from "ant-design-vue";
- import { useRouter } from "vue-router";
- const router = useRouter();
- import { getStudents, countStudents, getPackages } from "@/api/api";
- import { httpApp } from "@/plugins/axiosApp";
- import mustache from "mustache";
- async function getImageDim(
- blob: Blob
- ): Promise<[width: number, height: number]> {
- return new Promise((res) => {
- const img = new Image();
- img.src = URL.createObjectURL(blob);
- img.onload = () => {
- URL.revokeObjectURL(img.src);
- // console.log(img.width);
- res([img.width, img.height]);
- };
- });
- }
- // cache images
- async function cacheImages(urls: string) {
- let allPromiseCount = 0;
- let settledPromiseCount = 0;
- const MAX_CONCURRENT = 6;
- async function sleep() {
- if (allPromiseCount - settledPromiseCount >= MAX_CONCURRENT) {
- console.log("sleep because cache images thread is full");
- await new Promise((res) => setTimeout(res, 300));
- await sleep();
- }
- }
- for (const url of urls) {
- allPromiseCount++;
- await sleep();
- // console.log(url);
- httpApp
- .get(url, {
- responseType: "blob",
- headers: {
- // 怀疑 electron 有问题,这里没生效
- "Cache-Control": "no-cache",
- },
- })
- .catch((e) => {
- console.log(e, "cache error");
- })
- .finally(() => {
- settledPromiseCount++;
- });
- }
- }
- const totalCount = ref(0);
- let finishedCount = ref(0);
- let errorCount = ref(0);
- let students = [];
- const config = store.pageInputs["/image-download"];
- onMounted(async () => {
- const storePassedToNodeJs = JSON.parse(JSON.stringify(store));
- try {
- if (config.type === "1") {
- console.log("download start ", Date.now());
- const res = await countStudents(store.env.examId, {
- upload: true,
- withSheetUrl: true,
- withScoreDetail: config.watermark,
- withGroupScoreTrack: config.watermark && config.trackMode,
- examNumberIn: config.examNumber ?? "",
- subjectCodeIn: config.subjectCode ?? "",
- });
- totalCount.value = res.data;
- for (
- let pageNumber = 0;
- pageNumber * 10 < totalCount.value;
- pageNumber++
- ) {
- const resStudents = await getStudents(
- store.env.examId,
- pageNumber + 1,
- 10,
- {
- upload: true,
- withSheetUrl: true,
- withScoreDetail: config.watermark,
- withGroupScoreTrack: config.watermark && config.trackMode === "1",
- examNumberIn: config.examNumber ?? "",
- subjectCodeIn: config.subjectCode ?? "",
- }
- );
- students = resStudents.data;
- const urls = students.reduce(
- (accumulator, stu) => accumulator.concat(stu.sheetUrls),
- []
- );
- cacheImages(urls);
- for (const student of students) {
- for (const sheetUrl of student.sheetUrls) {
- 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)
- );
- if (config.append && window.electron.existsSync(filePath)) {
- console.log(filePath + " already exists");
- // 执行到这里时,可能图片已经cache了
- urls.splice(urls.indexOf(sheetUrl), 1);
- // console.log(urls);
- continue;
- }
- const imageRes = await httpApp.get(sheetUrl, {
- responseType: "blob",
- headers: {
- "Cache-Control": "no-cache",
- },
- });
- 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()));
- await window.electron.addWatermark(
- storePassedToNodeJs,
- arrayBuffer,
- width,
- height,
- filePath,
- student,
- index + 1,
- config.trackMode,
- config.x,
- config.y
- );
- } catch (error) {
- errorCount.value += 1;
- if (config.failover) {
- throw error;
- } else {
- console.log(student, error);
- continue;
- }
- }
- }
- // 下载完一个学生
- finishedCount.value += 1;
- }
- }
- console.log("all end ", Date.now());
- } else if (config.type === "2") {
- await processPackage();
- }
- const modal = Modal.success({});
- modal.update({
- title: "图片下载完成",
- content: "完成",
- onOk: () => router.back(),
- });
- } catch (error) {
- const modal = Modal.error({});
- console.log(error);
- modal.update({
- title: "图片下载出错",
- content: error.message || error,
- onOk: () => router.back(),
- });
- }
- });
- async function processPackage() {
- const res = await getPackages(store.env.examId, true, true);
- const array = res.data;
- totalCount.value = array.length;
- const urls = array.reduce((accumulator, p) => accumulator.concat(p.urls), []);
- cacheImages(urls);
- for (let i = 0; i < array.length; i++) {
- const p = array[i];
- p.examId = store.env.examId;
- for (let i = 0; i < p.urls.length; i++) {
- try {
- const index = i + 1;
- p.index = index;
- const filePath = window.electron.join(
- config.dir,
- mustache.render(config.template, p)
- );
- if (config.append && window.electron.existsSync(filePath)) {
- console.log(filePath + " already exists");
- urls.splice(urls.indexOf(p.urls[i]), 1);
- continue;
- }
- const imageRes = await httpApp.get(p.urls[i], {
- responseType: "blob",
- });
- await window.electron.saveImage(
- JSON.parse(JSON.stringify(store)),
- await imageRes.data.arrayBuffer(),
- filePath
- );
- } catch (error) {
- errorCount.value += 1;
- if (config.failover) {
- throw error;
- } else {
- console.log(p, error);
- continue;
- }
- }
- }
- finishedCount.value += 1;
- }
- }
- </script>
|