| | |
| | | <el-button type="primary" @click="openForm('add')"> |
| | | 新增台账 |
| | | </el-button> |
| | | <el-button type="primary" plain @click="openOtherAmountDialog"> |
| | | 其他金额维护 |
| | | </el-button> |
| | | <el-button type="primary" plain @click="handleImport">导入</el-button> |
| | | <el-button @click="handleOut">导出</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">删除</el-button> |
| | |
| | | </div> |
| | | </div> |
| | | <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange" |
| | | :expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" show-summary style="width: 100%" |
| | | :expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" :row-class-name="tableRowClassName" show-summary style="width: 100%" |
| | | :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 18.5em)"> |
| | | <el-table-column align="center" type="selection" width="55" fixed="left"/> |
| | | <el-table-column type="expand" width="60" fixed="left"> |
| | |
| | | width="100px" |
| | | align="center"> |
| | | <template #default="scope"> |
| | | <el-tag v-if="scope.row.approveStatus === 1" |
| | | |
| | | <el-tag v-if="scope.row.approveStatus === 1 && (!scope.row.shippingDate || !scope.row.shippingCarNumber)" |
| | | type="success">充足</el-tag> |
| | | <el-tag v-else |
| | | type="danger">不足</el-tag> |
| | | <el-tag v-else-if="scope.row.approveStatus === 0 && (scope.row.shippingDate || scope.row.shippingCarNumber)" |
| | | type="success">已出库</el-tag> |
| | | <el-tag v-else type="danger">不足</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="发货状态" width="140" align="center"> |
| | |
| | | <template #default="scope"> |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | type="primary" |
| | | :disabled="!canShip(scope.row)" |
| | | @click="openDeliveryForm(scope.row)"> |
| | | 发货 |
| | |
| | | <el-table-column label="录入人" prop="entryPersonName" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="录入日期" prop="entryDate" width="120" show-overflow-tooltip /> |
| | | <el-table-column label="签订日期" prop="executionDate" width="120" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="操作" min-width="100" align="center"> |
| | | <el-table-column label="交付日期" prop="deliveryDate" width="120" show-overflow-tooltip /> |
| | | <el-table-column label="备注" prop="remarks" width="200" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="操作" width="130" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="openForm('edit', scope.row)">编辑</el-button> |
| | | <!-- <el-button link type="primary" size="small" @click="openForm('view', scope.row)">详情</el-button>--> |
| | | <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">附件</el-button> |
| | | <!-- <el-button link type="primary" size="small" @click="openDeliveryForm(scope.row)">发货</el-button>--> |
| | | <el-button link type="primary" @click="openForm('edit', scope.row)" :disabled="!scope.row.isEdit">编辑</el-button> |
| | | <el-button link type="primary" @click="downLoadFile(scope.row)">附件</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | <FormDialog v-model="dialogFormVisible" :title="operationType === 'add' ? '新增销售台账页面' : '编辑销售台账页面'" :width="'70%'" |
| | | :operation-type="operationType" @close="closeDia" @confirm="submitForm" @cancel="closeDia"> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <!-- 报价单导入入口:放在表单顶部,选择后反显客户/业务员等 --> |
| | | <el-row v-if="operationType === 'add'" style="margin-bottom: 10px;"> |
| | | <el-col :span="24" style="text-align: right;"> |
| | | <el-button type="primary" plain @click="openQuotationDialog"> |
| | | 从销售报价导入 |
| | | </el-button> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="销售合同号:" prop="salesContractNo"> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="交货日期:" prop="entryDate"> |
| | | <el-date-picker style="width: 100%" v-model="form.deliveryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" |
| | | type="date" placeholder="请选择" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-form-item label="产品信息:" prop="entryDate"> |
| | | <el-button v-if="operationType !== 'view'" type="primary" @click="openProductForm('add')">添加</el-button> |
| | |
| | | </el-row> |
| | | <el-table :data="productData" border @selection-change="productSelected" show-summary |
| | | :summary-method="summarizeMainTable"> |
| | | <el-table-column align="center" type="selection" width="55" v-if="operationType !== 'view'" /> |
| | | <el-table-column align="center" type="selection" width="55" v-if="operationType !== 'view'" |
| | | :selectable="(row) => !isProductShipped(row)" /> |
| | | <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="taxExclusiveTotalPrice" :formatter="formattedNumber" /> |
| | | <el-table-column fixed="right" label="操作" min-width="60" align="center" v-if="operationType !== 'view'"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="openProductForm('edit', scope.row,scope.$index)">编辑</el-button> |
| | | <el-button link type="primary" size="small" |
| | | :disabled="isProductShipped(scope.row)" |
| | | @click="openProductForm('edit', scope.row,scope.$index)">编辑</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="备注·:" prop="remark"> |
| | | <el-input v-model="form.remark" placeholder="请输入" clearable type="textarea" :rows="2" :disabled="operationType === 'view'" /> |
| | | <el-form-item label="备注:" prop="remarks"> |
| | | <el-input v-model="form.remarks" placeholder="请输入" clearable type="textarea" :rows="2" :disabled="operationType === 'view'" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="附件材料:" prop="remark"> |
| | | <el-form-item label="附件材料:" prop="salesLedgerFiles"> |
| | | <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload |
| | | :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError" |
| | | :on-success="handleUploadSuccess" :on-remove="handleRemove"> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="quotationPage.total > 0" |
| | | :total="quotationPage.total" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :page="quotationPage.current" |
| | | :limit="quotationPage.size" |
| | | @pagination="quotationPaginationChange" |
| | | /> |
| | | |
| | | <template #footer> |
| | | <el-button @click="quotationDialogVisible = false">关闭</el-button> |
| | |
| | | <div v-for="(item, index) in printData" :key="index" class="print-page"> |
| | | <div class="delivery-note"> |
| | | <div class="header"> |
| | | <div class="company-name">鼎诚瑞实业有限责任公司</div> |
| | | <div class="document-title">零售发货单</div> |
| | | </div> |
| | | |
| | |
| | | <div class="info-row"> |
| | | <div> |
| | | <span class="label">客户名称:</span> |
| | | <span class="value">{{ item.customerName || '张爱有' }}</span> |
| | | <span class="value">{{ item.customerName }}</span> |
| | | </div> |
| | | <span class="label">单号:</span> |
| | | <span class="value">{{ item.salesContractNo }}</span> |
| | |
| | | <div> |
| | | <el-button |
| | | type="danger" |
| | | size="small" |
| | | @click="removeApproverNode(index)" |
| | | v-if="approverNodes.length > 1" |
| | | >删除</el-button> |
| | |
| | | <el-button @click="closeDeliveryDia">取消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 其他金额维护(新增/编辑/删除) --> |
| | | <el-dialog |
| | | v-model="otherAmountDialogVisible" |
| | | title="其他金额维护" |
| | | width="80%" |
| | | :close-on-click-modal="false" |
| | | @close="closeOtherAmountDialog" |
| | | > |
| | | <el-row :gutter="20"> |
| | | <el-col :span="14"> |
| | | <el-table |
| | | :data="otherAmountRecords" |
| | | border |
| | | v-loading="otherAmountLoading" |
| | | height="55vh" |
| | | > |
| | | <el-table-column label="编码" prop="code" min-width="120" show-overflow-tooltip /> |
| | | <el-table-column label="项目" prop="processName" min-width="180" show-overflow-tooltip /> |
| | | <el-table-column label="数量" prop="quantity" min-width="110" :formatter="formattedNumber" /> |
| | | <el-table-column label="单价(元)" prop="unitPrice" min-width="130" :formatter="formattedNumber" /> |
| | | <el-table-column label="金额(元)" prop="amount" min-width="160" :formatter="formattedNumber" /> |
| | | <el-table-column fixed="right" label="操作" width="160" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="handleOtherEdit(scope.row)">编辑</el-button> |
| | | <el-button link type="danger" size="small" @click="handleOtherDelete(scope.row)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="otherAmountTotal > 0" |
| | | :total="otherAmountTotal" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :page="otherAmountPage.current" |
| | | :limit="otherAmountPage.size" |
| | | @pagination="otherAmountPaginationChange" |
| | | /> |
| | | </el-col> |
| | | |
| | | <el-col :span="10"> |
| | | <div style="padding: 8px 0;"> |
| | | <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom: 10px;"> |
| | | <div style="font-weight:600;"> |
| | | {{ otherAmountOperationType === 'add' ? '新增其他金额' : '编辑其他金额' }} |
| | | </div> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | size="small" |
| | | @click="handleOtherAdd" |
| | | :disabled="otherAmountOperationType === 'add'" |
| | | > |
| | | 新增 |
| | | </el-button> |
| | | </div> |
| | | |
| | | <el-form |
| | | :model="otherAmountForm" |
| | | label-width="120px" |
| | | label-position="top" |
| | | :rules="otherAmountRules" |
| | | ref="otherAmountFormRef" |
| | | > |
| | | <el-form-item label="编码code"> |
| | | <el-input v-model="otherAmountForm.code" placeholder="请输入编码(可选)" clearable /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="项目processName" prop="processName"> |
| | | <el-input v-model="otherAmountForm.processName" placeholder="请输入项目名称" clearable /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="数量quantity" prop="quantity"> |
| | | <el-input-number |
| | | v-model="otherAmountForm.quantity" |
| | | :min="0" |
| | | :precision="2" |
| | | style="width:100%" |
| | | placeholder="请输入数量" |
| | | clearable |
| | | @change="recalcOtherAmount" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="单价unitPrice(元)" prop="unitPrice"> |
| | | <el-input-number |
| | | v-model="otherAmountForm.unitPrice" |
| | | :min="0" |
| | | :precision="2" |
| | | style="width:100%" |
| | | placeholder="请输入单价" |
| | | clearable |
| | | @change="recalcOtherAmount" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="金额amount(元)"> |
| | | <el-input v-model="otherAmountForm.amount" disabled /> |
| | | </el-form-item> |
| | | |
| | | <div style="display:flex; justify-content:flex-end; gap: 10px; margin-top: 8px;"> |
| | | <el-button @click="closeOtherAmountDialog">取消</el-button> |
| | | <el-button type="primary" @click="submitOtherAmountForm">保存</el-button> |
| | | </div> |
| | | </el-form> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | |
| | | delLedger, |
| | | addOrUpdateSalesLedgerProduct, |
| | | delProduct, |
| | | delLedgerFile, getProductInventory, |
| | | delLedgerFile, |
| | | getProductInventory, |
| | | salesLedgerProductProcessList, |
| | | salesLedgerProductProcessAdd, |
| | | salesLedgerProductProcessUpdate, |
| | | salesLedgerProductProcessDelete, |
| | | } from "@/api/salesManagement/salesLedger.js"; |
| | | import { modelList, productTreeList } from "@/api/basicData/product.js"; |
| | | import useFormData from "@/hooks/useFormData.js"; |
| | |
| | | customerId: "", |
| | | entryPerson: "", |
| | | entryDate: "", |
| | | deliveryDate: "", |
| | | maintenanceTime: "", |
| | | productData: [], |
| | | executionDate: "", |
| | |
| | | customerId: [{ required: true, message: "请选择", trigger: "change" }], |
| | | entryPerson: [{ required: true, message: "请选择", trigger: "change" }], |
| | | entryDate: [{ required: true, message: "请选择", trigger: "change" }], |
| | | deliveryDate: [{ required: true, message: "请选择", trigger: "change" }], |
| | | executionDate: [{ required: true, message: "请选择", trigger: "change" }], |
| | | }, |
| | | }); |
| | |
| | | quotationNo: "", |
| | | customer: "", |
| | | }); |
| | | // 报价单弹框分页 |
| | | const quotationPage = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }); |
| | | const selectedQuotation = ref(null); |
| | | |
| | | // 发货相关 |
| | |
| | | }, |
| | | }); |
| | | const { deliveryForm, deliveryRules } = toRefs(deliveryFormData); |
| | | |
| | | // 其他金额维护(工序/流程金额维护) |
| | | const otherAmountDialogVisible = ref(false); |
| | | const otherAmountLoading = ref(false); |
| | | const otherAmountRecords = ref([]); |
| | | const otherAmountTotal = ref(0); |
| | | const otherAmountPage = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | }); |
| | | |
| | | const otherAmountOperationType = ref("add"); // add/edit |
| | | const otherAmountFormRef = ref(null); |
| | | const otherAmountForm = reactive({ |
| | | id: null, |
| | | code: "", // 前端字段名:code;后端接口列表返回 remark,此处进行映射 |
| | | processName: "", |
| | | quantity: 0, |
| | | unitPrice: 0, |
| | | amount: "0.00", |
| | | }); |
| | | const otherAmountRules = reactive({ |
| | | processName: [{ required: true, message: "请输入项目名称", trigger: "change" }], |
| | | quantity: [{ required: true, message: "请输入数量", trigger: "blur" }], |
| | | unitPrice: [{ required: true, message: "请输入单价", trigger: "blur" }], |
| | | }); |
| | | |
| | | const recalcOtherAmount = () => { |
| | | const quantity = Number(otherAmountForm.quantity ?? 0) || 0; |
| | | const unitPrice = Number(otherAmountForm.unitPrice ?? 0) || 0; |
| | | otherAmountForm.amount = (quantity * unitPrice).toFixed(2); |
| | | }; |
| | | |
| | | const resetOtherAmountForm = (type = "add") => { |
| | | otherAmountOperationType.value = type; |
| | | otherAmountForm.id = null; |
| | | otherAmountForm.code = ""; |
| | | otherAmountForm.processName = ""; |
| | | otherAmountForm.quantity = 0; |
| | | otherAmountForm.unitPrice = 0; |
| | | otherAmountForm.amount = "0.00"; |
| | | }; |
| | | |
| | | const openOtherAmountDialog = () => { |
| | | otherAmountDialogVisible.value = true; |
| | | resetOtherAmountForm("add"); |
| | | // 打开弹框时刷新数据,避免长时间停留导致数据过期 |
| | | otherAmountPage.current = otherAmountPage.current || 1; |
| | | fetchOtherAmountList(); |
| | | }; |
| | | |
| | | const closeOtherAmountDialog = () => { |
| | | otherAmountDialogVisible.value = false; |
| | | resetOtherAmountForm("add"); |
| | | }; |
| | | |
| | | const fetchOtherAmountList = async () => { |
| | | otherAmountLoading.value = true; |
| | | try { |
| | | const params = { |
| | | current: otherAmountPage.current, |
| | | size: otherAmountPage.size, |
| | | }; |
| | | const res = await salesLedgerProductProcessList(params); |
| | | |
| | | // 兼容不同接口响应结构:可能是 res.records / res.total 或 res.data.records / res.data.total |
| | | const records = res?.records ?? res?.data?.records ?? []; |
| | | const total = res?.total ?? res?.data?.total ?? 0; |
| | | |
| | | otherAmountRecords.value = records.map((item) => { |
| | | const quantity = Number(item.quantity ?? 0) || 0; |
| | | const unitPrice = Number(item.unitPrice ?? 0) || 0; |
| | | const amount = Number(item.amount ?? quantity * unitPrice) || 0; |
| | | return { |
| | | id: item.id, |
| | | code: item.code ?? item.remark ?? "", |
| | | processName: item.processName ?? "", |
| | | quantity, |
| | | unitPrice, |
| | | amount: amount.toFixed(2), |
| | | }; |
| | | }); |
| | | |
| | | otherAmountTotal.value = total; |
| | | } finally { |
| | | otherAmountLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const otherAmountPaginationChange = (obj) => { |
| | | otherAmountPage.current = obj.page; |
| | | otherAmountPage.size = obj.limit; |
| | | fetchOtherAmountList(); |
| | | }; |
| | | |
| | | const handleOtherAdd = () => { |
| | | resetOtherAmountForm("add"); |
| | | }; |
| | | |
| | | const handleOtherEdit = (row) => { |
| | | if (!row) return; |
| | | otherAmountOperationType.value = "edit"; |
| | | otherAmountForm.id = row.id ?? null; |
| | | otherAmountForm.code = row.code ?? ""; |
| | | otherAmountForm.processName = row.processName ?? ""; |
| | | otherAmountForm.quantity = Number(row.quantity ?? 0) || 0; |
| | | otherAmountForm.unitPrice = Number(row.unitPrice ?? 0) || 0; |
| | | recalcOtherAmount(); |
| | | }; |
| | | |
| | | const submitOtherAmountForm = () => { |
| | | otherAmountFormRef.value?.validate((valid) => { |
| | | if (!valid) return; |
| | | |
| | | const payload = { |
| | | processName: otherAmountForm.processName, |
| | | quantity: Number(otherAmountForm.quantity) || 0, |
| | | unitPrice: Number(otherAmountForm.unitPrice) || 0, |
| | | amount: Number(otherAmountForm.amount) || 0, |
| | | // 列表返回字段是 remark,这里按“code=remark”做映射 |
| | | remark: otherAmountForm.code, |
| | | // 兼容后端可能直接使用 code 字段 |
| | | code: otherAmountForm.code, |
| | | }; |
| | | |
| | | if (otherAmountOperationType.value === "edit") { |
| | | payload.id = otherAmountForm.id; |
| | | salesLedgerProductProcessUpdate(payload).then(() => { |
| | | proxy.$modal.msgSuccess("保存成功"); |
| | | fetchOtherAmountList(); |
| | | resetOtherAmountForm("add"); |
| | | }); |
| | | } else { |
| | | salesLedgerProductProcessAdd(payload).then(() => { |
| | | proxy.$modal.msgSuccess("保存成功"); |
| | | fetchOtherAmountList(); |
| | | resetOtherAmountForm("add"); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const handleOtherDelete = (row) => { |
| | | if (!row?.id) return; |
| | | ElMessageBox.confirm("确认删除该记录?", "删除", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | return salesLedgerProductProcessDelete(row.id).then(() => { |
| | | proxy.$modal.msgSuccess("删除成功"); |
| | | fetchOtherAmountList(); |
| | | |
| | | if (otherAmountOperationType.value === "edit" && otherAmountForm.id === row.id) { |
| | | resetOtherAmountForm("add"); |
| | | } |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已取消"); |
| | | }); |
| | | }; |
| | | |
| | | // 发货审批人节点(仿协同审批 infoFormDia.vue) |
| | | const approverNodes = ref([{ id: 1, userId: null }]); |
| | |
| | | expandedRowKeys.value = []; |
| | | } |
| | | }; |
| | | |
| | | // 添加表行类名方法 |
| | | const tableRowClassName = ({ row }) => { |
| | | if (!row.deliveryDate) return ''; |
| | | if (row.isFh) return ''; |
| | | |
| | | const diff = row.deliveryDaysDiff; |
| | | if (diff === 15) { |
| | | return 'yellow'; |
| | | } else if (diff === 10) { |
| | | return 'pink'; |
| | | } else if (diff === 2) { |
| | | return 'purple'; |
| | | } else if (diff < 2) { |
| | | return 'red'; |
| | | } |
| | | }; |
| | | // 主表合计方法 |
| | | const summarizeMainTable = (param) => { |
| | | return proxy.summarizeTable(param, [ |
| | |
| | | const openQuotationDialog = async () => { |
| | | if (operationType.value === "view") return; |
| | | quotationDialogVisible.value = true; |
| | | // 打开弹窗时重置分页到第一页 |
| | | quotationPage.current = 1; |
| | | // 先确保客户列表已加载,便于后续回填 customerId |
| | | if (!customerOption.value || customerOption.value.length === 0) { |
| | | try { |
| | |
| | | quotationLoading.value = true; |
| | | try { |
| | | const params = { |
| | | // 兼容后端分页字段:这里沿用报价页面已有可用的字段命名 |
| | | currentPage: 1, |
| | | pageSize: 100, |
| | | // 后端分页字段:current / size |
| | | current: quotationPage.current, |
| | | size: quotationPage.size, |
| | | ...quotationSearchForm, |
| | | status: "通过", |
| | | }; |
| | | const res = await getQuotationList(params); |
| | | quotationList.value = res?.data?.records || []; |
| | | quotationPage.total = res?.data?.total || 0; |
| | | } finally { |
| | | quotationLoading.value = false; |
| | | } |
| | |
| | | const resetQuotationSearch = async () => { |
| | | quotationSearchForm.quotationNo = ""; |
| | | quotationSearchForm.customer = ""; |
| | | quotationPage.current = 1; |
| | | await fetchQuotationList(); |
| | | }; |
| | | |
| | | // 报价单弹框分页切换 |
| | | const quotationPaginationChange = (obj) => { |
| | | quotationPage.current = obj.page; |
| | | quotationPage.size = obj.limit; |
| | | fetchQuotationList(); |
| | | }; |
| | | |
| | | // 选中报价单后回填到台账表单 |
| | |
| | | selectedQuotation.value = row; |
| | | |
| | | // 业务员 |
| | | form.value.salesman = row.salesperson || ""; |
| | | form.value.salesman = (row.salesperson || "").trim(); |
| | | |
| | | // 客户名称 -> customerId |
| | | const customer = (customerOption.value || []).find((c) => c.customerName === row.customer); |
| | | const qCustomerName = String(row.customer || "").trim(); |
| | | const customer = (customerOption.value || []).find((c) => { |
| | | const name = String(c.customerName || "").trim(); |
| | | return name === qCustomerName || name.includes(qCustomerName) || qCustomerName.includes(name); |
| | | }); |
| | | if (customer?.id) { |
| | | form.value.customerId = customer.id; |
| | | } else { |
| | |
| | | const productIndex = ref(0); |
| | | // 打开产品弹框 |
| | | const openProductForm = async (type, row, index) => { |
| | | // 编辑时检查产品是否已发货或审核通过 |
| | | if (type === "edit" && isProductShipped(row)) { |
| | | proxy.$modal.msgWarning("已发货或审核通过的产品不能编辑"); |
| | | return; |
| | | } |
| | | |
| | | productOperationType.value = type; |
| | | productForm.value = {}; |
| | | proxy.resetForm("productFormRef"); |
| | |
| | | proxy.$modal.msgWarning("请选择数据"); |
| | | return; |
| | | } |
| | | |
| | | // 检查是否有已发货或审核通过的产品 |
| | | const shippedProducts = productSelectedRows.value.filter(row => isProductShipped(row)); |
| | | if (shippedProducts.length > 0) { |
| | | proxy.$modal.msgWarning("已发货或审核通过的产品不能删除"); |
| | | return; |
| | | } |
| | | |
| | | if (operationType.value === "add") { |
| | | productSelectedRows.value.forEach((selectedRow) => { |
| | | const index = productData.value.findIndex( |
| | |
| | | proxy.$modal.msg("已取消"); |
| | | }); |
| | | }; |
| | | /** 判断单个产品是否已发货(根据shippingStatus判断,已发货或审核通过不可编辑和删除) */ |
| | | const isProductShipped = (product) => { |
| | | if (!product) return false; |
| | | const status = String(product.shippingStatus || "").trim(); |
| | | // 如果发货状态是"已发货"或"审核通过",则不可编辑和删除 |
| | | return status === "已发货" || status === "审核通过"; |
| | | }; |
| | | |
| | | /** 判断销售订单下是否存在已发货/发货完成的产品(不可删除) */ |
| | | const hasShippedProducts = (products) => { |
| | | if (!products || !products.length) return false; |
| | | return products.some((p) => { |
| | | const status = String(p.shippingStatus || "").trim(); |
| | | // 有发货日期或车牌号视为已发货 |
| | | if (p.shippingDate || p.shippingCarNumber) return true; |
| | | // 已进行发货、发货完成、已发货 均不可删除 |
| | | return status === "已进行发货" || status === "发货完成" || status === "已发货"; |
| | | }); |
| | | }; |
| | | |
| | | // 删除 |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | const handleDelete = async () => { |
| | | if (selectedRows.value.length === 0) { |
| | | proxy.$modal.msgWarning("请选择数据"); |
| | | return; |
| | | } |
| | | const ids = selectedRows.value.map((item) => item.id); |
| | | |
| | | // 检查是否有已进行发货或发货完成的销售订单,若有则不允许删除 |
| | | const cannotDeleteNames = []; |
| | | for (const row of selectedRows.value) { |
| | | let products = row.children && row.children.length > 0 ? row.children : null; |
| | | if (!products) { |
| | | try { |
| | | const res = await productList({ salesLedgerId: row.id, type: 1 }); |
| | | products = res.data || []; |
| | | } catch { |
| | | products = []; |
| | | } |
| | | } |
| | | if (hasShippedProducts(products)) { |
| | | cannotDeleteNames.push(row.salesContractNo || `ID:${row.id}`); |
| | | } |
| | | } |
| | | if (cannotDeleteNames.length > 0) { |
| | | proxy.$modal.msgWarning("已进行发货或发货完成的销售订单不能删除:" + cannotDeleteNames.join("、")); |
| | | return; |
| | | } |
| | | |
| | | ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "取消", |
| | |
| | | <div class="print-page"> |
| | | <div class="delivery-note"> |
| | | <div class="header"> |
| | | <div class="company-name">鼎诚瑞实业有限责任公司</div> |
| | | <div class="document-title">零售发货单</div> |
| | | </div> |
| | | |
| | |
| | | </div> |
| | | <div> |
| | | <span class="label">客户名称:</span> |
| | | <span class="value">${item.customerName || '张爱有'}</span> |
| | | <span class="value">${item.customerName}</span> |
| | | </div> |
| | | </div> |
| | | <div class="info-row"> |
| | |
| | | margin-left: 10px; |
| | | } |
| | | |
| | | ::v-deep .yellow { |
| | | background-color: #FAF0DE; |
| | | } |
| | | |
| | | ::v-deep .pink { |
| | | background-color: #FAE1DE; |
| | | } |
| | | |
| | | ::v-deep .red { |
| | | background-color: #FAE1DE; |
| | | } |
| | | |
| | | ::v-deep .purple{ |
| | | background-color: #F4DEFA; |
| | | } |
| | | |
| | | .table_list { |
| | | margin-top: unset; |
| | | } |