From fbc58d6280a811f3c36696c530961f44c6491bb2 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期六, 17 十月 2026 14:06:39 +0800
Subject: [PATCH] refactor(mes): 重构二维码导出下载功能

---
 src/views/mes/pro/components/qr-export-task-modal.vue |   43 ++++++++++++++++++++++++++++++++++++-------
 1 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/src/views/mes/pro/components/qr-export-task-modal.vue b/src/views/mes/pro/components/qr-export-task-modal.vue
index 9330a7d..578f50c 100644
--- a/src/views/mes/pro/components/qr-export-task-modal.vue
+++ b/src/views/mes/pro/components/qr-export-task-modal.vue
@@ -2,19 +2,21 @@
   import type { QrExportTask } from '#/api/mes/pro/qrExport';
 
   import { onBeforeUnmount, onMounted, ref } from 'vue';
-  import { downloadFileFromBlobPart } from '@vben/utils';
   import { Button, message, Modal, Progress } from 'ant-design-vue';
 
   import {
     cancelQrExportTask,
-    downloadQrExportTask,
     getQrExportTask,
   } from '#/api/mes/pro/qrExport';
+  import { downloadQrExportZip, pickQrExportSaveFile } from '../qrexport/download-qr-export';
 
   const storageKey = 'mes-pro-last-qr-export-task-id';
   const visible = ref(false);
   const task = ref<QrExportTask>();
   const downloading = ref(false);
+  const downloadLoaded = ref(0);
+  const downloadTotal = ref(0);
+  let downloadController: AbortController | undefined;
   let timer: ReturnType<typeof setTimeout> | undefined;
 
   function stopPolling() {
@@ -56,15 +58,36 @@
 
   async function download() {
     if (!task.value?.downloadable || downloading.value) return;
+    const currentTask = task.value;
+    // 鏂囦欢閫夋嫨鍣ㄥ繀椤荤敱鐢ㄦ埛鐐瑰嚮鐩存帴瑙﹀彂锛屼笉鑳界瓑缃戠粶璇锋眰涔嬪悗鍐嶈皟鐢ㄣ��
+    const saveHandle = await pickQrExportSaveFile(`${currentTask.taskName}.zip`);
     downloading.value = true;
+    downloadLoaded.value = 0;
+    downloadTotal.value = currentTask.fileSize ?? 0;
+    const controller = new AbortController();
+    downloadController = controller;
     try {
-      const data = await downloadQrExportTask(task.value.id);
-      downloadFileFromBlobPart({ fileName: `${task.value.taskName}.zip`, source: data });
-      localStorage.removeItem(storageKey);
-      await refresh();
+      await downloadQrExportZip(currentTask, {
+        saveHandle,
+        signal: controller.signal,
+        onProgress(loaded, total) {
+          downloadLoaded.value = loaded;
+          downloadTotal.value = total;
+        },
+      });
+      message.success('ZIP 涓嬭浇瀹屾垚');
+    } catch (error: any) {
+      if (!controller.signal.aborted) {
+        message.error(error?.message ?? '涓嬭浇澶辫触锛岃閲嶈瘯');
+      }
     } finally {
       downloading.value = false;
+      if (downloadController === controller) downloadController = undefined;
     }
+  }
+
+  function formatSize(bytes: number) {
+    return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
   }
 
   onMounted(async () => {
@@ -81,7 +104,10 @@
       localStorage.removeItem(storageKey);
     }
   });
-  onBeforeUnmount(stopPolling);
+  onBeforeUnmount(() => {
+    stopPolling();
+    downloadController?.abort();
+  });
 
   defineExpose({ show, showLast });
 </script>
@@ -92,6 +118,9 @@
       <p>浠诲姟 #{{ task.id }} 路 {{ task.taskName }}</p>
       <p>宸茬敓鎴� {{ task.finishedCount }} / {{ task.totalCount }} 寮狅紝{{ task.statusName }}</p>
       <Progress :percent="task.progress" :status="task.status === 50 ? 'exception' : task.downloadable ? 'success' : 'active'" />
+      <p v-if="downloading" class="mt-2 text-sm">
+        姝e湪涓嬭浇 {{ formatSize(downloadLoaded) }} / {{ formatSize(downloadTotal) }}
+      </p>
       <p v-if="task.errorMsg" class="text-red-600">{{ task.errorMsg }}</p>
       <div class="mt-4 flex justify-end gap-2">
         <Button @click="refresh">鍒锋柊</Button>

--
Gitblit v1.9.3