From 12250a63a8f65a37451fd49392a3cc90facbceaa Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 19 十月 2026 17:31:29 +0800
Subject: [PATCH] feat(bagCode): 添加袋码批量生成后台任务支持

---
 src/views/mes/pro/bagCode/modules/raw-generate-form.vue |  101 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 93 insertions(+), 8 deletions(-)

diff --git a/src/views/mes/pro/bagCode/modules/raw-generate-form.vue b/src/views/mes/pro/bagCode/modules/raw-generate-form.vue
index 85c8d2a..e4e4817 100644
--- a/src/views/mes/pro/bagCode/modules/raw-generate-form.vue
+++ b/src/views/mes/pro/bagCode/modules/raw-generate-form.vue
@@ -1,19 +1,30 @@
 <script lang="ts" setup>
   import type { VbenFormSchema } from "#/adapter/form";
 
-  import { markRaw } from "vue";
+  import { markRaw, ref } from "vue";
 
   import { useVbenModal } from "@vben/common-ui";
 
-  import { message } from "ant-design-vue";
+  import { Button, message, Progress } from "ant-design-vue";
 
   import { useVbenForm } from "#/adapter/form";
   import { generateRawBagCodes } from "#/api/mes/pro/bagCode";
   import { MdmItemSelect } from "#/views/basicData/mdm/components";
 
+  import { isFinalTaskStatus, useGenerateTask } from "./use-generate-task";
+
   defineOptions({ name: "MesProBagCodeRawGenerateForm" });
 
   const emit = defineEmits(["success"]);
+
+  /** 骞傜瓑閿細鎵撳紑寮圭獥鏃剁敓鎴愶紝缃戠粶閲嶈瘯澶嶇敤锛涘け璐ュ悗閲嶆柊鐢熸垚 */
+  const requestId = ref("");
+
+  function newRequestId() {
+    return `${Date.now()}-${Math.random().toString(36).slice(2)}-${Math.random()
+      .toString(36)
+      .slice(2)}`;
+  }
 
   const schema: VbenFormSchema[] = [
     {
@@ -64,23 +75,47 @@
     async onConfirm() {
       const { valid } = await formApi.validate();
       if (!valid) return;
+      if (task.value && !isFinalTaskStatus(task.value.status)) return;
       modalApi.lock();
+      let asyncStarted = false;
       try {
         const values = await formApi.getValues();
         const result = await generateRawBagCodes({
           itemId: values.itemId,
           count: values.count,
           remark: values.remark,
+          requestId: requestId.value,
         });
+        if (result.async && result.taskId) {
+          asyncStarted = true;
+          modalApi.unlock();
+          // 澶ф壒閲忓凡杞悗鍙帮細淇濇寔寮圭獥鎵撳紑锛屽睍绀鸿繘搴﹀苟杞
+          startGenerateTask({
+            id: result.taskId,
+            status: 10,
+            statusName: "鎺掗槦涓�",
+            progress: 0,
+            totalCount: result.totalCount,
+            finishedCount: 0,
+            palletCount: result.palletCount,
+            uuid: result.uuid,
+          });
+          return;
+        }
         message.success(`宸叉垚鍔熺敓鎴� ${result.totalCount} 鏉″師濮嬭鐮乣);
         emit("success");
         await modalApi.close();
       } finally {
-        modalApi.unlock();
+        if (!asyncStarted) modalApi.unlock();
       }
     },
     async onOpenChange(isOpen: boolean) {
-      if (!isOpen) return;
+      if (!isOpen) {
+        stopGenerateTaskPolling();
+        return;
+      }
+      resetGenerateTask();
+      requestId.value = newRequestId();
       await formApi.setValues({
         itemId: undefined,
         count: undefined,
@@ -88,13 +123,63 @@
       });
     },
   });
+
+  const {
+    task,
+    canceling: generateTaskCanceling,
+    cancel: cancelGenerateTask,
+    reset: resetGenerateTask,
+    stopPolling: stopGenerateTaskPolling,
+    start: startGenerateTask,
+  } = useGenerateTask(modalApi, {
+    onSuccess: () => emit("success"),
+    onFailed: () => {
+      // 澶辫触鍚庢崲鏂扮殑骞傜瓑閿紝鍏佽鐢ㄦ埛鐩存帴閲嶆柊鎻愪氦
+      requestId.value = newRequestId();
+    },
+  });
 </script>
 
 <template>
   <Modal title="鐢熸垚鍘熷琚嬬爜" class="w-2/5">
-    <Form class="mx-4" />
-    <div class="mx-4 mb-2 rounded bg-gray-50 px-3 py-2 text-sm text-gray-500">
-      鍘熷琚嬬爜浠呴渶閫夋嫨鍝佺骞惰緭鍏ユ暟閲忥紝涓嶆崲绠楄閲忓崟浣嶇被鍨嬨�佷笉鐢熸垚鎵樼洏锛涘悗缁彲姝e父褰曞叆鎵规鎴栫粦瀹氭墭鐩�
-    </div>
+    <template v-if="task">
+      <div class="mx-4 mb-2">
+        <p class="mb-1 text-sm">
+          浠诲姟 #{{ task.id }} 路 {{ task.statusName }}
+        </p>
+        <p class="mb-2 text-sm text-gray-500">
+          宸茬敓鎴� {{ task.finishedCount ?? 0 }} / {{ task.totalCount ?? 0 }} 鏉�
+        </p>
+        <Progress
+          :percent="task.progress ?? 0"
+          :status="
+            task.status === 50
+              ? 'exception'
+              : task.status === 30
+                ? 'success'
+                : 'active'
+          "
+        />
+        <p v-if="task.errorMsg" class="mt-2 text-sm text-red-500">
+          {{ task.errorMsg }}
+        </p>
+        <div class="mt-4 flex justify-end">
+          <Button
+            danger
+            size="small"
+            :loading="generateTaskCanceling"
+            @click="cancelGenerateTask"
+          >
+            鍙栨秷鐢熸垚
+          </Button>
+        </div>
+      </div>
+    </template>
+    <template v-else>
+      <Form class="mx-4" />
+      <div class="mx-4 mb-2 rounded bg-gray-50 px-3 py-2 text-sm text-gray-500">
+        鍘熷琚嬬爜浠呴渶閫夋嫨鍝佺骞惰緭鍏ユ暟閲忥紝涓嶆崲绠楄閲忓崟浣嶇被鍨嬨�佷笉鐢熸垚鎵樼洏锛涘悗缁彲姝e父褰曞叆鎵规鎴栫粦瀹氭墭鐩�
+      </div>
+    </template>
   </Modal>
 </template>

--
Gitblit v1.9.3