diff --git a/src/option/payment/invoiceApplication.js b/src/option/payment/invoiceApplication.js index fa5ed87..3696382 100644 --- a/src/option/payment/invoiceApplication.js +++ b/src/option/payment/invoiceApplication.js @@ -6,6 +6,7 @@ export const invoiceApplicationTableColumns = [ { prop: 'issuerName', label: '开票方', minWidth: 150 }, { prop: 'receiverName', label: '受票方', minWidth: 150 }, { prop: 'invoiceAmount', label: '开票金额', minWidth: 130, money: true }, + { prop: 'estimatedCost', label: '暂估成本', minWidth: 130, money: true }, { prop: 'createUserName', label: '创建人', minWidth: 110 }, { prop: 'createTime', label: '创建时间', minWidth: 170 }, { prop: 'approvalStatusName', label: '状态', minWidth: 110, status: true }, diff --git a/src/views/payment/invoice-application-form.vue b/src/views/payment/invoice-application-form.vue index b4897ea..83b8138 100644 --- a/src/views/payment/invoice-application-form.vue +++ b/src/views/payment/invoice-application-form.vue @@ -86,6 +86,27 @@ /> + + + + + + + + + + + + + + + + + + + + + - - - @@ -385,6 +412,10 @@ + + + + @@ -491,6 +522,7 @@ import { getList as getReceivablePayableDetailList } from '@/api/settlement/rece import { getDictionary } from '@/api/system/dictbiz'; import { invoiceApplicationDetailColumns } from '@/option/payment/invoiceApplication'; import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue'; +import InvoiceWriteOffTable from '@/components/invoice-write-off-table/main.vue'; import { getMkPublicDetail } from '@/api/mk-process'; import { loadMkEnabled, submitMkApprovalFlow } from '@/utils/mk-approval'; @@ -538,12 +570,15 @@ const emptyForm = () => ({ sheets: [emptySheet()], attachments: [], remark: '', + // 项目利润率(小数,如0.04表示4%;保存时后端快照并重算暂估成本) + profitRate: null, }); export default { name: 'InvoiceApplicationForm', components: { VehicleAttachmentTable, + InvoiceWriteOffTable, }, data() { return { @@ -621,6 +656,24 @@ export default { 0 ); }, + // 项目利润率百分数展示/输入(后端存小数:0.04 ↔ 4) + profitRatePercent() { + const rate = Number(this.form.profitRate); + if (!Number.isFinite(rate) || rate <= 0) return ''; + return String(Math.round(rate * 10000) / 100); + }, + // 暂估成本 = 开票不含税金额合计 × 项目利润率(实时计算,后端保存时重算覆盖) + estimatedCost() { + const rate = Number(this.form.profitRate); + if (!Number.isFinite(rate) || rate <= 0) return 0; + const amountNoTaxTotal = this.form.sheets.reduce( + (sheetTotal, sheet) => + sheetTotal + + sheet.lines.reduce((lineTotal, line) => lineTotal + Number(line.amountNoTax || 0), 0), + 0 + ); + return amountNoTaxTotal * rate; + }, detailColumns() { return [...this.detailBaseColumns, ...this.feeItemColumns]; }, @@ -732,6 +785,13 @@ export default { this.transportTypeOptions.find(item => String(item.value) === String(value))?.label || value ); }, + // 项目利润率输入(百分数),转小数存储:4 → 0.04 + handleProfitRateInput(value) { + let normalized = String(value || '').replace(/[^\d.]/g, ''); + normalized = normalized.replace(/(\..*)\./g, '$1'); + const percent = Number(normalized); + this.form.profitRate = Number.isFinite(percent) && percent > 0 ? percent / 100 : null; + }, invoiceItemNames(categoryName) { return this.invoiceItems.filter(item => item.categoryName === categoryName); }, @@ -1173,6 +1233,7 @@ export default { contactName: this.form.contactName, contactPhone: this.form.contactPhone, email: this.form.email, + profitRate: Number(this.form.profitRate) > 0 ? Number(this.form.profitRate) : null, attachmentsJson: JSON.stringify(this.form.attachments || []), remark: this.form.remark, settlements: this.form.settlements.map(item => ({