From 1e697f13a97c01a460946bcf93d4d0baf09fcf17 Mon Sep 17 00:00:00 2001
From: 张诺 <zhang_12370@163.com>
Date: 星期二, 21 四月 2026 11:35:12 +0800
Subject: [PATCH] BOM模块移植,更新API路径并优化数据处理逻辑

---
 src/views/productionManagement/productStructure/Detail/index.vue |  114 +++++++++++++++++++++++++++++--------
 src/api/productionManagement/productStructure.js                 |   16 ++--
 src/api/productionManagement/productBom.js                       |   16 ++--
 src/views/productionManagement/productStructure/index.vue        |    2 
 4 files changed, 106 insertions(+), 42 deletions(-)

diff --git a/src/api/productionManagement/productBom.js b/src/api/productionManagement/productBom.js
index 2badea8..097d223 100644
--- a/src/api/productionManagement/productBom.js
+++ b/src/api/productionManagement/productBom.js
@@ -4,7 +4,7 @@
 // 鍒嗛〉鏌ヨ
 export function listPage(query) {
   return request({
-    url: "/productBom/listPage",
+    url: "/technologyBom/listPage",
     method: "get",
     params: query,
   });
@@ -13,7 +13,7 @@
 // 鏂板
 export function add(data) {
   return request({
-    url: "/productBom/add",
+    url: "/technologyBom/add",
     method: "post",
     data: data,
   });
@@ -22,7 +22,7 @@
 // 淇敼
 export function update(data) {
   return request({
-    url: "/productBom/update",
+    url: "/technologyBom/update",
     method: "put",
     data: data,
   });
@@ -31,7 +31,7 @@
 // 鎵归噺鍒犻櫎
 export function batchDelete(ids) {
   return request({
-    url: "/productBom/batchDelete",
+    url: "/technologyBom/batchDelete",
     method: "delete",
     data: ids,
   });
@@ -40,7 +40,7 @@
 // 鏍规嵁浜у搧鍨嬪彿ID鏌ヨBOM
 export function getByModel(productModelId) {
   return request({
-    url: "/productBom/getByModel",
+    url: "/technologyBom/getByModel",
     method: "get",
     params: { productModelId },
   });
@@ -49,7 +49,7 @@
 // 瀵煎嚭BOM
 export function exportBom(bomId) {
   return request({
-    url: "/productBom/exportBom",
+    url: "/technologyBom/exportBom",
     method: "post",
     params: { bomId },
     responseType: "blob",
@@ -59,8 +59,8 @@
 //  涓嬭浇妯℃澘
 export function downloadTemplate() {
   return request({
-    url: "/productBom/downloadTemplate",
+    url: "/technologyBom/downloadTemplate",
     method: "get",
     responseType: "blob",
   });
-}
\ No newline at end of file
+}
diff --git a/src/api/productionManagement/productStructure.js b/src/api/productionManagement/productStructure.js
index 5062e04..3b189e1 100644
--- a/src/api/productionManagement/productStructure.js
+++ b/src/api/productionManagement/productStructure.js
@@ -4,7 +4,7 @@
 // 鍒嗛〉鏌ヨ
 export function queryList(id) {
   return request({
-    url: "/productStructure/listBybomId/" + id,
+    url: "/technologyBomStructure/listByBomId/" + id,
     method: "get",
   });
 }
@@ -16,13 +16,13 @@
   });
 }
 
-// export function add(data) {
-//   return request({
-//     url: "/productStructure",
-//     method: "post",
-//     data: data,
-//   });
-// }
+export function addBomDetail(data) {
+  return request({
+    url: "/technologyBomStructure",
+    method: "post",
+    data: data,
+  });
+}
 // 鍒嗛〉鏌ヨ-浜у搧璁㈠崟
 export function queryList2(id) {
   return request({
diff --git a/src/views/productionManagement/productStructure/Detail/index.vue b/src/views/productionManagement/productStructure/Detail/index.vue
index 6734830..6fbe21b 100644
--- a/src/views/productionManagement/productStructure/Detail/index.vue
+++ b/src/views/productionManagement/productStructure/Detail/index.vue
@@ -64,6 +64,7 @@
                                filterable
                                clearable
                                style="width: 100%"
+                               @change="value => handleProcessChange(row, value)"
                                :disabled="!dataValue.isEdit || dataValue.dataList.some(item => (item as any).tempId === row.tempId)">
                       <el-option v-for="item in dataValue.processOptions"
                                  :key="item.id"
@@ -148,6 +149,7 @@
     </el-table>
     <product-select-dialog v-if="dataValue.showProductDialog"
                            v-model:model-value="dataValue.showProductDialog"
+                           :single="true"
                            @confirm="handleProduct" />
   </div>
 </template>
@@ -161,7 +163,7 @@
     reactive,
     ref,
   } from "vue";
-  import { queryList, add } from "@/api/productionManagement/productStructure.js";
+  import { queryList, addBomDetail } from "@/api/productionManagement/productStructure.js";
   import { listProcessBom } from "@/api/productionManagement/productionOrder.js";
   import { list } from "@/api/productionManagement/productionProcess";
   import { ElMessage } from "element-plus";
@@ -212,6 +214,71 @@
     isEdit: false,
   });
 
+  const normalizeListData = (source: any) => {
+    if (Array.isArray(source)) {
+      return source;
+    }
+    if (Array.isArray(source?.records)) {
+      return source.records;
+    }
+    return [];
+  };
+
+  const getProcessOptionById = (id: any) => {
+    if (id === undefined || id === null || id === "") {
+      return null;
+    }
+    return normalizeListData(dataValue.processOptions).find(
+      option => String(option.id) === String(id)
+    ) || null;
+  };
+
+  const syncProcessOperationFields = (item: any) => {
+    const processId = item.processId ?? item.operationId ?? "";
+    if (!processId) {
+      item.processId = "";
+      item.operationId = "";
+      item.processName = "";
+      item.operationName = "";
+      return;
+    }
+
+    const option = getProcessOptionById(processId);
+    const processName =
+      option?.name || item.processName || item.operationName || "";
+
+    item.processId = processId;
+    item.operationId = processId;
+    item.processName = processName;
+    item.operationName = processName;
+  };
+
+  const normalizeTreeData = (items: any[]) => {
+    items.forEach((item: any) => {
+      item.tempId = item.tempId || item.id || `${Date.now()}_${Math.random()}`;
+      syncProcessOperationFields(item);
+      if (Array.isArray(item.children) && item.children.length > 0) {
+        normalizeTreeData(item.children);
+      }
+    });
+  };
+
+  const buildSubmitTree = (items: any[]) => {
+    return items.map((item: any) => {
+      const current = { ...item };
+      syncProcessOperationFields(current);
+      current.children = Array.isArray(current.children)
+        ? buildSubmitTree(current.children)
+        : [];
+      return current;
+    });
+  };
+
+  const handleProcessChange = (row: any, value: any) => {
+    row.processId = value || "";
+    syncProcessOperationFields(row);
+  };
+
   const tableData = reactive([
     {
       productName: "",
@@ -231,37 +298,30 @@
       // 璁㈠崟鎯呭喌锛氫娇鐢ㄨ鍗曠殑浜у搧缁撴瀯鎺ュ彛
       const { data } = await listProcessBom({ orderId: routeOrderId.value });
       dataValue.dataList = (data as any) || [];
+      normalizeTreeData(dataValue.dataList);
     } else {
       // 闈炶鍗曟儏鍐碉細浣跨敤鍘熸潵鐨勬帴鍙�
       const { data } = await queryList(routeId.value);
       dataValue.dataList = (data as any) || [];
-      // 涓烘墍鏈夐」鍙婂叾瀛愰」璁剧疆name灞炴��
-      const setNameRecursively = (items: any[]) => {
-        items.forEach((item: any) => {
-          item.tempId = item.id;
-          item.processName =
-            dataValue.processOptions.find(option => option.id === item.processId)
-              ?.name || "";
-          if (item.children && item.children.length > 0) {
-            setNameRecursively(item.children);
-          }
-        });
-      };
-      setNameRecursively(dataValue.dataList);
+      console.log(dataValue);
+      normalizeTreeData(dataValue.dataList);
       console.log(dataValue.dataList, "dataValue.dataList");
     }
   };
 
   const fetchProcessOptions = async () => {
-    const { data } = await list();
-    dataValue.processOptions = data as any;
+    const { data } = await list({});
+    console.log(data, "dataValue.dataList");
+    dataValue.processOptions = normalizeListData(data);
   };
 
   const handleProduct = (row: any) => {
-    if (row?.length > 1) {
-      ElMessage.error("鍙兘閫夋嫨涓�涓骇鍝�");
+    if (!Array.isArray(row) || row.length === 0) {
+      ElMessage.warning("璇烽�夋嫨涓�涓骇鍝�");
+      return;
     }
-    const productData = row[0];
+    // 鍙厑璁镐竴涓細濡傛灉涓婃父杩斿洖浜嗗涓紝榛樿浣跨敤鏈�鍚庝竴娆¢�夋嫨骞惰鐩栧綋鍓嶅��
+    const productData = row[row.length - 1];
 
     //  鏈�澶栧眰缁勪欢涓紝涓庡綋鍓嶄骇鍝佺浉鍚岀殑浜у搧鍙兘鏈変竴涓�
     const isTopLevel = dataValue.dataList.some(
@@ -371,19 +431,18 @@
 
   const submit = () => {
     dataValue.loading = true;
+    normalizeTreeData(dataValue.dataList);
 
     // 鍏堣繘琛岃〃鍗曟牎楠�
     const valid = validateAll();
     console.log(dataValue.dataList, "dataValue.dataList");
     if (valid) {
-      add({
+      addBomDetail({
         bomId: routeId.value,
-        children: dataValue.dataList || [],
+        children: buildSubmitTree(dataValue.dataList || []),
       })
         .then(res => {
-          router.push({
-            path: "/productionManagement/productionManagement/productStructure/index",
-          });
+          router.go(-1);
           ElMessage.success("淇濆瓨鎴愬姛");
           dataValue.loading = false;
         })
@@ -441,6 +500,8 @@
           productModelId: undefined,
           processId: "",
           processName: "",
+          operationId: "",
+          operationName: "",
           unitQuantity: 0,
           demandedQuantity: 0,
           unit: "",
@@ -467,6 +528,9 @@
         model: undefined,
         productModelId: undefined,
         processId: "",
+        processName: "",
+        operationId: "",
+        operationName: "",
         unitQuantity: 0,
         demandedQuantity: 0,
         children: [],
@@ -518,4 +582,4 @@
     await fetchProcessOptions();
     await fetchData();
   });
-</script>
\ No newline at end of file
+</script>
diff --git a/src/views/productionManagement/productStructure/index.vue b/src/views/productionManagement/productStructure/index.vue
index bc5a538..8c9cfd1 100644
--- a/src/views/productionManagement/productStructure/index.vue
+++ b/src/views/productionManagement/productStructure/index.vue
@@ -141,7 +141,7 @@
   // 璁剧疆涓婁紶鐨勮姹傚ご閮�
   headers: { Authorization: "Bearer " + getToken() },
   // 涓婁紶鐨勫湴鍧�
-  url: import.meta.env.VITE_APP_BASE_API + "/productBom/uploadBom"
+  url: import.meta.env.VITE_APP_BASE_API + "/technologyBom/uploadBom"
 });
 
 const page = reactive({

--
Gitblit v1.9.3