From e545f964005b0c80b29a4417ca8275570778ac75 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期六, 14 三月 2026 13:29:44 +0800
Subject: [PATCH] 工艺路线加上产品和bom 样式优化

---
 src/views/productionManagement/processRoute/index.vue |  236 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 224 insertions(+), 12 deletions(-)

diff --git a/src/views/productionManagement/processRoute/index.vue b/src/views/productionManagement/processRoute/index.vue
index 33b57ad..afdd542 100644
--- a/src/views/productionManagement/processRoute/index.vue
+++ b/src/views/productionManagement/processRoute/index.vue
@@ -59,15 +59,41 @@
           </div>
         </div>
         <div class="card-body">
-          <div class="route-desc">{{ route.routeDesc || '鏆傛棤鎻忚堪' }}</div>
-          <el-button type="primary"
-                     link
-                     @click="toggleExpand(route)">
-            {{ route.expanded ? '鏀惰捣' : '灞曞紑宸ュ簭璺嚎' }}
-            <el-icon class="expand-icon">
-              <component :is="route.expanded ? 'ArrowUp' : 'ArrowDown'" />
-            </el-icon>
-          </el-button>
+          <div class="route-meta">
+            <span class="meta-item">
+              <el-icon>
+                <Box />
+              </el-icon>
+              <span class="meta-label">浜у搧:</span>
+              <span class="meta-value">{{ route.productName }} - {{ route.productModelName }}</span>
+            </span>
+            <span class="meta-item">
+              <el-icon>
+                <Document />
+              </el-icon>
+              <span class="meta-label">BOM:</span>
+              <span class="meta-value">{{ route.bomId || '-' }}</span>
+            </span>
+            <span class="meta-item">
+              <el-icon>
+                <Document />
+              </el-icon>
+              <span class="meta-label">璺嚎鎻忚堪:</span>
+              <span class="meta-value">{{ route.routeDesc || '鏆傛棤鎻忚堪' }}</span>
+            </span>
+          </div>
+          <div class="expand-btn-wrapper">
+            <el-button class="expand-btn"
+                       :class="{ expanded: route.expanded }"
+                       type="primary"
+                       text
+                       @click="toggleExpand(route)">
+              <span class="btn-text">{{ route.expanded ? '鏀惰捣宸ュ簭璺嚎' : '灞曞紑宸ュ簭璺嚎' }}</span>
+              <el-icon class="expand-icon">
+                <component :is="route.expanded ? 'ArrowUp' : 'ArrowDown'" />
+              </el-icon>
+            </el-button>
+          </div>
         </div>
         <div v-if="route.expanded"
              class="process-route">
@@ -189,6 +215,28 @@
                :rules="routeRules"
                ref="routeFormRef"
                label-width="120px">
+        <el-form-item label="浜у搧鍚嶇О"
+                      prop="productModelId">
+          <el-button type="primary"
+                     @click="showProductSelectDialog = true">
+            {{ routeForm.productName && routeForm.productModelName 
+              ? `${routeForm.productName} - ${routeForm.productModelName}` 
+              : '閫夋嫨浜у搧' }}
+          </el-button>
+        </el-form-item>
+        <el-form-item label="BOM"
+                      prop="bomId">
+          <el-select v-model="routeForm.bomId"
+                     placeholder="璇烽�夋嫨BOM"
+                     clearable
+                     :disabled="!routeForm.productModelId || bomOptions.length === 0"
+                     style="width: 100%">
+            <el-option v-for="item in bomOptions"
+                       :key="item.id"
+                       :label="item.bomNo || `BOM-${item.id}`"
+                       :value="item.id" />
+          </el-select>
+        </el-form-item>
         <el-form-item label="璺嚎缂栫爜"
                       prop="routeCode">
           <el-input v-model="routeForm.routeCode"
@@ -222,6 +270,10 @@
         </span>
       </template>
     </el-dialog>
+    <!-- 浜у搧閫夋嫨寮圭獥 -->
+    <ProductSelectDialog v-model="showProductSelectDialog"
+                         @confirm="handleProductSelect"
+                         single />
     <!-- 宸ュ簭鏂板/缂栬緫瀵硅瘽妗� -->
     <el-dialog v-model="processDialogVisible"
                :title="isProcessEdit ? '缂栬緫宸ュ簭' : '鏂板宸ュ簭'"
@@ -441,7 +493,7 @@
 </template>
 
 <script setup>
-  import { ref, reactive } from "vue";
+  import { ref, reactive, getCurrentInstance } from "vue";
   import { ElMessage, ElMessageBox } from "element-plus";
   import {
     Plus,
@@ -453,12 +505,23 @@
     Search,
     Check,
     Close,
+    Box,
+    Document,
   } from "@element-plus/icons-vue";
   import { listType } from "@/api/system/dict/type";
+  import { getByModel } from "@/api/productionManagement/productBom.js";
+  import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
 
   // 宸ヨ壓璺嚎鍒楄〃
   const routeList = ref([]);
   const dictTypes = ref([]);
+
+  // 鑾峰彇鍏ㄥ眬瀹炰緥
+  const { proxy } = getCurrentInstance();
+
+  // 浜у搧閫夋嫨鍜孊OM鐩稿叧
+  const showProductSelectDialog = ref(false);
+  const bomOptions = ref([]);
 
   // 宸ヨ壓璺嚎瀵硅瘽妗�
   const routeDialogVisible = ref(false);
@@ -466,12 +529,20 @@
   const routeFormRef = ref(null);
   const routeForm = reactive({
     id: null,
+    productModelId: null,
+    productName: "",
+    productModelName: "",
+    bomId: null,
     routeCode: "",
     routeName: "",
     routeDesc: "",
     status: "1",
   });
   const routeRules = {
+    productModelId: [
+      { required: true, message: "璇烽�夋嫨浜у搧", trigger: "change" },
+    ],
+    bomId: [{ required: true, message: "璇烽�夋嫨BOM", trigger: "change" }],
     routeCode: [{ required: true, message: "璇疯緭鍏ヨ矾绾跨紪鐮�", trigger: "blur" }],
     routeName: [{ required: true, message: "璇疯緭鍏ヨ矾绾垮悕绉�", trigger: "blur" }],
   };
@@ -537,6 +608,10 @@
     routeList.value = [
       {
         id: 1,
+        productModelId: 1,
+        productName: "鏍囧噯鐮屽潡",
+        productModelName: "3.5鍨�",
+        bomId: 1,
         routeCode: "ROUTE001",
         routeName: "鏍囧噯鐮屽潡鐢熶骇绾�",
         routeDesc: "鏍囧噯鐮屽潡鐢熶骇娴佺▼",
@@ -606,6 +681,10 @@
       },
       {
         id: 2,
+        productModelId: 2,
+        productName: "鏉挎潗",
+        productModelName: "5.0鍨�",
+        bomId: 2,
         routeCode: "ROUTE002",
         routeName: "鏉挎潗鐢熶骇绾�",
         routeDesc: "鏉挎潗鐢熶骇娴佺▼",
@@ -651,16 +730,25 @@
   const handleAddRoute = () => {
     isRouteEdit.value = false;
     routeForm.id = null;
+    routeForm.productModelId = null;
+    routeForm.productName = "";
+    routeForm.productModelName = "";
+    routeForm.bomId = null;
     routeForm.routeCode = "";
     routeForm.routeName = "";
     routeForm.routeDesc = "";
     routeForm.status = "1";
+    bomOptions.value = [];
     routeDialogVisible.value = true;
   };
 
   const handleEditRoute = route => {
     isRouteEdit.value = true;
     routeForm.id = route.id;
+    routeForm.productModelId = route.productModelId;
+    routeForm.productName = route.productName;
+    routeForm.productModelName = route.productModelName;
+    routeForm.bomId = route.bomId;
     routeForm.routeCode = route.routeCode;
     routeForm.routeName = route.routeName;
     routeForm.routeDesc = route.routeDesc;
@@ -687,6 +775,42 @@
         getRouteList();
       }
     });
+  };
+
+  // 浜у搧閫夋嫨澶勭悊
+  const handleProductSelect = async products => {
+    if (products && products.length > 0) {
+      const product = products[0];
+      // 鍏堟煡璇OM鍒楄〃锛堝繀閫夛級
+      try {
+        const res = await getByModel(product.id);
+        // 澶勭悊杩斿洖鐨凚OM鏁版嵁锛氬彲鑳芥槸鏁扮粍銆佸璞℃垨鍖呭惈data瀛楁
+        let bomList = [];
+        if (Array.isArray(res)) {
+          bomList = res;
+        } else if (res && res.data) {
+          bomList = Array.isArray(res.data) ? res.data : [res.data];
+        } else if (res && typeof res === "object") {
+          bomList = [res];
+        }
+
+        if (bomList.length > 0) {
+          routeForm.productModelId = product.id;
+          routeForm.productName = product.productName;
+          routeForm.productModelName = product.model;
+          routeForm.bomId = undefined; // 閲嶇疆BOM閫夋嫨
+          bomOptions.value = bomList;
+          showProductSelectDialog.value = false;
+          // 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
+          proxy.$refs["routeFormRef"]?.validateField("productModelId");
+        } else {
+          proxy.$modal.msgError("璇ヤ骇鍝佹病鏈塀OM锛岃鍏堝垱寤築OM");
+        }
+      } catch (error) {
+        // 濡傛灉鎺ュ彛杩斿洖404鎴栧叾浠栭敊璇紝璇存槑娌℃湁BOM
+        proxy.$modal.msgError("璇ヤ骇鍝佹病鏈塀OM锛岃鍏堝垱寤築OM");
+      }
+    }
   };
 
   const handleApproveRoute = route => {
@@ -1062,8 +1186,96 @@
         margin-bottom: 12px;
       }
 
-      .expand-icon {
-        margin-left: 4px;
+      .route-meta {
+        display: flex;
+        gap: 24px;
+        margin-bottom: 12px;
+        padding: 10px 14px;
+        background: linear-gradient(135deg, #f5f7fa 0%, #e8ecf1 100%);
+        border-radius: 8px;
+        border-left: 3px solid #409eff;
+
+        .meta-item {
+          display: flex;
+          align-items: center;
+          gap: 6px;
+          font-size: 13px;
+          margin-right: 40px;
+
+          .el-icon {
+            font-size: 14px;
+            color: #409eff;
+          }
+
+          .meta-label {
+            color: #909399;
+            font-weight: 500;
+          }
+
+          .meta-value {
+            color: #303133;
+            font-weight: 600;
+          }
+        }
+      }
+
+      .expand-btn-wrapper {
+        display: flex;
+        justify-content: center;
+        margin-top: 8px;
+
+        .expand-btn {
+          padding: 8px 20px;
+          border-radius: 20px;
+          background: linear-gradient(135deg, #ecf5ff 0%, #d9ecff 100%);
+          border: 1px solid #b3d8ff;
+          transition: all 0.3s ease;
+
+          .btn-text {
+            font-size: 13px;
+            font-weight: 500;
+            color: #409eff;
+            margin-right: 6px;
+          }
+
+          .expand-icon {
+            font-size: 14px;
+            color: #409eff;
+            transition: transform 0.3s ease;
+          }
+
+          &:hover {
+            background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
+            border-color: #409eff;
+            box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
+
+            .btn-text,
+            .expand-icon {
+              color: #fff;
+            }
+          }
+
+          &.expanded {
+            background: linear-gradient(135deg, #f0f9eb 0%, #e1f3d8 100%);
+            border-color: #a5d69a;
+
+            .btn-text,
+            .expand-icon {
+              color: #67c23a;
+            }
+
+            &:hover {
+              background: linear-gradient(135deg, #67c23a 0%, #85ce61 100%);
+              border-color: #67c23a;
+              box-shadow: 0 4px 12px rgba(103, 194, 58, 0.3);
+
+              .btn-text,
+              .expand-icon {
+                color: #fff;
+              }
+            }
+          }
+        }
       }
     }
 

--
Gitblit v1.9.3