| | |
| | | prop="specificationModel" /> |
| | | <el-table-column label="单位" |
| | | prop="unit" /> |
| | | <el-table-column label="入库审核状态" |
| | | <el-table-column label="入库审核状态" |
| | | prop="stockInApprovalStatus" |
| | | width="120"> |
| | | <template #default="scope"> |
| | |
| | | </el-table-column> |
| | | <el-table-column label="数量" |
| | | prop="quantity" /> |
| | | <el-table-column label="销售发货数量" |
| | | prop="shippedQuantity" /> |
| | | <el-table-column label="可用数量" |
| | | prop="availableQuality" /> |
| | | <el-table-column label="退货数量" |
| | | prop="returnQuality" /> |
| | | prop="returnQuantity" /> |
| | | <el-table-column label="税率(%)" |
| | | prop="taxRate" /> |
| | | <el-table-column label="含税单价(元)" |
| | |
| | | <el-table-column label="项目名称" |
| | | prop="projectName" |
| | | width="320" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="采购类别" |
| | | prop="purchaseCategory" |
| | | width="100" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="提货方式" |
| | | prop="pickupMethod" |
| | | width="100" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="采购油品" |
| | | prop="purchaseOilProduct" |
| | | width="100" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="物流方式" |
| | | prop="logisticsMethod" |
| | | width="100" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="采购油库" |
| | | prop="oilDepotName" |
| | | width="150" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="客户名称" |
| | | prop="customerName" |
| | | width="150" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="最佳到站日期" |
| | | prop="bestArrivalDate" |
| | | width="120" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="采购数量(吨)" |
| | | prop="purchaseQuantity" |
| | | width="120" |
| | | align="center" /> |
| | | <el-table-column label="采购申请订单状态" |
| | | prop="purchaseOrderStatus" |
| | | width="140" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="审批状态" |
| | | prop="approvalStatus" |
| | |
| | | width="200" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" /> |
| | | <el-table-column label="实际合同金额(元)" |
| | | prop="netContractAmount" |
| | | width="200" |
| | | show-overflow-tooltip |
| | | :formatter="(_, __, cellValue) => formatMoney(cellValue)" /> |
| | | <el-table-column label="录入人" |
| | | prop="recorderName" |
| | | width="120" |
| | |
| | | <el-button link |
| | | type="primary" |
| | | @click="openForm('edit', scope.row)" |
| | | :disabled="scope.row.stockInStatus === '完全入库'">编辑 |
| | | :disabled="scope.row.approvalStatus === 3">编辑 |
| | | </el-button> |
| | | <el-button link |
| | | type="primary" |
| | |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="付款方式"> |
| | | <el-input v-model="form.paymentMethod" |
| | | placeholder="请输入" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="签订日期:" |
| | | prop="executionDate"> |
| | | <el-form-item label="最佳到站日期:" |
| | | prop="bestArrivalDate"> |
| | | <el-date-picker style="width: 100%" |
| | | v-model="form.executionDate" |
| | | v-model="form.bestArrivalDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="付款方式"> |
| | | <el-input v-model="form.paymentMethod" |
| | | placeholder="请输入" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="录入人:" |
| | | prop="recorderId"> |
| | | <el-select v-model="form.recorderId" |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="签订日期:" |
| | | prop="executionDate"> |
| | | <el-date-picker style="width: 100%" |
| | | v-model="form.executionDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="请选择" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="录入日期:" |
| | | prop="entryDate"> |
| | | <el-date-picker style="width: 100%" |
| | |
| | | type="date" |
| | | placeholder="请选择" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-section-title">采购入库提交</div> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="申请提交时间:" |
| | | prop="applicationSubmitTime"> |
| | | <el-date-picker style="width: 100%" |
| | | v-model="form.applicationSubmitTime" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | type="datetime" |
| | | placeholder="请选择" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="采购类别:" |
| | | prop="purchaseCategory"> |
| | | <el-radio-group v-model="form.purchaseCategory" |
| | | @change="purchaseCategoryChange"> |
| | | <el-radio value="客存">客存</el-radio> |
| | | <el-radio value="代储">代储</el-radio> |
| | | <el-radio value="采购入库">采购入库</el-radio> |
| | | <el-radio value="采购直销">采购直销</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="物流方式:" |
| | | prop="logisticsMethod"> |
| | | <el-select v-model="form.logisticsMethod" |
| | | placeholder="请选择" |
| | | clearable |
| | | style="width: 100%"> |
| | | <el-option label="厂家配送" |
| | | value="厂家配送" /> |
| | | <el-option label="委外物流" |
| | | value="委外物流" /> |
| | | <el-option label="客户自提" |
| | | value="客户自提" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="提货方式:" |
| | | prop="pickupMethod"> |
| | | <el-radio-group v-model="form.pickupMethod"> |
| | | <el-radio value="暂不提货">暂不提货</el-radio> |
| | | <el-radio value="提货">提货</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="采购油库:" |
| | | prop="oilDepotId"> |
| | | <el-select v-model="form.oilDepotId" |
| | | placeholder="请选择" |
| | | clearable |
| | | popper-class="oil-depot-select-popper" |
| | | style="width: 100%"> |
| | | <el-option v-for="item in oilDepotList" |
| | | :key="item.id" |
| | | :label="item.depotName" |
| | | :value="item.id"> |
| | | <div class="oil-depot-option"> |
| | | <div class="oil-depot-option-title">{{ item.depotName }}</div> |
| | | <div class="oil-depot-option-line">负责人:{{ item.chargePerson }}</div> |
| | | <div class="oil-depot-option-line">联系电话:{{ item.phone }}</div> |
| | | <div class="oil-depot-option-line">所属公司:{{ item.company }}</div> |
| | | <div class="oil-depot-option-line">启用日期:{{ item.enableDate }}</div> |
| | | </div> |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="客户名称:" |
| | | prop="customerName"> |
| | | <el-input v-model="form.customerName" |
| | | placeholder="仅采购类别为代储/采购直销时可填写" |
| | | clearable |
| | | :disabled="!['代储', '采购直销'].includes(form.purchaseCategory)" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="采购数量(吨):" |
| | | prop="purchaseQuantity"> |
| | | <el-input-number v-model="form.purchaseQuantity" |
| | | :precision="0" |
| | | :step="1" |
| | | :min="0" |
| | | placeholder="请输入" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-section-title">系统信息</div> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="采购申请订单状态:" |
| | | prop="purchaseOrderStatus"> |
| | | <el-select v-model="form.purchaseOrderStatus" |
| | | placeholder="请选择" |
| | | clearable |
| | | style="width: 100%"> |
| | | <el-option label="已申请,未装车" |
| | | value="已申请,未装车" /> |
| | | <el-option label="以出厂,未入库" |
| | | value="以出厂,未入库" /> |
| | | <el-option label="已入库" |
| | | value="已入库" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | getPurchaseTemplateList, |
| | | delPurchaseTemplate, |
| | | } from "@/api/procurementManagement/procurementLedger.js"; |
| | | import { allOilDepot } from "@/api/basicData/oilDepot.js"; |
| | | import useFormData from "@/hooks/useFormData.js"; |
| | | const FileList = defineAsyncComponent(() => |
| | | import("@/components/Dialog/FileList.vue") |
| | |
| | | const productOptions = ref([]); |
| | | const salesContractList = ref([]); |
| | | const supplierList = ref([]); |
| | | const oilDepotList = ref([]); |
| | | const tableLoading = ref(false); |
| | | const recordId = ref(); |
| | | const fileListDialogVisible = ref(false); |
| | |
| | | // 获取入库状态标签类型 |
| | | const getStockInStatusType = status => { |
| | | const typeMap = { |
| | | "待入库": "info", // 待入库 - 灰色 |
| | | "入库中": "warning", // 入库中 - 橙色 |
| | | "完全入库": "success", // 完全入库 - 绿色 |
| | | 待入库: "info", // 待入库 - 灰色 |
| | | 入库中: "warning", // 入库中 - 橙色 |
| | | 完全入库: "success", // 完全入库 - 绿色 |
| | | }; |
| | | return typeMap[status] || ""; |
| | | }; |
| | |
| | | // 获取入库审核状态标签类型 |
| | | const getStockInApprovalStatusType = status => { |
| | | const typeMap = { |
| | | "待入库": "info", // 待入库 - 灰色 |
| | | "入库中": "warning", // 入库中 - 橙色 |
| | | "完全入库": "success", // 完全入库 - 绿色 |
| | | 待入库: "info", // 待入库 - 灰色 |
| | | 入库中: "warning", // 入库中 - 橙色 |
| | | 完全入库: "success", // 完全入库 - 绿色 |
| | | }; |
| | | return typeMap[status] || ""; |
| | | }; |
| | |
| | | paymentMethod: "", |
| | | executionDate: "", |
| | | isChecked: false, |
| | | purchaseCategory: "", |
| | | purchaseOilProduct: "", |
| | | logisticsMethod: "", |
| | | pickupMethod: "", |
| | | oilDepotId: "", |
| | | customerName: "", |
| | | bestArrivalDate: "", |
| | | purchaseQuantity: "", |
| | | purchaseOrderStatus: "", |
| | | applicationSubmitTime: "", |
| | | }, |
| | | rules: { |
| | | purchaseContractNumber: [ |
| | | { required: true, message: "请输入", trigger: "blur" }, |
| | | { required: false, message: "请输入", trigger: "blur" }, |
| | | ], |
| | | projectName: [ |
| | | { required: true, message: "请输入项目名称", trigger: "blur" }, |
| | |
| | | supplierId: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | entryDate: [{ required: true, message: "请选择", trigger: "change" }], |
| | | executionDate: [{ required: true, message: "请选择", trigger: "change" }], |
| | | purchaseCategory: [ |
| | | { required: true, message: "请选择采购类别", trigger: "change" }, |
| | | ], |
| | | purchaseOilProduct: [ |
| | | { required: true, message: "请选择采购油品", trigger: "change" }, |
| | | ], |
| | | oilDepotId: [ |
| | | { required: true, message: "请选择采购油库", trigger: "change" }, |
| | | ], |
| | | purchaseQuantity: [ |
| | | { required: true, message: "请输入采购数量", trigger: "change" }, |
| | | ], |
| | | }, |
| | | }); |
| | | const { form, rules } = toRefs(data); |
| | |
| | | }; |
| | | // 主表合计方法 |
| | | const summarizeMainTable = param => { |
| | | return proxy.summarizeTable(param, ["contractAmount"]); |
| | | return proxy.summarizeTable(param, ["contractAmount", "netContractAmount"]); |
| | | }; |
| | | const formatMoney = value => { |
| | | if (value === null || value === undefined || value === "") { |
| | | return "--"; |
| | | } |
| | | const num = Number(value); |
| | | return Number.isFinite(num) ? num.toFixed(2) : "--"; |
| | | }; |
| | | // 子表合计方法 |
| | | const summarizeProTable = param => { |
| | |
| | | const openForm = async (type, row) => { |
| | | // 编辑时检查入库状态,完全入库时不能编辑 |
| | | if (type === "edit" && row) { |
| | | if (row.stockInStatus === '完全入库') { |
| | | if (row.stockInStatus === "完全入库") { |
| | | proxy.$modal.msgWarning("完全入库状态的记录不能编辑"); |
| | | return; |
| | | } |
| | |
| | | isTemplateNameDuplicate.value = false; |
| | | try { |
| | | // 并行加载基础数据 |
| | | const [salesRes, supplierRes] = await Promise.all([ |
| | | const [salesRes, supplierRes, oilDepotRes] = await Promise.all([ |
| | | getSalesNo(), |
| | | getOptions(), |
| | | allOilDepot(), |
| | | ]); |
| | | |
| | | salesContractList.value = salesRes || []; |
| | |
| | | supplierList.value = (supplierRes.data || []).filter( |
| | | item => item.isWhite === 0 |
| | | ); |
| | | oilDepotList.value = oilDepotRes?.data || []; |
| | | |
| | | form.value.entryDate = getCurrentDate(); |
| | | |
| | | if (type === "add") { |
| | | // 新增时生成采购合同号 |
| | | try { |
| | | const purchaseNoRes = await createPurchaseNo(); |
| | | if (purchaseNoRes?.data) { |
| | | form.value.purchaseContractNumber = purchaseNoRes.data; |
| | | } |
| | | } catch (error) { |
| | | console.error("生成采购合同号失败:", error); |
| | | proxy.$modal.msgWarning("生成采购合同号失败"); |
| | | } |
| | | } else if (type === "edit" && row?.id) { |
| | | if (type === "edit" && row?.id) { |
| | | // 编辑时加载数据 |
| | | currentId.value = row.id; |
| | | try { |
| | |
| | | form.value = { ...purchaseRes, stockInStatus: row.stockInStatus }; |
| | | fileList.value = purchaseRes.storageBlobVOS || []; |
| | | // 使用 productList 接口获取产品列表,以获取入库审核状态 |
| | | const productRes = await productList({ salesLedgerId: row.id, type: 2 }); |
| | | const productRes = await productList({ |
| | | salesLedgerId: row.id, |
| | | type: 2, |
| | | }); |
| | | productData.value = productRes.data || []; |
| | | } catch (error) { |
| | | console.error("加载采购台账数据失败:", error); |
| | |
| | | |
| | | // 提交表单 |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | proxy.$refs["formRef"].validate(async valid => { |
| | | if (valid) { |
| | | if (productData.value.length > 0) { |
| | | // 新增时,需要从每个产品对象中删除 id 字段 |
| | |
| | | delete submitData.id; |
| | | } |
| | | |
| | | // 如果采购合同号为空,则根据录入日期自动生成 |
| | | if (!submitData.purchaseContractNumber) { |
| | | try { |
| | | const purchaseNoRes = await createPurchaseNo(submitData.entryDate); |
| | | if (purchaseNoRes?.data) { |
| | | submitData.purchaseContractNumber = purchaseNoRes.data; |
| | | } |
| | | } catch (error) { |
| | | console.error("生成采购合同号失败:", error); |
| | | proxy.$modal.msgWarning("生成采购合同号失败"); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | addOrEditPurchase(submitData).then(res => { |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | closeDia(); |
| | |
| | | // 打开产品弹框 |
| | | const openProductForm = async (type, row, index) => { |
| | | // 编辑时检查产品入库审核状态,完全入库时不能编辑 |
| | | if (type === "edit" && row && row.stockInApprovalStatus === '完全入库') { |
| | | if (type === "edit" && row && row.stockInApprovalStatus === "完全入库") { |
| | | proxy.$modal.msgWarning("完全入库状态的产品不能编辑"); |
| | | return; |
| | | } |
| | |
| | | }; |
| | | // 删除产品 |
| | | const deleteProduct = () => { |
| | | if (productData.value.length <= 1) { |
| | | proxy.$modal.msgWarning("采购台账至少需要保留一条产品数据"); |
| | | return; |
| | | } |
| | | if (productSelectedRows.value.length === 0) { |
| | | proxy.$modal.msgWarning("请选择数据"); |
| | | return; |
| | | } |
| | | // 检查选中的产品中是否有完全入库的 |
| | | const hasFullyStocked = productSelectedRows.value.some( |
| | | row => row.stockInApprovalStatus === '完全入库' |
| | | row => row.stockInApprovalStatus === "完全入库" |
| | | ); |
| | | if (hasFullyStocked) { |
| | | proxy.$modal.msgWarning("选中的产品中包含完全入库的产品,无法删除"); |
| | |
| | | } |
| | | } |
| | | }; |
| | | // 采购类别改变:仅代储/采购直销时客户名称可用,切换后清空 |
| | | const purchaseCategoryChange = val => { |
| | | if (!["代储", "采购直销"].includes(val)) { |
| | | form.value.customerName = ""; |
| | | } |
| | | }; |
| | | |
| | | // 销售合同选择改变方法 |
| | | const salesLedgerChange = async row => { |
| | | console.log("row", row); |
| | |
| | | contractNo: form.value.salesLedgerId, |
| | | }); |
| | | if (code == 200) { |
| | | productData.value = data; |
| | | productData.value = data || []; |
| | | } |
| | | }; |
| | | |
| | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | // 表单分栏标题:蓝色竖条 + 浅蓝底色,突出分区 |
| | | .form-section-title { |
| | | margin: 18px 0 14px; |
| | | padding: 8px 14px; |
| | | font-size: 15px; |
| | | font-weight: 600; |
| | | color: #1d6fd8; |
| | | background: linear-gradient(90deg, rgba(64, 158, 255, 0.14), rgba(64, 158, 255, 0.02)); |
| | | border-left: 4px solid #409eff; |
| | | border-radius: 3px; |
| | | } |
| | | |
| | | .invalid-row { |
| | | opacity: 0.6; |
| | | background-color: #f5f7fa; |
| | |
| | | .select-button-group { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | // 采购油库下拉选项:小卡片样式 |
| | | .oil-depot-option { |
| | | padding: 8px 10px; |
| | | |
| | | .oil-depot-option-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .oil-depot-option-line { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | line-height: 1.8; |
| | | } |
| | | } |
| | | |
| | | // 审批人节点容器样式 |
| | |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | <style lang="scss"> |
| | | // 下拉面板渲染在 body 下,需全局样式 |
| | | .oil-depot-select-popper { |
| | | .el-select-dropdown__item { |
| | | height: auto; |
| | | line-height: normal; |
| | | padding: 4px 0; |
| | | } |
| | | |
| | | .oil-depot-option { |
| | | border: 1px solid #e4e7ed; |
| | | border-radius: 6px; |
| | | background-color: #fafbfc; |
| | | |
| | | &:hover { |
| | | border-color: #409eff; |
| | | background-color: #f0f7ff; |
| | | } |
| | | } |
| | | } |
| | | </style> |