✨ 客商档案新增金蝶客商查询回填与同步金蝶重推入口
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 => {
|
||||
return request({
|
||||
url: '/blade-transport/baidu-ocr/recognize-url',
|
||||
|
||||
@@ -109,6 +109,12 @@
|
||||
{{ row.status === 1 ? '启用' : '停用' }}
|
||||
</el-tag>
|
||||
</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 }">
|
||||
<el-link
|
||||
type="primary"
|
||||
@@ -165,6 +171,17 @@
|
||||
>
|
||||
{{ row.status === 1 ? '停用' : '启用' }}
|
||||
</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
|
||||
type="danger"
|
||||
v-if="hasPermission('customer_archive_delete') && row.approvalStatus === 'draft'"
|
||||
@@ -266,6 +283,7 @@
|
||||
placeholder="请输入"
|
||||
maxlength="18"
|
||||
show-word-limit
|
||||
:disabled="kingdeeLocked"
|
||||
@input="
|
||||
archiveForm.unifiedCreditCode = String(
|
||||
archiveForm.unifiedCreditCode || ''
|
||||
@@ -281,6 +299,7 @@
|
||||
placeholder="请输入"
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
:disabled="kingdeeLocked"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -304,12 +323,23 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<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-col>
|
||||
<el-col :span="6">
|
||||
<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
|
||||
v-for="item in businessScopeOptions"
|
||||
:key="item.value"
|
||||
@@ -331,11 +361,12 @@
|
||||
v-model="archiveForm.businessEndDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
:disabled="archiveForm.businessTermType === '长期'"
|
||||
:disabled="kingdeeLocked || archiveForm.businessTermType === '长期'"
|
||||
@change="handleBusinessEndDateChange"
|
||||
/>
|
||||
<el-checkbox
|
||||
:model-value="archiveForm.businessTermType === '长期'"
|
||||
:disabled="kingdeeLocked"
|
||||
@change="handleNoFixedTermChange"
|
||||
>
|
||||
无固定期限
|
||||
@@ -367,6 +398,7 @@
|
||||
:options="regionOptions"
|
||||
:props="regionCascaderProps"
|
||||
:placeholder="archiveForm.registeredRegionName || '请选择省市区'"
|
||||
:disabled="kingdeeLocked"
|
||||
clearable
|
||||
filterable
|
||||
@change="handleRegisteredRegionChange"
|
||||
@@ -387,6 +419,7 @@
|
||||
v-model="archiveForm.registeredDetailAddress"
|
||||
maxlength="255"
|
||||
placeholder="请输入详细地址"
|
||||
:disabled="kingdeeLocked"
|
||||
@input="checkOverflow('registeredDetailInput', 'registeredDetailOverflow')"
|
||||
/>
|
||||
</el-tooltip>
|
||||
@@ -446,6 +479,7 @@
|
||||
<el-input
|
||||
v-model="archiveForm.registeredCapital"
|
||||
maxlength="18"
|
||||
:disabled="kingdeeLocked"
|
||||
@input="value => handleDecimalInput('registeredCapital', value)"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -1492,6 +1526,8 @@ import {
|
||||
remove,
|
||||
getScoreTemplate,
|
||||
recognizeBusinessLicenseOcr,
|
||||
queryKingdeeCustomer,
|
||||
syncKingdee,
|
||||
} from '@/api/vehicle/customer-archive';
|
||||
import {
|
||||
getList as getCreditScoreQuantificationList,
|
||||
@@ -1565,23 +1601,13 @@ export default {
|
||||
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) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
if (code.length !== 18 || ![...code].every(char => charset.includes(char))) {
|
||||
callback(new Error('统一社会信用代码必须为18位有效字符'));
|
||||
return;
|
||||
}
|
||||
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('统一社会信用代码校验码错误'));
|
||||
const error = this.unifiedCreditCodeError(code);
|
||||
if (error) {
|
||||
callback(new Error(error));
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
@@ -1621,6 +1647,9 @@ export default {
|
||||
originalAccessType: '',
|
||||
activeTab: 'scores',
|
||||
archiveForm: this.emptyArchive(),
|
||||
kingdeeBlocked: false,
|
||||
kingdeeQueriedCode: '',
|
||||
kingdeeQueryTimer: null,
|
||||
currentScore: { details: [] },
|
||||
scoreRecordIndex: -1,
|
||||
scoreAttachmentFiles: [],
|
||||
@@ -1967,6 +1996,12 @@ export default {
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
minWidth: 170,
|
||||
},
|
||||
{
|
||||
label: '金蝶同步状态',
|
||||
prop: 'kingdeeStatus',
|
||||
slot: true,
|
||||
minWidth: 110,
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
prop: 'status',
|
||||
@@ -2004,6 +2039,9 @@ export default {
|
||||
const authority = this.userInfo.authority || '';
|
||||
return authority.includes('admin');
|
||||
},
|
||||
kingdeeLocked() {
|
||||
return this.archiveForm.kingdeeStatus === 'exist';
|
||||
},
|
||||
permissionList() {
|
||||
return {
|
||||
addBtn: false,
|
||||
@@ -2179,6 +2217,9 @@ export default {
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
'archiveForm.unifiedCreditCode'(val) {
|
||||
this.handleKingdeeCreditCodeChange(val);
|
||||
},
|
||||
'archiveForm.registeredDetailAddress'() {
|
||||
this.$nextTick(() => this.checkOverflow('registeredDetailInput', 'registeredDetailOverflow'));
|
||||
},
|
||||
@@ -2190,6 +2231,101 @@ export default {
|
||||
hasPermission(code) {
|
||||
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 显示完整地址
|
||||
checkOverflow(refName, flag) {
|
||||
const inst = this.$refs[refName];
|
||||
@@ -2219,6 +2355,9 @@ export default {
|
||||
invoices: [],
|
||||
scores: [],
|
||||
changeRecords: [],
|
||||
kingdeeStatus: 'none',
|
||||
kingdeeFailReason: '',
|
||||
kingdeeSyncTime: null,
|
||||
};
|
||||
},
|
||||
getDetailList(type) {
|
||||
@@ -3919,6 +4058,7 @@ export default {
|
||||
}
|
||||
this.archiveForm = this.emptyArchive();
|
||||
this.originalAccessType = '';
|
||||
this.resetKingdeeQueryState();
|
||||
this.qualificationFiles = [];
|
||||
this.qualificationUploadFiles = [];
|
||||
this.ocrQualificationUploadFiles = [];
|
||||
@@ -3927,6 +4067,7 @@ export default {
|
||||
},
|
||||
resetArchive() {
|
||||
this.readonly = false;
|
||||
this.resetKingdeeQueryState();
|
||||
this.changeRecordDetailVisible = false;
|
||||
this.changeRecordDetail = null;
|
||||
this.changeRecordDetailRows = [];
|
||||
@@ -4047,6 +4188,10 @@ export default {
|
||||
return archive;
|
||||
},
|
||||
saveArchive() {
|
||||
if (this.kingdeeBlocked) {
|
||||
this.$message.warning('金蝶审核中,请稍后重新添加');
|
||||
return;
|
||||
}
|
||||
this.$refs.archiveForm.validate(valid => {
|
||||
if (!valid) {
|
||||
this.$message.warning('请先完整填写必填项');
|
||||
@@ -4060,6 +4205,10 @@ export default {
|
||||
});
|
||||
},
|
||||
saveAndSubmitArchive() {
|
||||
if (this.kingdeeBlocked) {
|
||||
this.$message.warning('金蝶审核中,请稍后重新添加');
|
||||
return;
|
||||
}
|
||||
this.$refs.archiveForm.validate(valid => {
|
||||
if (!valid) {
|
||||
this.$message.warning('请先完整填写必填项');
|
||||
@@ -4707,6 +4856,25 @@ export default {
|
||||
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) {
|
||||
this.$confirm('是否确认审核不通过?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
|
||||
Reference in New Issue
Block a user