<template>
|
<div class="app-container">
|
<!-- 搜索过滤区 -->
|
<el-form :model="searchForm" :inline="true">
|
<el-form-item label="采购合同号">
|
<el-input v-model="searchForm.purchaseContractNumber" placeholder="请输入" />
|
</el-form-item>
|
<el-form-item label="供应商">
|
<el-input v-model="searchForm.supplierName" placeholder="请输入" />
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" @click="search">搜索</el-button>
|
<el-button @click="resetSearch">重置</el-button>
|
</el-form-item>
|
</el-form>
|
|
<!-- 表格展示区 -->
|
<el-table :data="orderList" border v-loading="loading" height="calc(100vh - 12em)">
|
<!-- 添加序号列 -->
|
<el-table-column align="center" label="序号" type="index" width="60" />
|
<el-table-column prop="purchaseContractNumber" label="采购合同号" show-overflow-tooltip />
|
<el-table-column prop="supplierName" label="供应商" show-overflow-tooltip />
|
<el-table-column label="付款状态">
|
<template #default="scope">
|
<el-tag
|
:type="getPaymentStatusType(scope.row.paymentStatus)"
|
size="small"
|
>
|
{{ getPaymentStatusText(scope.row.paymentStatus) }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column label="收货状态">
|
<template #default="scope">
|
<el-tag
|
:type="getReceiptStatusType(scope.row.receiptStatus)"
|
size="small"
|
>
|
{{ getReceiptStatusText(scope.row.receiptStatus) }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column prop="receivedQuantity" label="已收货数量"/>
|
<el-table-column prop="unreceivedQuantity" label="未收货数量"/>
|
<el-table-column label="操作" width="200" fixed="right" align="center">
|
<template #default="scope">
|
<el-button
|
type="primary"
|
size="small"
|
@click="confirmReceipter(scope.row)"
|
>
|
确认收货
|
</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
<!-- 在表格下方添加分页 -->
|
<pagination
|
v-show="total > 0"
|
:total="total"
|
layout="total, sizes, prev, pager, next, jumper"
|
:page="page.current"
|
:limit="page.size"
|
@pagination="paginationChange"
|
/>
|
<!-- 确认收货对话框 -->
|
<el-dialog v-model="receiptDialogVisible" title="确认收货" width="70%">
|
<el-form :model="receiptForm" label-width="120px" ref="formRef">
|
<el-form-item label="采购合同号">
|
<el-input v-model="receiptForm.purchaseContractNumber" disabled />
|
</el-form-item>
|
<el-form-item label="异常原因">
|
<el-input
|
v-model="receiptForm.exceptionReason"
|
type="textarea"
|
placeholder="请输入异常原因(不合格时填写)"
|
/>
|
</el-form-item>
|
<el-table
|
:data="productList"
|
border
|
v-loading="loadingProducts"
|
@selection-change="handleSelectionChange"
|
>
|
<el-table-column align="center" type="selection" width="55" />
|
<el-table-column
|
align="center"
|
label="序号"
|
type="index"
|
width="60"
|
/>
|
<el-table-column label="产品大类" prop="productCategory" />
|
<el-table-column label="规格型号" prop="specificationModel" />
|
<el-table-column label="单位" prop="unit" width="70" />
|
<el-table-column label="供应商" prop="supplierName" width="100" />
|
<el-table-column label="采购数量" prop="quantity" width="100" />
|
<el-table-column label="待入库数量" prop="quantity0" width="100" />
|
<el-table-column label="本次入库数量" prop="quantityStock" width="150">
|
<template #default="scope">
|
<el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.quantityStock" />
|
</template>
|
</el-table-column>
|
<!-- 合格或不合格-->
|
<el-table-column label="是否合格" width="100">
|
<template #default="scope">
|
<el-select v-model="scope.row.isQualified" placeholder="请选择">
|
<el-option label="合格" value="1" />
|
<el-option label="不合格" value="2" />
|
</el-select>
|
</template>
|
</el-table-column>
|
<el-table-column label="税率(%)" prop="taxRate" width="120" />
|
<el-table-column
|
label="含税单价(元)"
|
prop="taxInclusiveUnitPrice"
|
:formatter="formattedNumber"
|
width="150"
|
/>
|
<el-table-column
|
label="含税总价(元)"
|
prop="taxInclusiveTotalPrice"
|
:formatter="formattedNumber"
|
width="150"
|
/>
|
<el-table-column
|
label="不含税总价(元)"
|
prop="taxExclusiveTotalPrice"
|
:formatter="formattedNumber"
|
width="150"
|
/>
|
</el-table>
|
</el-form>
|
<template #footer>
|
<el-button @click="receiptDialogVisible = false">取消</el-button>
|
<el-button type="primary" @click="submitReceipt">确认收货</el-button>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script setup>
|
import {ref, onMounted, getCurrentInstance} from 'vue'
|
import {
|
getPurchaseOrders,
|
confirmReceipt,
|
addPurchaseException
|
} from '@/api/procurementManagement/transferManagement.js'
|
import {selectProductRecordListByPuechaserId, addSutockIn, updateStockIn} from "@/api/inventoryManagement/stockIn.js";
|
import useUserStore from "@/store/modules/user.js";
|
|
|
const userStore = useUserStore()
|
const { proxy } = getCurrentInstance()
|
|
// 数据定义
|
const orderList = ref([])
|
const receiptDialogVisible = ref(false)
|
const receiptForm = ref({
|
purchaseContractNumber: '',
|
exceptionReason: '',
|
purchaseLedgerId: '',
|
})
|
const operationType = ref('')// 操作类型: 'add' 或 'edit'
|
const productList = ref([]);// 产品列表数据
|
const loadingProducts = ref(false);// 产品加载状态
|
const selectedRows = ref([]);
|
const loading = ref(false);
|
const total = ref(0); // 总记录数
|
// 搜索表单
|
const searchForm = ref({
|
purchaseContractNumber: '',
|
supplierName: '',
|
})
|
// 分页数据
|
const page = reactive({
|
current: 1,
|
size: 100, // 每页显示数量
|
});
|
|
// 分页变化处理
|
const paginationChange = (obj) => {
|
page.current = obj.page;
|
page.size = obj.limit;
|
getReceiptOrders(); // 重新获取数据
|
};
|
// 获取订单列表
|
const getReceiptOrders = async () => {
|
loading.value = true;
|
try {
|
const response = await getPurchaseOrders({
|
...searchForm.value,
|
current: page.current,
|
size: page.size
|
});
|
// 使用 Promise.all 处理所有异步请求
|
const processedOrders = await Promise.all(response.data.records.map(async (order) => {
|
// 等待异步获取产品记录
|
const productRes = await selectProductRecordListByPuechaserId({
|
purchaseContractNumber: order.purchaseContractNumber
|
});
|
|
// 确保 productRes.data 存在
|
if (productRes && productRes.data && Array.isArray(productRes.data)) {
|
// 计算总数量
|
order.totalQuantity = productRes.data.reduce((acc, cur) => acc + (cur.quantity || 0), 0);
|
// 计算未收货数量
|
order.unreceivedQuantity = productRes.data.reduce((acc, cur) => acc + (cur.quantity0 || 0), 0);
|
// 计算已收货数量
|
order.receivedQuantity = order.totalQuantity - order.unreceivedQuantity;
|
|
// 修正状态判断逻辑(使用 === 进行比较)
|
if (order.unreceivedQuantity === 0) {
|
order.paymentStatus = 1;
|
order.receiptStatus = 1;
|
} else if (order.receivedQuantity === 0) {
|
order.paymentStatus = 3;
|
order.receiptStatus = 3;
|
} else {
|
order.paymentStatus = 2;
|
order.receiptStatus = 2;
|
}
|
} else {
|
// 如果没有产品记录,设置默认值
|
order.totalQuantity = 0;
|
order.unreceivedQuantity = 0;
|
order.receivedQuantity = 0;
|
order.receiptStatus = 3; // 未入库
|
}
|
|
return order;
|
}));
|
|
// 正确赋值给 orderList
|
orderList.value = processedOrders;
|
total.value = response.data.total;
|
} catch (error) {
|
console.error('获取订单列表失败:', error);
|
proxy.$modal.msgError('获取订单列表失败');
|
} finally {
|
loading.value = false;
|
}
|
}
|
|
// 付款状态显示处理
|
const getPaymentStatusText = (status) => {
|
const statusMap = { '1': '已付款', '2': '部分付款', '3': '未付款' }
|
return statusMap[status] || '未知'
|
}
|
|
const getPaymentStatusType = (status) => {
|
const typeMap = { '1': 'success', '2': 'warning', '3': 'danger' }
|
return typeMap[status] || 'info'
|
}
|
|
// 收货状态处理
|
const getReceiptStatusText = (status) => {
|
const statusMap = { '1': '收货完成', '2': '部分入库', '3': '未入库' }
|
return statusMap[status] || '未知'
|
}
|
|
const getReceiptStatusType = (status) => {
|
const typeMap = { '1': 'success', '2': 'warning', '3': 'info' }
|
return typeMap[status] || 'info'
|
}
|
const exceedsAddLimit = (product) => {
|
const stock = Number(product?.quantityStock ?? 0);
|
const waiting = Number(product?.quantity0 ?? 0);
|
if (!Number.isFinite(stock) || !Number.isFinite(waiting)) {
|
return false;
|
}
|
return stock > waiting;
|
};
|
const exceedsEditLimit = (product) => {
|
const stock = Number(product?.quantityStock ?? 0);
|
const waiting = Number(product?.quantity0 ?? 0);
|
const original = Number(product?.originalQuantityStock ?? 0);
|
if (!Number.isFinite(stock) || !Number.isFinite(waiting) || !Number.isFinite(original)) {
|
return false;
|
}
|
return stock > waiting + original;
|
};
|
const updatePro = async () => {
|
const target = selectedRows.value[0];
|
const stock = Number(target?.quantityStock ?? 0);
|
if (!Number.isFinite(stock) || stock <= 0) {
|
proxy.$modal.msgWarning('请填写有效的入库数量');
|
return;
|
}
|
if (exceedsEditLimit(target)) {
|
proxy.$modal.msgError('本次入库数量不能超过原入库数量与待入库数量之和');
|
return;
|
}
|
const stockInData = {
|
id: selectedRows.value[0].recordId,
|
quantityStock: Number(selectedRows.value[0].quantityStock),// 使用新格式化函数
|
};
|
await updateStockIn(stockInData)
|
proxy.$modal.msgSuccess('修改入库成功')
|
closeDia()
|
getReceiptOrders() // 刷新列表
|
}
|
// 表格选择数据
|
const handleSelectionChange = (selection) => {
|
// 过滤掉子数据
|
selectedRows.value = selection.filter(item => item.id);
|
}
|
// 打开弹框-确认收货
|
const confirmReceipter = (row) => {
|
receiptForm.value = {
|
purchaseContractNumber: row.purchaseContractNumber,
|
purchaseLedgerId: row.id,
|
exceptionReason: ''
|
}
|
selectedRows.value = []
|
receiptDialogVisible.value = true
|
fetchProductsByContract()
|
}
|
|
const fetchProductsByContract = async () =>
|
{
|
try {
|
loadingProducts.value = true
|
// 根据合同查询产品记录
|
const productRes = await selectProductRecordListByPuechaserId({
|
purchaseContractNumber: receiptForm.value.purchaseContractNumber
|
});
|
console.log('productRes:', productRes)
|
operationType.value = 'add'
|
if (!productRes.data || productRes.data.length === 0) {
|
proxy.$modal.msgWarning('该合同下没有产品记录')
|
productList.value = [];
|
return
|
}
|
// 处理产品数据,添加本次入库数量字段
|
productList.value = productRes.data.map(item => ({
|
...item,
|
quantityStock: 0,
|
originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? 0),
|
}))
|
selectedRows.value = productList.value
|
} catch (error) {
|
console.error('查询产品记录失败:', error)
|
proxy.$modal.msgError('查询产品记录失败')
|
productList.value = [];
|
} finally {
|
loadingProducts.value = false
|
}
|
}
|
|
|
// 提交收货确认
|
const submitReceipt = async () => {
|
if(operationType.value !== 'add'){
|
await updatePro()
|
return
|
}
|
try {
|
await proxy.$refs.formRef.validate()
|
// 验证入库数量
|
const invalidProducts = selectedRows.value.filter((product) => {
|
const stock = Number(product?.quantityStock ?? 0);
|
if (!Number.isFinite(stock) || stock <= 0) {
|
return true;
|
}
|
return exceedsAddLimit(product);
|
})
|
|
if (invalidProducts.length > 0) {
|
proxy.$modal.msgError('本次入库数量需大于0,且不能超过待入库数量')
|
return
|
}
|
loading.value = true
|
// 准备提交数据 - 修改为后端需要的格式
|
const stockInData = {
|
// 入库单基本信息
|
...receiptForm.value,
|
nickName: userStore.nickName,
|
details: selectedRows.value.map(product => ({
|
id: product.id,
|
inboundQuantity: Number(product.quantityStock)
|
})),
|
};
|
//如果产品合格
|
if(productList.value.every(product => product.isQualified === '1')){
|
await addSutockIn(stockInData)
|
|
proxy.$modal.msgSuccess('确认收货,入库成功')
|
}else{
|
stockInData.details.forEach(item => {
|
const ProcurementExceptionRecord = {
|
purchaseContractNumber: receiptForm.value.purchaseContractNumber,
|
purchaseLedgerId: receiptForm.value.purchaseLedgerId,
|
exceptionNum: item.inboundQuantity,
|
exceptionReason: receiptForm.value.exceptionReason
|
}
|
addPurchaseException(ProcurementExceptionRecord).then(response => {
|
proxy.$modal.msgSuccess('产品不合格,采购异常记录成功')
|
})
|
})
|
}
|
closeDia()
|
getReceiptOrders() // 刷新列表
|
|
} catch (error) {
|
console.error('提交失败:', error)
|
if (!error.errors) {
|
proxy.$modal.msgError('操作失败,请重试')
|
}
|
} finally {
|
loading.value = false
|
}
|
}
|
// 关闭弹框
|
const closeDia = () => {
|
proxy.$refs.formRef.resetFields()
|
receiptDialogVisible.value = false
|
}
|
// 搜索和重置
|
const search = () => {
|
getReceiptOrders()
|
}
|
|
const resetSearch = () => {
|
searchForm.value = {
|
purchaseContractNumber: '',
|
supplierName: '',
|
}
|
getReceiptOrders()
|
}
|
|
onMounted(() => {
|
getReceiptOrders()
|
})
|
</script>
|