From 0764bf3a422b703ec7a9b53815ee30c49b13aac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com> Date: Mon, 9 Nov 2026 18:18:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=BC=80=E7=A5=A8=E7=94=B3=E8=AF=B7?= =?UTF-8?q?=E6=8E=A5=E5=85=A5=E6=9A=82=E4=BC=B0=E6=88=90=E6=9C=AC=E4=B8=8E?= =?UTF-8?q?=E5=86=B2=E9=94=80=E6=98=8E=E7=BB=86=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/option/payment/invoiceApplication.js | 1 + .../payment/invoice-application-form.vue | 67 ++++++++++++++++++- 2 files changed, 65 insertions(+), 3 deletions(-) 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 => ({