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} 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; }