Files
tms-erp-web/src/utils/mk-approval.js
T

202 lines
6.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}