✨ 新增导入结算单页面,并优化 MK 开关缓存与客商同步入口

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-16 00:56:55 +08:00
parent a19097d1be
commit c5a74acd00
22 changed files with 1891 additions and 55 deletions
+65 -13
View File
@@ -61,9 +61,18 @@ export const MK_BIZ = {
const MK_SWITCH_NAME = '开启MK';
async function loadMkTemplateList() {
/** 进程内缓存,避免每次提交都打字典;登录后同一会话开关一般不变 */
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' });
return res?.data?.data || [];
mkTemplateListCache = res?.data?.data || [];
return mkTemplateListCache;
}
/** 业务字典 mk_template:名称「开启MK」且键值为 1 时才请求 MK */
@@ -72,10 +81,37 @@ export function isMkEnabled(list = []) {
return String(matched?.dictKey ?? '').trim() === '1';
}
/** 加载业务字典并判断是否开启 MK */
export async function loadMkEnabled() {
const list = await loadMkTemplateList();
return isMkEnabled(list);
/** 清除 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) {
@@ -99,19 +135,22 @@ export function isMkApprovedStatus(bizType, approvalStatus) {
}
/**
* 提交 MK 审核流
* 提交 MK 审核流。未开启 MK 时直接跳过,不请求流程实例相关接口。
* @param {Object} options
* @param {string} options.bizType 业务类型
* @param {string|number} options.bizId 业务主键(后端据此生成/复用 formInstanceId)
* @param {string|number} options.bizId 业务主键
* @param {string} [options.subjectName] 标题后缀
* @param {string} [options.approvalStatus] 提交前的审批状态(须在业务 submit 改状态前取值;通过态强制新建实例)
* @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}`));
@@ -119,17 +158,29 @@ export async function submitMkApprovalFlow({
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)) {
return;
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;
return true;
}
}
if ((conf.rejected || []).includes(approvalStatus)) {
@@ -139,11 +190,12 @@ export async function submitMkApprovalFlow({
const subject = subjectName
? `${conf.subjectPrefix}:${subjectName}`
: `${conf.subjectPrefix}:${bizIdText}`;
return processSubmit({
await processSubmit({
templateCode,
bizId: bizIdText,
subject,
bizType,
forceNewFormInstance,
});
return true;
}