From 1c15c3ddecdb0284a47eb763cbfcf6978fcb186b Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 28 四月 2026 10:23:53 +0800
Subject: [PATCH] Merge branch 'dev_NEW_pro' of http://114.132.189.42:9002/r/product-inventory-management into dev_NEW_pro

---
 src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue |  183 +++++++++++++++++++++++++++++++--------------
 1 files changed, 125 insertions(+), 58 deletions(-)

diff --git a/src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue b/src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue
index 6b040d6..991f2a1 100644
--- a/src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue
+++ b/src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue
@@ -13,25 +13,25 @@
                 border
                 row-key="tempId">
         <el-table-column label="宸ュ簭鍚嶇О"
-                         min-width="180">
+                         min-width="140">
           <template #default="{ row }">
-            <span v-if="row.bom === true">{{ row.processName || "-" }}</span>
+            <span v-if="row.bom === true">{{ row.operationName || "-" }}</span>
             <el-select v-else
-                       v-model="row.processName"
+                       v-model="row.operationName"
                        placeholder="璇烽�夋嫨宸ュ簭"
                        clearable
                        filterable
                        style="width: 100%;"
                        @change="val => handleProcessNameChange(row, val)">
               <el-option v-for="item in processOptions"
-                         :key="item.id"
+                         :key="item.technologyOperationId"
                          :label="item.name"
                          :value="item.name" />
             </el-select>
           </template>
         </el-table-column>
         <el-table-column label="鍘熸枡鍚嶇О"
-                         min-width="160">
+                         min-width="140">
           <template #default="{ row }">
             <span v-if="row.bom === true">{{ row.materialName || "-" }}</span>
             <el-button v-else
@@ -43,17 +43,37 @@
           </template>
         </el-table-column>
         <el-table-column label="鍘熸枡鍨嬪彿"
-                         min-width="180">
+                         min-width="140">
           <template #default="{ row }">
             {{ row.materialModel || "-" }}
+          </template>
+        </el-table-column>
+        <!-- 鎵瑰彿澶氶�� -->
+        <el-table-column min-width="200">
+          <template #header>
+            <span style="color: #f56c6c; margin-right: 4px;">*</span>
+            <span>鎵瑰彿</span>
+          </template>
+          <template #default="{ row }">
+            <el-select v-model="row.batchNo"
+                       multiple
+                       collapse-tags
+                       collapse-tags-indicator
+                       placeholder="璇烽�夋嫨鎵瑰彿"
+                       style="width: 100%;">
+              <el-option v-for="item in row.batchNoList"
+                         :key="item"
+                         :label="item"
+                         :value="item" />
+            </el-select>
           </template>
         </el-table-column>
         <el-table-column label="闇�姹傛暟閲�"
                          min-width="120">
           <template #default="{ row }">
-            <span v-if="row.bom === true">{{ row.requiredQty ?? "-" }}</span>
+            <span v-if="row.bom === true">{{ row.demandedQuantity ?? "-" }}</span>
             <el-input-number v-else
-                             v-model="row.requiredQty"
+                             v-model="row.demandedQuantity"
                              :min="0"
                              :precision="3"
                              :step="1"
@@ -63,7 +83,7 @@
           </template>
         </el-table-column>
         <el-table-column label="璁¢噺鍗曚綅"
-                         width="120">
+                         width="100">
           <template #default="{ row }">
             {{ row.unit || "-" }}
           </template>
@@ -110,12 +130,18 @@
   import { computed, ref, watch } from "vue";
   import { ElMessage } from "element-plus";
   import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
-  import { findProductProcessRouteItemList } from "@/api/productionManagement/productProcessRoute.js";
+  import {
+    findProductProcessRouteItemList,
+    listMain,
+  } from "@/api/productionManagement/productProcessRoute.js";
   import {
     listMaterialPickingDetail,
+    listMaterialPickingBom,
     listMaterialPickingLedger,
     saveMaterialPickingLedger,
+    updateMaterialPickingLedger,
   } from "@/api/productionManagement/productionOrder.js";
+  import { queryList2 } from "@/api/productionManagement/productStructure.js";
 
   const props = defineProps({
     modelValue: { type: Boolean, default: false },
@@ -139,16 +165,22 @@
   const createMaterialRow = (row = {}) => ({
     tempId: row.id || `temp_${++materialTempId}`,
     id: row.id,
-    processId: row.processId,
-    productProcessId: row.productProcessId || row.processId,
-    processName: row.processName || "",
+    processId: row.processId || row.technologyOperationId,
+    technologyOperationId: row.technologyOperationId || row.processId,
+    operationName: row.operationName || "",
     bom: row.bom === true,
-    materialModelId: row.materialModelId,
-    materialName: row.materialName || "",
-    materialModel: row.materialModel || "",
-    requiredQty: Number(row.requiredQty ?? 0),
+    materialModelId: row.materialModelId || row.productModelId,
+    materialName: row.materialName || row.productName || "",
+    materialModel: row.materialModel || row.model || "",
+    demandedQuantity: Number(row.requiredQty ?? row.demandedQuantity ?? 0),
     unit: row.unit || "",
-    pickQty: Number(row.pickQty ?? row.requiredQty ?? 0),
+    pickQty: Number(row.pickQty ?? row.pickQuantity ?? 0),
+    batchNo: row.batchNo
+      ? typeof row.batchNo === "string"
+        ? row.batchNo.split(",")
+        : row.batchNo
+      : [],
+    batchNoList: row.batchNoList || [],
   });
 
   const getProcessOptions = async () => {
@@ -161,19 +193,20 @@
       : res?.data?.records || [];
     const processMap = new Map();
     routeList.forEach(item => {
-      const processId = item.processId;
-      const processName = item.processName;
-      if (!processId || !processName) return;
-      const key = `${processId}_${processName}`;
+      const processId = item.technologyOperationId;
+      const operationName = item.operationName;
+      if (!processId || !operationName) return;
+      const key = `${processId}_${operationName}`;
       if (!processMap.has(key)) {
         processMap.set(key, {
           id: processId,
-          name: processName,
+          name: operationName,
         });
       }
     });
     processOptions.value = Array.from(processMap.values());
   };
+  const isDetail = ref(true);
 
   const loadMaterialData = async () => {
     if (!props.orderRow?.id) return;
@@ -181,23 +214,23 @@
     materialTableData.value = [];
     await getProcessOptions();
     try {
-      const detailRes = await listMaterialPickingDetail({
-        orderId: props.orderRow.id,
-      });
+      const detailRes = await listMaterialPickingDetail(props.orderRow.id);
       const detailList = Array.isArray(detailRes?.data)
         ? detailRes.data
         : detailRes?.data?.records || [];
       if (detailList.length > 0) {
+        isDetail.value = true;
         materialTableData.value = detailList.map(item => createMaterialRow(item));
         return;
+      } else {
+        isDetail.value = false;
+        const bomRes = await listMaterialPickingBom(props.orderRow.id);
+        const bomList = Array.isArray(bomRes?.data)
+          ? bomRes.data
+          : bomRes?.data?.records || [];
+        materialTableData.value = bomList.map(item => createMaterialRow(item));
+        return;
       }
-      const ledgerRes = await listMaterialPickingLedger({
-        orderId: props.orderRow.id,
-      });
-      const ledgerList = Array.isArray(ledgerRes?.data)
-        ? ledgerRes.data
-        : ledgerRes?.data?.records || [];
-      materialTableData.value = ledgerList.map(item => createMaterialRow(item));
     } finally {
       materialTableLoading.value = false;
     }
@@ -225,14 +258,16 @@
     materialTableData.value.splice(index, 1);
   };
 
-  const handleProcessNameChange = (row, processName) => {
-    const process = processOptions.value.find(item => item.name === processName);
-    row.productProcessId = process?.id;
+  const handleProcessNameChange = (row, operationName) => {
+    const process = processOptions.value.find(
+      item => item.name === operationName
+    );
+    row.technologyOperationId = process?.technologyOperationId;
   };
 
   const handleRequiredQtyChange = (row, val) => {
     const required = Number(val ?? 0);
-    row.requiredQty = required;
+    row.demandedQuantity = required;
     if (!row.pickQty || Number(row.pickQty) === 0) {
       row.pickQty = required;
     }
@@ -246,6 +281,8 @@
   };
 
   const handleMaterialProductConfirm = products => {
+    console.log(products, "products");
+
     if (!products || products.length === 0) return;
     const index = currentMaterialSelectRowIndex.value;
     if (index < 0 || !materialTableData.value[index]) return;
@@ -257,6 +294,7 @@
       product.materialName || product.productName || product.name || "";
     row.materialModel = product.materialModel || product.model || "";
     row.unit = product.unit || product.measureUnit || "";
+    row.batchNoList = product.batchNoList;
     currentMaterialSelectRowIndex.value = -1;
     materialProductDialogVisible.value = false;
   };
@@ -266,22 +304,24 @@
       return { valid: false, message: "璇峰厛鏂板棰嗘枡鏁版嵁" };
     }
     const invalidNewRow = materialTableData.value.find(
-      item => item.bom !== true && (!item.processName || !item.materialName)
+      item => item.bom !== true && (!item.operationName || !item.materialName)
     );
     if (invalidNewRow) {
       return { valid: false, message: "鏂板琛岀殑宸ュ簭鍚嶇О鍜屽師鏂欏悕绉颁负蹇呭~椤�" };
     }
     const invalidRow = materialTableData.value.find(
       item =>
-        !item.processName ||
+        !item.operationName ||
         !item.materialName ||
-        item.requiredQty === null ||
-        item.requiredQty === undefined ||
+        !item.batchNo ||
+        item.batchNo.length === 0 ||
+        item.demandedQuantity === null ||
+        item.demandedQuantity === undefined ||
         item.pickQty === null ||
         item.pickQty === undefined
     );
     if (invalidRow) {
-      return { valid: false, message: "璇峰畬鍠勫伐搴忋�佸師鏂欏拰鏁伴噺鍚庡啀淇濆瓨" };
+      return { valid: false, message: "璇峰畬鍠勫伐搴忋�佸師鏂欍�佹壒鍙峰拰鏁伴噺鍚庡啀淇濆瓨" };
     }
     return { valid: true, message: "" };
   };
@@ -295,22 +335,49 @@
     }
     materialSaving.value = true;
     try {
-      await saveMaterialPickingLedger({
-        orderId: props.orderRow.id,
-        items: materialTableData.value.map(item => ({
-          id: item.id,
-          processId: item.processName,
-          productProcessId: item.productProcessId,
-          processName: item.processName,
-          bom: item.bom === true,
-          materialModelId: item.materialModelId,
-          materialName: item.materialName,
-          materialModel: item.materialModel,
-          requiredQty: item.requiredQty,
-          unit: item.unit,
-          pickQty: item.pickQty,
-        })),
-      });
+      if (isDetail.value) {
+        await updateMaterialPickingLedger({
+          productionOrderId: props.orderRow.id,
+          productionOrderPickDto: materialTableData.value.map(item => ({
+            id: item.id,
+            // processId: item.operationName,
+            technologyOperationId: item.technologyOperationId,
+            operationName: item.operationName,
+            bom: item.bom === true,
+            productModelId: item.materialModelId,
+            // materialName: item.materialName,
+            // materialModel: item.materialModel,
+            demandedQuantity: item.demandedQuantity,
+            unit: item.unit,
+            pickQuantity: item.pickQty,
+            batchNo: Array.isArray(item.batchNo)
+              ? item.batchNo.join(",")
+              : item.batchNo,
+          })),
+        });
+      } else {
+        await saveMaterialPickingLedger({
+          productionOrderId: props.orderRow.id,
+          productionOrderPickDto: materialTableData.value.map(item => ({
+            id: item.id,
+            // processId: item.operationName,
+            technologyOperationId: item.technologyOperationId,
+            operationName: item.operationName,
+            bom: item.bom === true,
+            productModelId: item.materialModelId,
+            // materialName: item.materialName,
+            // materialModel: item.materialModel,
+            demandedQuantity: item.demandedQuantity,
+            unit: item.unit,
+            pickQuantity: item.pickQty,
+            batchNo: Array.isArray(item.batchNo)
+              ? item.batchNo.join(",")
+              : item.batchNo,
+          })),
+        });
+      }
+
+      ElMessage({ message: "棰嗘枡鎴愬姛", type: "success" });
       emit("saved");
       dialogVisible.value = false;
     } finally {

--
Gitblit v1.9.3