c5a74acd00
Co-authored-by: Cursor <cursoragent@cursor.com>
202 lines
6.1 KiB
JavaScript
202 lines
6.1 KiB
JavaScript
import { getDictionary } from '@/api/system/dictbiz';
|
||
import { hasMkProcessInstance, processDelete, processSubmit } from '@/api/system/business-process';
|
||
import { ElMessage } from 'element-plus';
|
||
|
||
export const MK_BIZ = {
|
||
'customer-archive': {
|
||
dictName: '提交客商审核流',
|
||
subjectPrefix: '客商准入审批',
|
||
rejected: ['rejected'],
|
||
approved: ['approved'],
|
||
},
|
||
'project-apply': {
|
||
dictName: '提交项目审核流',
|
||
subjectPrefix: '项目审批',
|
||
rejected: ['rejected', 'change_rejected', 'withdrawn'],
|
||
approved: ['approved', 'change_approved'],
|
||
},
|
||
'contract-manage': {
|
||
dictName: '提交合同审核流',
|
||
subjectPrefix: '合同审批',
|
||
rejected: ['rejected', 'change_rejected', 'withdrawn'],
|
||
approved: ['approved', 'change_approved'],
|
||
},
|
||
'pre-settlement': {
|
||
dictName: '提交预结算审核流',
|
||
subjectPrefix: '预结算审批',
|
||
rejected: ['returned'],
|
||
approved: ['approved'],
|
||
},
|
||
'formal-settlement': {
|
||
dictName: '提交正式结算审核流',
|
||
subjectPrefix: '正式结算审批',
|
||
rejected: ['returned'],
|
||
approved: ['approved'],
|
||
},
|
||
'payment-application': {
|
||
dictName: '提交付款审核流',
|
||
subjectPrefix: '付款审批',
|
||
rejected: ['returned'],
|
||
approved: ['approved'],
|
||
},
|
||
'invoice-application': {
|
||
dictName: '提交开票审核流',
|
||
subjectPrefix: '开票审批',
|
||
rejected: ['returned'],
|
||
approved: ['approved'],
|
||
},
|
||
'invoice-receipt': {
|
||
dictName: '提交收票审核流',
|
||
subjectPrefix: '收票审批',
|
||
rejected: ['returned'],
|
||
approved: ['approved'],
|
||
},
|
||
'bill-payment': {
|
||
dictName: '提交汇票付款审核流',
|
||
subjectPrefix: '汇票付款审批',
|
||
rejected: ['returned'],
|
||
approved: ['approved'],
|
||
},
|
||
};
|
||
|
||
const MK_SWITCH_NAME = '开启MK';
|
||
|
||
/** 进程内缓存,避免每次提交都打字典;登录后同一会话开关一般不变 */
|
||
let mkEnabledCache = null;
|
||
let mkEnabledPromise = null;
|
||
let mkTemplateListCache = null;
|
||
|
||
async function loadMkTemplateList(force = false) {
|
||
if (!force && mkTemplateListCache) {
|
||
return mkTemplateListCache;
|
||
}
|
||
const res = await getDictionary({ code: 'mk_template' });
|
||
mkTemplateListCache = res?.data?.data || [];
|
||
return mkTemplateListCache;
|
||
}
|
||
|
||
/** 业务字典 mk_template:名称「开启MK」且键值为 1 时才请求 MK */
|
||
export function isMkEnabled(list = []) {
|
||
const matched = list.find(item => String(item.dictValue || '').trim() === MK_SWITCH_NAME);
|
||
return String(matched?.dictKey ?? '').trim() === '1';
|
||
}
|
||
|
||
/** 清除 MK 开关缓存(字典变更后可调用) */
|
||
export function clearMkEnabledCache() {
|
||
mkEnabledCache = null;
|
||
mkEnabledPromise = null;
|
||
mkTemplateListCache = null;
|
||
}
|
||
|
||
/**
|
||
* 加载业务字典并判断是否开启 MK
|
||
* @param {boolean} [force=false] 是否强制刷新缓存
|
||
*/
|
||
export async function loadMkEnabled(force = false) {
|
||
if (!force && mkEnabledCache !== null) {
|
||
return mkEnabledCache;
|
||
}
|
||
if (!force && mkEnabledPromise) {
|
||
return mkEnabledPromise;
|
||
}
|
||
mkEnabledPromise = loadMkTemplateList(force)
|
||
.then(list => {
|
||
mkEnabledCache = isMkEnabled(list);
|
||
return mkEnabledCache;
|
||
})
|
||
.catch(error => {
|
||
mkEnabledCache = false;
|
||
throw error;
|
||
})
|
||
.finally(() => {
|
||
mkEnabledPromise = null;
|
||
});
|
||
return mkEnabledPromise;
|
||
}
|
||
|
||
export async function resolveMkTemplateCode(dictName, list) {
|
||
const dictList = list || (await loadMkTemplateList());
|
||
const matched = dictList.find(item => String(item.dictValue || '').trim() === dictName);
|
||
const templateCode = matched?.dictKey;
|
||
if (!templateCode) {
|
||
ElMessage.warning(`未配置业务字典 mk_template「${dictName}」,无法提交审核流`);
|
||
return Promise.reject(new Error(`未配置业务字典 mk_template「${dictName}」`));
|
||
}
|
||
return String(templateCode);
|
||
}
|
||
|
||
/**
|
||
* 是否属于「审核通过后再提交」需要新建表单实例的状态
|
||
*/
|
||
export function isMkApprovedStatus(bizType, approvalStatus) {
|
||
const conf = MK_BIZ[bizType];
|
||
if (!conf) return false;
|
||
return (conf.approved || []).includes(approvalStatus);
|
||
}
|
||
|
||
/**
|
||
* 提交 MK 审核流。未开启 MK 时直接跳过,不请求流程实例相关接口。
|
||
* @param {Object} options
|
||
* @param {string} options.bizType 业务类型
|
||
* @param {string|number} options.bizId 业务主键
|
||
* @param {string} [options.subjectName] 标题后缀
|
||
* @param {string} [options.approvalStatus] 提交前的审批状态
|
||
* @param {boolean} [options.mkEnabled] 调用方已知开关时传入,false 时立即跳过
|
||
* @returns {Promise<boolean>} true=已发起/复用 MK 流程,false=未开启或已跳过
|
||
*/
|
||
export async function submitMkApprovalFlow({
|
||
bizType,
|
||
bizId,
|
||
subjectName = '',
|
||
approvalStatus = '',
|
||
mkEnabled,
|
||
} = {}) {
|
||
const conf = MK_BIZ[bizType];
|
||
if (!conf) {
|
||
return Promise.reject(new Error(`不支持的MK业务类型:${bizType}`));
|
||
}
|
||
if (bizId == null || bizId === '') {
|
||
return Promise.reject(new Error('业务id不能为空'));
|
||
}
|
||
|
||
// 调用方显式关闭,或字典未开启:不请求 hasMkProcessInstance / processSubmit 等 MK 接口
|
||
if (mkEnabled === false) {
|
||
return false;
|
||
}
|
||
const enabled = mkEnabled === true ? true : await loadMkEnabled();
|
||
if (!enabled) {
|
||
return false;
|
||
}
|
||
|
||
const list = await loadMkTemplateList();
|
||
if (!isMkEnabled(list)) {
|
||
mkEnabledCache = false;
|
||
return false;
|
||
}
|
||
|
||
const bizIdText = String(bizId);
|
||
const forceNewFormInstance = isMkApprovedStatus(bizType, approvalStatus);
|
||
// 审核通过后再提交必须新建流程;其余场景已有有效实例则跳过
|
||
if (!forceNewFormInstance) {
|
||
const existsRes = await hasMkProcessInstance({ bizId: bizIdText });
|
||
if (existsRes?.data?.data) {
|
||
return true;
|
||
}
|
||
}
|
||
if ((conf.rejected || []).includes(approvalStatus)) {
|
||
await processDelete({ bizId: bizIdText });
|
||
}
|
||
const templateCode = await resolveMkTemplateCode(conf.dictName, list);
|
||
const subject = subjectName
|
||
? `${conf.subjectPrefix}:${subjectName}`
|
||
: `${conf.subjectPrefix}:${bizIdText}`;
|
||
await processSubmit({
|
||
templateCode,
|
||
bizId: bizIdText,
|
||
subject,
|
||
bizType,
|
||
forceNewFormInstance,
|
||
});
|
||
return true;
|
||
}
|