diff --git a/src/api/settlement/formalSettlement.js b/src/api/settlement/formalSettlement.js
index cfb5267..bad7c4c 100644
--- a/src/api/settlement/formalSettlement.js
+++ b/src/api/settlement/formalSettlement.js
@@ -36,3 +36,5 @@ export const adjustDetail = data =>
request({ url: `${baseUrl}/adjust-detail`, method: 'post', data });
export const applyPayment = data =>
request({ url: `${baseUrl}/apply-payment`, method: 'post', data });
+export const applyPayments = data =>
+ request({ url: `${baseUrl}/apply-payments`, method: 'post', data });
diff --git a/src/views/settlement/components/formal-settlement-editor.vue b/src/views/settlement/components/formal-settlement-editor.vue
index 6f861d8..7491a0e 100644
--- a/src/views/settlement/components/formal-settlement-editor.vue
+++ b/src/views/settlement/components/formal-settlement-editor.vue
@@ -4,11 +4,7 @@
v-bind="editorContainerProps"
@update:model-value="visible = $event"
>
-
+
+ {{ formatQuantity(row) }}
@@ -570,7 +571,6 @@
0) appendSummary('其他费用', residualAmount, row.feeType);
+ if (Math.abs(residualAmount) >= 0.005) {
+ appendSummary('其他费用', residualAmount, row.feeType);
+ }
});
const manualFees = this.summaryFees.filter(row => row.manualFlag === 1);
@@ -1479,8 +1476,11 @@ export default {
return `${amount.toFixed(2)} ${currency || 'RMB'}`;
},
formatQuantity(row) {
- if (row.transportQuantity === undefined || row.transportQuantity === null) return '-';
- return `${row.transportQuantity}${row.quantityUnit ? ` ${row.quantityUnit}` : ''}`;
+ const value = row.transportQuantity;
+ if (value === undefined || value === null || value === '') return '-';
+ const quantity = Number(value);
+ if (!Number.isFinite(quantity)) return '-';
+ return `${quantity.toFixed(2)}${row.quantityUnit ? ` ${row.quantityUnit}` : ''}`;
},
displayValue(value) {
return value === undefined || value === null || value === '' ? '-' : value;
diff --git a/src/views/settlement/formal-settlement.vue b/src/views/settlement/formal-settlement.vue
index 60e992e..e9d782b 100644
--- a/src/views/settlement/formal-settlement.vue
+++ b/src/views/settlement/formal-settlement.vue
@@ -48,6 +48,7 @@
>
-
+
+
+ 已选择 {{ paymentDialog.rows.length }} 条同合同应付正式结算单,请确认各单申请金额。
+
+
+
+
+ {{
+ formatMoney(paymentRemaining(row), row.currency)
+ }}
+
+
+
+
+
+
+
+
+
{{
paymentDialog.row.formalSettlementNo || '-'
}}
@@ -180,6 +206,7 @@ export default {
visible: false,
loading: false,
row: {},
+ rows: [],
form: { appliedAmount: 0, remark: '' },
},
};
@@ -193,11 +220,7 @@ export default {
return this.searchExpanded ? this.searchFields : this.searchFields.slice(0, 4);
},
paymentAvailable() {
- return Math.max(
- 0,
- Number(this.paymentDialog.row.settlementAmount || 0) -
- Number(this.paymentDialog.row.appliedPaymentAmount || 0)
- );
+ return this.paymentRemaining(this.paymentDialog.row);
},
},
watch: {
@@ -340,29 +363,52 @@ export default {
this.loadTable();
},
openPaymentDialog() {
- const row = this.selectedOne('付款申请');
- if (!row) return;
- if (row.approvalStatus !== 'approved' || row.settlementType !== 'payable')
+ if (!this.selection.length) return this.$message.warning('请至少选择一条正式结算单');
+ const rows = this.selection;
+ if (rows.some(row => row.approvalStatus !== 'approved' || row.settlementType !== 'payable'))
return this.$message.warning('仅审批通过的应付正式结算单允许发起付款申请');
+ const contractIds = new Set(rows.map(row => String(row.contractId || '')));
+ if (rows.length > 1 && (contractIds.size !== 1 || contractIds.has('')))
+ return this.$message.warning('批量付款申请必须选择同一个合同的正式结算单');
+ const paymentRows = rows.map(row => ({ ...row, appliedAmount: this.paymentRemaining(row) }));
+ if (paymentRows.some(row => row.appliedAmount <= 0))
+ return this.$message.warning('所选正式结算单均须存在剩余可申请金额');
this.paymentDialog = {
visible: true,
loading: false,
- row,
- form: { appliedAmount: 0, remark: '' },
+ row: paymentRows[0],
+ rows: paymentRows,
+ form: {
+ appliedAmount: paymentRows.length === 1 ? paymentRows[0].appliedAmount : 0,
+ remark: '',
+ },
};
},
async submitPayment() {
- if (Number(this.paymentDialog.form.appliedAmount || 0) <= 0)
+ const paymentRows = this.paymentDialog.rows;
+ if (paymentRows.length > 1) {
+ if (paymentRows.some(row => Number(row.appliedAmount || 0) <= 0))
+ return this.$message.warning('请输入各正式结算单的申请付款金额');
+ if (paymentRows.some(row => Number(row.appliedAmount) > this.paymentRemaining(row)))
+ return this.$message.warning('申请付款金额不能超过剩余可申请金额');
+ } else if (Number(this.paymentDialog.form.appliedAmount || 0) <= 0) {
return this.$message.warning('请输入申请付款金额');
+ }
this.paymentDialog.loading = true;
try {
- const response = await api.applyPayment({
- id: this.paymentDialog.row.id,
- ...this.paymentDialog.form,
- });
+ const response =
+ paymentRows.length > 1
+ ? await api.applyPayments({
+ items: paymentRows.map(row => ({ id: row.id, appliedAmount: row.appliedAmount })),
+ remark: this.paymentDialog.form.remark,
+ })
+ : await api.applyPayment({ id: this.paymentDialog.row.id, ...this.paymentDialog.form });
const data = this.unwrapData(response);
- this.$message.success(`付款申请已生成:${data}`);
+ this.$message.success(
+ Array.isArray(data) ? `已生成 ${data.length} 条付款申请` : `付款申请已生成:${data}`
+ );
this.paymentDialog.visible = false;
+ this.selection = [];
this.loadTable();
} finally {
this.paymentDialog.loading = false;
@@ -474,6 +520,12 @@ export default {
formatMoney(value, currency = 'RMB') {
return `${Number(value || 0).toFixed(2)} ${currency || 'RMB'}`;
},
+ paymentRemaining(row) {
+ const remaining =
+ row?.remainingPayableAmount ??
+ Number(row?.settlementAmount || 0) - Number(row?.appliedPaymentAmount || 0);
+ return Math.max(0, Number(remaining || 0));
+ },
},
};
@@ -512,6 +564,10 @@ export default {
.formal-page__table-panel {
margin-top: 8px;
}
+.formal-payment-dialog__batch-tip {
+ margin-bottom: 12px;
+ color: #606266;
+}
.formal-page :deep(.el-table) {
--el-table-border-color: #eff1f7;
}