74f801a081
- 新增模块注册表 api 与进程内缓存(首次使用拉一次、并发共用同一个请求), 启用清单驱动「可新建审批链」的模块下拉与审核列表模块筛选 - reviewFlowConfigEdit 不再维护硬编码模块清单;停用模块的历史配置按 「标题(已停用)」回显,避免下拉空白 - module → detailKey 的映射收敛到 detailKeyOf 一处,moduleDetailConfig 未命中注册表时回退 module 本身(停用模块的详情仍可打开) - 审核流每级新增「审批人规则」输入(USER:<userId> / COLLEGE_ROLE:<roleCode>, 分号拼装多段,留空沿用「指定人」),随该级提交 reviewerRule 并回显 - 新增 scripts/selfcheck-module-registry.mjs:前端无单测基建时验证下拉过滤、 detailKey 回退与停用模块回显
86 lines
2.6 KiB
TypeScript
86 lines
2.6 KiB
TypeScript
/**
|
|
* 模块注册表的纯逻辑:选项构造、module → detailKey 映射、标题回退。
|
|
*
|
|
* 这里刻意不依赖 request / Vue,便于 scripts/selfcheck-module-registry.mjs
|
|
* 在无单测基建的前端仓库里直接验证行为。副作用(拉取与缓存)在
|
|
* src/utils/module-registry.ts。
|
|
*/
|
|
|
|
/** 注册表条目(与后端 ModuleRegistry 字段一致) */
|
|
export interface RegistryModule {
|
|
module?: string;
|
|
title?: string;
|
|
detailKey?: string;
|
|
enabled?: number;
|
|
sortNumber?: number;
|
|
}
|
|
|
|
/** 下拉选项 */
|
|
export interface ModuleOption {
|
|
label: string;
|
|
value: string;
|
|
}
|
|
|
|
/**
|
|
* 构造模块下拉选项:只含启用模块,按 sortNumber 升序,标题取注册表 title。
|
|
*
|
|
* 停用模块(enabled=0)不出现在「可新建审批链」的下拉里,历史数据仍可查,
|
|
* 见 docs/adr/0006-approval-chain-convergence.md。
|
|
*/
|
|
export const toModuleOptions = (list?: RegistryModule[]): ModuleOption[] => {
|
|
return (list || [])
|
|
.filter((item) => !!item.module && item.enabled === 1)
|
|
.slice()
|
|
.sort((a, b) => (a.sortNumber ?? 0) - (b.sortNumber ?? 0))
|
|
.map((item) => ({
|
|
label: item.title || item.module || '',
|
|
value: item.module || ''
|
|
}));
|
|
};
|
|
|
|
/**
|
|
* module → 详情页配置键(moduleDetailConfig.ts 的键)的唯一映射。
|
|
*
|
|
* 注册表里没有该模块时回退 module 本身:停用模块的历史审批链仍能打开详情,
|
|
* 而注册表的 detail_key 与 module 不一致时以注册表为准。
|
|
*/
|
|
export const resolveDetailKey = (
|
|
list: RegistryModule[] | undefined,
|
|
module?: string
|
|
): string | undefined => {
|
|
if (!module) {
|
|
return undefined;
|
|
}
|
|
const item = (list || []).find((entry) => entry.module === module);
|
|
return item?.detailKey || module;
|
|
};
|
|
|
|
/** 模块标题,注册表未命中时回退 module 本身,避免回显成空白 */
|
|
export const resolveModuleTitle = (
|
|
list: RegistryModule[] | undefined,
|
|
module?: string
|
|
): string | undefined => {
|
|
if (!module) {
|
|
return undefined;
|
|
}
|
|
const item = (list || []).find((entry) => entry.module === module);
|
|
return item?.title || module;
|
|
};
|
|
|
|
/**
|
|
* 编辑存量配置时把当前值补进下拉。
|
|
*
|
|
* 停用模块不在启用清单里,但历史审批链仍要回显标题而不是空白/裸 module 值,
|
|
* 因此按「标题(已停用)」补一项;已经在清单里则原样返回。
|
|
*/
|
|
export const ensureModuleOption = (
|
|
options: ModuleOption[],
|
|
module?: string,
|
|
moduleName?: string
|
|
): ModuleOption[] => {
|
|
if (!module || options.some((item) => item.value === module)) {
|
|
return options;
|
|
}
|
|
return [{ label: `${moduleName || module}(已停用)`, value: module }, ...options];
|
|
};
|