✨ 完善客商MK审核提交、地区校验与流程实例校验
提交增加 loading,拆分所在地区/详细地址校验,支持 MK 审核跳转,并在已有流程实例时跳过重复提交。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -29,3 +29,30 @@ export const processDelete = data => {
|
|||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询 MK 流程实例是否仍存在(有数据则无需删除/重新提交)
|
||||||
|
* @param {Object} params
|
||||||
|
* @param {string} params.bizId 业务 id(formInstanceId)
|
||||||
|
*/
|
||||||
|
export const hasMkProcessInstance = params => {
|
||||||
|
return request({
|
||||||
|
url: '/blade-system/businessProcess/hasMkProcessInstance',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 MK 审批页跳转链接(后端按 thirdParty.mk 配置拼接,含 SSO)
|
||||||
|
* @param {Object} params
|
||||||
|
* @param {string} [params.bizId] 业务 id(如客商 id)
|
||||||
|
* @param {string} [params.processInstanceId] 流程实例 id
|
||||||
|
*/
|
||||||
|
export const getMKApprovalUrl = params => {
|
||||||
|
return request({
|
||||||
|
url: '/blade-system/businessProcess/getMKApprovalUrl',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { getDictionary } from '@/api/system/dictbiz';
|
import { getDictionary } from '@/api/system/dictbiz';
|
||||||
import { processDelete, processSubmit } from '@/api/system/business-process';
|
import { hasMkProcessInstance, processDelete, processSubmit } from '@/api/system/business-process';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
export const MK_BIZ = {
|
export const MK_BIZ = {
|
||||||
@@ -53,6 +53,12 @@ export function isMkEnabled(list = []) {
|
|||||||
return String(matched?.dictKey ?? '').trim() === '1';
|
return String(matched?.dictKey ?? '').trim() === '1';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 加载业务字典并判断是否开启 MK */
|
||||||
|
export async function loadMkEnabled() {
|
||||||
|
const list = await loadMkTemplateList();
|
||||||
|
return isMkEnabled(list);
|
||||||
|
}
|
||||||
|
|
||||||
export async function resolveMkTemplateCode(dictName, list) {
|
export async function resolveMkTemplateCode(dictName, list) {
|
||||||
const dictList = list || (await loadMkTemplateList());
|
const dictList = list || (await loadMkTemplateList());
|
||||||
const matched = dictList.find(item => String(item.dictValue || '').trim() === dictName);
|
const matched = dictList.find(item => String(item.dictValue || '').trim() === dictName);
|
||||||
@@ -78,6 +84,11 @@ export async function submitMkApprovalFlow({
|
|||||||
if (!isMkEnabled(list)) {
|
if (!isMkEnabled(list)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// 先查 MK 流程实例:已有数据则不删除、不重新提交
|
||||||
|
const existsRes = await hasMkProcessInstance({ bizId: String(formInstanceId) });
|
||||||
|
if (existsRes?.data?.data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if ((conf.rejected || []).includes(approvalStatus)) {
|
if ((conf.rejected || []).includes(approvalStatus)) {
|
||||||
await processDelete({ formInstanceId: String(formInstanceId) });
|
await processDelete({ formInstanceId: String(formInstanceId) });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,9 +155,21 @@
|
|||||||
>
|
>
|
||||||
复评
|
复评
|
||||||
</el-link>
|
</el-link>
|
||||||
|
<el-link
|
||||||
|
type="primary"
|
||||||
|
v-if="
|
||||||
|
mkEnabled &&
|
||||||
|
hasPermission('customer_archive_approve') &&
|
||||||
|
row.approvalStatus === 'reviewing'
|
||||||
|
"
|
||||||
|
@click="handleMkAudit(row)"
|
||||||
|
>
|
||||||
|
审核
|
||||||
|
</el-link>
|
||||||
<el-link
|
<el-link
|
||||||
type="success"
|
type="success"
|
||||||
v-if="
|
v-if="
|
||||||
|
!mkEnabled &&
|
||||||
hasPermission('customer_archive_approve') &&
|
hasPermission('customer_archive_approve') &&
|
||||||
row.approvalStatus === 'reviewing' &&
|
row.approvalStatus === 'reviewing' &&
|
||||||
row.reviewStatus === '已完成'
|
row.reviewStatus === '已完成'
|
||||||
@@ -168,7 +180,11 @@
|
|||||||
</el-link>
|
</el-link>
|
||||||
<el-link
|
<el-link
|
||||||
type="warning"
|
type="warning"
|
||||||
v-if="hasPermission('customer_archive_reject') && row.approvalStatus === 'reviewing'"
|
v-if="
|
||||||
|
!mkEnabled &&
|
||||||
|
hasPermission('customer_archive_reject') &&
|
||||||
|
row.approvalStatus === 'reviewing'
|
||||||
|
"
|
||||||
@click="handleReject(row)"
|
@click="handleReject(row)"
|
||||||
>
|
>
|
||||||
审核不通过
|
审核不通过
|
||||||
@@ -374,7 +390,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="所在地区" prop="registeredDetailAddress" required>
|
<el-form-item label="所在地区" prop="registeredRegionName" required>
|
||||||
<div class="archive-form__address">
|
<div class="archive-form__address">
|
||||||
<el-cascader
|
<el-cascader
|
||||||
ref="registeredRegionCascader"
|
ref="registeredRegionCascader"
|
||||||
@@ -1511,7 +1527,8 @@ import {
|
|||||||
getDetail as getCreditScoreQuantificationDetail,
|
getDetail as getCreditScoreQuantificationDetail,
|
||||||
} from '@/api/vehicle/credit-score-quantification';
|
} from '@/api/vehicle/credit-score-quantification';
|
||||||
import { getDictionary } from '@/api/system/dictbiz';
|
import { getDictionary } from '@/api/system/dictbiz';
|
||||||
import { submitMkApprovalFlow } from '@/utils/mk-approval';
|
import { getMKApprovalUrl } from '@/api/system/business-process';
|
||||||
|
import { loadMkEnabled, submitMkApprovalFlow } from '@/utils/mk-approval';
|
||||||
import { getDeptTree } from '@/api/system/dept';
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
import { getLazyTree } from '@/api/base/region';
|
import { getLazyTree } from '@/api/base/region';
|
||||||
import { exportBlob } from '@/api/common';
|
import { exportBlob } from '@/api/common';
|
||||||
@@ -1608,19 +1625,6 @@ export default {
|
|||||||
}
|
}
|
||||||
callback();
|
callback();
|
||||||
};
|
};
|
||||||
const validateRegisteredAddress = (rule, value, callback) => {
|
|
||||||
const regionName = (this.archiveForm.registeredRegionName || '').trim();
|
|
||||||
const detailAddress = String(value || '').trim();
|
|
||||||
if (!regionName) {
|
|
||||||
callback(new Error('请选择省市区'));
|
|
||||||
} else if (!detailAddress) {
|
|
||||||
callback(new Error('请输入详细地址'));
|
|
||||||
} else if (detailAddress.length > 255) {
|
|
||||||
callback(new Error('详细地址最多255个字符'));
|
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
query: {},
|
query: {},
|
||||||
@@ -1749,6 +1753,8 @@ export default {
|
|||||||
approved: { label: '审核通过', type: 'success' },
|
approved: { label: '审核通过', type: 'success' },
|
||||||
rejected: { label: '审核不通过', type: 'danger' },
|
rejected: { label: '审核不通过', type: 'danger' },
|
||||||
},
|
},
|
||||||
|
/** 业务字典 mk_template「开启MK」=1 */
|
||||||
|
mkEnabled: false,
|
||||||
formRules: {
|
formRules: {
|
||||||
customerCode: [{ max: 20, message: '客商编号最多20个字符', trigger: 'blur' }],
|
customerCode: [{ max: 20, message: '客商编号最多20个字符', trigger: 'blur' }],
|
||||||
fullName: [{ required: true, message: '请输入客商名称', trigger: 'blur' }],
|
fullName: [{ required: true, message: '请输入客商名称', trigger: 'blur' }],
|
||||||
@@ -1771,8 +1777,10 @@ export default {
|
|||||||
registeredCapital: [{ validator: validateNonNegative, trigger: 'blur' }],
|
registeredCapital: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||||||
maxCreditLimit: [{ validator: validateNonNegative, trigger: 'blur' }],
|
maxCreditLimit: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||||||
applyCreditLimit: [{ validator: validateNonNegative, trigger: 'blur' }],
|
applyCreditLimit: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||||||
|
registeredRegionName: [{ required: true, message: '请选择省市区', trigger: 'change' }],
|
||||||
registeredDetailAddress: [
|
registeredDetailAddress: [
|
||||||
{ validator: validateRegisteredAddress, trigger: ['change', 'blur'] },
|
{ required: true, message: '请输入详细地址', trigger: 'blur' },
|
||||||
|
{ max: 255, message: '详细地址最多255个字符', trigger: 'blur' },
|
||||||
],
|
],
|
||||||
businessScope: [
|
businessScope: [
|
||||||
{
|
{
|
||||||
@@ -2028,6 +2036,7 @@ export default {
|
|||||||
this.initDeptTree();
|
this.initDeptTree();
|
||||||
this.initRegionOptions();
|
this.initRegionOptions();
|
||||||
this.initBusinessDictionaries();
|
this.initBusinessDictionaries();
|
||||||
|
this.initMkEnabled();
|
||||||
this.initScoreQuantificationOptions();
|
this.initScoreQuantificationOptions();
|
||||||
if (this.isArchivePage) {
|
if (this.isArchivePage) {
|
||||||
this.reviewMode = this.$route.query.review === '1';
|
this.reviewMode = this.$route.query.review === '1';
|
||||||
@@ -2863,12 +2872,12 @@ export default {
|
|||||||
handleRegisteredRegionChange(value) {
|
handleRegisteredRegionChange(value) {
|
||||||
if (!value || !value.length) {
|
if (!value || !value.length) {
|
||||||
this.archiveForm.registeredRegionName = '';
|
this.archiveForm.registeredRegionName = '';
|
||||||
this.$refs.archiveForm?.validateField('registeredDetailAddress');
|
this.$refs.archiveForm?.validateField('registeredRegionName');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.archiveForm.registeredRegionName = this.getRegisteredRegionLabels(value).join('');
|
this.archiveForm.registeredRegionName = this.getRegisteredRegionLabels(value).join('');
|
||||||
this.$refs.archiveForm?.validateField('registeredDetailAddress');
|
this.$refs.archiveForm?.validateField('registeredRegionName');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleInvoiceRegisteredRegionChange(value) {
|
handleInvoiceRegisteredRegionChange(value) {
|
||||||
@@ -2899,6 +2908,15 @@ export default {
|
|||||||
this.sortQualificationFiles();
|
this.sortQualificationFiles();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
initMkEnabled() {
|
||||||
|
loadMkEnabled()
|
||||||
|
.then(enabled => {
|
||||||
|
this.mkEnabled = !!enabled;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.mkEnabled = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
initScoreQuantificationOptions() {
|
initScoreQuantificationOptions() {
|
||||||
this.scoreQuantificationLoading = true;
|
this.scoreQuantificationLoading = true;
|
||||||
return getCreditScoreQuantificationList(1, 9999, { status: 1 })
|
return getCreditScoreQuantificationList(1, 9999, { status: 1 })
|
||||||
@@ -4206,30 +4224,37 @@ export default {
|
|||||||
// 仅提交时落变更记录;保存不记录
|
// 仅提交时落变更记录;保存不记录
|
||||||
archive.recordChange = true;
|
archive.recordChange = true;
|
||||||
if (!this.validateScoreForApproval(archive)) return;
|
if (!this.validateScoreForApproval(archive)) return;
|
||||||
submit(archive).then(res => {
|
const loading = ElLoading.service({
|
||||||
const data = res.data.data;
|
lock: true,
|
||||||
const id = (data && typeof data === 'object' ? data.id : data) || this.archiveForm.id;
|
text: '提交中',
|
||||||
if (!id) {
|
background: 'rgba(255, 255, 255, 0.7)',
|
||||||
this.closeArchive();
|
|
||||||
this.onLoad(this.page);
|
|
||||||
this.$message({ type: 'success', message: '保存成功,请在列表提交审批' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const fullName =
|
|
||||||
(data && typeof data === 'object' ? data.fullName : '') ||
|
|
||||||
archive.fullName ||
|
|
||||||
this.archiveForm.fullName ||
|
|
||||||
'';
|
|
||||||
this.submitCustomerApproval(
|
|
||||||
id,
|
|
||||||
fullName,
|
|
||||||
archive.approvalStatus || this.archiveForm.approvalStatus
|
|
||||||
).then(() => {
|
|
||||||
this.closeArchive();
|
|
||||||
this.onLoad(this.page);
|
|
||||||
this.$message({ type: 'success', message: '提交成功!' });
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
submit(archive)
|
||||||
|
.then(res => {
|
||||||
|
const data = res.data.data;
|
||||||
|
const id = (data && typeof data === 'object' ? data.id : data) || this.archiveForm.id;
|
||||||
|
if (!id) {
|
||||||
|
this.closeArchive();
|
||||||
|
this.onLoad(this.page);
|
||||||
|
this.$message({ type: 'success', message: '保存成功,请在列表提交审批' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const fullName =
|
||||||
|
(data && typeof data === 'object' ? data.fullName : '') ||
|
||||||
|
archive.fullName ||
|
||||||
|
this.archiveForm.fullName ||
|
||||||
|
'';
|
||||||
|
return this.submitCustomerApproval(
|
||||||
|
id,
|
||||||
|
fullName,
|
||||||
|
archive.approvalStatus || this.archiveForm.approvalStatus
|
||||||
|
).then(() => {
|
||||||
|
this.closeArchive();
|
||||||
|
this.onLoad(this.page);
|
||||||
|
this.$message({ type: 'success', message: '提交成功!' });
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.finally(() => loading.close());
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@@ -4928,6 +4953,24 @@ export default {
|
|||||||
this.$message({ type: 'success', message: '已撤回至草稿状态!' });
|
this.$message({ type: 'success', message: '已撤回至草稿状态!' });
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
handleMkAudit(row) {
|
||||||
|
if (!row?.id) {
|
||||||
|
this.$message.warning('客商ID为空,无法打开审核页');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
getMKApprovalUrl({ bizId: String(row.id) })
|
||||||
|
.then(res => {
|
||||||
|
const url = res?.data?.data;
|
||||||
|
if (!url) {
|
||||||
|
this.$message.error('获取审核跳转地址失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.open(url, '_blank');
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.$message.error('获取审核跳转地址失败');
|
||||||
|
});
|
||||||
|
},
|
||||||
handleApprove(row) {
|
handleApprove(row) {
|
||||||
this.$confirm('是否确认审核通过?', '提示', {
|
this.$confirm('是否确认审核通过?', '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
|
|||||||
Reference in New Issue
Block a user