From fdd158306bf6dc3584f5110a385323f4a8dfb463 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 02 九月 2026 14:25:10 +0800
Subject: [PATCH] feat(wms): 重构仓库管理系统并优化图表显示

---
 src/views/mes/qc/batchtrace/modules/trace-detail.vue |  148 ++++++++++++++++++++++++------------------------
 1 files changed, 74 insertions(+), 74 deletions(-)

diff --git a/src/views/mes/qc/batchtrace/modules/trace-detail.vue b/src/views/mes/qc/batchtrace/modules/trace-detail.vue
index 8d01d5b..b26d2ff 100644
--- a/src/views/mes/qc/batchtrace/modules/trace-detail.vue
+++ b/src/views/mes/qc/batchtrace/modules/trace-detail.vue
@@ -1,34 +1,29 @@
 <script lang="ts" setup>
-import type { MesWmBatchApi } from '#/api/mes/wm/batch';
+import type { MesTraceBatchApi } from '#/api/mes/trace/batch';
 
-import { ref } from 'vue';
+import { computed, ref } from 'vue';
 
 import { useVbenModal } from '@vben/common-ui';
 
-import { Tabs, Tooltip } from 'ant-design-vue';
+import { Descriptions, Spin, Tabs, Tag, message } from 'ant-design-vue';
 
-import { useDescription } from '#/components/description';
+import { getBatchTraceDetail } from '#/api/mes/trace/batch';
 
-import { useDetailSchema } from '../data';
-import ProcessTraceList from './process-trace-list.vue';
-import PurchaseSourceList from './purchase-source-list.vue';
-import SalesTargetList from './sales-target-list.vue';
-import TraceList from './trace-list.vue';
+import TraceDecision from './TraceDecision.vue';
+import TraceGraph from './TraceGraph.vue';
+import TraceStageOverview from './TraceStageOverview.vue';
+import TraceTimeline from './TraceTimeline.vue';
 
-const detailData = ref<MesWmBatchApi.Batch>(); // 褰撳墠鎵规璇︽儏
-const subTabsName = ref<
-  | 'backward'
-  | 'forward'
-  | 'purchase'
-  | 'sales'
-  | 'process'
->('forward'); // 褰撳墠婵�娲荤殑杩芥函椤电
-
-const [Descriptions] = useDescription({
-  bordered: true,
-  column: 3,
-  schema: useDetailSchema(),
+const detailData = ref<MesTraceBatchApi.Detail>();
+const loading = ref(false);
+const activeTab = ref('overview');
+const formatDate = (value?: string) => value ? new Date(value).toLocaleString() : '鏈褰�';
+const riskLevel = computed(() => {
+  if (!detailData.value) return 'NORMAL';
+  return detailData.value.decision?.riskLevel || (detailData.value.quality?.result === 2 ? 'HIGH' : 'NORMAL');
 });
+const riskLabel = computed(() => riskLevel.value === 'HIGH' ? '楂橀闄�' : riskLevel.value === 'NORMAL' ? '姝e父' : '闇�鍏虫敞');
+const riskColor = computed(() => riskLevel.value === 'HIGH' ? 'red' : riskLevel.value === 'NORMAL' ? 'green' : 'orange');
 
 const [Modal, modalApi] = useVbenModal({
   onOpenChange(isOpen) {
@@ -36,66 +31,71 @@
       detailData.value = undefined;
       return;
     }
-    detailData.value = modalApi.getData<MesWmBatchApi.Batch>();
-    subTabsName.value = 'forward';
+    const row = modalApi.getData<{ code?: string }>();
+    if (row?.code) {
+      void loadDetail(row.code);
+    }
+    activeTab.value = 'overview';
   },
 });
+
+async function loadDetail(code: string) {
+  loading.value = true;
+  try {
+    detailData.value = await getBatchTraceDetail(code);
+  } catch {
+    message.error('鎵规杩芥函璇︽儏鍔犺浇澶辫触');
+  } finally {
+    loading.value = false;
+  }
+}
 </script>
 
 <template>
   <Modal
-    title="鎵规杩芥函"
-    class="w-4/5"
+    title="鍏ㄩ摼璺壒娆¤拷婧�"
+    class="w-11/12"
     :show-cancel-button="false"
     :show-confirm-button="false"
   >
-    <Descriptions class="mx-4 mt-2" :data="detailData" />
-    <Tabs
-      v-if="detailData?.code"
-      v-model:active-key="subTabsName"
-      class="mx-4 mt-4"
-      type="card"
-    >
-      <Tabs.TabPane key="forward">
-        <template #tab>
-          <Tooltip title="椤虹潃鐢熶骇娴佸線涓嬫父鏌ワ細璇ユ壒娆¤鍝簺宸ュ崟娑堣�楀悗锛屼骇鍑烘垚浜嗗摢浜涙垚鍝佹壒娆�">
-            <span>鍚戝墠杩芥函</span>
-          </Tooltip>
-        </template>
-        <TraceList :batch-code="detailData.code" direction="forward" />
-      </Tabs.TabPane>
-      <Tabs.TabPane key="backward">
-        <template #tab>
-          <Tooltip title="閫嗙潃鐢熶骇娴佸線涓婃父鏌ワ細鐢熶骇璇ユ壒娆℃椂锛屾秷鑰椾簡鍝簺鍘熸枡鎵规">
-            <span>鍚戝悗杩芥函</span>
-          </Tooltip>
-        </template>
-        <TraceList :batch-code="detailData.code" direction="backward" />
-      </Tabs.TabPane>
-      <Tabs.TabPane key="purchase">
-        <template #tab>
-          <Tooltip title="鍘熸枡渚ф潵婧愶細璇ユ壒娆″搴旂殑閲囪喘鍏ュ簱鍗曚笌 IQC 鏉ユ枡妫�楠岃褰�">
-            <span>閲囪喘鏉ユ簮</span>
-          </Tooltip>
-        </template>
-        <PurchaseSourceList :batch-code="detailData.code" />
-      </Tabs.TabPane>
-      <Tabs.TabPane key="sales">
-        <template #tab>
-          <Tooltip title="鎴愬搧渚у幓鍚戯細璇ユ壒娆″搴旂殑閿�鍞嚭搴撳崟涓� OQC 鍑哄巶妫�楠岃褰�">
-            <span>閿�鍞幓鍚�</span>
-          </Tooltip>
-        </template>
-        <SalesTargetList :batch-code="detailData.code" />
-      </Tabs.TabPane>
-      <Tabs.TabPane key="process">
-        <template #tab>
-          <Tooltip title="鍚勫伐搴忕殑鎶曞叆/浜у嚭浜嬩欢锛氳鎵规鍦ㄥ摢浜涘伐搴忚鎶曞叆鎴栦骇鍑猴紝鍙婃暟閲忓拰璐ㄩ噺鐘舵��">
-            <span>宸ュ簭娴佽浆</span>
-          </Tooltip>
-        </template>
-        <ProcessTraceList :batch-code="detailData.code" />
-      </Tabs.TabPane>
-    </Tabs>
+    <Spin :spinning="loading">
+      <div v-if="detailData" class="px-2">
+        <div class="mb-4 grid grid-cols-2 gap-3 lg:grid-cols-5">
+          <div class="rounded border bg-blue-50 px-4 py-3"><div class="text-muted-foreground text-xs">琚嬬爜鏁伴噺</div><div class="mt-1 text-lg font-semibold text-blue-700">{{ detailData.bagTotal ?? 0 }}</div></div>
+          <div class="rounded border bg-violet-50 px-4 py-3"><div class="text-muted-foreground text-xs">鎵樼洏鏁伴噺</div><div class="mt-1 text-lg font-semibold text-violet-700">{{ detailData.palletCount ?? 0 }}</div></div>
+          <div class="rounded border bg-green-50 px-4 py-3"><div class="text-muted-foreground text-xs">鍏ュ簱鏁伴噺</div><div class="mt-1 text-lg font-semibold text-green-700">{{ detailData.decision?.inboundQuantity ?? detailData.inbound?.quantity ?? 0 }}</div></div>
+          <div class="rounded border bg-orange-50 px-4 py-3"><div class="text-muted-foreground text-xs">閿�鍞幓鍚�</div><div class="mt-1 text-lg font-semibold text-orange-700">{{ detailData.decision?.salesTargetCount ?? detailData.salesTargets?.length ?? 0 }}</div></div>
+          <div class="col-span-2 rounded border px-4 py-3 lg:col-span-1" :class="riskLevel === 'HIGH' ? 'border-red-200 bg-red-50' : riskLevel === 'NORMAL' ? 'border-green-200 bg-green-50' : 'border-orange-200 bg-orange-50'"><div class="text-muted-foreground text-xs">缁煎悎椋庨櫓</div><div class="mt-1"><Tag :color="riskColor">{{ riskLabel }}</Tag></div></div>
+        </div>
+        <Descriptions bordered :column="{ xs: 1, sm: 2, md: 3 }" size="small">
+          <Descriptions.Item label="杩芥函鍏ュ彛">{{ detailData.requestCode || '鏈褰�' }}</Descriptions.Item>
+          <Descriptions.Item label="鍏ュ彛绫诲瀷"><Tag color="blue">{{ detailData.sourceType || 'BATCH' }}</Tag></Descriptions.Item>
+          <Descriptions.Item label="鎵规鐘舵��">{{ detailData.batchStatusName || '鏈煡' }}</Descriptions.Item>
+          <Descriptions.Item label="鍝佺">{{ detailData.itemName || detailData.itemCode || '鏈褰�' }}</Descriptions.Item>
+          <Descriptions.Item label="鎵规鍙�">{{ detailData.batchCode || '鏈褰�' }}</Descriptions.Item>
+          <Descriptions.Item label="璐d换浜�">{{ detailData.ownerUserName || '鏈褰�' }}</Descriptions.Item>
+          <Descriptions.Item label="鐢熶骇绾�">{{ detailData.lineName || detailData.lineCode || '鏈褰�' }}</Descriptions.Item>
+          <Descriptions.Item label="璁″垝鏁伴噺">{{ detailData.planQuantity ?? 0 }}</Descriptions.Item>
+          <Descriptions.Item label="鐢熶骇鏃ユ湡">{{ formatDate(detailData.produceDate) }}</Descriptions.Item>
+          <Descriptions.Item label="鍏ュ簱鏃堕棿">{{ formatDate(detailData.inboundTime || detailData.inbound?.eventTime) }}</Descriptions.Item>
+        </Descriptions>
+
+        <Tabs v-model:active-key="activeTab" class="mt-4" type="card">
+          <Tabs.TabPane key="overview" tab="闃舵鎬昏">
+            <TraceStageOverview :detail="detailData" />
+          </Tabs.TabPane>
+          <Tabs.TabPane key="timeline" tab="鍏ㄩ摼璺椂闂寸嚎">
+            <TraceTimeline :detail="detailData" />
+          </Tabs.TabPane>
+          <Tabs.TabPane key="graph" tab="娴佸姩鍥捐氨">
+            <TraceGraph :detail="detailData" />
+          </Tabs.TabPane>
+          <Tabs.TabPane key="decision" tab="鍐崇瓥鍒嗘瀽">
+            <TraceDecision :detail="detailData" />
+          </Tabs.TabPane>
+        </Tabs>
+      </div>
+      <div v-else-if="!loading" class="py-12 text-center text-muted-foreground">鏆傛棤杩芥函鏁版嵁</div>
+    </Spin>
   </Modal>
 </template>

--
Gitblit v1.9.3