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