<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="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)">
|
{{ 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.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);
|
});
|
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>
|