From f78fae4c3fdc85f2a16530ff054204eefcbbb00d Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期二, 25 八月 2026 18:53:10 +0800
Subject: [PATCH] Merge branch 'dev_天津_建诚恒商贸' of http://114.132.189.42:9002/r/product-inventory-management into dev_天津_建诚恒商贸

---
 src/views/productionManagement/productionOrder/index.vue |  158 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 145 insertions(+), 13 deletions(-)

diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue
index 93fc177..6e0c55a 100644
--- a/src/views/productionManagement/productionOrder/index.vue
+++ b/src/views/productionManagement/productionOrder/index.vue
@@ -75,6 +75,26 @@
                        :color="progressColor(toProgressPercentage(row?.completionStatus))"
                        :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''" />
         </template>
+        <template #processRouteStatus="{ row }">
+          <div v-if="row.processRouteStatus && row.processRouteStatus.length"
+               class="process-progress-container">
+            <div v-for="(item, index) in row.processRouteStatus"
+                 :key="index"
+                 class="process-step">
+              <div class="step-content">
+                <div class="step-circle"
+                     :class="{ 'is-completed': item.percentage >= 100 }">
+                  <span class="step-percentage"
+                        :style="{ color: item.percentage >= 70 ? item.percentage >= 100 ? '#67c23a' : '#f56c6c' : '#000' }">{{ item.percentage }}%</span>
+                </div>
+                <div class="step-name">{{ item.name }}</div>
+              </div>
+              <div v-if="index < row.processRouteStatus.length - 1"
+                   class="step-line"></div>
+            </div>
+          </div>
+          <span v-else>-</span>
+        </template>
       </PIMTable>
     </div>
     <el-dialog v-model="bindRouteDialogVisible"
@@ -105,7 +125,8 @@
     <!-- 鏉ユ簮鏁版嵁寮圭獥 -->
     <el-dialog v-model="sourceDataDialogVisible"
                title="鏉ユ簮鏁版嵁"
-               width="1200px">
+               width="1200px"
+               custom-class="source-data-dialog">
       <div v-if="sourceRowData"
            class="applyno-summary1">
         <div class="summary-item">
@@ -215,6 +236,7 @@
     getProductOrderSource,
     updateProductOrder,
   } from "@/api/productionManagement/productionOrder.js";
+  import { productWorkOrderPage } from "@/api/productionManagement/workOrder.js";
   import { listMain as getOrderProcessRouteMain } from "@/api/productionManagement/productProcessRoute.js";
   import MaterialLedgerDialog from "@/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue";
   import MaterialDetailDialog from "@/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue";
@@ -241,7 +263,17 @@
     total: 0,
   });
 
-  const tableColumn = ref([
+  const processColumnWidth = computed(() => {
+    if (!tableData.value || tableData.value.length === 0) return "200px";
+    const maxProcesses = Math.max(
+      ...tableData.value.map(row => row.processRouteStatus?.length || 0)
+    );
+    if (maxProcesses === 0) return "100px";
+    // 姣忎釜宸ュ簭鍦嗗湀 36px + 绾挎潯 30px = 66px锛岄澶栧姞 60px 杈硅窛鍜屾枃瀛楃┖闂�
+    return `${maxProcesses * 66 + 60}px`;
+  });
+
+  const tableColumn = computed(() => [
     {
       label: "鐢熶骇璁㈠崟鍙�",
       prop: "npsNo",
@@ -296,6 +328,13 @@
     {
       label: "瀹屾垚鏁伴噺",
       prop: "completeQuantity",
+    },
+    {
+      label: "宸ュ簭鐢熶骇杩涘害",
+      prop: "processRouteStatus",
+      dataType: "slot",
+      slot: "processRouteStatus",
+      width: processColumnWidth.value,
     },
     {
       dataType: "slot",
@@ -364,7 +403,7 @@
           name: "棰嗘枡",
           type: "text",
           color: "#5EC7AB",
-          showHide: row => !row.endOrder,
+          showHide: row => !row.endOrder && !row.returned,
           clickFun: row => {
             openMaterialDialog(row);
           },
@@ -373,7 +412,7 @@
           name: "琛ユ枡",
           type: "text",
           color: "#5EC7AB",
-          showHide: row => !row.endOrder,
+          showHide: row => !row.endOrder && !row.returned,
           clickFun: row => {
             openMaterialSupplementDialog(row);
           },
@@ -449,7 +488,7 @@
     if (!Number.isFinite(n)) return 0;
     if (n <= 0) return 0;
     if (n >= 100) return 100;
-    return Math.round(n);
+    return parseFloat(n.toFixed(2));
   };
 
   // 30/50/80/100 鍒嗘棰滆壊锛氱孩/姗�/钃�/缁�
@@ -532,7 +571,7 @@
 
   const openBindRouteDialog = async (row, type) => {
     bindForm.orderId = row.id;
-    bindForm.routeId = type === "add" ? null : row.processRouteCode;
+    bindForm.routeId = type === "add" ? null : row.technologyRoutingId;
     bindRouteDialogVisible.value = true;
     routeOptions.value = [];
     if (!row.productModelId) {
@@ -630,10 +669,35 @@
     const params = { ...searchForm.value, ...page };
     params.entryDate = undefined;
     productOrderListPage(params)
-      .then(res => {
-        tableLoading.value = false;
-        tableData.value = res.data.records;
+      .then(async res => {
+        const records = res.data.records || [];
+        // 涓烘瘡涓鍗曟煡璇㈠搴旂殑宸ュ簭杩涘害鏁版嵁
+        const processPromises = records.map(async item => {
+          if (item.npsNo) {
+            try {
+              const workOrderRes = await productWorkOrderPage({
+                npsNo: item.npsNo,
+                size: 100,
+              });
+              const workOrders = workOrderRes.data.records || [];
+              // 鎸夌収宸ュ簭椤哄簭鎺掑簭锛堝鏋滄湁椤哄簭瀛楁锛屽亣璁句负 orderNum 鎴栨寜杩斿洖椤哄簭锛�
+              // 杞崲涓� processRouteStatus 鏍煎紡
+              const processRouteStatus = workOrders.map(wo => ({
+                name: wo.operationName || "鏈煡宸ュ簭",
+                percentage: wo.completionStatus > 100 ? 100 : wo.completionStatus,
+              }));
+              return { ...item, processRouteStatus };
+            } catch (error) {
+              console.error(`鑾峰彇宸ュ崟 ${item.npsNo} 杩涘害澶辫触:`, error);
+              return { ...item, processRouteStatus: [] };
+            }
+          }
+          return { ...item, processRouteStatus: [] };
+        });
+
+        tableData.value = await Promise.all(processPromises);
         page.total = res.data.total;
+        tableLoading.value = false;
       })
       .catch(() => {
         tableLoading.value = false;
@@ -660,6 +724,7 @@
           bomNo: row.bomNo || "",
           description: data.description || "",
           quantity: row.quantity || 0,
+          technologyRoutingId: data.technologyRoutingId,
           orderId,
           type: "order",
           editable: !row.endOrder,
@@ -747,9 +812,9 @@
     })
       .then(() => {
         proxy.download(
-          "/productOrder/export",
+          "/productionOrder/export",
           { ...searchForm.value },
-          "鐢熶骇璁㈠崟.xlsx"
+          "鐢熶骇璁㈠崟鏁版嵁.xlsx"
         );
       })
       .catch(() => {
@@ -813,6 +878,64 @@
   .table_list {
     margin-top: unset;
   }
+
+  .process-progress-container {
+    display: inline-flex;
+    align-items: center;
+    padding: 10px 0;
+    white-space: nowrap;
+
+    .process-step {
+      display: flex;
+      align-items: center;
+      position: relative;
+
+      .step-content {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        z-index: 1;
+
+        .step-circle {
+          width: 36px;
+          height: 36px;
+          border-radius: 50%;
+          border: 2px solid #409eff;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          background-color: #fff;
+          margin-bottom: 4px;
+
+          .step-percentage {
+            font-size: 11px;
+            font-weight: bold;
+          }
+
+          &.is-completed {
+            border-color: #67c23a;
+            .step-percentage {
+              color: #67c23a;
+            }
+          }
+        }
+
+        .step-name {
+          font-size: 12px;
+          color: #606266;
+          white-space: nowrap;
+        }
+      }
+
+      .step-line {
+        width: 30px;
+        height: 1px;
+        background-color: #dcdfe6;
+        margin: 0 -2px;
+        margin-top: -20px; // 鍚戜笂鍋忕Щ浠ュ榻愬渾蹇�
+      }
+    }
+  }
 </style>
 <style lang="scss">
   .status-cell {
@@ -820,6 +943,17 @@
     color: #409eff;
     font-family: "Courier New", monospace;
     text-shadow: 0 1px 2px rgba(64, 158, 255, 0.2);
+  }
+
+  .source-data-dialog {
+    display: flex;
+    flex-direction: column;
+    max-height: 80vh;
+
+    .el-dialog__body {
+      overflow-y: auto;
+      flex: 1;
+    }
   }
 
   .source-table-container {
@@ -830,8 +964,6 @@
     display: flex;
     flex-direction: column;
     gap: 16px;
-    max-height: 500px;
-    overflow-y: auto;
     padding: 10px;
     background-color: #f5f7fa;
     border-radius: 4px;

--
Gitblit v1.9.3