From 4cea678dd431db704ed6c47f7c486281672fccb6 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期一, 30 三月 2026 15:07:12 +0800
Subject: [PATCH] 销售统计看板

---
 src/views/productionPlan/trackProgress/index.vue |  807 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 740 insertions(+), 67 deletions(-)

diff --git a/src/views/productionPlan/trackProgress/index.vue b/src/views/productionPlan/trackProgress/index.vue
index bd48010..9a4ceda 100644
--- a/src/views/productionPlan/trackProgress/index.vue
+++ b/src/views/productionPlan/trackProgress/index.vue
@@ -1,11 +1,24 @@
 <template>
   <div class="app-container">
-    <PageHeader content="鐢熶骇璁″垝杩借釜杩涘害">
+    <PageHeader v-if="applyNo"
+                content="鐢熶骇璁″垝杩借釜杩涘害">
     </PageHeader>
     <el-card style="height:82vh;overflow:auto;">
       <template #header>
         <div class="card-header">
-          <span>鐢宠鍗曠紪鍙� - {{ rowData.applyNo || '' }}</span>
+          <el-form :inline="true"
+                   :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-form-item>
+          </el-form>
         </div>
       </template>
       <!-- 鍩虹淇℃伅 -->
@@ -27,52 +40,6 @@
       </div>
       <div class="progress-container">
         <div class="progress-section">
-          <h3 class="section-title">杩涘害淇℃伅</h3>
-          <div class="progress-item">
-            <div class="progress-label">瀹屾垚杩涘害锛�</div>
-            <div class="progress-content">
-              <el-progress :percentage="trackProgressForm.completionRate"
-                           :color="customColors"
-                           :status="trackProgressForm.completionRate === 100 ? 'success' : ''" />
-            </div>
-          </div>
-          <div class="progress-item">
-            <div class="progress-label">杩涘害璇︽儏锛�</div>
-            <div class="progress-content">
-              <el-table :data="trackProgressForm.progressDetails"
-                        border
-                        style="width: auto; height: 300px">
-                <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
-                          @click="handleClickStep(row)">{{ 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>
-            </div>
-          </div>
-        </div>
-        <div class="progress-section">
           <h3 class="section-title">璁㈠崟淇℃伅</h3>
           <div v-for="item in rowData.orderList"
                :key="item.orderNo"
@@ -80,23 +47,206 @@
             <el-descriptions :column="3"
                              border>
               <el-descriptions-item label="璁㈠崟缂栧彿">{{ item.orderNo || '-' }}</el-descriptions-item>
-              <el-descriptions-item label="璁㈠崟鐘舵��">
+              <!-- <el-descriptions-item label="璁㈠崟鐘舵��">
                 <el-tag :type="getStatusType(item.status)">{{ getStatusText(item.status) }}</el-tag>
-              </el-descriptions-item>
+              </el-descriptions-item> -->
               <el-descriptions-item label="寮�濮嬫棩鏈�">{{ item.startTime || '-' }}</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="瀹屾垚杩涘害">
                 <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>
         </div>
       </div>
     </el-card>
+    <!-- 鐢熶骇鎶ュ伐璇︽儏寮圭獥 -->
+    <el-dialog v-model="detailDialogVisible"
+               :title="'鐢熶骇鎶ュ伐璇︽儏'"
+               width="1000px"
+               :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>
+              </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>
+              <!-- 鍙傛暟淇℃伅 -->
+              <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 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>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="detailDialogVisible = false">鍏抽棴</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -104,6 +254,7 @@
   import { ref, reactive, onMounted } from "vue";
   import { ElMessage } from "element-plus";
   import { useRouter, useRoute } from "vue-router";
+  import dayjs from "dayjs";
 
   const router = useRouter();
   const route = useRoute();
@@ -119,6 +270,16 @@
     progressDetails: [],
     remark: "",
   });
+
+  // 鎼滅储琛ㄥ崟
+  const searchForm = reactive({
+    applyNo: "",
+  });
+
+  // 鐢熶骇鎶ュ伐璇︽儏寮圭獥
+  const detailDialogVisible = ref(false);
+  const detailData = ref({});
+  const baseUrl = import.meta.env.VITE_APP_BASE_API;
 
   // 鑾峰彇鐘舵�佺被鍨�
   const getStatusType = status => {
@@ -153,7 +314,7 @@
   const generateProgressDetails = status => {
     const details = [
       {
-        step: "璁″垝纭",
+        step: "璁㈠崟鐢熸垚",
         status: "completed",
         quantity: 233,
         startTime: "2026-03-01 09:00:00",
@@ -231,6 +392,30 @@
     router.push("/productionPlan/productionPlan");
   };
 
+  // 澶勭悊鎼滅储
+  const handleSearch = () => {
+    const applyNo = searchForm.applyNo.trim();
+    if (!applyNo) {
+      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();
+  };
+
   // 鐢熸垚妯℃嫙璁㈠崟鏁版嵁
   const generateOrderList = () => {
     return [
@@ -239,6 +424,7 @@
         status: 1,
         quantity: 233.28,
         completeQuantity: 14,
+        remainingQuantity: 149.28,
         completionRate: 6,
         startTime: "2026-03-25",
       },
@@ -247,6 +433,7 @@
         status: 2,
         quantity: 150.5,
         completeQuantity: 100,
+        remainingQuantity: 50.5,
         completionRate: 67,
         startTime: "2026-03-20",
       },
@@ -255,30 +442,222 @@
         status: 0,
         quantity: 80.0,
         completeQuantity: 0,
+        remainingQuantity: 80.0,
         completionRate: 0,
         startTime: "2026-03-30",
       },
     ];
   };
 
+  // 澶勭悊鐐瑰嚮姝ラ鏌ョ湅璇︽儏
+  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;
+  };
+
+  // 鏍煎紡鍖栨椂闂�
+  const formatTime = time => {
+    return time ? dayjs(time).format("YYYY-MM-DD HH:mm:ss") : "-";
+  };
+
+  // 鏍煎紡鍖栨枃浠跺垪琛�
+  const formatFileList = fileList => {
+    return fileList.map(file => ({
+      name: file.fileName,
+      url: baseUrl + file.fileUrl,
+      size: file.fileSize,
+    }));
+  };
+
+  // 鑾峰彇BOM鍒楄〃
+  const getBomList = paramList => {
+    return paramList.filter(item => item.bomId);
+  };
+
+  // 鑾峰彇鍙傛暟鍒楄〃
+  const getParamList = paramList => {
+    return paramList.filter(item => !item.bomId);
+  };
+
+  // 鎸塻ourceSort鍒嗙粍鍙傛暟
+  const getParamGroups = paramList => {
+    const params = getParamList(paramList);
+    const groups = {};
+
+    params.forEach(param => {
+      const sort = param.sourceSort || 1;
+      if (!groups[sort]) {
+        groups[sort] = [];
+      }
+      // 璁$畻缁撴灉
+      let result = "鍚堟牸";
+      let standardText = "";
+      if (param.valueMode === 1) {
+        // 鍗曞�兼瘮杈�
+        if (param.standardValue !== null && param.standardValue !== undefined) {
+          standardText = param.standardValue;
+          if (param.paramValue !== param.standardValue) {
+            result = "涓嶅悎鏍�";
+          }
+        } else {
+          standardText = "-";
+          result = "鍚堟牸";
+        }
+      } else if (param.valueMode === 2) {
+        // 鍖洪棿姣旇緝
+        if (param.minValue !== null || param.maxValue !== null) {
+          standardText =
+            (param.minValue ? param.minValue : "-鈭�") +
+            "~" +
+            (param.maxValue ? param.maxValue : "+鈭�");
+          if (
+            param.paramValue < param.minValue ||
+            param.paramValue > param.maxValue
+          ) {
+            result = "涓嶅悎鏍�";
+          }
+        } else {
+          standardText = "-";
+          result = "鍚堟牸";
+        }
+      } else {
+        // 榛樿鎯呭喌
+        standardText = "-";
+        result = "鍚堟牸";
+      }
+      groups[sort].push({
+        ...param,
+        standardText,
+        result,
+      });
+    });
+
+    // 杞崲涓烘暟缁勬牸寮�
+    return Object.entries(groups).map(([key, items]) => ({
+      sourceSort: key,
+      items,
+    }));
+  };
+
+  // 涓轰笉鍚堟牸鐨勮娣诲姞鏍峰紡
+  const rowClassName = ({ row }) => {
+    return row.result === "涓嶅悎鏍�" ? "warning-row" : "";
+  };
+
+  const applyNo = ref(null);
   // 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
   onMounted(() => {
     // 浠庤矾鐢卞弬鏁颁腑鑾峰彇鏁版嵁
-    const data = route.query.row
-      ? JSON.parse(decodeURIComponent(route.query.row))
+    applyNo.value = route.query.applyNo
+      ? decodeURIComponent(route.query.applyNo)
       : null;
-    if (data) {
-      // 璧嬪�肩粰rowData
-      Object.assign(rowData, data);
-      // 璧嬪�肩粰琛ㄥ崟鏁版嵁
-      trackProgressForm.materialCode = data.materialCode;
-      trackProgressForm.currentStatus = data.status;
-      trackProgressForm.progressDetails = generateProgressDetails(data.status);
-      trackProgressForm.completionRate = calculateCompletionRate(
-        trackProgressForm.progressDetails
-      );
-      trackProgressForm.remark = "";
-    }
+    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();
   });
@@ -296,6 +675,14 @@
     justify-content: space-between;
     align-items: center;
     padding: 0 10px;
+  }
+
+  .search-form {
+    width: 100%;
+  }
+
+  .search-form .el-form-item {
+    margin-right: 10px;
   }
 
   .action-buttons {
@@ -379,6 +766,7 @@
     box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.08);
     flex: 1;
     transition: all 0.3s ease;
+    width: 100%;
   }
 
   .progress-section:hover {
@@ -438,4 +826,289 @@
     border-radius: 12px;
     padding: 2px 10px;
   }
+
+  /* 寮圭獥鏍峰紡 */
+  .detail-container {
+    max-height: 600px;
+    overflow-y: auto;
+    padding: 0 16px;
+  }
+
+  .process-item {
+    margin-bottom: 24px;
+    padding: 20px;
+    background-color: #ffffff;
+    border-radius: 8px;
+    border: 1px solid #ebeef5;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+  }
+
+  .process-header {
+    margin-bottom: 20px;
+    padding-bottom: 12px;
+    border-bottom: 1px solid #f0f2f5;
+  }
+
+  .process-title {
+    font-size: 15px;
+    font-weight: 600;
+    margin-bottom: 12px;
+    color: #1a1a1a;
+    display: flex;
+    align-items: center;
+  }
+
+  .process-title::before {
+    content: "";
+    display: inline-block;
+    width: 4px;
+    height: 16px;
+    background-color: #409eff;
+    margin-right: 8px;
+    border-radius: 2px;
+  }
+
+  .process-info {
+    display: flex;
+    gap: 20px;
+    font-size: 13px;
+    color: #606266;
+  }
+
+  .process-label {
+    padding: 4px 12px;
+    background-color: #ecf5ff;
+    border-radius: 4px;
+    color: #409eff;
+    font-weight: 500;
+  }
+
+  .process-details {
+    margin-bottom: 20px;
+  }
+
+  .param-section {
+    margin-bottom: 20px;
+    background-color: #f9f9f9;
+    border-radius: 6px;
+    padding: 16px;
+    border: 1px solid #f0f2f5;
+  }
+
+  .param-title {
+    font-size: 14px;
+    font-weight: 600;
+    margin-bottom: 14px;
+    color: #1a1a1a;
+    padding-bottom: 8px;
+    border-bottom: 1px solid #e8e8e8;
+  }
+
+  .file-section {
+    margin-top: 20px;
+    background-color: #f9f9f9;
+    border-radius: 6px;
+    padding: 16px;
+    border: 1px solid #f0f2f5;
+  }
+
+  .file-title {
+    font-size: 14px;
+    font-weight: 600;
+    margin-bottom: 14px;
+    color: #1a1a1a;
+    padding-bottom: 8px;
+    border-bottom: 1px solid #e8e8e8;
+  }
+
+  .file-grid {
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
+    gap: 16px;
+  }
+
+  .file-item {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    background-color: #ffffff;
+    border: 1px solid #e8e8e8;
+    border-radius: 6px;
+    padding: 10px;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+    transition: all 0.3s ease;
+  }
+
+  .file-item:hover {
+    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+    border-color: #409eff;
+    transform: translateY(-2px);
+  }
+
+  .file-info {
+    width: 100%;
+    text-align: center;
+  }
+
+  .file-name {
+    font-size: 12px;
+    color: #606266;
+    word-break: break-all;
+    line-height: 1.4;
+  }
+
+  .param-group {
+    margin-bottom: 16px;
+    padding: 14px;
+    background-color: #ffffff;
+    border-radius: 6px;
+    border: 1px solid #e8e8e8;
+  }
+
+  .group-header {
+    margin-bottom: 12px;
+    padding-bottom: 8px;
+    border-bottom: 1px solid #f0f2f5;
+  }
+
+  .num1 {
+    color: #1107cc;
+    font-weight: 600;
+  }
+
+  .num2 {
+    color: #0fcf25;
+    font-weight: 600;
+  }
+
+  .num3 {
+    color: #d31818;
+    font-weight: 600;
+  }
+
+  .group-title {
+    font-size: 14px;
+    font-weight: 600;
+    color: #303133;
+  }
+
+  .param-grid {
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+    gap: 16px;
+  }
+
+  .param-item {
+    display: flex;
+    align-items: center;
+    gap: 12px;
+    padding: 8px 0;
+    border-bottom: 1px solid #f5f7fa;
+  }
+
+  .param-item:last-child {
+    border-bottom: none;
+  }
+
+  .param-label {
+    font-size: 13px;
+    color: #606266;
+    min-width: 100px;
+    font-weight: 500;
+  }
+
+  .param-value {
+    font-size: 13px;
+    color: #1a1a1a;
+    font-weight: 600;
+    flex: 1;
+  }
+
+  .param-unit {
+    font-size: 12px;
+    color: #909399;
+    background-color: #f0f2f5;
+    padding: 2px 6px;
+    border-radius: 3px;
+  }
+
+  .dialog-footer {
+    text-align: center;
+    padding: 20px;
+    border-top: 1px solid #ebeef5;
+  }
+
+  .dialog-footer .el-button {
+    min-width: 100px;
+    padding: 8px 20px;
+  }
+
+  /* 鑷畾涔夊璇濇鏍峰紡 */
+  :deep(.custom-dialog) {
+    border-radius: 12px;
+    overflow: hidden;
+  }
+
+  :deep(.custom-dialog .el-dialog__header) {
+    background-color: #f5f7fa;
+    padding: 20px;
+    border-bottom: 1px solid #ebeef5;
+  }
+
+  :deep(.custom-dialog .el-dialog__title) {
+    font-size: 18px;
+    font-weight: 600;
+    color: #1a1a1a;
+  }
+
+  :deep(.custom-dialog .el-dialog__body) {
+    padding: 20px;
+  }
+
+  /* 琛ㄦ牸鏍峰紡浼樺寲 */
+  :deep(.el-table) {
+    border-radius: 6px;
+    overflow: hidden;
+  }
+
+  :deep(.el-table th) {
+    background-color: #f5f7fa;
+    font-weight: 600;
+    color: #303133;
+  }
+
+  :deep(.el-table tr:hover > td) {
+    background-color: #ecf5ff !important;
+  }
+
+  /* 鎻忚堪鍒楄〃鏍峰紡浼樺寲 */
+  :deep(.el-descriptions) {
+    border-radius: 6px;
+    overflow: hidden;
+  }
+
+  :deep(.el-descriptions__label) {
+    font-weight: 500;
+    color: #606266;
+  }
+
+  :deep(.el-descriptions__content) {
+    color: #1a1a1a;
+    font-weight: 500;
+  }
+
+  /* 涓嶅悎鏍艰鏍峰紡 */
+  :deep(.el-table .warning-row) {
+    background-color: #fef0f0 !important;
+  }
+
+  .detail-card {
+    border-radius: 8px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+  }
+
+  .card-header {
+    font-weight: 600;
+    color: #303133;
+  }
 </style>
\ No newline at end of file

--
Gitblit v1.9.3