From 0c2901e13dcc61ebae45aa7433d71b43bbf56d25 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期三, 22 四月 2026 15:42:17 +0800
Subject: [PATCH] Merge branch 'dev_New' into dev_NEW_pro

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

diff --git a/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue b/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue
new file mode 100644
index 0000000..9c50fc8
--- /dev/null
+++ b/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue
@@ -0,0 +1,181 @@
+<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">
+          <template #default="{ 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>
+      <template #footer>
+        <span class="dialog-footer">
+          <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-table>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="supplementRecordDialogVisible = false">鍏抽棴</el-button>
+        </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-table>
+
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary" :loading="materialReturnConfirming" @click="handleReturnConfirm">纭鎻愪氦</el-button>
+          <el-button @click="returnSummaryDialogVisible = false">鍙栨秷</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+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);
+  });
+  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