🐛 修复收票付款与结算费用选择框长文本展示

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-21 11:53:56 +08:00
parent 8d25e186b1
commit 1c798046fd
3 changed files with 227 additions and 90 deletions
+86 -40
View File
@@ -121,7 +121,7 @@
><div class="payment-form-page__percentage-input">
<el-input-number
v-model="form.paymentRatio"
:disabled="readonly || multipleSettlementRows"
:disabled="readonly"
:min="0"
:max="100"
:precision="2"
@@ -134,7 +134,7 @@
><el-form-item label="申请付款金额" prop="appliedAmount"
><el-input-number
v-model="form.appliedAmount"
:disabled="readonly || multipleSettlementRows"
:disabled="readonly"
:min="0"
:precision="2"
:step="0.01"
@@ -1024,8 +1024,12 @@ export default {
},
settlementRows() {
if (this.referenceRows.length > 1) {
// 多结算单:行内比例/金额独立维护,不回落到表头比例(表头与结算信息不关联)
return this.referenceRows.map(item => {
const paymentRatio = item.paymentRatio ?? this.form.paymentRatio;
const paymentRatio =
item.paymentRatio === undefined || item.paymentRatio === null || item.paymentRatio === ''
? 0
: Number(item.paymentRatio);
const appliedAmount = Number(item.appliedAmount || 0);
return {
...item,
@@ -1098,7 +1102,8 @@ export default {
},
'form.paymentRatio'(value) {
this.checkContractPaymentRatio(value);
if (this.amountSyncing || this.multipleSettlementRows || !this.paymentAmountBase) return;
// 上方比例仅用于反算申请付款金额,不联动结算信息列表
if (this.amountSyncing || !this.paymentAmountBase) return;
this.amountSyncing = true;
this.form.appliedAmount = Number(
((this.paymentAmountBase * Number(value || 0)) / 100).toFixed(2)
@@ -1108,7 +1113,8 @@ export default {
});
},
'form.appliedAmount'(value) {
if (this.amountSyncing || this.multipleSettlementRows || !this.paymentAmountBase) return;
// 上方申请付款金额反算比例,不联动结算信息列表
if (this.amountSyncing || !this.paymentAmountBase) return;
this.amountSyncing = true;
this.form.paymentRatio = Number(
((Number(value || 0) / this.paymentAmountBase) * 100).toFixed(2)
@@ -1121,11 +1127,11 @@ export default {
if (
this.amountSyncing ||
this.form.paymentType === 'project_advance' ||
this.multipleSettlementRows ||
!this.paymentAmountBase
) {
return;
}
// 结算金额变化时按上方比例重算申请付款金额,仍不联动结算信息明细
this.amountSyncing = true;
this.form.appliedAmount = Number(
((this.paymentAmountBase * Number(this.form.paymentRatio || 0)) / 100).toFixed(2)
@@ -1547,13 +1553,27 @@ export default {
(total, item) => total + Number(item.payableAmount || 0),
0
);
const appliedAmount = referenceRows.reduce(
const multiple = referenceRows.length > 1;
// 多结算单:表头比例/申请金额独立;单结算单:沿用行金额或按比例计算
const paymentRatio = Number(this.form.paymentRatio || 0);
const rowsAppliedTotal = referenceRows.reduce(
(total, item) => total + Number(item.appliedAmount || 0),
0
);
const paymentRatio = settlementAmount
? Number(((appliedAmount / settlementAmount) * 100).toFixed(2))
: 0;
const headerAppliedAmount = multiple
? Number(((settlementAmount * paymentRatio) / 100).toFixed(2))
: Number(
(
rowsAppliedTotal > 0
? rowsAppliedTotal
: (payableAmount * paymentRatio) / 100
).toFixed(2)
);
const headerPaymentRatio = multiple
? paymentRatio
: settlementAmount
? Number(((headerAppliedAmount / settlementAmount) * 100).toFixed(2))
: paymentRatio;
const settlementIds = rows.map(item => item.settlementId || item.id).filter(Boolean);
this.amountSyncing = true;
this.referenceRows = referenceRows;
@@ -1580,8 +1600,8 @@ export default {
settlementAmount: Number(settlementAmount.toFixed(2)),
payableAmount: Number(payableAmount.toFixed(2)),
billType: '',
paymentRatio,
appliedAmount: Number(appliedAmount.toFixed(2)),
paymentRatio: headerPaymentRatio,
appliedAmount: headerAppliedAmount,
invoices: rows.flatMap(item =>
this.createInvoiceRows(item.invoices || [], item.formalSettlementNo || item.settlementNo)
),
@@ -1838,19 +1858,21 @@ export default {
(total, item) => total + Number(item.payableAmount || 0),
0
);
const appliedAmount = this.referenceRows.reduce(
const multiple = this.referenceRows.length > 1;
const paymentRatio = Number(this.form.paymentRatio || 0);
const rowsAppliedTotal = this.referenceRows.reduce(
(total, item) => total + Number(item.appliedAmount || 0),
0
);
const multiple = this.referenceRows.length > 1;
const paymentRatio = multiple
? settlementAmount
? Number(((appliedAmount / settlementAmount) * 100).toFixed(2))
: 0
: Number(this.form.paymentRatio || 0);
// 多结算单:表头申请金额只由上方比例计算;单结算单仍按可付款金额×比例
const headerAppliedAmount = multiple
? Number(appliedAmount.toFixed(2))
? Number(((settlementAmount * paymentRatio) / 100).toFixed(2))
: Number(((payableAmount * paymentRatio) / 100).toFixed(2));
const headerPaymentRatio = multiple
? paymentRatio
: settlementAmount && rowsAppliedTotal > 0
? Number(((rowsAppliedTotal / settlementAmount) * 100).toFixed(2))
: paymentRatio;
// 尾款付款场景下选择预付结算单时保留尾款付款类型,不强制改为进度预付
this.amountSyncing = true;
Object.assign(this.form, {
@@ -1876,7 +1898,7 @@ export default {
settlementAmount: Number(settlementAmount.toFixed(2)),
payableAmount: Number(payableAmount.toFixed(2)),
billType: '',
paymentRatio,
paymentRatio: headerPaymentRatio,
appliedAmount: headerAppliedAmount,
});
this.rememberSettlementParties(first.payerName, first.payeeName);
@@ -3074,19 +3096,16 @@ export default {
if (settlementAmount <= 0) return 100;
return Number(Math.min(100, (payableAmount / settlementAmount) * 100).toFixed(2));
},
/**
* 多结算单行金额规范化:仅在行内反算比例,不使用表头比例灌入(表头与结算信息不关联)。
*/
seedMultipleRowPayments(rows = []) {
if (rows.length <= 1) return;
const ratio = Number(this.form.paymentRatio || 0);
rows.forEach(item => {
const settlementAmount = Number(item.settlementAmount || 0);
const payableAmount = Number(item.payableAmount || 0);
const hasRatio =
item.paymentRatio !== null && item.paymentRatio !== undefined && item.paymentRatio !== '';
if (hasRatio) return;
let applied = Number(item.appliedAmount || 0);
if (applied <= 0 && ratio > 0) {
applied = Number(((settlementAmount * ratio) / 100).toFixed(2));
}
if (!Number.isFinite(applied) || applied < 0) applied = 0;
if (applied > payableAmount) applied = Number(payableAmount.toFixed(2));
item.appliedAmount = Number(applied.toFixed(2));
item.paymentRatio = settlementAmount
@@ -3102,6 +3121,25 @@ export default {
item.settlementNo === row.settlementNo
);
},
/** 结算信息付款金额合计 */
settlementRowsAppliedTotal(rows = this.referenceRows) {
return (rows || []).reduce((total, item) => total + Number(item.appliedAmount || 0), 0);
},
/** 结算信息合计不得超过上方申请付款金额 */
ensureSettlementAppliedWithinHeader(showWarning = true) {
if (!this.multipleSettlementRows) return true;
const headerApplied = Number(this.form.appliedAmount || 0);
const rowsTotal = Number(this.settlementRowsAppliedTotal().toFixed(2));
if (rowsTotal - headerApplied > 1e-8) {
if (showWarning) {
this.$message.warning(
`结算信息付款金额合计(${rowsTotal.toFixed(2)})不能大于申请付款金额(${headerApplied.toFixed(2)})`
);
}
return false;
}
return true;
},
handleRowPaymentRatioChange(row, value) {
const target = this.findReferenceRow(row);
if (!target) return;
@@ -3114,7 +3152,9 @@ export default {
target.paymentRatio = settlementAmount
? Number(((applied / settlementAmount) * 100).toFixed(2))
: Number(ratio.toFixed(2));
this.syncHeaderPaymentFromRows();
// 仅刷新结算金额/可付款金额合计,不回写表头申请金额与比例
this.syncHeaderSettlementTotalsFromRows();
this.ensureSettlementAppliedWithinHeader(true);
},
handleRowAppliedAmountChange(row, value) {
const target = this.findReferenceRow(row);
@@ -3128,9 +3168,11 @@ export default {
target.paymentRatio = settlementAmount
? Number(((target.appliedAmount / settlementAmount) * 100).toFixed(2))
: 0;
this.syncHeaderPaymentFromRows();
this.syncHeaderSettlementTotalsFromRows();
this.ensureSettlementAppliedWithinHeader(true);
},
syncHeaderPaymentFromRows() {
/** 多结算单时仅同步结算金额/可付款金额合计,申请付款金额与比例由上方独立维护 */
syncHeaderSettlementTotalsFromRows() {
if (this.referenceRows.length <= 1) return;
const settlementAmount = this.referenceRows.reduce(
(total, item) => total + Number(item.settlementAmount || 0),
@@ -3140,22 +3182,18 @@ export default {
(total, item) => total + Number(item.payableAmount || 0),
0
);
const appliedAmount = this.referenceRows.reduce(
(total, item) => total + Number(item.appliedAmount || 0),
0
);
this.amountSyncing = true;
this.form.settlementAmount = Number(settlementAmount.toFixed(2));
this.form.payableAmount = Number(payableAmount.toFixed(2));
this.form.appliedAmount = Number(appliedAmount.toFixed(2));
this.form.paymentRatio = settlementAmount
? Number(((appliedAmount / settlementAmount) * 100).toFixed(2))
: 0;
this.$nextTick(() => {
this.amountSyncing = false;
this.$refs.formRef?.validateField?.(['settlementAmount', 'paymentRatio', 'appliedAmount']);
this.$refs.formRef?.validateField?.(['settlementAmount', 'appliedAmount']);
});
},
/** @deprecated 兼容旧调用名,行为见 syncHeaderSettlementTotalsFromRows */
syncHeaderPaymentFromRows() {
this.syncHeaderSettlementTotalsFromRows();
},
payload() {
// 驳回重提前再清一次:避免历史误存的正式结算单 ID 盖过预结算引用
this.clearFormalReferenceWhenPreOnly();
@@ -3311,6 +3349,14 @@ export default {
ElMessage.warning(`${invalidRow.settlementNo || '结算单'}付款金额不能超过可付款金额`);
return false;
}
const rowsTotal = Number(this.settlementRowsAppliedTotal().toFixed(2));
if (rowsTotal - appliedAmount > 1e-8) {
this.clearMessages();
ElMessage.warning(
`结算信息付款金额合计(${rowsTotal.toFixed(2)})不能大于申请付款金额(${appliedAmount.toFixed(2)})`
);
return false;
}
}
if (this.form.paymentType === 'project_advance' && !this.form.projectId) {
this.clearMessages();