From f9e50ae5b6c79c5ca88b0ac994db73d750c77592 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期一, 27 四月 2026 17:53:01 +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