1、修复基础配置

2、修复业务模块
3、拆分页面代码
This commit is contained in:
2026-09-03 15:59:34 +08:00
parent 40925cb21f
commit 024e77801e
9 changed files with 720 additions and 179 deletions
@@ -438,20 +438,16 @@
class="settlement-detail-page__dialog-form"
>
<el-form-item label="更新范围" prop="contractId">
<el-select
v-model="updateFeeForm.contractId"
clearable
filterable
<el-input
:model-value="updateContractName"
class="settlement-detail-page__generate-select"
readonly
placeholder="请选择合同"
@change="handleUpdateContractChange"
>
<el-option
v-for="item in updateContractOptions"
:key="item.id"
:label="item.contractName"
:value="item.id"
/>
</el-select>
<template #append>
<el-button @click="openUpdateContractDialog">选择</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item label="合同计费方案" prop="billingPlanId">
<el-select
@@ -817,35 +813,112 @@
ref="generateContractTable"
v-loading="generateContractDialog.loading"
:data="generateContractDialog.rows"
style="width: 100%"
border
highlight-current-row
@current-change="generateContractDialog.current = $event"
@row-dblclick="selectGenerateContract"
@row-dblclick="selectContract"
>
<el-table-column type="index" label="序号" width="64" align="center" />
<el-table-column
v-for="column in contractSelectionColumns"
:key="column.prop"
:prop="column.prop"
:label="column.label"
:min-width="column.minWidth"
prop="contractNo"
label="合同编号"
min-width="180"
align="center"
show-overflow-tooltip
>
<template #default="{ row }">
<span v-if="column.prop === 'organizationName'">{{
row.organizationName || row.deptName || '-'
}}</span>
<span v-else-if="column.prop === 'contractCategory'">{{
contractCategoryName(row.contractCategory)
}}</span>
<span v-else-if="column.prop === 'signType'">{{ signTypeName(row.signType) }}</span>
<span v-else>{{ displayValue(row[column.prop]) }}</span>
</template>
</el-table-column>
:formatter="formatContractSelectionCell"
/>
<el-table-column
prop="contractName"
label="合同名称"
min-width="220"
align="center"
show-overflow-tooltip
:formatter="formatContractSelectionCell"
/>
<el-table-column
prop="projectName"
label="所属项目"
min-width="170"
align="center"
show-overflow-tooltip
:formatter="formatContractSelectionCell"
/>
<el-table-column
prop="organizationName"
label="所属组织"
min-width="170"
align="center"
show-overflow-tooltip
:formatter="formatContractSelectionCell"
/>
<el-table-column
prop="contractCategory"
label="合同类别"
min-width="130"
align="center"
show-overflow-tooltip
:formatter="formatContractSelectionCell"
/>
<el-table-column
prop="signType"
label="签约类型"
min-width="120"
align="center"
show-overflow-tooltip
:formatter="formatContractSelectionCell"
/>
<el-table-column
prop="partyA"
label="甲方"
min-width="170"
align="center"
show-overflow-tooltip
:formatter="formatContractSelectionCell"
/>
<el-table-column
prop="partyB"
label="乙方"
min-width="170"
align="center"
show-overflow-tooltip
:formatter="formatContractSelectionCell"
/>
<el-table-column
prop="startDate"
label="开始日期"
min-width="130"
align="center"
show-overflow-tooltip
:formatter="formatContractSelectionCell"
/>
<el-table-column
prop="endDate"
label="结束日期"
min-width="130"
align="center"
show-overflow-tooltip
:formatter="formatContractSelectionCell"
/>
<el-table-column
prop="temporaryStartDate"
label="临时效力起"
min-width="130"
align="center"
show-overflow-tooltip
:formatter="formatContractSelectionCell"
/>
<el-table-column
prop="temporaryEndDate"
label="临时效力止"
min-width="130"
align="center"
show-overflow-tooltip
:formatter="formatContractSelectionCell"
/>
<el-table-column label="操作" width="90" fixed="right" align="center">
<template #default="{ row }">
<el-link type="primary" @click.stop="selectGenerateContract(row)">选择</el-link>
<el-link type="primary" @click.stop="selectContract(row)">选择</el-link>
</template>
</el-table-column>
</el-table>
@@ -862,7 +935,7 @@
</div>
<template #footer>
<el-button @click="generateContractDialog.visible = false">取消</el-button>
<el-button type="primary" @click="selectGenerateContract(generateContractDialog.current)">
<el-button type="primary" @click="selectContract(generateContractDialog.current)">
确定
</el-button>
</template>
@@ -900,21 +973,6 @@ import {
signTypeOptions,
} from '@/option/business/common';
const contractSelectionColumns = [
{ prop: 'contractNo', label: '合同编号', minWidth: 180 },
{ prop: 'contractName', label: '合同名称', minWidth: 220 },
{ prop: 'projectName', label: '所属项目', minWidth: 170 },
{ prop: 'organizationName', label: '所属组织', minWidth: 170 },
{ prop: 'contractCategory', label: '合同类别', minWidth: 130 },
{ prop: 'signType', label: '签约类型', minWidth: 120 },
{ prop: 'partyA', label: '甲方', minWidth: 170 },
{ prop: 'partyB', label: '乙方', minWidth: 170 },
{ prop: 'startDate', label: '开始日期', minWidth: 130 },
{ prop: 'endDate', label: '结束日期', minWidth: 130 },
{ prop: 'temporaryStartDate', label: '临时效力起', minWidth: 130 },
{ prop: 'temporaryEndDate', label: '临时效力止', minWidth: 130 },
];
const ADJUST_BILLING_ELEMENTS = [
'按重量',
'按体积',
@@ -1008,7 +1066,6 @@ export default {
effectiveTypeOptions,
contractStageOptions,
contractApprovalStatusOptions,
contractSelectionColumns,
transportTypeOptions: [],
billingPlanOptions: [],
transferDialog: { visible: false, loading: false, submitting: false },
@@ -1019,6 +1076,7 @@ export default {
transferPage: { current: 1, size: 10, total: 0 },
generateDialog: { visible: false, loading: false },
generateQuery: {},
contractDialogMode: 'generate',
generateContractDialog: {
visible: false,
loading: false,
@@ -1053,24 +1111,16 @@ export default {
);
return contract?.contractName || '';
},
updateContractName() {
const contractId = this.updateFeeForm.contractId;
const contract = [...this.updateContractOptions, ...this.contractOptions].find(
item => String(item.id) === String(contractId)
);
return contract?.contractName || '';
},
generateContractCategory() {
return this.settlementType === 'payable' ? '承运商合同' : '客户合同';
},
contractCategoryName(value) {
return (
this.contractCategoryOptions.find(item => String(item.value) === String(value))?.label ||
this.formatCell(value)
);
},
signTypeName(value) {
return (
this.signTypeOptions.find(item => String(item.value) === String(value))?.label ||
this.formatCell(value)
);
},
displayValue(value) {
return this.formatCell(value);
},
settlementTypeLabel() {
if (this.settlementType === 'receivable') return '应收';
if (this.settlementType === 'payable') return '应付';
@@ -1158,6 +1208,21 @@ export default {
this.clearAdjustCalculations();
},
methods: {
contractCategoryName(value) {
return (
this.contractCategoryOptions.find(item => String(item.value) === String(value))?.label ||
this.formatCell(value)
);
},
signTypeName(value) {
return (
this.signTypeOptions.find(item => String(item.value) === String(value))?.label ||
this.formatCell(value)
);
},
displayValue(value) {
return this.formatCell(value);
},
async loadTransportTypeOptions() {
const res = await getDictionary({ code: 'transport_type' });
const records = res.data?.data || [];
@@ -1435,6 +1500,26 @@ export default {
}
},
openGenerateContractDialog() {
this.contractDialogMode = 'generate';
this.generateContractDialog.visible = true;
this.generateContractDialog.expanded = false;
this.generateContractDialog.current = null;
this.generateContractDialog.page.current = 1;
this.loadGenerateContracts();
},
openUpdateContractDialog() {
this.contractDialogMode = 'update';
this.generateContractDialog.query = {
contractNo: '',
contractName: '',
projectName: '',
organizationName: '',
contractCategory: '',
signType: '',
effectiveType: '',
contractStage: '',
approvalStatus: '',
};
this.generateContractDialog.visible = true;
this.generateContractDialog.expanded = false;
this.generateContractDialog.current = null;
@@ -1456,16 +1541,30 @@ export default {
const data = this.unwrapPage(res);
this.generateContractDialog.rows = data.records || [];
this.generateContractDialog.page.total = Number(data.total || 0);
this.layoutGenerateContractTable();
} finally {
this.generateContractDialog.loading = false;
this.layoutGenerateContractTable();
}
},
layoutGenerateContractTable() {
this.$nextTick(() => {
this.$refs.generateContractTable?.doLayout?.();
window.requestAnimationFrame(() => {
this.$refs.generateContractTable?.doLayout?.();
});
});
},
formatContractSelectionCell(row, column, cellValue) {
if (column.property === 'organizationName') {
return this.displayValue(row.organizationName || row.deptName);
}
if (column.property === 'contractCategory') {
return this.contractCategoryName(row.contractCategory);
}
if (column.property === 'signType') {
return this.signTypeName(row.signType);
}
return this.displayValue(cellValue);
},
searchGenerateContracts() {
this.generateContractDialog.page.current = 1;
this.loadGenerateContracts();
@@ -1488,7 +1587,7 @@ export default {
this.generateContractDialog.page.current = 1;
this.loadGenerateContracts();
},
selectGenerateContract(row) {
selectContract(row) {
if (!row) {
this.$message.warning('请选择合同');
return;
@@ -1500,11 +1599,18 @@ export default {
partyA: row.partyA || row.payerName,
partyB: row.partyB || row.payeeName,
};
const index = this.contractOptions.findIndex(item => String(item.id) === String(contract.id));
if (index >= 0) this.contractOptions.splice(index, 1, contract);
else this.contractOptions.push(contract);
this.generateQuery.contractId = contract.id;
this.handleGenerateContractChange(contract.id);
const targetOptions =
this.contractDialogMode === 'update' ? this.updateContractOptions : this.contractOptions;
const index = targetOptions.findIndex(item => String(item.id) === String(contract.id));
if (index >= 0) targetOptions.splice(index, 1, contract);
else targetOptions.push(contract);
if (this.contractDialogMode === 'update') {
this.updateFeeForm.contractId = contract.id;
this.handleUpdateContractChange(contract.id);
} else {
this.generateQuery.contractId = contract.id;
this.handleGenerateContractChange(contract.id);
}
this.generateContractDialog.visible = false;
this.generateContractDialog.current = null;
},
@@ -1918,22 +2024,30 @@ export default {
this.changePage.current = 1;
this.loadChangeRecords();
},
async openUpdateFeeDialog(row) {
await this.loadUpdateFeeContracts();
openUpdateFeeDialog(row) {
this.updateFeeDialog = { ...this.updateFeeDialog, visible: true, row: row || null };
this.updateFeeForm = {
settlementType: this.settlementType || undefined,
contractId: row?.contractId || '',
billingPlanId: '',
};
if (row?.contractId) {
const contract = {
...row,
id: row.contractId,
deptId: row.deptId || row.organizationId,
deptName: row.deptName || row.organizationName,
partyA: row.partyA || row.payerName,
partyB: row.partyB || row.payeeName,
};
const index = this.updateContractOptions.findIndex(
item => String(item.id) === String(contract.id)
);
if (index >= 0) this.updateContractOptions.splice(index, 1, contract);
else this.updateContractOptions.push(contract);
}
this.handleUpdateContractChange(this.updateFeeForm.contractId);
},
async loadUpdateFeeContracts() {
const res = await api.getUpdateFeeContracts({
settlementType: this.settlementType || undefined,
});
this.updateContractOptions = res.data?.data || [];
},
handleUpdateContractChange(contractId) {
this.updateFeeForm.billingPlanId = '';
if (!contractId) {
@@ -2392,7 +2506,7 @@ export default {
const currency = row.currency || 'RMB';
return {
...row,
unitPriceText: this.money(row.unitPrice, currency),
unitPriceText: this.hasMultipleCargo(row) ? '-' : this.money(row.unitPrice, currency),
freightAmountText: this.money(row.freightAmount, currency),
otherFeeAmountText: this.money(row.otherFeeAmount, currency),
totalAmountText: this.money(row.totalAmount, currency),
@@ -2402,6 +2516,67 @@ export default {
'-',
};
},
parseCargoRows(value) {
if (value === null || value === undefined || value === '') return [];
if (Array.isArray(value)) return value;
if (typeof value === 'object') return [value];
try {
const parsed = JSON.parse(value);
if (Array.isArray(parsed)) return parsed;
return parsed && typeof parsed === 'object' ? [parsed] : [];
} catch (error) {
return [];
}
},
hasMultipleCargo(row = {}) {
const countFields = [
'cargoCount',
'goodsCount',
'cargoNum',
'goodsNum',
'cargoNumber',
'goodsNumber',
'cargoSize',
'goodsSize',
'cargoItemCount',
'goodsItemCount',
];
if (
countFields.some(field => {
const count = Number(row[field]);
return Number.isFinite(count) && count > 1;
})
) {
return true;
}
const cargoSources = [
row.goodsJson,
row.goodsList,
row.goodsRows,
row.cargoList,
row.cargoRows,
row.goods,
row.cargoDetails,
row.cargoItems,
row.cargoNames,
row.goodsNames,
];
if (cargoSources.some(source => this.parseCargoRows(source).length > 1)) {
return true;
}
const summaryValues = [row.cargoName, row.cargoInfo, row.goodsInfo];
if (summaryValues.some(value => Array.isArray(value) && value.length > 1)) return true;
const summaryText = summaryValues
.filter(value => value !== null && value !== undefined)
.map(value => String(value))
.join('');
return (
/等\s*\d+\s*[种个]\s*货物/.test(summaryText) ||
summaryText.split(/[、,,;]/).filter(Boolean).length > 1
);
},
collectFeeItemNames(rows) {
const names = [];
(rows || []).forEach(row => {