✨ 客商档案新增金蝶客商查询回填与同步金蝶重推入口
This commit is contained in:
@@ -113,6 +113,26 @@ export const getScoreTemplate = quantificationId => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const queryKingdeeCustomer = creditCode => {
|
||||||
|
return request({
|
||||||
|
url: '/blade-transport/bfi/customer/query-by-credit-code',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
creditCode,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const syncKingdee = id => {
|
||||||
|
return request({
|
||||||
|
url: '/blade-transport/customer-archive/sync-kingdee',
|
||||||
|
method: 'post',
|
||||||
|
params: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const recognizeBusinessLicenseOcr = imageUrl => {
|
export const recognizeBusinessLicenseOcr = imageUrl => {
|
||||||
return request({
|
return request({
|
||||||
url: '/blade-transport/baidu-ocr/recognize-url',
|
url: '/blade-transport/baidu-ocr/recognize-url',
|
||||||
|
|||||||
@@ -109,6 +109,12 @@
|
|||||||
{{ row.status === 1 ? '启用' : '停用' }}
|
{{ row.status === 1 ? '启用' : '停用' }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
|
<template #kingdeeStatus="{ row }">
|
||||||
|
<el-tag v-if="row.kingdeeStatus === 'synced'" type="success">已推送</el-tag>
|
||||||
|
<el-tag v-else-if="row.kingdeeStatus === 'exist'" type="primary">金蝶已有</el-tag>
|
||||||
|
<el-tag v-else-if="row.kingdeeStatus === 'failed'" type="danger">推送失败</el-tag>
|
||||||
|
<el-tag v-else type="info">未推送</el-tag>
|
||||||
|
</template>
|
||||||
<template #menu="{ row }">
|
<template #menu="{ row }">
|
||||||
<el-link
|
<el-link
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -165,6 +171,17 @@
|
|||||||
>
|
>
|
||||||
{{ row.status === 1 ? '停用' : '启用' }}
|
{{ row.status === 1 ? '停用' : '启用' }}
|
||||||
</el-link>
|
</el-link>
|
||||||
|
<el-link
|
||||||
|
type="primary"
|
||||||
|
v-if="
|
||||||
|
hasPermission('customer_archive_sync') &&
|
||||||
|
row.approvalStatus === 'approved' &&
|
||||||
|
row.kingdeeStatus === 'failed'
|
||||||
|
"
|
||||||
|
@click="handleSyncKingdee(row)"
|
||||||
|
>
|
||||||
|
同步金蝶
|
||||||
|
</el-link>
|
||||||
<el-link
|
<el-link
|
||||||
type="danger"
|
type="danger"
|
||||||
v-if="hasPermission('customer_archive_delete') && row.approvalStatus === 'draft'"
|
v-if="hasPermission('customer_archive_delete') && row.approvalStatus === 'draft'"
|
||||||
@@ -266,6 +283,7 @@
|
|||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
maxlength="18"
|
maxlength="18"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
|
:disabled="kingdeeLocked"
|
||||||
@input="
|
@input="
|
||||||
archiveForm.unifiedCreditCode = String(
|
archiveForm.unifiedCreditCode = String(
|
||||||
archiveForm.unifiedCreditCode || ''
|
archiveForm.unifiedCreditCode || ''
|
||||||
@@ -281,6 +299,7 @@
|
|||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
maxlength="100"
|
maxlength="100"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
|
:disabled="kingdeeLocked"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -304,12 +323,23 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="企业法人" prop="legalPerson">
|
<el-form-item label="企业法人" prop="legalPerson">
|
||||||
<el-input v-model="archiveForm.legalPerson" maxlength="10" show-word-limit />
|
<el-input
|
||||||
|
v-model="archiveForm.legalPerson"
|
||||||
|
maxlength="10"
|
||||||
|
show-word-limit
|
||||||
|
:disabled="kingdeeLocked"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="经营范围" prop="businessScope" required>
|
<el-form-item label="经营范围" prop="businessScope" required>
|
||||||
<el-select v-model="archiveForm.businessScope" multiple filterable clearable>
|
<el-select
|
||||||
|
v-model="archiveForm.businessScope"
|
||||||
|
multiple
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
:disabled="kingdeeLocked"
|
||||||
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in businessScopeOptions"
|
v-for="item in businessScopeOptions"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
@@ -331,11 +361,12 @@
|
|||||||
v-model="archiveForm.businessEndDate"
|
v-model="archiveForm.businessEndDate"
|
||||||
type="date"
|
type="date"
|
||||||
value-format="YYYY-MM-DD"
|
value-format="YYYY-MM-DD"
|
||||||
:disabled="archiveForm.businessTermType === '长期'"
|
:disabled="kingdeeLocked || archiveForm.businessTermType === '长期'"
|
||||||
@change="handleBusinessEndDateChange"
|
@change="handleBusinessEndDateChange"
|
||||||
/>
|
/>
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
:model-value="archiveForm.businessTermType === '长期'"
|
:model-value="archiveForm.businessTermType === '长期'"
|
||||||
|
:disabled="kingdeeLocked"
|
||||||
@change="handleNoFixedTermChange"
|
@change="handleNoFixedTermChange"
|
||||||
>
|
>
|
||||||
无固定期限
|
无固定期限
|
||||||
@@ -367,6 +398,7 @@
|
|||||||
:options="regionOptions"
|
:options="regionOptions"
|
||||||
:props="regionCascaderProps"
|
:props="regionCascaderProps"
|
||||||
:placeholder="archiveForm.registeredRegionName || '请选择省市区'"
|
:placeholder="archiveForm.registeredRegionName || '请选择省市区'"
|
||||||
|
:disabled="kingdeeLocked"
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
@change="handleRegisteredRegionChange"
|
@change="handleRegisteredRegionChange"
|
||||||
@@ -387,6 +419,7 @@
|
|||||||
v-model="archiveForm.registeredDetailAddress"
|
v-model="archiveForm.registeredDetailAddress"
|
||||||
maxlength="255"
|
maxlength="255"
|
||||||
placeholder="请输入详细地址"
|
placeholder="请输入详细地址"
|
||||||
|
:disabled="kingdeeLocked"
|
||||||
@input="checkOverflow('registeredDetailInput', 'registeredDetailOverflow')"
|
@input="checkOverflow('registeredDetailInput', 'registeredDetailOverflow')"
|
||||||
/>
|
/>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@@ -446,6 +479,7 @@
|
|||||||
<el-input
|
<el-input
|
||||||
v-model="archiveForm.registeredCapital"
|
v-model="archiveForm.registeredCapital"
|
||||||
maxlength="18"
|
maxlength="18"
|
||||||
|
:disabled="kingdeeLocked"
|
||||||
@input="value => handleDecimalInput('registeredCapital', value)"
|
@input="value => handleDecimalInput('registeredCapital', value)"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -1492,6 +1526,8 @@ import {
|
|||||||
remove,
|
remove,
|
||||||
getScoreTemplate,
|
getScoreTemplate,
|
||||||
recognizeBusinessLicenseOcr,
|
recognizeBusinessLicenseOcr,
|
||||||
|
queryKingdeeCustomer,
|
||||||
|
syncKingdee,
|
||||||
} from '@/api/vehicle/customer-archive';
|
} from '@/api/vehicle/customer-archive';
|
||||||
import {
|
import {
|
||||||
getList as getCreditScoreQuantificationList,
|
getList as getCreditScoreQuantificationList,
|
||||||
@@ -1565,23 +1601,13 @@ export default {
|
|||||||
const code = String(value || '')
|
const code = String(value || '')
|
||||||
.trim()
|
.trim()
|
||||||
.toUpperCase();
|
.toUpperCase();
|
||||||
const charset = '0123456789ABCDEFGHJKLMNPQRTUWXY';
|
|
||||||
const weights = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28];
|
|
||||||
if (!code) {
|
if (!code) {
|
||||||
callback();
|
callback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (code.length !== 18 || ![...code].every(char => charset.includes(char))) {
|
const error = this.unifiedCreditCodeError(code);
|
||||||
callback(new Error('统一社会信用代码必须为18位有效字符'));
|
if (error) {
|
||||||
return;
|
callback(new Error(error));
|
||||||
}
|
|
||||||
const sum = [...code.slice(0, 17)].reduce(
|
|
||||||
(total, char, index) => total + charset.indexOf(char) * weights[index],
|
|
||||||
0
|
|
||||||
);
|
|
||||||
const checkCode = charset[(31 - (sum % 31)) % 31];
|
|
||||||
if (code[17] !== checkCode) {
|
|
||||||
callback(new Error('统一社会信用代码校验码错误'));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
callback();
|
callback();
|
||||||
@@ -1621,6 +1647,9 @@ export default {
|
|||||||
originalAccessType: '',
|
originalAccessType: '',
|
||||||
activeTab: 'scores',
|
activeTab: 'scores',
|
||||||
archiveForm: this.emptyArchive(),
|
archiveForm: this.emptyArchive(),
|
||||||
|
kingdeeBlocked: false,
|
||||||
|
kingdeeQueriedCode: '',
|
||||||
|
kingdeeQueryTimer: null,
|
||||||
currentScore: { details: [] },
|
currentScore: { details: [] },
|
||||||
scoreRecordIndex: -1,
|
scoreRecordIndex: -1,
|
||||||
scoreAttachmentFiles: [],
|
scoreAttachmentFiles: [],
|
||||||
@@ -1967,6 +1996,12 @@ export default {
|
|||||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
minWidth: 170,
|
minWidth: 170,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '金蝶同步状态',
|
||||||
|
prop: 'kingdeeStatus',
|
||||||
|
slot: true,
|
||||||
|
minWidth: 110,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '状态',
|
label: '状态',
|
||||||
prop: 'status',
|
prop: 'status',
|
||||||
@@ -2004,6 +2039,9 @@ export default {
|
|||||||
const authority = this.userInfo.authority || '';
|
const authority = this.userInfo.authority || '';
|
||||||
return authority.includes('admin');
|
return authority.includes('admin');
|
||||||
},
|
},
|
||||||
|
kingdeeLocked() {
|
||||||
|
return this.archiveForm.kingdeeStatus === 'exist';
|
||||||
|
},
|
||||||
permissionList() {
|
permissionList() {
|
||||||
return {
|
return {
|
||||||
addBtn: false,
|
addBtn: false,
|
||||||
@@ -2179,6 +2217,9 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
'archiveForm.unifiedCreditCode'(val) {
|
||||||
|
this.handleKingdeeCreditCodeChange(val);
|
||||||
|
},
|
||||||
'archiveForm.registeredDetailAddress'() {
|
'archiveForm.registeredDetailAddress'() {
|
||||||
this.$nextTick(() => this.checkOverflow('registeredDetailInput', 'registeredDetailOverflow'));
|
this.$nextTick(() => this.checkOverflow('registeredDetailInput', 'registeredDetailOverflow'));
|
||||||
},
|
},
|
||||||
@@ -2190,6 +2231,101 @@ export default {
|
|||||||
hasPermission(code) {
|
hasPermission(code) {
|
||||||
return this.isAdmin || this.validData(this.permission[code], false);
|
return this.isAdmin || this.validData(this.permission[code], false);
|
||||||
},
|
},
|
||||||
|
unifiedCreditCodeError(value) {
|
||||||
|
const code = String(value || '')
|
||||||
|
.trim()
|
||||||
|
.toUpperCase();
|
||||||
|
const charset = '0123456789ABCDEFGHJKLMNPQRTUWXY';
|
||||||
|
const weights = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28];
|
||||||
|
if (code.length !== 18 || ![...code].every(char => charset.includes(char))) {
|
||||||
|
return '统一社会信用代码必须为18位有效字符';
|
||||||
|
}
|
||||||
|
const sum = [...code.slice(0, 17)].reduce(
|
||||||
|
(total, char, index) => total + charset.indexOf(char) * weights[index],
|
||||||
|
0
|
||||||
|
);
|
||||||
|
const checkCode = charset[(31 - (sum % 31)) % 31];
|
||||||
|
if (code[17] !== checkCode) {
|
||||||
|
return '统一社会信用代码校验码错误';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
resetKingdeeQueryState() {
|
||||||
|
this.kingdeeBlocked = false;
|
||||||
|
this.kingdeeQueriedCode = '';
|
||||||
|
clearTimeout(this.kingdeeQueryTimer);
|
||||||
|
this.kingdeeQueryTimer = null;
|
||||||
|
},
|
||||||
|
// 新增态下统一社会信用代码录入完成后自动查询金蝶(A902-1),防抖 500ms
|
||||||
|
handleKingdeeCreditCodeChange(val) {
|
||||||
|
this.kingdeeBlocked = false;
|
||||||
|
if (this.readonly || this.archiveForm.id) return;
|
||||||
|
const code = String(val || '')
|
||||||
|
.trim()
|
||||||
|
.toUpperCase();
|
||||||
|
if (code.length !== 18 || this.unifiedCreditCodeError(code)) return;
|
||||||
|
if (this.kingdeeQueriedCode === code) return;
|
||||||
|
this.kingdeeQueriedCode = code;
|
||||||
|
clearTimeout(this.kingdeeQueryTimer);
|
||||||
|
this.kingdeeQueryTimer = setTimeout(() => this.fetchKingdeeCustomer(code), 500);
|
||||||
|
},
|
||||||
|
async fetchKingdeeCustomer(code) {
|
||||||
|
let customer = null;
|
||||||
|
try {
|
||||||
|
const res = await queryKingdeeCustomer(code);
|
||||||
|
customer = res?.data?.data || null;
|
||||||
|
} catch (error) {
|
||||||
|
this.$message.warning('金蝶查询失败,可继续填写,审批通过后系统将自动复查');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 防止响应返回时用户已修改代码
|
||||||
|
if (String(this.archiveForm.unifiedCreditCode || '').trim().toUpperCase() !== code) return;
|
||||||
|
if (!customer) return;
|
||||||
|
if (customer.status === 'C') {
|
||||||
|
this.applyKingdeeCustomer(customer);
|
||||||
|
this.$alert('金蝶已创建该客户,将获取金蝶的工商信息,相关字段已自动回填并锁定。', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.kingdeeBlocked = true;
|
||||||
|
this.$alert('金蝶审核中,请稍后重新添加。', '提示', { confirmButtonText: '确定' });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
applyKingdeeCustomer(customer) {
|
||||||
|
const form = this.archiveForm;
|
||||||
|
form.kingdeeStatus = 'exist';
|
||||||
|
// 工商信息以金蝶为准,直接覆盖(后续字段锁定)
|
||||||
|
if (customer.name) form.fullName = customer.name;
|
||||||
|
if (customer.artificialperson) form.legalPerson = customer.artificialperson;
|
||||||
|
if (customer.bizpartnerAddress) form.registeredDetailAddress = customer.bizpartnerAddress;
|
||||||
|
if (customer.regcapital) {
|
||||||
|
const capital = String(customer.regcapital).replace(/,/g, '').match(/\d+(?:\.\d+)?/);
|
||||||
|
if (capital) form.registeredCapital = capital[0];
|
||||||
|
}
|
||||||
|
if (customer.businessterm) this.applyBusinessTermRecognition(customer.businessterm);
|
||||||
|
if (customer.businessscope) {
|
||||||
|
const matchedScopes = this.businessScopeOptions
|
||||||
|
.filter(
|
||||||
|
item =>
|
||||||
|
customer.businessscope.includes(item.label) ||
|
||||||
|
customer.businessscope.includes(item.value)
|
||||||
|
)
|
||||||
|
.map(item => item.value);
|
||||||
|
if (matchedScopes.length) form.businessScope = matchedScopes;
|
||||||
|
}
|
||||||
|
if (!form.shortName && customer.simplename) form.shortName = customer.simplename;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
[
|
||||||
|
'unifiedCreditCode',
|
||||||
|
'fullName',
|
||||||
|
'legalPerson',
|
||||||
|
'registeredCapital',
|
||||||
|
'businessEndDate',
|
||||||
|
'businessScope',
|
||||||
|
'registeredDetailAddress',
|
||||||
|
].forEach(prop => this.$refs.archiveForm?.validateField(prop));
|
||||||
|
});
|
||||||
|
},
|
||||||
// 检测输入框文本是否溢出,仅溢出时才允许 tooltip 显示完整地址
|
// 检测输入框文本是否溢出,仅溢出时才允许 tooltip 显示完整地址
|
||||||
checkOverflow(refName, flag) {
|
checkOverflow(refName, flag) {
|
||||||
const inst = this.$refs[refName];
|
const inst = this.$refs[refName];
|
||||||
@@ -2219,6 +2355,9 @@ export default {
|
|||||||
invoices: [],
|
invoices: [],
|
||||||
scores: [],
|
scores: [],
|
||||||
changeRecords: [],
|
changeRecords: [],
|
||||||
|
kingdeeStatus: 'none',
|
||||||
|
kingdeeFailReason: '',
|
||||||
|
kingdeeSyncTime: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getDetailList(type) {
|
getDetailList(type) {
|
||||||
@@ -3919,6 +4058,7 @@ export default {
|
|||||||
}
|
}
|
||||||
this.archiveForm = this.emptyArchive();
|
this.archiveForm = this.emptyArchive();
|
||||||
this.originalAccessType = '';
|
this.originalAccessType = '';
|
||||||
|
this.resetKingdeeQueryState();
|
||||||
this.qualificationFiles = [];
|
this.qualificationFiles = [];
|
||||||
this.qualificationUploadFiles = [];
|
this.qualificationUploadFiles = [];
|
||||||
this.ocrQualificationUploadFiles = [];
|
this.ocrQualificationUploadFiles = [];
|
||||||
@@ -3927,6 +4067,7 @@ export default {
|
|||||||
},
|
},
|
||||||
resetArchive() {
|
resetArchive() {
|
||||||
this.readonly = false;
|
this.readonly = false;
|
||||||
|
this.resetKingdeeQueryState();
|
||||||
this.changeRecordDetailVisible = false;
|
this.changeRecordDetailVisible = false;
|
||||||
this.changeRecordDetail = null;
|
this.changeRecordDetail = null;
|
||||||
this.changeRecordDetailRows = [];
|
this.changeRecordDetailRows = [];
|
||||||
@@ -4047,6 +4188,10 @@ export default {
|
|||||||
return archive;
|
return archive;
|
||||||
},
|
},
|
||||||
saveArchive() {
|
saveArchive() {
|
||||||
|
if (this.kingdeeBlocked) {
|
||||||
|
this.$message.warning('金蝶审核中,请稍后重新添加');
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.$refs.archiveForm.validate(valid => {
|
this.$refs.archiveForm.validate(valid => {
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
this.$message.warning('请先完整填写必填项');
|
this.$message.warning('请先完整填写必填项');
|
||||||
@@ -4060,6 +4205,10 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
saveAndSubmitArchive() {
|
saveAndSubmitArchive() {
|
||||||
|
if (this.kingdeeBlocked) {
|
||||||
|
this.$message.warning('金蝶审核中,请稍后重新添加');
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.$refs.archiveForm.validate(valid => {
|
this.$refs.archiveForm.validate(valid => {
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
this.$message.warning('请先完整填写必填项');
|
this.$message.warning('请先完整填写必填项');
|
||||||
@@ -4707,6 +4856,25 @@ export default {
|
|||||||
this.$message({ type: 'success', message: '审核通过!' });
|
this.$message({ type: 'success', message: '审核通过!' });
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
handleSyncKingdee(row) {
|
||||||
|
this.$confirm('是否确认推送金蝶?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
})
|
||||||
|
.then(() => syncKingdee(row.id))
|
||||||
|
.then(res => {
|
||||||
|
const archive = res?.data?.data || {};
|
||||||
|
if (archive.kingdeeStatus === 'synced') {
|
||||||
|
this.$message.success('推送成功,金蝶客户编码与客商编号一致');
|
||||||
|
} else if (archive.kingdeeStatus === 'exist') {
|
||||||
|
this.$message.info('金蝶已有该客商档案,无需推送');
|
||||||
|
} else {
|
||||||
|
this.$message.warning(`推送失败:${archive.kingdeeFailReason || '未知原因'}`);
|
||||||
|
}
|
||||||
|
this.onLoad(this.page);
|
||||||
|
});
|
||||||
|
},
|
||||||
handleReject(row) {
|
handleReject(row) {
|
||||||
this.$confirm('是否确认审核不通过?', '提示', {
|
this.$confirm('是否确认审核不通过?', '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
|
|||||||
Reference in New Issue
Block a user