From b7e3bc6bbe2f6464f4f92e457212fac7ea61758d Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期二, 28 四月 2026 11:04:33 +0800
Subject: [PATCH] 领料功能

---
 src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue |  338 +++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 199 insertions(+), 139 deletions(-)

diff --git a/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue b/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue
index 9c50fc8..a83ff6a 100644
--- a/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue
+++ b/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue
@@ -1,44 +1,82 @@
 <template>
   <div>
-    <el-dialog v-model="dialogVisible" title="棰嗘枡璇︽儏" width="1400px" @close="handleClose">
-      <el-table v-loading="materialDetailLoading" :data="materialDetailTableData" border row-key="id">
-        <el-table-column label="宸ュ簭鍚嶇О" prop="processName" min-width="180" />
-        <el-table-column label="鍘熸枡鍚嶇О" prop="materialName" min-width="160" />
-        <el-table-column label="鍘熸枡鍨嬪彿" prop="materialModel" min-width="180" />
-        <el-table-column label="闇�姹傛暟閲�" prop="requiredQty" min-width="110" />
-        <el-table-column label="璁¢噺鍗曚綅" prop="unit" width="100" />
-        <el-table-column label="棰嗙敤鏁伴噺" prop="pickQty" min-width="110" />
-        <el-table-column label="琛ユ枡鏁伴噺" min-width="120">
+    <el-dialog v-model="dialogVisible"
+               title="棰嗘枡璇︽儏"
+               width="1400px"
+               @close="handleClose">
+      <el-table v-loading="materialDetailLoading"
+                :data="materialDetailTableData"
+                border
+                row-key="id">
+        <el-table-column label="宸ュ簭鍚嶇О"
+                         prop="operationName"
+                         min-width="180" />
+        <el-table-column label="鍘熸枡鍚嶇О"
+                         prop="productName"
+                         min-width="160" />
+        <el-table-column label="鍘熸枡鍨嬪彿"
+                         prop="model"
+                         min-width="180" />
+        <el-table-column label="鎵瑰彿"
+                         prop="batchNo"
+                         min-width="150" />
+        <el-table-column label="闇�姹傛暟閲�"
+                         prop="demandedQuantity"
+                         min-width="110" />
+        <el-table-column label="璁¢噺鍗曚綅"
+                         prop="unit"
+                         width="100" />
+        <el-table-column label="棰嗙敤鏁伴噺"
+                         prop="pickQuantity"
+                         min-width="110" />
+        <el-table-column label="琛ユ枡鏁伴噺"
+                         min-width="120">
           <template #default="{ row }">
-            <el-button type="primary" link @click="handleViewSupplementRecord(row)">
+            <el-button type="primary"
+                       link
+                       @click="handleViewSupplementRecord(row)">
               {{ row.supplementQty ?? 0 }}
             </el-button>
           </template>
         </el-table-column>
-        <el-table-column label="閫�鏂欐暟閲�" prop="returnQty" min-width="110" />
-        <el-table-column label="瀹為檯鏁伴噺" prop="actualQty" min-width="110" />
+        <el-table-column label="閫�鏂欐暟閲�"
+                         prop="returnQty"
+                         min-width="110" />
+        <el-table-column label="瀹為檯鏁伴噺"
+                         prop="actualQty"
+                         min-width="110" />
       </el-table>
       <template #footer>
         <span class="dialog-footer">
-          <el-button
-            type="warning"
-            :loading="materialReturnConfirming"
-            :disabled="!canOpenReturnSummary"
-            @click="openReturnSummaryDialog"
-          >
+          <el-button type="warning"
+                     :loading="materialReturnConfirming"
+                     :disabled="!canOpenReturnSummary"
+                     @click="openReturnSummaryDialog">
             閫�鏂欑‘璁�
           </el-button>
           <el-button @click="dialogVisible = false">鍙栨秷</el-button>
         </span>
       </template>
     </el-dialog>
-
-    <el-dialog v-model="supplementRecordDialogVisible" title="琛ユ枡璁板綍" width="800px">
-      <el-table v-loading="supplementRecordLoading" :data="supplementRecordTableData" border row-key="id">
-        <el-table-column label="琛ユ枡鏁伴噺" prop="supplementQty" min-width="120" />
-        <el-table-column label="琛ユ枡浜�" prop="supplementUserName" min-width="120" />
-        <el-table-column label="琛ユ枡鏃ユ湡" prop="supplementTime" min-width="160" />
-        <el-table-column label="琛ユ枡鍘熷洜" prop="supplementReason" min-width="200" />
+    <el-dialog v-model="supplementRecordDialogVisible"
+               title="琛ユ枡璁板綍"
+               width="800px">
+      <el-table v-loading="supplementRecordLoading"
+                :data="supplementRecordTableData"
+                border
+                row-key="id">
+        <el-table-column label="琛ユ枡鏁伴噺"
+                         prop="supplementQty"
+                         min-width="120" />
+        <el-table-column label="琛ユ枡浜�"
+                         prop="supplementUserName"
+                         min-width="120" />
+        <el-table-column label="琛ユ枡鏃ユ湡"
+                         prop="supplementTime"
+                         min-width="160" />
+        <el-table-column label="琛ユ枡鍘熷洜"
+                         prop="supplementReason"
+                         min-width="200" />
       </el-table>
       <template #footer>
         <span class="dialog-footer">
@@ -46,18 +84,30 @@
         </span>
       </template>
     </el-dialog>
-
-    <el-dialog v-model="returnSummaryDialogVisible" title="閫�鏂欐眹鎬荤‘璁�" width="900px">
-      <el-table :data="returnSummaryList" border row-key="summaryKey">
-        <el-table-column label="鍘熸枡鍚嶇О" prop="materialName" min-width="180" />
-        <el-table-column label="鍘熸枡鍨嬪彿" prop="materialModel" min-width="180" />
-        <el-table-column label="璁¢噺鍗曚綅" prop="unit" min-width="100" />
-        <el-table-column label="閫�鏂欐眹鎬绘暟閲�" prop="returnQtyTotal" min-width="140" />
+    <el-dialog v-model="returnSummaryDialogVisible"
+               title="閫�鏂欐眹鎬荤‘璁�"
+               width="900px">
+      <el-table :data="returnSummaryList"
+                border
+                row-key="summaryKey">
+        <el-table-column label="鍘熸枡鍚嶇О"
+                         prop="materialName"
+                         min-width="180" />
+        <el-table-column label="鍘熸枡鍨嬪彿"
+                         prop="materialModel"
+                         min-width="180" />
+        <el-table-column label="璁¢噺鍗曚綅"
+                         prop="unit"
+                         min-width="100" />
+        <el-table-column label="閫�鏂欐眹鎬绘暟閲�"
+                         prop="returnQtyTotal"
+                         min-width="140" />
       </el-table>
-
       <template #footer>
         <span class="dialog-footer">
-          <el-button type="primary" :loading="materialReturnConfirming" @click="handleReturnConfirm">纭鎻愪氦</el-button>
+          <el-button type="primary"
+                     :loading="materialReturnConfirming"
+                     @click="handleReturnConfirm">纭鎻愪氦</el-button>
           <el-button @click="returnSummaryDialogVisible = false">鍙栨秷</el-button>
         </span>
       </template>
@@ -66,116 +116,126 @@
 </template>
 
 <script setup>
-import { computed, ref, watch } from "vue";
-import { ElMessage } from "element-plus";
-import { listMaterialPickingDetail, listMaterialSupplementRecord, confirmMaterialReturn } from "@/api/productionManagement/productionOrder.js";
+  import { computed, ref, watch } from "vue";
+  import { ElMessage } from "element-plus";
+  import {
+    listMaterialPickingDetail,
+    listMaterialSupplementRecord,
+    confirmMaterialReturn,
+  } from "@/api/productionManagement/productionOrder.js";
 
-const props = defineProps({
-  modelValue: { type: Boolean, default: false },
-  orderRow: { type: Object, default: null },
-});
-const emit = defineEmits(["update:modelValue", "confirmed"]);
-
-const dialogVisible = computed({
-  get: () => props.modelValue,
-  set: val => emit("update:modelValue", val),
-});
-
-const materialDetailLoading = ref(false);
-const materialDetailTableData = ref([]);
-const materialReturnConfirming = ref(false);
-const supplementRecordDialogVisible = ref(false);
-const supplementRecordLoading = ref(false);
-const supplementRecordTableData = ref([]);
-const returnSummaryDialogVisible = ref(false);
-const returnSummaryList = ref([]);
-const calcReturnQty = item =>
-  Number(item.pickQty || 0) + Number(item.supplementQty || 0) - Number(item.actualQty || 0);
-const canOpenReturnSummary = computed(() =>
-  materialDetailTableData.value.some(item => calcReturnQty(item) > 0)
-);
-
-const loadDetailList = async () => {
-  if (!props.orderRow?.id) return;
-  materialDetailLoading.value = true;
-  materialDetailTableData.value = [];
-  try {
-    const res = await listMaterialPickingDetail({ orderId: props.orderRow.id });
-    materialDetailTableData.value = res.data || [];
-  } finally {
-    materialDetailLoading.value = false;
-  }
-};
-
-watch(
-  () => dialogVisible.value,
-  visible => {
-    if (visible) {
-      loadDetailList();
-    }
-  }
-);
-
-const handleClose = () => {
-  materialDetailTableData.value = [];
-};
-
-const handleViewSupplementRecord = async row => {
-  if (!row?.id) return;
-  supplementRecordDialogVisible.value = true;
-  supplementRecordLoading.value = true;
-  supplementRecordTableData.value = [];
-  try {
-    const res = await listMaterialSupplementRecord({ materialDetailId: row.id });
-    supplementRecordTableData.value = res.data || [];
-  } finally {
-    supplementRecordLoading.value = false;
-  }
-};
-
-const buildReturnSummary = () => {
-  const map = new Map();
-  materialDetailTableData.value.forEach(item => {
-    const returnQty = calcReturnQty(item);
-    if (returnQty <= 0) return;
-    const key = `${item.materialModelId || ""}_${item.materialName || ""}_${item.materialModel || ""}_${item.unit || ""}`;
-    const old = map.get(key) || {
-      summaryKey: key,
-      materialName: item.materialName || "",
-      materialModel: item.materialModel || "",
-      unit: item.unit || "",
-      returnQtyTotal: 0,
-    };
-    old.returnQtyTotal += returnQty;
-    map.set(key, old);
+  const props = defineProps({
+    modelValue: { type: Boolean, default: false },
+    orderRow: { type: Object, default: null },
   });
-  return Array.from(map.values());
-};
+  const emit = defineEmits(["update:modelValue", "confirmed"]);
 
-const openReturnSummaryDialog = async () => {
-  if (!canOpenReturnSummary.value) {
-    ElMessage.warning("閫�鏂欐暟閲�=棰嗙敤鏁伴噺+琛ユ枡鏁伴噺-瀹為檯鏁伴噺锛屼笖闇�澶т簬0");
-    return;
-  }
-  returnSummaryList.value = buildReturnSummary();
-  returnSummaryDialogVisible.value = true;
-};
+  const dialogVisible = computed({
+    get: () => props.modelValue,
+    set: val => emit("update:modelValue", val),
+  });
 
-const handleReturnConfirm = async () => {
-  if (!props.orderRow?.id) return;
-  materialReturnConfirming.value = true;
-  try {
-    await confirmMaterialReturn({
-      orderId: props.orderRow.id,
-      returnSummaryList: returnSummaryList.value,
+  const materialDetailLoading = ref(false);
+  const materialDetailTableData = ref([]);
+  const materialReturnConfirming = ref(false);
+  const supplementRecordDialogVisible = ref(false);
+  const supplementRecordLoading = ref(false);
+  const supplementRecordTableData = ref([]);
+  const returnSummaryDialogVisible = ref(false);
+  const returnSummaryList = ref([]);
+  const calcReturnQty = item =>
+    Number(item.pickQuantity || 0) +
+    Number(item.supplementQty || 0) -
+    Number(item.actualQty || 0);
+  const canOpenReturnSummary = computed(() =>
+    materialDetailTableData.value.some(item => calcReturnQty(item) > 0)
+  );
+
+  const loadDetailList = async () => {
+    if (!props.orderRow?.id) return;
+    materialDetailLoading.value = true;
+    materialDetailTableData.value = [];
+    try {
+      const res = await listMaterialPickingDetail(props.orderRow.id);
+      materialDetailTableData.value = res.data || [];
+    } finally {
+      materialDetailLoading.value = false;
+    }
+  };
+
+  watch(
+    () => dialogVisible.value,
+    visible => {
+      if (visible) {
+        loadDetailList();
+      }
+    }
+  );
+
+  const handleClose = () => {
+    materialDetailTableData.value = [];
+  };
+
+  const handleViewSupplementRecord = async row => {
+    if (!row?.id) return;
+    supplementRecordDialogVisible.value = true;
+    supplementRecordLoading.value = true;
+    supplementRecordTableData.value = [];
+    try {
+      const res = await listMaterialSupplementRecord({
+        materialDetailId: row.id,
+      });
+      supplementRecordTableData.value = res.data || [];
+    } finally {
+      supplementRecordLoading.value = false;
+    }
+  };
+
+  const buildReturnSummary = () => {
+    const map = new Map();
+    materialDetailTableData.value.forEach(item => {
+      const returnQty = calcReturnQty(item);
+      if (returnQty <= 0) return;
+      const key = `${item.productModelId || ""}_${item.productName || ""}_${
+        item.model || ""
+      }_${item.unit || ""}`;
+      const old = map.get(key) || {
+        summaryKey: key,
+        materialName: item.productName || "",
+        materialModel: item.model || "",
+        unit: item.unit || "",
+        returnQtyTotal: 0,
+      };
+      old.returnQtyTotal += returnQty;
+      map.set(key, old);
     });
-    returnSummaryDialogVisible.value = false;
-    dialogVisible.value = false;
-    emit("confirmed");
-  } finally {
-    materialReturnConfirming.value = false;
-  }
-};
+    return Array.from(map.values());
+  };
+
+  const openReturnSummaryDialog = async () => {
+    if (!canOpenReturnSummary.value) {
+      ElMessage.warning("閫�鏂欐暟閲�=棰嗙敤鏁伴噺+琛ユ枡鏁伴噺-瀹為檯鏁伴噺锛屼笖闇�澶т簬0");
+      return;
+    }
+    returnSummaryList.value = buildReturnSummary();
+    returnSummaryDialogVisible.value = true;
+  };
+
+  const handleReturnConfirm = async () => {
+    if (!props.orderRow?.id) return;
+    materialReturnConfirming.value = true;
+    try {
+      await confirmMaterialReturn({
+        orderId: props.orderRow.id,
+        returnSummaryList: returnSummaryList.value,
+      });
+      returnSummaryDialogVisible.value = false;
+      dialogVisible.value = false;
+      emit("confirmed");
+    } finally {
+      materialReturnConfirming.value = false;
+    }
+  };
 </script>
 
 <style scoped lang="scss"></style>

--
Gitblit v1.9.3