<template>
|
<el-dialog
|
v-model="visible"
|
title="领料"
|
width="1000px"
|
top="3vh"
|
:close-on-click-modal="false"
|
destroy-on-close
|
class="material-requisition-dialog"
|
>
|
<div class="material-requisition-form">
|
<!-- 原材料 Tab -->
|
|
<div class="operation-bar">
|
<el-button type="primary" @click="handleAdd">新增</el-button>
|
</div>
|
<el-table :data="materialList" border style="width: 100%" height="50vh">
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
<el-table-column prop="productName" label="产品名称" min-width="150" />
|
<el-table-column prop="model" label="型号" min-width="150" />
|
<el-table-column prop="unit" label="单位" width="80" align="center" />
|
<!-- <el-table-column prop="qualitity" label="可领用数量" width="100" align="center">
|
<template #default="{ row }">
|
{{ row.qualitity || 0 }}
|
</template>
|
</el-table-column> -->
|
<el-table-column prop="requisitionQty" label="领用数量" width="120" align="center">
|
<template #default="{ row }">
|
<el-input-number
|
v-model="row.requisitionQty"
|
:min="0"
|
:max="row.qualitity || 0"
|
:precision="2"
|
:controls="false"
|
:disabled="!row.qualitity"
|
style="width: 100%"
|
/>
|
</template>
|
</el-table-column>
|
<el-table-column prop="remark" label="备注" min-width="150">
|
<template #default="{ row }">
|
<el-input v-model="row.remark" placeholder="请输入备注" clearable />
|
</template>
|
</el-table-column>
|
<el-table-column label="操作" width="80" align="center">
|
<template #default="{ $index }">
|
<el-button type="danger" link @click="handleDelete($index)">删除</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button type="primary" :loading="saving" @click="handleConfirm">确 认</el-button>
|
<el-button @click="handleCancel">取 消</el-button>
|
</span>
|
</template>
|
|
<!-- 新增原材料弹窗 -->
|
<el-dialog
|
v-model="addDialogVisible"
|
title="选择原材料"
|
width="800px"
|
top="5vh"
|
:close-on-click-modal="false"
|
append-to-body
|
>
|
<el-table
|
:data="availableMaterials"
|
border
|
style="width: 100%"
|
height="50vh"
|
@selection-change="handleSelectionChange"
|
>
|
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
<el-table-column prop="productName" label="产品名称" min-width="150" />
|
<el-table-column prop="model" label="型号" min-width="150" />
|
<el-table-column prop="unit" label="单位" width="80" align="center" />
|
<!-- <el-table-column prop="qualitity" label="可领用数量" width="100" align="center">
|
<template #default="{ row }">
|
{{ row.qualitity || 0 }}
|
</template>
|
</el-table-column> -->
|
</el-table>
|
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button type="primary" @click="handleAddConfirm">确 定</el-button>
|
<el-button @click="addDialogVisible = false">取 消</el-button>
|
</span>
|
</template>
|
</el-dialog>
|
</el-dialog>
|
</template>
|
|
<script setup>
|
import { ref, computed, watch } from 'vue';
|
import { ElMessage } from 'element-plus';
|
import { drawMaterials } from '@/api/productionManagement/productionOrder.js';
|
import { getMaterials } from '@/api/inventoryManagement/stockInventory.js';
|
|
const props = defineProps({
|
modelValue: {
|
type: Boolean,
|
default: false
|
},
|
orderData: {
|
type: Object,
|
default: () => ({})
|
}
|
});
|
|
const emit = defineEmits(['update:modelValue', 'confirm']);
|
|
const visible = computed({
|
get: () => props.modelValue,
|
set: (val) => emit('update:modelValue', val)
|
});
|
|
const loading = ref(false);
|
const saving = ref(false);
|
const activeTab = ref('material');
|
const materialList = ref([]);
|
|
// 新增弹窗相关
|
const addDialogVisible = ref(false);
|
const availableMaterials = ref([]);
|
const selectedMaterials = ref([]);
|
|
// 监听弹框打开,加载数据
|
watch(() => props.modelValue, (val) => {
|
if (val && props.orderData) {
|
loadMaterialList();
|
}
|
});
|
|
const loadMaterialList = async () => {
|
const order = props.orderData;
|
const drawMaterialsData = order.drawMaterials;
|
const bomId = order?.bomId;
|
|
// 先获取getMaterials的最新数据
|
let materialsFromApi = [];
|
if (bomId) {
|
try {
|
const res = await getMaterials({ bomId });
|
materialsFromApi = res.data || [];
|
} catch (error) {
|
console.error('查询原材料列表失败:', error);
|
}
|
}
|
|
// 加载已保存的领料数据
|
if (drawMaterialsData) {
|
try {
|
const list = typeof drawMaterialsData === 'string'
|
? JSON.parse(drawMaterialsData)
|
: drawMaterialsData;
|
// 合并数据:使用API的qualitity,使用保存的requisitionQty和remark
|
materialList.value = list.map(savedItem => {
|
const apiItem = materialsFromApi.find(m => m.id === savedItem.id || m.productModelId === savedItem.productModelId);
|
return {
|
...savedItem,
|
qualitity: apiItem?.qualitity ?? savedItem.qualitity ?? 0,
|
requisitionQty: savedItem.requisitionQty || 0
|
};
|
});
|
} catch (e) {
|
console.error('解析领料数据失败:', e);
|
materialList.value = [];
|
}
|
} else {
|
materialList.value = [];
|
}
|
};
|
|
// 打开新增弹窗
|
const handleAdd = async () => {
|
const order = props.orderData;
|
const bomId = order?.bomId;
|
if (!bomId) {
|
ElMessage.warning('当前订单缺少BOM信息');
|
return;
|
}
|
|
loading.value = true;
|
try {
|
const res = await getMaterials({ bomId });
|
console.log('getMaterials返回数据:', res.data);
|
// 直接展示所有数据,不过滤
|
availableMaterials.value = res.data || [];
|
selectedMaterials.value = [];
|
addDialogVisible.value = true;
|
} catch (error) {
|
console.error('查询原材料列表失败:', error);
|
ElMessage.error('查询原材料列表失败');
|
} finally {
|
loading.value = false;
|
}
|
};
|
|
// 选择变化
|
const handleSelectionChange = (selection) => {
|
selectedMaterials.value = selection;
|
};
|
|
// 确认添加
|
const handleAddConfirm = () => {
|
if (selectedMaterials.value.length === 0) {
|
ElMessage.warning('请选择至少一条记录');
|
return;
|
}
|
|
// 过滤掉已存在的(通过id和productModelId判断)
|
const existingIds = materialList.value.map(item => item.id);
|
const existingProductModelIds = materialList.value.map(item => item.productModelId);
|
|
const newItems = selectedMaterials.value
|
.filter(item => !existingIds.includes(item.id) && !existingProductModelIds.includes(item.productModelId))
|
.map(item => ({
|
...item,
|
requisitionQty: 0,
|
remark: ''
|
}));
|
|
if (newItems.length === 0) {
|
ElMessage.warning('所选数据已存在,无需重复添加');
|
return;
|
}
|
|
materialList.value = [...materialList.value, ...newItems];
|
addDialogVisible.value = false;
|
ElMessage.success(`成功添加 ${newItems.length} 条记录`);
|
};
|
|
// 删除
|
const handleDelete = (index) => {
|
materialList.value.splice(index, 1);
|
};
|
|
const handleCancel = () => {
|
visible.value = false;
|
materialList.value = [];
|
activeTab.value = 'material';
|
};
|
|
const handleConfirm = async () => {
|
const orderId = props.orderData?.id;
|
if (!orderId) {
|
ElMessage.error('订单ID不存在');
|
return;
|
}
|
|
const drawMaterialsList = materialList.value.map(item => ({
|
...item,
|
requisitionQty: item.requisitionQty || 0
|
}));
|
|
const postData = {
|
id: orderId,
|
drawMaterials: JSON.stringify(drawMaterialsList)
|
};
|
|
saving.value = true;
|
try {
|
await drawMaterials(postData);
|
ElMessage.success('领料保存成功');
|
visible.value = false;
|
materialList.value = [];
|
activeTab.value = 'material';
|
} catch (error) {
|
console.error('保存领料失败:', error);
|
ElMessage.error('保存领料失败');
|
} finally {
|
saving.value = false;
|
}
|
};
|
</script>
|
|
<style scoped lang="scss">
|
.material-requisition-form {
|
.operation-bar {
|
margin-bottom: 15px;
|
}
|
|
.el-tabs {
|
height: 100%;
|
}
|
|
.el-table {
|
margin-top: 10px;
|
}
|
}
|
|
.dialog-footer {
|
display: flex;
|
justify-content: flex-end;
|
gap: 10px;
|
}
|
|
:deep(.el-dialog) {
|
height: 85vh;
|
margin-top: 3vh !important;
|
display: flex;
|
flex-direction: column;
|
}
|
|
:deep(.el-dialog__body) {
|
flex: 1;
|
overflow-y: auto;
|
padding: 15px 20px;
|
}
|
|
:deep(.el-dialog__header) {
|
padding: 15px 20px;
|
border-bottom: 1px solid #e4e7ed;
|
}
|
|
:deep(.el-dialog__footer) {
|
padding: 15px 20px;
|
border-top: 1px solid #e4e7ed;
|
}
|
|
:deep(.el-tabs__content) {
|
height: calc(100% - 55px);
|
}
|
|
:deep(.el-tab-pane) {
|
height: 100%;
|
}
|
</style>
|