1、调整导入运单

2、调整对账
This commit is contained in:
2026-09-10 22:50:18 +08:00
parent 38e53e01af
commit 1a9cd55d66
17 changed files with 374 additions and 149 deletions
@@ -565,7 +565,7 @@
/>
</el-form-item>
<el-form-item label="合同类别">
<el-select v-model="contractDialog.query.contractCategory" clearable placeholder="请选择">
<el-select :model-value="contractDialogCategory" disabled placeholder="请选择">
<el-option
v-for="item in contractCategoryOptions"
:key="item.value"
@@ -1027,7 +1027,7 @@ export default {
contractName: '',
projectName: '',
organizationName: '',
contractCategory: '',
contractCategory: '承运商合同',
signType: '',
effectiveType: '',
contractStage: '',
@@ -1161,6 +1161,9 @@ export default {
settlementTypeName() {
return this.form.settlementType === 'receivable' ? '应收' : '应付';
},
contractDialogCategory() {
return '承运商合同';
},
summaryTotal() {
// 与结算合计表格的合计行保持一致:包含手工添加的费用与明细调整后的金额。
if (this.summaryFees.length) {
@@ -1257,8 +1260,8 @@ export default {
deptId: first.deptId,
deptName: first.deptName,
settlementType,
partyA: settlementType === 'receivable' ? first.payeeName : first.payerName,
partyB: settlementType === 'receivable' ? first.payerName : first.payeeName,
partyA: first.payerName,
partyB: first.payeeName,
});
}
this.handleContractChange(contractId);
@@ -1415,7 +1418,10 @@ export default {
const { data } = await getContractList(
this.contractDialog.page.current,
this.contractDialog.page.size,
{ ...this.contractDialog.query }
{
...this.contractDialog.query,
contractCategory: this.contractDialogCategory,
}
);
const page = data?.data || {};
this.contractDialog.rows = page.records || [];
@@ -1434,7 +1440,7 @@ export default {
contractName: '',
projectName: '',
organizationName: '',
contractCategory: '',
contractCategory: this.contractDialogCategory,
signType: '',
effectiveType: '',
contractStage: '',
@@ -1519,13 +1525,8 @@ export default {
this.form.deptId = contract.deptId;
this.form.deptName = contract.deptName;
this.form.settlementType = contract.settlementType || 'payable';
if (this.form.settlementType === 'receivable') {
this.form.payerName = contract.partyB;
this.form.payeeName = contract.partyA;
} else {
this.form.payerName = contract.partyA;
this.form.payeeName = contract.partyB;
}
this.form.payerName = contract.partyA;
this.form.payeeName = contract.partyB;
this.summaryFees = [];
},
async saveDraft(shouldSubmit) {
@@ -205,10 +205,18 @@
<section-card title="导入外部账单">
<template #extra>
<div class="reconciliation-editor__actions" v-if="editable">
<el-button type="primary" plain @click="downloadTemplate('vehicle')"
<el-button
v-if="form.reconciliationMode === 'vehicle'"
type="primary"
plain
@click="downloadTemplate('vehicle')"
>下载整车对账模板</el-button
>
<el-button type="primary" plain @click="downloadTemplate('cargo')"
<el-button
v-if="form.reconciliationMode === 'cargo'"
type="primary"
plain
@click="downloadTemplate('cargo')"
>下载货物明细对账模板</el-button
>
<el-button type="primary" plain @click="chooseImport">导入</el-button>
@@ -374,6 +382,11 @@
formatMoney(row.settlementAmount, row.currency)
}}</template></el-table-column
>
<el-table-column label="审批状态" width="110"
><template #default="{ row }">{{
formalApprovalStatusLabel(row.approvalStatus)
}}</template></el-table-column
>
<el-table-column label="操作" width="100" fixed="right" align="center">
<template #default="{ row }">
<el-link type="primary" @click="selectFormal(row)">选择</el-link>
@@ -1081,6 +1094,19 @@ export default {
getFeeItemAmount(row, name) {
return (row.feeItems || this.parseFeeItems(row.feeItemsJson))[name] ?? 0;
},
formalApprovalStatusLabel(value) {
return (
{
draft: '草稿',
reviewing: '审批中',
approved: '审批通过',
returned: '已驳回',
voided: '已作废',
}[value] ||
value ||
'-'
);
},
async loadFormalOptions() {
this.formalDialog.loading = true;
try {
@@ -1096,20 +1122,8 @@ export default {
params
)
);
let rows = data.records || [];
let total = data.total || 0;
if (!rows.length) {
const fallback = await formalSettlementApi.getList(
this.formalDialog.page.current,
this.formalDialog.page.size,
params
);
const fallbackData = this.unwrapData(fallback);
rows = fallbackData.records || [];
total = fallbackData.total || 0;
}
this.formalDialog.rows = rows;
this.formalDialog.page.total = total;
this.formalDialog.rows = data.records || [];
this.formalDialog.page.total = data.total || 0;
} finally {
this.formalDialog.loading = false;
}
@@ -1120,6 +1134,9 @@ export default {
await this.selectFormal(this.formalDialog.selected[0]);
},
async selectFormal(selected) {
if (selected?.approvalStatus && selected.approvalStatus !== 'draft') {
return this.$message.warning('只能选择草稿状态的正式结算单');
}
const formalSettlementChanged = this.form.formalSettlementId !== selected.id;
this.form = {
...this.form,
@@ -1489,7 +1506,14 @@ export default {
}
},
async downloadTemplate(mode) {
const response = await api.template(mode);
if (!this.form.formalSettlementId) {
return this.$message.warning('请先选择正式结算单');
}
const response = await api.template(mode, {
id: this.currentId,
formalSettlementId: this.form.formalSettlementId,
feeItems: this.internalFeeItemNames.join(','),
});
downloadXls(
response.data,
`${mode === 'cargo' ? '货物明细对账模板' : '整车总额对账模板'}.xlsx`
@@ -145,7 +145,9 @@
:align="column.align || 'center'"
show-overflow-tooltip
>
<template #default="{ row }">{{ formatDetailCell(row, column.prop) }}</template>
<template #default="{ row }">
{{ formatFeeDetailCell(row, column.prop) }}
</template>
</el-table-column>
</el-table>
</el-tab-pane>
@@ -398,12 +400,14 @@
maxlength="300"
placeholder="请输入调整原因"
/>
<span v-else-if="column.prop === 'adjustAmountText'">
{{ fixedTwoDecimals(row.adjustAmount) }}
</span>
<span v-else-if="column.prop === 'afterAmountText'">
{{ fixedTwoDecimals(row.afterAmount) }}
<span v-else-if="column.prop === 'originalAmountText'">
{{
Number(row.adjustAmount || 0) !== 0
? fixedTwoDecimals(row.afterAmount)
: fixedTwoDecimals(row.originalAmount)
}}
</span>
<span v-else>{{ formatDetailCell(row, column.prop) }}</span>
</template>
</el-table-column>
@@ -1135,7 +1139,13 @@ export default {
},
feeDetailColumns() {
const baseColumns = feeDetailBaseColumns.filter(column => column.prop !== 'freightAmount');
return [...baseColumns, ...this.dynamicFeeColumns, ...feeDetailTailColumns];
const hasAdjustment = this.feeRows.some(row => Number(row.adjustAmount || 0) !== 0);
const tailColumns = feeDetailTailColumns.map(col =>
col.prop === 'originalAmountText' && hasAdjustment
? { ...col, label: '调整后金额' }
: col
);
return [...baseColumns, ...this.dynamicFeeColumns, ...tailColumns];
},
displayTableColumns() {
const columns = this.tableColumns.filter(
@@ -1181,7 +1191,7 @@ export default {
adjustFeeColumns() {
const baseColumns = feeDetailBaseColumns.filter(column => column.prop !== 'freightAmount');
const tailColumns = feeDetailTailColumns.filter(column => column.prop !== 'remark');
const afterAmountIndex = tailColumns.findIndex(column => column.prop === 'afterAmountText');
const afterAmountIndex = tailColumns.findIndex(column => column.prop === 'originalAmountText');
tailColumns.splice(afterAmountIndex + 1, 0, {
label: '调整原因',
prop: 'changeReason',
@@ -2596,6 +2606,22 @@ export default {
}
return this.formatCell(row?.[prop]);
},
formatFeeDetailCell(row, prop) {
if (prop !== 'originalAmountText') return this.formatDetailCell(row, prop);
const adjustAmount = Number(row?.adjustAmount || 0);
if (adjustAmount === 0) return this.formatDetailCell(row, prop);
const adjustedAmount = Number(
row?.afterAmount ?? row?.adjustedAmount ?? row?.settlementAmount
);
if (Number.isFinite(adjustedAmount)) return this.fixedTwoDecimals(adjustedAmount);
const originalAmount = Number(row?.originalAmount ?? row?.originalAmountText);
return Number.isFinite(originalAmount)
? this.fixedTwoDecimals(originalAmount + adjustAmount)
: this.formatCell(row?.afterAmountText);
},
formatCell(value) {
return value === null || value === undefined || value === '' ? '-' : value;
},