调整结算模块

This commit is contained in:
2026-09-07 19:37:27 +08:00
parent 0d070d4b34
commit a7315b4491
21 changed files with 1876 additions and 635 deletions
+101 -158
View File
@@ -476,7 +476,7 @@
<span>{{ row.reviewStatus }}</span>
</template>
</el-table-column>
<el-table-column label="操作" min-width="135" align="center">
<el-table-column label="操作" width="135" fixed="right" align="center">
<template #default="{ row }">
<el-link type="primary" @click="openScore(row.__raw, row.__rawIndex)">
详情
@@ -513,7 +513,13 @@
<span>{{ row.branchName || archiveForm.deptName || '-' }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="130" align="center" v-if="!readonly">
<el-table-column
label="操作"
width="130"
fixed="right"
align="center"
v-if="!readonly"
>
<template #default="{ row }">
<el-link type="primary" @click="openContact(row.__raw, row.__rawIndex)">
修改
@@ -542,7 +548,13 @@
<el-table-column label="收款账号" prop="bankAccount" min-width="180" />
<el-table-column label="开户行" prop="bankName" min-width="180" />
<el-table-column label="备注" prop="remark" min-width="180" />
<el-table-column label="操作" width="130" align="center" v-if="!readonly">
<el-table-column
label="操作"
width="130"
fixed="right"
align="center"
v-if="!readonly"
>
<template #default="{ row }">
<el-link type="primary" @click="openReceipt(row.__raw, row.__rawIndex)">
修改
@@ -578,7 +590,13 @@
</template>
</el-table-column>
<el-table-column label="邮箱" prop="email" min-width="180" />
<el-table-column label="操作" width="130" align="center" v-if="!readonly">
<el-table-column
label="操作"
width="130"
fixed="right"
align="center"
v-if="!readonly"
>
<template #default="{ row }">
<el-link type="primary" @click="openInvoice(row.__raw, row.__rawIndex)">
修改
@@ -1004,13 +1022,15 @@
<el-input v-model="invoiceForm.registeredPhone" maxlength="20" />
</el-form-item>
<el-form-item label="注册地址" prop="registeredRegionName">
<el-input
v-model="invoiceForm.registeredRegionName"
readonly
maxlength="100"
placeholder="点击后弹出地图组件"
suffix-icon="el-icon-location"
@click="handleInvoiceRegisteredMapPick"
<el-cascader
ref="invoiceRegisteredRegionCascader"
v-model="invoiceForm.registeredRegionPath"
:options="regionOptions"
:props="regionCascaderProps"
:placeholder="invoiceForm.registeredRegionName || '请选择省市区'"
clearable
filterable
@change="handleInvoiceRegisteredRegionChange"
/>
</el-form-item>
<el-form-item label="详细地址" prop="registeredDetailAddress">
@@ -1023,11 +1043,9 @@
<el-input
ref="invoiceDetailInput"
v-model="invoiceForm.registeredDetailAddress"
readonly
maxlength="255"
placeholder="点击后弹出地图组件"
suffix-icon="el-icon-location"
@click="handleInvoiceRegisteredMapPick"
placeholder="请输入详细地址"
@input="checkOverflow('invoiceDetailInput', 'invoiceDetailOverflow')"
/>
</el-tooltip>
</el-form-item>
@@ -1058,26 +1076,21 @@
<el-form-item label="收件人姓名" prop="receiverName">
<el-input v-model="invoiceForm.receiverName" maxlength="30" />
</el-form-item>
<el-form-item label="收件人地址" prop="receiverRegionName">
<div class="invoice-form__address">
<el-form-item label="收件人地址" prop="receiverAddress">
<el-tooltip
:content="invoiceForm.receiverAddress"
placement="top"
:disabled="!invoiceReceiverOverflow"
style="display: block; width: 100%"
>
<el-input
v-model="invoiceForm.receiverRegionName"
readonly
maxlength="100"
placeholder="点击后弹出地图组件"
@click="handleInvoiceReceiverMapPick"
/>
<el-input
v-model="invoiceForm.receiverDetailAddress"
ref="invoiceReceiverInput"
v-model="invoiceForm.receiverAddress"
maxlength="255"
placeholder="请输入详细地址"
><template #suffix
><el-icon
class="invoice-form__address-location"
@click="handleInvoiceReceiverMapPick"
><Location /></el-icon></template
></el-input>
</div>
placeholder="请输入收件人地址"
@input="checkOverflow('invoiceReceiverInput', 'invoiceReceiverOverflow')"
/>
</el-tooltip>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -1415,7 +1428,7 @@ import { downloadFileByUrl, downloadXls } from '@/utils/util';
import { getToken } from '@/utils/auth';
import { getUploadHeaders } from '@/utils/upload';
import { normalizeSearchRangeParams } from '@/utils/search-range';
import { ArrowRight, Location } from '@element-plus/icons-vue';
import { ArrowRight } from '@element-plus/icons-vue';
import { ElImageViewer, ElLoading } from 'element-plus';
import { OpenFileViewer } from '@open-file-viewer/vue';
import { fallbackPlugin, imagePlugin, officePlugin, textPlugin } from '@open-file-viewer/core';
@@ -1445,7 +1458,6 @@ export default {
components: {
SectionCard,
ArrowRight,
Location,
ElImageViewer,
OpenFileViewer,
PdfPreview,
@@ -1588,6 +1600,7 @@ export default {
invoiceForm: this.emptyInvoice(),
registeredDetailOverflow: false,
invoiceDetailOverflow: false,
invoiceReceiverOverflow: false,
qualificationFiles: [],
qualificationUploadFiles: [],
ocrQualificationUploadFiles: [],
@@ -1690,15 +1703,13 @@ export default {
invoiceType: [{ required: true, message: '请选择发票类型', trigger: 'change' }],
registeredPhone: [{ required: true, message: '请输入注册电话', trigger: 'blur' }],
bankName: [{ required: true, message: '请输入开户行名称', trigger: 'blur' }],
registeredRegionName: [{ required: true, message: '请选择注册地址', trigger: 'blur' }],
registeredRegionName: [{ required: true, message: '请选择注册地址', trigger: 'change' }],
registeredDetailAddress: [
{ required: true, message: '请输入详细地址', trigger: 'blur' },
{ max: 255, message: '详细地址最多255个字符', trigger: 'blur' },
],
bankAccount: [{ required: true, message: '请输入银行账号', trigger: 'blur' }],
receiverDetailAddress: [
{ max: 255, message: '收件人详细地址最多255个字符', trigger: 'blur' },
],
receiverAddress: [{ max: 255, message: '收件人地址最多255个字符', trigger: 'blur' }],
email: [{ type: 'email', message: '请输入正确的邮箱', trigger: 'blur' }],
},
option: {
@@ -2028,6 +2039,9 @@ export default {
'invoiceForm.registeredDetailAddress'() {
this.$nextTick(() => this.checkOverflow('invoiceDetailInput', 'invoiceDetailOverflow'));
},
'invoiceForm.receiverAddress'() {
this.$nextTick(() => this.checkOverflow('invoiceReceiverInput', 'invoiceReceiverOverflow'));
},
},
methods: {
hasPermission(code) {
@@ -2472,14 +2486,13 @@ export default {
bankName: '',
registeredPhone: '',
bankAccount: '',
registeredRegionPath: [],
registeredRegionName: '',
registeredDetailAddress: '',
registeredAddress: '',
email: '',
receiverName: '',
receiverPhone: '',
receiverRegionName: '',
receiverDetailAddress: '',
receiverAddress: '',
isDefault: 0,
};
@@ -2568,8 +2581,8 @@ export default {
}
return null;
},
getRegisteredRegionLabels(value) {
const nodes = this.$refs.registeredRegionCascader?.getCheckedNodes?.() || [];
getRegisteredRegionLabels(value, refName = 'registeredRegionCascader') {
const nodes = this.$refs[refName]?.getCheckedNodes?.() || [];
if (nodes.length && nodes[0].pathLabels?.length) {
return nodes[0].pathLabels;
}
@@ -2588,6 +2601,20 @@ export default {
this.$refs.archiveForm?.validateField('registeredDetailAddress');
});
},
handleInvoiceRegisteredRegionChange(value) {
if (!value || !value.length) {
this.invoiceForm.registeredRegionName = '';
this.$refs.invoiceForm?.validateField('registeredRegionName');
return;
}
this.$nextTick(() => {
this.invoiceForm.registeredRegionName = this.getRegisteredRegionLabels(
value,
'invoiceRegisteredRegionCascader'
).join('');
this.$refs.invoiceForm?.validateField('registeredRegionName');
});
},
initBusinessDictionaries() {
this.loadDictOptions('nature_of_client', 'customerNatureOptions', [], options => {
const customerNatureColumn = this.findColumn(this.option.column, 'customerNature');
@@ -2815,21 +2842,22 @@ export default {
.join('')
);
},
// 省市区 + 详细地址为当前录入口径,registeredAddress 仅作为历史数据兜底
formatInvoiceRegisteredAddress(row = {}) {
return (
row.registeredAddress ||
[row.registeredRegionName, row.registeredDetailAddress]
.map(item => String(item || '').trim())
.filter(Boolean)
.join('')
);
},
formatInvoiceReceiverAddress(row = {}) {
const address = [row.receiverRegionName, row.receiverDetailAddress]
const address = [row.registeredRegionName, row.registeredDetailAddress]
.map(item => String(item || '').trim())
.filter(Boolean)
.join('');
return address || row.registeredAddress || '';
},
formatInvoiceReceiverAddress(row = {}) {
const address = String(row.receiverAddress || '').trim();
if (address) return address;
// 历史数据中收件人地址拆分为行政区划 + 详细地址两个字段
return [row.receiverRegionName, row.receiverDetailAddress]
.map(item => String(item || '').trim())
.filter(Boolean)
.join('');
return address || row.receiverAddress || '';
},
normalizeContact(contact = {}) {
const contactAddress =
@@ -2899,28 +2927,6 @@ export default {
: '可搜索地址或点击地图选点';
this.contactMapBox = true;
},
handleInvoiceRegisteredMapPick() {
this.contactMapTarget = 'invoiceRegistered';
this.contactMapKeyword =
this.invoiceForm.registeredDetailAddress || this.invoiceForm.registeredRegionName || '';
this.contactMapSelected = this.buildContactMapSelection({
address: this.invoiceForm.registeredDetailAddress,
regionName: this.invoiceForm.registeredRegionName,
});
this.contactMapStatus = '可搜索地址或点击地图选点';
this.contactMapBox = true;
},
handleInvoiceReceiverMapPick() {
this.contactMapTarget = 'invoiceReceiver';
this.contactMapKeyword =
this.invoiceForm.receiverDetailAddress || this.invoiceForm.receiverRegionName || '';
this.contactMapSelected = this.buildContactMapSelection({
address: this.invoiceForm.receiverDetailAddress,
regionName: this.invoiceForm.receiverRegionName,
});
this.contactMapStatus = '可搜索地址或点击地图选点';
this.contactMapBox = true;
},
loadAmap() {
if (window.AMap && window.AMap.Map) {
return Promise.resolve();
@@ -3062,29 +3068,6 @@ export default {
this.$message.warning('请先搜索或点击地图完成选点');
return;
}
if (this.contactMapTarget === 'invoiceRegistered') {
this.invoiceForm.registeredRegionName =
this.contactMapSelected.regionName || this.invoiceForm.registeredRegionName;
this.invoiceForm.registeredDetailAddress = this.formatMapDetailAddress(
this.contactMapSelected.detailAddress || this.invoiceForm.registeredDetailAddress,
this.invoiceForm.registeredRegionName
);
this.$refs.invoiceForm?.validateField('registeredRegionName');
this.contactMapBox = false;
return;
}
if (this.contactMapTarget === 'invoiceReceiver') {
this.invoiceForm.receiverRegionName =
this.contactMapSelected.regionName || this.invoiceForm.receiverRegionName;
this.invoiceForm.receiverDetailAddress = this.formatMapDetailAddress(
this.contactMapSelected.detailAddress || this.invoiceForm.receiverDetailAddress,
this.invoiceForm.receiverRegionName
);
this.invoiceForm.receiverAddress = this.formatInvoiceReceiverAddress(this.invoiceForm);
this.$refs.invoiceForm?.validateField('receiverRegionName');
this.contactMapBox = false;
return;
}
this.contactForm.detailAddress =
this.contactMapSelected.detailAddress || this.contactForm.detailAddress;
this.contactForm.regionName =
@@ -3096,14 +3079,6 @@ export default {
this.$refs.contactForm?.validateField('detailAddress');
this.contactMapBox = false;
},
formatMapDetailAddress(address, regionName) {
const rawAddress = String(address || '').trim();
const rawRegionName = String(regionName || '').trim();
if (!rawAddress || !rawRegionName) return rawAddress;
return rawAddress.startsWith(rawRegionName)
? rawAddress.slice(rawRegionName.length).trim()
: rawAddress;
},
buildContactMapSelection({ lng, lat, address, regionName, regionCode }) {
const longitude = this.formatCoordinate(lng);
const latitude = this.formatCoordinate(lat);
@@ -3241,26 +3216,27 @@ export default {
.catch(() => {});
},
normalizeInvoice(invoice = {}) {
// receiverRegionName / receiverDetailAddress 为历史拆分字段,现已合并为单一的收件人地址
const { receiverRegionName, receiverDetailAddress, ...rest } = invoice;
const registeredDetailAddress =
invoice.registeredDetailAddress ||
(invoice.registeredRegionName ? '' : invoice.registeredAddress) ||
'';
const receiverDetailAddress =
invoice.receiverDetailAddress ||
(invoice.receiverRegionName ? '' : invoice.receiverAddress) ||
'';
return {
...this.emptyInvoice(),
...invoice,
...rest,
registeredRegionPath: Array.isArray(invoice.registeredRegionPath)
? invoice.registeredRegionPath
: [],
registeredDetailAddress,
registeredAddress: this.formatInvoiceRegisteredAddress({
...invoice,
registeredDetailAddress,
}),
receiverDetailAddress,
receiverAddress: this.formatInvoiceReceiverAddress({
...invoice,
receiverRegionName,
receiverDetailAddress,
receiverAddress: invoice.receiverAddress,
}),
};
},
@@ -3269,7 +3245,10 @@ export default {
this.invoiceForm = row ? this.normalizeInvoice(row) : this.emptyInvoice();
this.invoiceBox = true;
this.$nextTick(() => {
this.$nextTick(() => this.checkOverflow('invoiceDetailInput', 'invoiceDetailOverflow'));
this.$nextTick(() => {
this.checkOverflow('invoiceDetailInput', 'invoiceDetailOverflow');
this.checkOverflow('invoiceReceiverInput', 'invoiceReceiverOverflow');
});
});
},
resetInvoice() {
@@ -3280,11 +3259,7 @@ export default {
saveInvoice() {
this.$refs.invoiceForm.validate(valid => {
if (!valid) return;
const invoice = this.normalizeInvoice({
...this.invoiceForm,
registeredAddress: this.formatInvoiceRegisteredAddress(this.invoiceForm),
receiverAddress: this.formatInvoiceReceiverAddress(this.invoiceForm),
});
const invoice = this.normalizeInvoice(this.invoiceForm);
if (this.invoiceIndex > -1) {
this.archiveForm.invoices.splice(this.invoiceIndex, 1, invoice);
} else {
@@ -3626,15 +3601,6 @@ export default {
)
);
},
validateQualificationMaterials(
files = this.qualificationFiles,
customerType = this.archiveForm.customerType
) {
const missing = this.getMissingQualificationTypes(files, customerType);
if (!missing.length) return true;
this.$message.warning(`请先上传客商材料:${missing.join('、')}`);
return false;
},
downloadAttachments() {
const source = this.selectedQualificationFiles.length
? this.selectedQualificationFiles
@@ -3851,15 +3817,8 @@ export default {
this.invoiceForm = this.emptyInvoice();
this.$refs.archiveForm?.clearValidate();
},
// 客商材料不做提交校验,仅在页面上提示未上传项
validateFormalForApproval(archive) {
if (
!this.validateQualificationMaterials(
this.parseAttachments(archive.qualificationAttachments),
archive.customerType
)
) {
return false;
}
if (archive.accessType !== 'formal') return true;
const hasCompletedScore = (archive.scores || []).some(
item => item.selfStatus === '已完成' || item.reviewStatus === '已完成' || item.finalScore
@@ -3911,7 +3870,11 @@ export default {
.map(item => this.normalizeReceipt(item))
.filter(item => item.accountName || item.accountHolderName || item.bankAccount);
archive.invoices = (archive.invoices || [])
.map(item => this.normalizeInvoice(item))
.map(item => {
const invoice = this.normalizeInvoice(item);
delete invoice.registeredRegionPath;
return invoice;
})
.filter(item => item.invoiceTitle || item.taxNo || item.bankAccount);
archive.scores = (archive.scores || []).map(score => {
const calculatedScore = this.calculateScore(score);
@@ -5129,26 +5092,6 @@ export default {
font-size: 13px;
}
.invoice-form__address {
display: flex;
gap: 10px;
width: 100%;
.el-input {
flex: 1;
min-width: 0;
}
.el-input:first-child {
flex: 0 0 38%;
}
}
.invoice-form__address-location {
cursor: pointer;
color: #909399;
}
.score-detail-table {
width: 100%;
margin-top: 12px;