From 2b3d9f38998fa0a3903e7789c690e62cf957d4b9 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期三, 01 四月 2026 16:38:39 +0800
Subject: [PATCH] 追踪进度接口对接,主生产计划右侧操作栏透光问题修改

---
 src/api/productionPlan/productionPlan.js          |   12 
 src/views/index.vue                               |   69 ++++
 src/views/productionPlan/productionPlan/index.vue |    8 
 src/views/productionPlan/trackProgress/index.vue  |  667 +++++++++++++++++++++++++-------------------------
 4 files changed, 414 insertions(+), 342 deletions(-)

diff --git a/src/api/productionPlan/productionPlan.js b/src/api/productionPlan/productionPlan.js
index f064db9..beefbc8 100644
--- a/src/api/productionPlan/productionPlan.js
+++ b/src/api/productionPlan/productionPlan.js
@@ -68,4 +68,14 @@
     method: "post",
     data: query,
   });
-}
\ No newline at end of file
+}
+
+
+// 杩借釜杩涘害
+export function trackProgressByNo(query) {
+  return request({
+    url: "/track/trackProgressByNo",
+    method: "get",
+    params: query,
+  });
+}
diff --git a/src/views/index.vue b/src/views/index.vue
index c6f00fc..65babe5 100644
--- a/src/views/index.vue
+++ b/src/views/index.vue
@@ -16,9 +16,9 @@
                    type="primary"
                    plain
                    @click="refreshDashboardData">鍒锋柊鏁版嵁</el-button>
-        <el-button size="small"
+        <!-- <el-button size="small"
                    plain
-                   @click="configDialogVisible = true">棣栭〉閰嶇疆</el-button>
+                   @click="configDialogVisible = true">棣栭〉閰嶇疆</el-button> -->
       </div>
     </div>
     <div class="content-grid">
@@ -40,7 +40,7 @@
             </el-button>
           </div>
         </section>
-        <section class="section-card">
+        <!-- <section class="section-card">
           <div class="section-title">閲嶇偣寰呭姙</div>
           <div class="todo-row"
                v-for="todo in todos"
@@ -49,7 +49,7 @@
                     :type="todo.type">{{ todo.level }}</el-tag>
             <span>{{ todo.title }}</span>
           </div>
-        </section>
+        </section> -->
         <section class="section-card">
           <div class="section-title">缁忚惀鍏虫敞</div>
           <div class="focus-row"
@@ -157,11 +157,10 @@
           </section>
           <section class="section-card"
                    v-if="isSectionVisible('costChart')">
-            <div class="section-title">鑳借�椾笌鎴愭湰缁撴瀯</div>
+            <div class="section-title">鑳借�楃被鍨嬪崰姣�</div>
             <Echarts :chartStyle="chartStyle"
-                     :legend="costLegend"
                      :tooltip="pieTooltip"
-                     :series="costSeries"
+                     :series="energyTypeSeries"
                      style="height: 260px" />
           </section>
         </div>
@@ -542,6 +541,61 @@
       data: [],
     },
   ]);
+
+  // 鑳借�楃被鍨嬪崰姣旀暟鎹�
+  const energyTypeSeries = reactive([
+    {
+      type: "pie",
+      radius: ["40%", "70%"],
+      center: ["50%", "50%"],
+      avoidLabelOverlap: false,
+      itemStyle: {
+        borderRadius: 10,
+        borderColor: "#fff",
+        borderWidth: 2,
+      },
+      label: {
+        show: true,
+        formatter: "{b}: {d}%",
+      },
+      data: [
+        { value: 0, name: "姘�", itemStyle: { color: "#409EFF" } },
+        { value: 0, name: "鐢�", itemStyle: { color: "#E6A23C" } },
+        { value: 0, name: "姘�", itemStyle: { color: "#F56C6C" } },
+      ],
+    },
+  ]);
+
+  // 妯℃嫙鑳借�楁暟鎹�
+  const energyData = reactive({
+    water: 120,
+    electricity: 350,
+    gas: 80,
+  });
+
+  // 鏇存柊鑳借�楃被鍨嬪崰姣斿浘琛�
+  const updateEnergyTypeChart = () => {
+    const { water, electricity, gas } = energyData;
+    const total = water + electricity + gas;
+
+    energyTypeSeries[0].data = [
+      {
+        value: total > 0 ? ((water / total) * 100).toFixed(2) : 0,
+        name: "姘�",
+        itemStyle: { color: "#409EFF" },
+      },
+      {
+        value: total > 0 ? ((electricity / total) * 100).toFixed(2) : 0,
+        name: "鐢�",
+        itemStyle: { color: "#E6A23C" },
+      },
+      {
+        value: total > 0 ? ((gas / total) * 100).toFixed(2) : 0,
+        name: "姘�",
+        itemStyle: { color: "#F56C6C" },
+      },
+    ];
+  };
 
   const planTable = reactive([]);
   const recentTrendCards = reactive([
@@ -982,6 +1036,7 @@
     loadQualityData();
     loadCostComposition();
     loadWarningCenter();
+    updateEnergyTypeChart();
     lastUpdatedAt.value = new Date().toLocaleString();
   };
 
diff --git a/src/views/productionPlan/productionPlan/index.vue b/src/views/productionPlan/productionPlan/index.vue
index b337aa3..9cdbfd6 100644
--- a/src/views/productionPlan/productionPlan/index.vue
+++ b/src/views/productionPlan/productionPlan/index.vue
@@ -674,7 +674,10 @@
     router.push({
       path: "/productionPlan/trackProgress",
       query: {
-        applyNo: encodeURIComponent(row.applyNo),
+        id: row.id,
+        applyNo: row.applyNo,
+        productName: row.productName,
+        model: row.model,
       },
     });
   };
@@ -1559,4 +1562,7 @@
   //     margin-bottom: 0px !important;
   //   }
   // }
+  :deep(.el-table .el-table__body-wrapper tr td) {
+    background-color: #fff;
+  }
 </style>
diff --git a/src/views/productionPlan/trackProgress/index.vue b/src/views/productionPlan/trackProgress/index.vue
index 9a4ceda..0a130a9 100644
--- a/src/views/productionPlan/trackProgress/index.vue
+++ b/src/views/productionPlan/trackProgress/index.vue
@@ -10,92 +10,118 @@
                    :model="searchForm"
                    class="search-form">
             <el-form-item label="鐢宠鍗曠紪鍙�">
-              <el-input v-model="searchForm.applyNo"
-                        placeholder="璇疯緭鍏ョ敵璇峰崟缂栧彿"
-                        style="width: 400px;"></el-input>
-            </el-form-item>
-            <el-form-item>
-              <el-button type="primary"
-                         @click="handleSearch">鎼滅储</el-button>
+              <el-select v-model="selectedApplyNo"
+                         filterable
+                         remote
+                         reserve-keyword
+                         placeholder="璇疯緭鍏ョ敵璇峰崟缂栧彿"
+                         :loading="applyNoLoading"
+                         :remote-method="handleApplyNoSearch"
+                         @change="handleSearch"
+                         style="width: 400px;">
+                <el-option v-for="option in applyNoOptions"
+                           :key="option.id"
+                           :label="option.applyNo+'-'+option.productName+'-'+option.model"
+                           :value="option.id" />
+              </el-select>
             </el-form-item>
           </el-form>
         </div>
       </template>
       <!-- 鍩虹淇℃伅 -->
-      <div class="detail-section">
+      <div v-if="rowData.productionPlanDto"
+           class="detail-section">
         <h3 class="section-title">鍩虹淇℃伅</h3>
-        <el-descriptions :column="3"
-                         border>
-          <el-descriptions-item label="鐢宠鍗曠紪鍙�">{{ rowData.applyNo || '-' }}</el-descriptions-item>
-          <el-descriptions-item label="浜у搧鍚嶇О">{{ rowData.productName || '-' }}</el-descriptions-item>
-          <el-descriptions-item label="浜у搧瑙勬牸">{{ rowData.model || '-' }}</el-descriptions-item>
-          <el-descriptions-item label="鐗╂枡缂栫爜">{{ rowData.materialCode || '-' }}</el-descriptions-item>
-          <el-descriptions-item label="涓嬪彂鏁伴噺">{{ rowData.assignedQuantity || 0 }} <span class="unit">鏂�</span></el-descriptions-item>
-          <el-descriptions-item label="褰撳墠鐘舵��">
-            <el-tag :type="getStatusType(rowData.status)">
-              {{ getStatusText(rowData.status) }}
-            </el-tag>
-          </el-descriptions-item>
-        </el-descriptions>
+        <el-skeleton :loading="loading"
+                     animated>
+          <template #template>
+            <el-skeleton-item variant="p"
+                              style="width: 80%" />
+            <el-skeleton-item variant="p"
+                              style="width: 60%" />
+            <el-skeleton-item variant="p"
+                              style="width: 40%" />
+          </template>
+          <el-descriptions :column="3"
+                           border>
+            <el-descriptions-item label="鐢宠鍗曠紪鍙�">{{ rowData.productionPlanDto?.applyNo || '-' }}</el-descriptions-item>
+            <el-descriptions-item label="浜у搧鍚嶇О">{{ rowData.productionPlanDto?.productName || '-' }}</el-descriptions-item>
+            <el-descriptions-item label="浜у搧瑙勬牸">{{ rowData.productionPlanDto?.model || '-' }}</el-descriptions-item>
+            <el-descriptions-item label="鐗╂枡缂栫爜">{{ rowData.productionPlanDto?.materialCode || '-' }}</el-descriptions-item>
+            <el-descriptions-item label="涓嬪彂鏁伴噺">{{ rowData.productionPlanDto?.assignedQuantity || 0 }} <span class="unit">鏂�</span></el-descriptions-item>
+            <el-descriptions-item label="褰撳墠鐘舵��">
+              <el-tag :type="getStatusType(rowData.productionPlanDto?.status)">
+                {{ getStatusText(rowData.productionPlanDto?.status) }}
+              </el-tag>
+            </el-descriptions-item>
+          </el-descriptions>
+        </el-skeleton>
       </div>
-      <div class="progress-container">
+      <el-empty v-else
+                description="鏆傛棤鏁版嵁" />
+      <div v-if="rowData.orderDtoList"
+           class="progress-container">
         <div class="progress-section">
           <h3 class="section-title">璁㈠崟淇℃伅</h3>
-          <div v-for="item in rowData.orderList"
-               :key="item.orderNo"
-               class="order-item">
-            <el-descriptions :column="3"
-                             border>
-              <el-descriptions-item label="璁㈠崟缂栧彿">{{ item.orderNo || '-' }}</el-descriptions-item>
-              <!-- <el-descriptions-item label="璁㈠崟鐘舵��">
-                <el-tag :type="getStatusType(item.status)">{{ getStatusText(item.status) }}</el-tag>
-              </el-descriptions-item> -->
-              <el-descriptions-item label="寮�濮嬫棩鏈�">{{ item.startTime || '-' }}</el-descriptions-item>
-              <el-descriptions-item label="瀹屾垚杩涘害">
-                <el-progress :percentage="item.completionRate"
-                             :color="customColors(item.completionRate)"
-                             :status="item.completionRate === 100 ? 'success' : ''"
-                             style="width: 120px;" />
-              </el-descriptions-item>
-              <el-descriptions-item label="闇�姹傛暟閲�">{{ item.quantity || 0 }} <span class="unit">鏂�</span></el-descriptions-item>
-              <el-descriptions-item label="瀹屾垚鏁伴噺">{{ item.completeQuantity || 0 }} <span class="unit">鏂�</span></el-descriptions-item>
-              <el-descriptions-item label="鍓╀綑鏁伴噺">{{ item.remainingQuantity || 0 }} <span class="unit">鏂�</span></el-descriptions-item>
-            </el-descriptions>
-            <el-table :data="trackProgressForm.progressDetails"
-                      border
-                      style="width: auto; height: 200px">
-              <el-table-column prop="step"
-                               label="姝ラ锛堢偣鍑绘煡鐪嬭鎯咃級"
-                               align="center">
-                <template #default="{ row, $index }">
-                  <el-link v-if="$index!=0"
-                           @click="handleClickStep(row)"
-                           type="primary">{{ row.step }}</el-link>
-                  <span v-else>{{ row.step }}</span>
-                </template>
-              </el-table-column>
-              <!-- <el-table-column prop="status"
-                               label="鐘舵��"
-                               align="center">
-                <template #default="scope">
-                  <el-tag :type="scope.row.status === 'completed' ? 'success' : scope.row.status === 'processing' ? 'warning' : 'info'">
-                    {{ scope.row.status === 'completed' ? '宸插畬鎴�' : scope.row.status === 'processing' ? '杩涜涓�' : '寰呭紑濮�' }}
-                  </el-tag>
-                </template>
-              </el-table-column> -->
-              <el-table-column prop="quantity"
-                               label="鏁伴噺"
-                               align="center" />
-              <el-table-column prop="startTime"
-                               label="鏃堕棿"
-                               align="center" />
-              <el-table-column prop="startTime1"
-                               label="宀椾綅浜哄憳"
-                               align="center" />
-            </el-table>
-          </div>
+          <el-skeleton :loading="loading"
+                       animated>
+            <template #template>
+              <el-skeleton-item variant="p"
+                                style="width: 80%" />
+              <el-skeleton-item variant="p"
+                                style="width: 60%" />
+              <el-skeleton-item variant="p"
+                                style="width: 40%" />
+              <el-skeleton-item variant="p"
+                                style="width: 100%" />
+            </template>
+            <div v-for="(item, index) in rowData.orderDtoList"
+                 :key="item.productOrderDto?.npsNo || index"
+                 class="order-item">
+              <el-descriptions :column="3"
+                               border>
+                <el-descriptions-item label="璁㈠崟缂栧彿">{{ item.productOrderDto?.npsNo || '-' }}</el-descriptions-item>
+                <el-descriptions-item label="寮�濮嬫棩鏈�">{{ item.productOrderDto?.startTime || '-' }}</el-descriptions-item>
+                <el-descriptions-item label="瀹屾垚杩涘害">
+                  <el-progress :percentage="item.productOrderDto?.completionStatus"
+                               :color="customColors(item.productOrderDto?.completionStatus)"
+                               :status="item.productOrderDto?.completionStatus === 100 ? 'success' : ''"
+                               style="width: 120px;" />
+                </el-descriptions-item>
+                <el-descriptions-item label="闇�姹傛暟閲�">{{ item.productOrderDto?.quantity || 0 }} <span class="unit">鏂�</span></el-descriptions-item>
+                <el-descriptions-item label="瀹屾垚鏁伴噺">{{ item.productOrderDto?.completeQuantity || 0 }} <span class="unit">鏂�</span></el-descriptions-item>
+                <el-descriptions-item label="鍓╀綑鏁伴噺">{{ (item.productOrderDto?.quantity - item.productOrderDto?.completeQuantity) || 0 }} <span class="unit">鏂�</span></el-descriptions-item>
+              </el-descriptions>
+              <el-table :data="item.productionProductMainDtos"
+                        border
+                        style="width: auto; max-height: 200px">
+                <el-table-column prop="step"
+                                 label="鎶ュ伐锛堢偣鍑绘煡鐪嬭鎯咃級"
+                                 align="center">
+                  <template #default="{ row }">
+                    <el-link @click="handleClickStep(row)"
+                             type="primary">{{ row.productNo }}</el-link>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="quantity"
+                                 label="鏁伴噺锛堟柟锛�"
+                                 align="center" />
+                <el-table-column prop="reportingTime"
+                                 label="鏃堕棿"
+                                 align="center" />
+                <el-table-column prop="schedule"
+                                 label="鐝"
+                                 align="center" />
+                <el-table-column prop="postName"
+                                 label="宀椾綅浜哄憳"
+                                 align="center" />
+              </el-table>
+            </div>
+          </el-skeleton>
         </div>
       </div>
+      <el-empty v-else-if="rowData.productionPlanDto"
+                description="鏆傛棤杩涘害" />
     </el-card>
     <!-- 鐢熶骇鎶ュ伐璇︽儏寮圭獥 -->
     <el-dialog v-model="detailDialogVisible"
@@ -104,142 +130,159 @@
                :close-on-click-modal="false"
                custom-class="custom-dialog">
       <div class="detail-container">
-        <!-- 鍩虹淇℃伅 -->
-        <div class="detail-section">
-          <h3 class="section-title">鍩虹淇℃伅</h3>
-          <el-descriptions :column="3"
-                           border>
-            <el-descriptions-item label="鐢熶骇璁㈠崟鍙�">{{ detailData.npsNo || '-' }}</el-descriptions-item>
-            <el-descriptions-item label="鐝粍"><el-tag :type="detailData.schedule == '鐧界彮' ? 'primary' : 'warning'">{{ detailData.schedule || '-' }}</el-tag></el-descriptions-item>
-            <el-descriptions-item label="宀椾綅浜哄憳">{{ detailData.postName || '-' }}</el-descriptions-item>
-            <el-descriptions-item label="浜у搧缂栫爜">{{ detailData.materialCode || '-' }}</el-descriptions-item>
-            <el-descriptions-item label="浜у搧鍚嶇О">{{ detailData.productName || '-' }}</el-descriptions-item>
-            <el-descriptions-item label="瑙勬牸">{{ detailData.model || '-' }}</el-descriptions-item>
-            <el-descriptions-item label="鍚堟牸鏁伴噺"><span class="num2">{{ detailData.qualifiedQuantity || 0 }}</span> <span class="unit">鏂�</span></el-descriptions-item>
-            <el-descriptions-item label="涓嶅悎鏍兼暟閲�"><span class="num3">{{ detailData.unqualifiedQuantity || 0 }}</span> <span class="unit">鏂�</span></el-descriptions-item>
-            <el-descriptions-item label="鎬绘暟閲�"><span class="num1">{{ detailData.quantity || 0 }}</span> <span class="unit">鏂�</span></el-descriptions-item>
-            <el-descriptions-item label="鎶ュ伐鏃堕棿">{{ formatTime(detailData.reportingTime) }}</el-descriptions-item>
-            <el-descriptions-item label="鍒涘缓鏃堕棿">{{ formatTime(detailData.createTime) }}</el-descriptions-item>
-            <el-descriptions-item label="鏇存柊鏃堕棿">{{ formatTime(detailData.updateTime) }}</el-descriptions-item>
-          </el-descriptions>
-        </div>
-        <!-- 宸ュ簭淇℃伅 -->
-        <div class="detail-section"
-             v-if="detailData.productionProductRouteItemDtoList && detailData.productionProductRouteItemDtoList.length > 0">
-          <h3 class="section-title">宸ュ簭淇℃伅</h3>
-          <div v-for="(process) in detailData.productionProductRouteItemDtoList"
-               :key="process.id"
-               class="process-item">
-            <div class="process-header">
-              <h4 class="process-title">{{ process.processName || '-' }}</h4>
-              <div class="process-info">
-                <span class="process-label">宀椾綅浜哄憳锛歿{ process.postName || '-' }}</span>
-                <span class="process-label">宸ュ簭ID锛歿{ process.processNo || '-' }}</span>
+        <el-skeleton :loading="dialogLoading"
+                     animated>
+          <template #template>
+            <el-skeleton-item variant="p"
+                              style="width: 80%" />
+            <el-skeleton-item variant="p"
+                              style="width: 60%" />
+            <el-skeleton-item variant="p"
+                              style="width: 40%" />
+            <el-skeleton-item variant="h3"
+                              style="width: 50%" />
+            <el-skeleton-item variant="p"
+                              style="width: 100%" />
+            <el-skeleton-item variant="p"
+                              style="width: 100%" />
+          </template>
+          <!-- 鍩虹淇℃伅 -->
+          <div class="detail-section">
+            <h3 class="section-title">鍩虹淇℃伅</h3>
+            <el-descriptions :column="3"
+                             border>
+              <el-descriptions-item label="鐢熶骇璁㈠崟鍙�">{{ detailData.npsNo || '-' }}</el-descriptions-item>
+              <el-descriptions-item label="鐝粍"><el-tag :type="detailData.schedule == '鐧界彮' ? 'primary' : 'warning'">{{ detailData.schedule || '-' }}</el-tag></el-descriptions-item>
+              <el-descriptions-item label="宀椾綅浜哄憳">{{ detailData.postName || '-' }}</el-descriptions-item>
+              <el-descriptions-item label="浜у搧缂栫爜">{{ detailData.materialCode || '-' }}</el-descriptions-item>
+              <el-descriptions-item label="浜у搧鍚嶇О">{{ detailData.productName || '-' }}</el-descriptions-item>
+              <el-descriptions-item label="瑙勬牸">{{ detailData.model || '-' }}</el-descriptions-item>
+              <el-descriptions-item label="鍚堟牸鏁伴噺"><span class="num2">{{ detailData.qualifiedQuantity || 0 }}</span> <span class="unit">鏂�</span></el-descriptions-item>
+              <el-descriptions-item label="涓嶅悎鏍兼暟閲�"><span class="num3">{{ detailData.unqualifiedQuantity || 0 }}</span> <span class="unit">鏂�</span></el-descriptions-item>
+              <el-descriptions-item label="鎬绘暟閲�"><span class="num1">{{ detailData.quantity || 0 }}</span> <span class="unit">鏂�</span></el-descriptions-item>
+              <el-descriptions-item label="鎶ュ伐鏃堕棿">{{ formatTime(detailData.reportingTime) }}</el-descriptions-item>
+              <el-descriptions-item label="鍒涘缓鏃堕棿">{{ formatTime(detailData.createTime) }}</el-descriptions-item>
+              <el-descriptions-item label="鏇存柊鏃堕棿">{{ formatTime(detailData.updateTime) }}</el-descriptions-item>
+            </el-descriptions>
+          </div>
+          <!-- 宸ュ簭淇℃伅 -->
+          <div class="detail-section"
+               v-if="detailData.productionProductRouteItemDtoList && detailData.productionProductRouteItemDtoList.length > 0">
+            <h3 class="section-title">宸ュ簭淇℃伅</h3>
+            <div v-for="(process) in detailData.productionProductRouteItemDtoList"
+                 :key="process.id"
+                 class="process-item">
+              <div class="process-header">
+                <h4 class="process-title">{{ process.processName || '-' }}</h4>
+                <div class="process-info">
+                  <span class="process-label">宀椾綅浜哄憳锛歿{ process.postName || '-' }}</span>
+                  <span class="process-label">宸ュ簭ID锛歿{ process.processNo || '-' }}</span>
+                </div>
               </div>
-            </div>
-            <!-- 宸ュ簭鍩烘湰淇℃伅 -->
-            <div class="process-details">
-              <el-descriptions :column="2"
-                               border>
-                <el-descriptions-item label="璁惧寮傚父鎯呭喌">{{ process.equipmentMalfunction || '-' }}</el-descriptions-item>
-                <el-descriptions-item label="褰撶彮璁惧澶勭疆">{{ process.equipmentDisposal || '-' }}</el-descriptions-item>
-                <el-descriptions-item label="宸ヨ壓浜哄憳浜ゅ緟"
-                                      :span="2">{{ process.processExplained || '-' }}</el-descriptions-item>
-              </el-descriptions>
-            </div>
-            <!-- 宸ュ簭鍙傛暟 -->
-            <div v-if="process.productionProductRouteItemParamDtoList && process.productionProductRouteItemParamDtoList.length > 0">
-              <!-- BOM淇℃伅 -->
-              <div class="param-section"
-                   v-if="getBomList(process.productionProductRouteItemParamDtoList).length > 0">
-                <h5 class="param-title">鎶曞叆鍝佷俊鎭�</h5>
-                <el-table :data="getBomList(process.productionProductRouteItemParamDtoList)"
-                          style="width: 100%"
-                          size="small">
-                  <el-table-column prop="paramName"
-                                   label="浜у搧鍚嶇О"
-                                   min-width="120"></el-table-column>
-                  <el-table-column prop="model"
-                                   label="瑙勬牸鍨嬪彿"
-                                   min-width="120"></el-table-column>
-                  <el-table-column prop="productValue"
-                                   label="鎶曞叆閲�"
-                                   min-width="100"></el-table-column>
-                  <el-table-column prop="unit"
-                                   label="鍗曚綅"
-                                   width="80"></el-table-column>
-                </el-table>
+              <!-- 宸ュ簭鍩烘湰淇℃伅 -->
+              <div class="process-details">
+                <el-descriptions :column="2"
+                                 border>
+                  <el-descriptions-item label="璁惧寮傚父鎯呭喌">{{ process.equipmentMalfunction || '-' }}</el-descriptions-item>
+                  <el-descriptions-item label="褰撶彮璁惧澶勭疆">{{ process.equipmentDisposal || '-' }}</el-descriptions-item>
+                  <el-descriptions-item label="宸ヨ壓浜哄憳浜ゅ緟"
+                                        :span="2">{{ process.processExplained || '-' }}</el-descriptions-item>
+                </el-descriptions>
               </div>
-              <!-- 鍙傛暟淇℃伅 -->
-              <div class="param-section"
-                   v-if="getParamList(process.productionProductRouteItemParamDtoList).length > 0">
-                <h5 class="param-title">鐢熶骇璁板綍</h5>
-                <el-card v-for="group in getParamGroups(process.productionProductRouteItemParamDtoList)"
-                         :key="group.sourceSort"
-                         class="detail-card"
-                         style="margin-top: 10px;">
-                  <template #header>
-                    <div class="card-header">
-                      <span v-if="Object.keys(getParamGroups(process.productionProductRouteItemParamDtoList)).length > 1">鐢熶骇璁板綍缁� - {{ group.sourceSort }}</span>
-                      <span v-else>鐢熶骇璁板綍</span>
-                    </div>
-                  </template>
-                  <el-table :data="group.items"
+              <!-- 宸ュ簭鍙傛暟 -->
+              <div v-if="process.productionProductRouteItemParamDtoList && process.productionProductRouteItemParamDtoList.length > 0">
+                <!-- BOM淇℃伅 -->
+                <div class="param-section"
+                     v-if="getBomList(process.productionProductRouteItemParamDtoList).length > 0">
+                  <h5 class="param-title">鎶曞叆鍝佷俊鎭�</h5>
+                  <el-table :data="getBomList(process.productionProductRouteItemParamDtoList)"
                             style="width: 100%"
-                            :row-class-name="rowClassName">
+                            size="small">
                     <el-table-column prop="paramName"
-                                     label="鎸囨爣" />
+                                     label="浜у搧鍚嶇О"
+                                     min-width="120"></el-table-column>
+                    <el-table-column prop="model"
+                                     label="瑙勬牸鍨嬪彿"
+                                     min-width="120"></el-table-column>
+                    <el-table-column prop="productValue"
+                                     label="鎶曞叆閲�"
+                                     min-width="100"></el-table-column>
                     <el-table-column prop="unit"
                                      label="鍗曚綅"
-                                     width="100">
-                      <template #default="scope">
-                        {{ scope.row.unit || "/" }}
-                      </template>
-                    </el-table-column>
-                    <el-table-column prop="standardText"
-                                     label="鏍囧噯鍊�" />
-                    <el-table-column prop="paramValue"
-                                     label="瀹為檯鍊�" />
-                    <el-table-column prop="result"
-                                     label="缁撴灉"
-                                     width="100">
-                      <template #default="scope">
-                        <el-tag :type="scope.row.result === '鍚堟牸' ? 'success' : 'danger'">
-                          {{ scope.row.result }}
-                        </el-tag>
-                      </template>
-                    </el-table-column>
+                                     width="80"></el-table-column>
                   </el-table>
-                </el-card>
+                </div>
+                <!-- 鍙傛暟淇℃伅 -->
+                <div class="param-section"
+                     v-if="getParamList(process.productionProductRouteItemParamDtoList).length > 0">
+                  <h5 class="param-title">鐢熶骇璁板綍</h5>
+                  <el-card v-for="group in getParamGroups(process.productionProductRouteItemParamDtoList)"
+                           :key="group.sourceSort"
+                           class="detail-card"
+                           style="margin-top: 10px;">
+                    <template #header>
+                      <div class="card-header">
+                        <span v-if="Object.keys(getParamGroups(process.productionProductRouteItemParamDtoList)).length > 1">鐢熶骇璁板綍缁� - {{ group.sourceSort }}</span>
+                        <span v-else>鐢熶骇璁板綍</span>
+                      </div>
+                    </template>
+                    <el-table :data="group.items"
+                              style="width: 100%"
+                              :row-class-name="rowClassName">
+                      <el-table-column prop="paramName"
+                                       label="鎸囨爣" />
+                      <el-table-column prop="unit"
+                                       label="鍗曚綅"
+                                       width="100">
+                        <template #default="scope">
+                          {{ scope.row.unit || "/" }}
+                        </template>
+                      </el-table-column>
+                      <el-table-column prop="standardText"
+                                       label="鏍囧噯鍊�" />
+                      <el-table-column prop="paramValue"
+                                       label="瀹為檯鍊�" />
+                      <el-table-column prop="result"
+                                       label="缁撴灉"
+                                       width="100">
+                        <template #default="scope">
+                          <el-tag :type="scope.row.result === '鍚堟牸' ? 'success' : 'danger'">
+                            {{ scope.row.result }}
+                          </el-tag>
+                        </template>
+                      </el-table-column>
+                    </el-table>
+                  </el-card>
+                </div>
               </div>
-            </div>
-            <!-- 涓婁紶鏂囦欢 -->
-            <div class="file-section"
-                 v-if="process.fileList && process.fileList.length > 0">
-              <h5 class="file-title">涓婁紶鏂囦欢</h5>
-              <div class="file-grid">
-                <div v-for="file in process.fileList"
-                     :key="file.id"
-                     class="file-item">
-                  <el-image style="width: 100px; height: 100px"
-                            v-if="file.fileUrl"
-                            :src="baseUrl + file.fileUrl"
-                            :zoom-rate="1.2"
-                            :max-scale="7"
-                            :alt="file.fileName"
-                            :min-scale="0.2"
-                            :preview-src-list="formatFileList(process.fileList)"
-                            show-progress
-                            :initial-index="4"
-                            fit="cover" />
-                  <div class="file-info">
-                    <span class="file-name">{{ file.fileName || '-' }}</span>
+              <!-- 涓婁紶鏂囦欢 -->
+              <div class="file-section"
+                   v-if="process.fileList && process.fileList.length > 0">
+                <h5 class="file-title">涓婁紶鏂囦欢</h5>
+                <div class="file-grid">
+                  <div v-for="file in process.fileList"
+                       :key="file.id"
+                       class="file-item">
+                    <el-image style="width: 100px; height: 100px"
+                              v-if="file.fileUrl"
+                              :src="baseUrl + file.fileUrl"
+                              :zoom-rate="1.2"
+                              :max-scale="7"
+                              :alt="file.fileName"
+                              :min-scale="0.2"
+                              :preview-src-list="formatFileList(process.fileList)"
+                              show-progress
+                              :initial-index="4"
+                              fit="cover" />
+                    <div class="file-info">
+                      <span class="file-name">{{ file.fileName || '-' }}</span>
+                    </div>
                   </div>
                 </div>
               </div>
             </div>
           </div>
-        </div>
+        </el-skeleton>
       </div>
       <template #footer>
         <div class="dialog-footer">
@@ -255,6 +298,11 @@
   import { ElMessage } from "element-plus";
   import { useRouter, useRoute } from "vue-router";
   import dayjs from "dayjs";
+  import {
+    trackProgressByNo,
+    productionPlanListPage,
+  } from "@/api/productionPlan/productionPlan";
+  import { productionReportDetail } from "@/api/productionManagement/productionReporting.js";
 
   const router = useRouter();
   const route = useRoute();
@@ -271,15 +319,21 @@
     remark: "",
   });
 
-  // 鎼滅储琛ㄥ崟
-  const searchForm = reactive({
-    applyNo: "",
-  });
-
   // 鐢熶骇鎶ュ伐璇︽儏寮圭獥
   const detailDialogVisible = ref(false);
   const detailData = ref({});
   const baseUrl = import.meta.env.VITE_APP_BASE_API;
+
+  // 鍔犺浇鐘舵��
+  const loading = ref(false);
+  // 寮圭獥鍔犺浇鐘舵��
+  const dialogLoading = ref(false);
+
+  // 鐢宠鍗曚笅鎷夋鏁版嵁
+  const applyNoOptions = ref([]);
+  const applyNoLoading = ref(false);
+  const applyNoQuery = ref("");
+  const selectedApplyNo = ref(null);
 
   // 鑾峰彇鐘舵�佺被鍨�
   const getStatusType = status => {
@@ -392,28 +446,52 @@
     router.push("/productionPlan/productionPlan");
   };
 
+  // 澶勭悊鐢宠鍗曠紪鍙锋悳绱�
+  const handleApplyNoSearch = query => {
+    if (query) {
+      applyNoLoading.value = true;
+      productionPlanListPage({
+        current: -1,
+        size: -1,
+        applyNo: query,
+      })
+        .then(res => {
+          // 杞崲鏁版嵁鏍煎紡涓轰笅鎷夋鎵�闇�鐨勬牸寮�
+          applyNoOptions.value = res.data.records;
+        })
+        .catch(error => {
+          console.error(error);
+        })
+        .finally(() => {
+          applyNoLoading.value = false;
+        });
+    } else {
+      applyNoOptions.value = [];
+    }
+  };
+
   // 澶勭悊鎼滅储
   const handleSearch = () => {
-    const applyNo = searchForm.applyNo.trim();
-    if (!applyNo) {
-      ElMessage.warning("璇疯緭鍏ョ敵璇峰崟缂栧彿");
+    if (!selectedApplyNo.value) {
+      ElMessage.warning("璇烽�夋嫨鐢宠鍗曠紪鍙�");
       return;
     }
-    // 杩欓噷鍙互娣诲姞鎼滅储閫昏緫锛屼緥濡傝皟鐢ˋPI鑾峰彇鏁版嵁
-    // 鐩墠浣跨敤妯℃嫙鏁版嵁
-    ElMessage.success(`鎼滅储鐢宠鍗曠紪鍙�: ${applyNo}`);
-    // 妯℃嫙鎼滅储缁撴灉
-    rowData.applyNo = applyNo;
-    rowData.productName = "鎼滅储缁撴灉浜у搧";
-    rowData.model = "鎼滅储缁撴灉瑙勬牸";
-    rowData.materialCode = "MAT-" + applyNo;
-    rowData.assignedQuantity = 100;
-    rowData.status = 1;
-    trackProgressForm.progressDetails = generateProgressDetails(1);
-    trackProgressForm.completionRate = calculateCompletionRate(
-      trackProgressForm.progressDetails
-    );
-    rowData.orderList = generateOrderList();
+    // 璋冪敤API鑾峰彇鏁版嵁
+    loading.value = true;
+    trackProgressByNo({ productionPlanId: selectedApplyNo.value })
+      .then(res => {
+        console.log(res, "鎼滅储缁撴灉");
+        // 鍚堝苟鏁版嵁鍒皉owData
+        Object.assign(rowData, res.data);
+        ElMessage.success("鎼滅储鎴愬姛");
+      })
+      .catch(error => {
+        ElMessage.error("鎼滅储澶辫触锛岃绋嶅悗閲嶈瘯");
+        console.error(error);
+      })
+      .finally(() => {
+        loading.value = false;
+      });
   };
 
   // 鐢熸垚妯℃嫙璁㈠崟鏁版嵁
@@ -451,97 +529,23 @@
 
   // 澶勭悊鐐瑰嚮姝ラ鏌ョ湅璇︽儏
   const handleClickStep = row => {
-    // 杩欓噷鍙互娣诲姞鑾峰彇鎶ュ伐璇︽儏鏁版嵁鐨勯�昏緫
-    // 鐩墠浣跨敤妯℃嫙鏁版嵁
-    detailData.value = {
-      npsNo: "NPS-2026-001",
-      schedule: "鐧界彮",
-      postName: "寮犱笁",
-      materialCode: rowData.materialCode || "MAT-001",
-      productName: rowData.productName || "浜у搧A",
-      model: rowData.model || "瑙勬牸A",
-      qualifiedQuantity: 100,
-      unqualifiedQuantity: 5,
-      quantity: 105,
-      reportingTime: new Date(),
-      createTime: new Date(),
-      updateTime: new Date(),
-      productionProductRouteItemDtoList: [
-        {
-          id: 1,
-          processName: "宸ュ簭1",
-          postName: "寮犱笁",
-          processNo: "PROC-001",
-          equipmentMalfunction: "鏃犲紓甯�",
-          equipmentDisposal: "姝e父杩愯",
-          processExplained: "鎸夌収鏍囧噯宸ヨ壓鎿嶄綔",
-          productionProductRouteItemParamDtoList: [
-            {
-              id: 11,
-              paramName: "鍘熸潗鏂橝",
-              model: "鍨嬪彿A",
-              productValue: "100",
-              unit: "kg",
-              bomId: 101,
-            },
-            {
-              id: 12,
-              paramName: "娓╁害",
-              paramValue: "25",
-              unit: "掳C",
-              sourceSort: 1,
-              valueMode: 2,
-              minValue: 20,
-              maxValue: 30,
-            },
-            {
-              id: 13,
-              paramName: "鍘嬪姏",
-              paramValue: "1.5",
-              unit: "MPa",
-              sourceSort: 1,
-              valueMode: 2,
-              minValue: 1.0,
-              maxValue: 2.0,
-            },
-            {
-              id: 14,
-              paramName: "杞��",
-              paramValue: "1500",
-              unit: "rpm",
-              sourceSort: 2,
-              valueMode: 1,
-              standardValue: "1500",
-            },
-            {
-              id: 15,
-              paramName: "鐢垫祦",
-              paramValue: "12",
-              unit: "A",
-              sourceSort: 2,
-              valueMode: 2,
-              minValue: 10,
-              maxValue: 15,
-            },
-          ],
-          fileList: [
-            {
-              id: 21,
-              fileName: "鐢熶骇璁板綍1.jpg",
-              fileUrl: "/upload/files/20260301/12345.jpg",
-              fileSize: 1024000,
-            },
-            {
-              id: 22,
-              fileName: "鐢熶骇璁板綍2.jpg",
-              fileUrl: "/upload/files/20260301/67890.jpg",
-              fileSize: 2048000,
-            },
-          ],
-        },
-      ],
-    };
-    detailDialogVisible.value = true;
+    // 鑾峰彇鎶ュ伐璇︽儏鏁版嵁
+    dialogLoading.value = true;
+    productionReportDetail(row.id)
+      .then(res => {
+        console.log(res, "鎶ュ伐璇︽儏");
+        // 灏咥PI杩斿洖鐨勬暟鎹祴鍊肩粰detailData
+        detailData.value = res.data;
+        // 鎵撳紑寮圭獥
+        detailDialogVisible.value = true;
+      })
+      .catch(error => {
+        ElMessage.error("鑾峰彇鎶ュ伐璇︽儏澶辫触锛岃绋嶅悗閲嶈瘯");
+        console.error(error);
+      })
+      .finally(() => {
+        dialogLoading.value = false;
+      });
   };
 
   // 鏍煎紡鍖栨椂闂�
@@ -637,29 +641,26 @@
   // 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
   onMounted(() => {
     // 浠庤矾鐢卞弬鏁颁腑鑾峰彇鏁版嵁
-    applyNo.value = route.query.applyNo
-      ? decodeURIComponent(route.query.applyNo)
+    selectedApplyNo.value = route.query.applyNo
+      ? route.query.applyNo +
+        "-" +
+        route.query.productName +
+        "-" +
+        route.query.model
       : null;
-    searchForm.applyNo = applyNo.value;
 
-    // 鐢熸垚鍋囨暟鎹�
-    rowData.applyNo = applyNo.value || "APPLY-2026-001";
-    rowData.productName = "娴嬭瘯浜у搧";
-    rowData.model = "娴嬭瘯瑙勬牸";
-    rowData.materialCode = "MAT-001";
-    rowData.assignedQuantity = 233;
-    rowData.status = 1;
-    // 璧嬪�肩粰琛ㄥ崟鏁版嵁
-    trackProgressForm.materialCode = rowData.materialCode;
-    trackProgressForm.currentStatus = rowData.status;
-    trackProgressForm.progressDetails = generateProgressDetails(rowData.status);
-    trackProgressForm.completionRate = calculateCompletionRate(
-      trackProgressForm.progressDetails
-    );
-    trackProgressForm.remark = "";
-
-    // 鐢熸垚妯℃嫙璁㈠崟鏁版嵁
-    rowData.orderList = generateOrderList();
+    if (route.query.id) {
+      loading.value = true;
+      trackProgressByNo({ productionPlanId: route.query.id })
+        .then(res => {
+          console.log(res, "杩借釜杩涘害");
+          // 鍚堝苟鏁版嵁鍒皉owData
+          Object.assign(rowData, res.data);
+        })
+        .finally(() => {
+          loading.value = false;
+        });
+    }
   });
 </script>
 

--
Gitblit v1.9.3