| | |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" |
| | | @click="openForm('add')">新增入库</el-button> |
| | | @click="openFormadd('add')">订单入库</el-button> |
| | | <el-button type="primary" |
| | | @click="openDirectForm('add')">新增入库</el-button> |
| | | <el-button @click="handleOut">导出</el-button> |
| | | <el-button type="danger" |
| | | plain |
| | |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- 直接新增入库对话框 --> |
| | | <el-dialog v-model="directDialogVisible" |
| | | title="新增入库" |
| | | width="70%" |
| | | @close="closeDirectDia"> |
| | | <el-form :model="directForm" |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="directRules" |
| | | ref="directFormRef"> |
| | | <el-form :model="directQuery" |
| | | class="mb-2"> |
| | | <el-form-item label="产品大类"> |
| | | <el-tree-select v-model="directQuery.productId" |
| | | placeholder="请选择产品大类" |
| | | clearable |
| | | check-strictly |
| | | @change="handleProductCategoryChange" |
| | | :data="productList" |
| | | :disabled="typeValue === 'edit'" |
| | | :render-after-expand="false" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | <el-form-item label="规格型号"> |
| | | <el-select v-model="directQuery.productModelId" |
| | | placeholder="请先选择产品大类" |
| | | clearable |
| | | filterable |
| | | :disabled="!directQuery.productId || typeValue === 'edit'"> |
| | | <el-option v-for="item in productModelList" |
| | | :key="item.id" |
| | | :label="item.model" |
| | | :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="入库数量"> |
| | | <el-input v-model="directQuery.inboundQuantity" |
| | | placeholder="输入入库数量" |
| | | clearable /> |
| | | </el-form-item> |
| | | <el-form-item label="预警数量"> |
| | | <el-input v-model="directQuery.warnNum" |
| | | placeholder="输入预警数量" |
| | | clearable /> |
| | | </el-form-item> |
| | | <el-form-item label="缺货数量"> |
| | | <el-input v-model="directQuery.outStockQuantity" |
| | | placeholder="输入缺货数量" |
| | | clearable /> |
| | | </el-form-item> |
| | | <el-form-item label="缺货情况"> |
| | | <el-input v-model="directQuery.shortageDescription" |
| | | placeholder="输入缺货情况" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" |
| | | @click="submitDirectForm">确认</el-button> |
| | | <el-button @click="closeDirectDia">取消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | addSutockIn, |
| | | delStockIn, |
| | | selectProductRecordListByPuechaserId, |
| | | addProduct, |
| | | } from "@/api/inventoryManagement/stockIn.js"; |
| | | import { purchaseListPage } from "@/api/procurementManagement/procurementLedger.js"; |
| | | import { productTreeList, modelList } from "@/api/basicData/product.js"; |
| | | |
| | | const userStore = useUserStore(); |
| | | const { proxy } = getCurrentInstance(); |
| | |
| | | { required: true, message: "请输入入库批次", trigger: "blur" }, |
| | | ], |
| | | }, |
| | | // 直接新增入库相关 |
| | | directDialogVisible: false, |
| | | directForm: { |
| | | id: null, |
| | | productId: null, |
| | | productModel: "", |
| | | inboundQuantity: 0, |
| | | warnNum: 0, |
| | | outStockQuantity: 0, |
| | | shortageDescription: "", |
| | | }, |
| | | directRules: { |
| | | supplierId: [ |
| | | { required: true, message: "请选择供应商", trigger: "change" }, |
| | | ], |
| | | inboundTime: [ |
| | | { required: true, message: "请选择入库时间", trigger: "change" }, |
| | | ], |
| | | inboundBatch: [ |
| | | { required: true, message: "请输入入库批次", trigger: "blur" }, |
| | | ], |
| | | }, |
| | | directQuery: { |
| | | productId: null, |
| | | productModelId: null, |
| | | inboundQuantity: 0, |
| | | warnNum: 0, |
| | | outStockQuantity: 0, |
| | | shortageDescription: "", |
| | | }, |
| | | directProductList: [], |
| | | directLoading: false, |
| | | directSelectedRows: [], |
| | | // 产品相关 |
| | | productList: [], |
| | | productModelList: [], |
| | | }); |
| | | const { searchForm, form, rules } = toRefs(data); |
| | | const { |
| | | searchForm, |
| | | form, |
| | | rules, |
| | | directDialogVisible, |
| | | directForm, |
| | | directRules, |
| | | directQuery, |
| | | directProductList, |
| | | directLoading, |
| | | directSelectedRows, |
| | | productModelList, |
| | | } = toRefs(data); |
| | | |
| | | const formatPurchaseOption = (item = {}) => { |
| | | const contract = item.purchaseContractNumber || "--"; |
| | |
| | | loadingProducts.value = false; |
| | | } |
| | | }; |
| | | |
| | | // 打开弹框 |
| | | const openForm = async (type, row) => { |
| | | const openFormadd = async (type, row) => { |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | selectedRows.value = []; |
| | |
| | | loadingProducts.value = false; |
| | | } |
| | | } |
| | | }; |
| | | // 打开订单入库弹框 |
| | | const openForm = async (type, row) => { |
| | | if (row.salesLedgerProductId) { |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | selectedRows.value = []; |
| | | await loadPurchaseOptions(); |
| | | |
| | | if (type === "add") { |
| | | // 新增时初始化表单 |
| | | form.value = { |
| | | id: null, |
| | | purchaseContractNumber: "", |
| | | supplierId: null, |
| | | supplierName: "", |
| | | inboundTime: "", |
| | | inboundBatch: "", |
| | | recorderId: userStore.userId, |
| | | recorderName: userStore.name, |
| | | entryDate: getCurrentDate(), |
| | | remark: "", |
| | | }; |
| | | productList.value = []; // 清空产品列表 |
| | | } else { |
| | | form.value = JSON.parse(JSON.stringify(row)); |
| | | try { |
| | | loadingProducts.value = true; |
| | | // 根据合同号加载对应的产品列表(假设 getProductByContract 是可用接口) |
| | | const res = await selectProductRecordListByPuechaserId({ |
| | | purchaseContractNumber: form.value.purchaseContractNumber, |
| | | id: row.id, |
| | | }); |
| | | productList.value = res.data.map(item => ({ |
| | | ...item, |
| | | quantityStock: Number( |
| | | item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0 |
| | | ), |
| | | originalQuantityStock: Number( |
| | | item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0 |
| | | ), |
| | | })); |
| | | selectedRows.value = productList.value; |
| | | } catch (error) { |
| | | console.error("加载产品失败:", error); |
| | | proxy.$modal.msgError("加载产品失败"); |
| | | productList.value = []; |
| | | } finally { |
| | | loadingProducts.value = false; |
| | | } |
| | | } |
| | | } else { |
| | | // 直接新增入库 |
| | | openDirectForm(type, row); |
| | | } |
| | | }; |
| | | const typeValue = ref("add"); |
| | | // 打开直接新增入库弹框 |
| | | const openDirectForm = async (type, row) => { |
| | | typeValue.value = type; |
| | | directDialogVisible.value = true; |
| | | directSelectedRows.value = []; |
| | | directQuery.value = { |
| | | productId: null, |
| | | productModelId: null, |
| | | productCategory: "", |
| | | inboundQuantity: 0, |
| | | warnNum: 0, |
| | | outStockQuantity: 0, |
| | | shortageDescription: "", |
| | | }; |
| | | directProductList.value = []; |
| | | directForm.value = { |
| | | id: null, |
| | | supplierId: null, |
| | | supplierName: "", |
| | | inboundTime: "", |
| | | inboundBatch: "", |
| | | recorderId: userStore.userId, |
| | | recorderName: userStore.name, |
| | | entryDate: getCurrentDate(), |
| | | remark: "", |
| | | }; |
| | | |
| | | // 确保产品大类数据已加载 |
| | | // if (productList.value.length === 0) { |
| | | // await loadProductList(); |
| | | // } |
| | | if (type === "edit" && row) { |
| | | // 编辑模式,回显数据 |
| | | console.log(row, "=============="); |
| | | directForm.value = { ...row }; |
| | | // 回显其他字段 |
| | | directQuery.value.inboundQuantity = row.inboundNum || row.inboundQuantity; |
| | | directQuery.value.warnNum = row.warnNum || 0; |
| | | directQuery.value.outStockQuantity = row.outStockQuantity || 0; |
| | | directQuery.value.shortageDescription = row.shortageDescription || ""; |
| | | // 回显产品大类和规格型号 |
| | | if (row.productModelId) { |
| | | // 这里需要根据实际情况获取产品大类ID,暂时假设row中有productId字段 |
| | | if (row.productId) { |
| | | directQuery.value.productId = row.productId; |
| | | // 更新产品类别名称 |
| | | const productCategory = findNodeById(productList.value, row.productId); |
| | | if (productCategory) { |
| | | directQuery.value.productCategory = productCategory; |
| | | } |
| | | // 根据产品大类加载规格型号列表并回显 |
| | | await loadProductModelList(row.productId); |
| | | directQuery.value.productModelId = row.productModelId; |
| | | } else { |
| | | // 如果没有productId字段,尝试根据productCategory查找 |
| | | // 这里需要根据实际情况调整查找逻辑 |
| | | directQuery.value.productId = row.productCategory || ""; |
| | | directQuery.value.productModelId = row.specificationModel; |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // 转换产品树数据格式为 el-tree-select 所需格式 |
| | | function convertIdToValue(data) { |
| | | return data.map(item => { |
| | | const { id, children, ...rest } = item; |
| | | const newItem = { |
| | | ...rest, |
| | | value: id, |
| | | label: item.productName, |
| | | }; |
| | | if (children && children.length > 0) { |
| | | newItem.children = convertIdToValue(children); |
| | | } |
| | | return newItem; |
| | | }); |
| | | } |
| | | |
| | | // 根据 ID 查找节点名称 |
| | | const findNodeById = (nodes, productId) => { |
| | | for (let i = 0; i < nodes.length; i++) { |
| | | if (nodes[i].value === productId) { |
| | | return nodes[i].label; |
| | | } |
| | | if (nodes[i].children && nodes[i].children.length > 0) { |
| | | const foundNode = findNodeById(nodes[i].children, productId); |
| | | if (foundNode) { |
| | | return foundNode; |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | }; |
| | | |
| | | // 加载产品大类列表 |
| | | const loadProductList = async () => { |
| | | try { |
| | | const res = await productTreeList(); |
| | | // 确保数据格式符合 el-tree-select 要求 |
| | | if (Array.isArray(res)) { |
| | | productList.value = convertIdToValue(res); |
| | | } else { |
| | | productList.value = []; |
| | | } |
| | | } catch (error) { |
| | | console.error("加载产品大类失败:", error); |
| | | proxy.$modal.msgError("加载产品大类失败"); |
| | | } |
| | | }; |
| | | |
| | | // 处理产品大类变化 |
| | | const handleProductCategoryChange = value => { |
| | | directQuery.value.productModelId = ""; |
| | | productModelList.value = []; |
| | | if (value) { |
| | | // 根据产品大类加载规格型号列表 |
| | | loadProductModelList(value); |
| | | // 更新产品类别名称 |
| | | const productCategory = findNodeById(productList.value, value); |
| | | if (productCategory) { |
| | | directQuery.value.productCategory = productCategory; |
| | | } |
| | | } else { |
| | | directQuery.value.productCategory = ""; |
| | | } |
| | | }; |
| | | |
| | | // 加载产品型号列表 |
| | | const loadProductModelList = async productId => { |
| | | try { |
| | | const res = await modelList({ id: productId }); |
| | | productModelList.value = res; |
| | | } catch (error) { |
| | | console.error("加载规格型号失败:", error); |
| | | proxy.$modal.msgError("加载规格型号失败"); |
| | | } |
| | | }; |
| | | |
| | | // 直接新增入库搜索产品 |
| | | const onDirectSearch = async () => { |
| | | try { |
| | | directLoading.value = true; |
| | | // 这里需要调用产品搜索API,暂时模拟数据 |
| | | // 实际项目中应该调用真实的产品查询接口 |
| | | directProductList.value = [ |
| | | { |
| | | id: 1, |
| | | productCategory: "电子产品", |
| | | specificationModel: "A-100", |
| | | unit: "个", |
| | | quantityStock: 0, |
| | | outStockQuantity: 0, |
| | | shortageDescription: "", |
| | | taxRate: 13, |
| | | taxInclusiveUnitPrice: 100, |
| | | }, |
| | | { |
| | | id: 2, |
| | | productCategory: "电子产品", |
| | | specificationModel: "A-200", |
| | | unit: "个", |
| | | quantityStock: 0, |
| | | outStockQuantity: 0, |
| | | shortageDescription: "", |
| | | taxRate: 13, |
| | | taxInclusiveUnitPrice: 200, |
| | | }, |
| | | { |
| | | id: 3, |
| | | productCategory: "办公用品", |
| | | specificationModel: "B-100", |
| | | unit: "套", |
| | | quantityStock: 0, |
| | | outStockQuantity: 0, |
| | | shortageDescription: "", |
| | | taxRate: 13, |
| | | taxInclusiveUnitPrice: 50, |
| | | }, |
| | | ]; |
| | | } catch (error) { |
| | | console.error("搜索产品失败:", error); |
| | | proxy.$modal.msgError("搜索产品失败"); |
| | | directProductList.value = []; |
| | | } finally { |
| | | directLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | // 直接新增入库重置搜索 |
| | | const onDirectReset = () => { |
| | | directQuery.value = { |
| | | productId: null, |
| | | productModelId: null, |
| | | inboundQuantity: 0, |
| | | warnNum: 0, |
| | | outStockQuantity: 0, |
| | | shortageDescription: "", |
| | | }; |
| | | directProductList.value = []; |
| | | }; |
| | | |
| | | // 处理直接新增入库产品选择 |
| | | const handleDirectSelectionChange = selection => { |
| | | directSelectedRows.value = selection.filter(item => item.id); |
| | | }; |
| | | |
| | | const updatePro = async () => { |
| | |
| | | } |
| | | }; |
| | | |
| | | // 关闭弹框 |
| | | // 关闭订单入库弹框 |
| | | const closeDia = () => { |
| | | proxy.$refs.formRef.resetFields(); |
| | | dialogFormVisible.value = false; |
| | | }; |
| | | |
| | | // 关闭直接新增入库弹框 |
| | | const closeDirectDia = () => { |
| | | if (proxy.$refs.directFormRef) { |
| | | proxy.$refs.directFormRef.resetFields(); |
| | | } |
| | | directDialogVisible.value = false; |
| | | }; |
| | | |
| | | // 提交直接新增入库表单 |
| | | const submitDirectForm = async () => { |
| | | // 验证至少选择了一个产品 |
| | | console.log(directQuery.value, "directQuery.value"); |
| | | if (!directQuery.value.productModelId) { |
| | | proxy.$modal.msgWarning("请先选择产品及规格型号"); |
| | | return; |
| | | } |
| | | await proxy.$refs.directFormRef.validate(); |
| | | if (directQuery.value.inboundQuantity <= 0) { |
| | | proxy.$modal.msgError("本次入库数量需大于0"); |
| | | return; |
| | | } |
| | | |
| | | // 准备提交数据 |
| | | const submitData = { |
| | | ...directQuery.value, |
| | | // 如果是编辑模式,添加id |
| | | ...(directForm.value.id && { id: directForm.value.id }), |
| | | }; |
| | | |
| | | addProduct(submitData).then(res => { |
| | | if (res.code === 200) { |
| | | proxy.$modal.msgSuccess("操作成功"); |
| | | closeDirectDia(); |
| | | getList(); // 刷新列表 |
| | | } else { |
| | | proxy.$modal.msgError(res.msg || "操作失败"); |
| | | } |
| | | }); |
| | | }; |
| | | // 表格选择数据 |
| | | const handleSelectionChange = selection => { |
| | |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | loadProductList(); |
| | | }); |
| | | </script> |
| | | |