Files
supervision-test-frontend-repo/src/composables/useSelectNameResolver.ts
T
wsm 4df8b3e31d !74 fix(bpm): 修复选人组件 Name 翻译使用错误字段及查询顺序问题
* fix(bpm): 修复选人组件 Name 翻译使用错误字段及查询顺序问题
* feat(bpm): 默认审批意见改为完全由后端节点配置驱动,移除所有写死模板
* fix(bpm): 修复节点默认审批意见配置 UI 绑定错误,支持 extraVars 变量解析
* feat(bpm): 新增条件变量默认审批意见,支持按流程变量值动态预填审批意见
2026-07-01 11:07:18 +00:00

109 lines
4.2 KiB
TypeScript

import { queryDepartTreeSync, getUserList } from '/@/api/common/api';
interface NameFieldConfig {
/** Names 后缀的基础字段名,如 'measureResDept' → 写入 target['measureResDeptNames'] */
field: string;
/** 'dept' | 'user' */
type: 'dept' | 'user';
/** 自定义取值器,默认读取 target[field] */
getValue?: () => string;
}
function flatDeptTree(list: any[]): Record<string, string> {
const map: Record<string, string> = {};
for (const item of list) {
if (item.id && item.departName) {
map[item.id] = item.departName;
}
if (item.children?.length) {
Object.assign(map, flatDeptTree(item.children));
}
}
return map;
}
/**
* 选人/选部门字段名称翻译器。
* - resolveAll() 通过 API 批量翻译,在表单数据加载后调用
* - selectHandler(field) 生成 @select 事件处理器,用于运行时更新
*/
export function useSelectNameResolver(
target: Record<string, any>,
configs: NameFieldConfig[]
) {
async function resolveAll() {
try {
const deptConfigs = configs.filter(c => c.type === 'dept');
const userConfigs = configs.filter(c => c.type === 'user');
if (deptConfigs.length) {
// 收集所有 dept IDs
const allDeptIds = new Set<string>();
for (const c of deptConfigs) {
const val = c.getValue ? c.getValue() : target[c.field];
const ids = String(val || '').split(',').map((s: string) => s.trim()).filter(Boolean);
ids.forEach(id => allDeptIds.add(id));
}
if (allDeptIds.size) {
const tree = await queryDepartTreeSync({ ids: [...allDeptIds].join(',') });
const deptMap = flatDeptTree(tree || []);
for (const c of deptConfigs) {
const val = c.getValue ? c.getValue() : target[c.field];
const ids = String(val || '').split(',').map((s: string) => s.trim()).filter(Boolean);
target[c.field + 'Names'] = ids.map(id => deptMap[id] || id).join('、');
}
}
}
if (userConfigs.length) {
const allUserIds = new Set<string>();
for (const c of userConfigs) {
const val = c.getValue ? c.getValue() : target[c.field];
const ids = String(val || '').split(',').map((s: string) => s.trim()).filter(Boolean);
ids.forEach(id => allUserIds.add(id));
}
if (allUserIds.size) {
const idList = [...allUserIds];
const userMap: Record<string, string> = {};
// 先按 id 查
const idRes = await getUserList({ id: idList.join(','), isMultiTranslate: 'true', pageNo: 1, pageSize: 999 });
const idRecords = idRes?.records || idRes?.result?.records || [];
for (const u of idRecords) {
if (u.id && u.realname) userMap[String(u.id)] = u.realname;
if (u.username && u.realname) userMap[u.username] = u.realname;
}
// 未匹配到的再按 username 查
const unmatched = idList.filter(id => !userMap[id]);
if (unmatched.length) {
const nameRes = await getUserList({ username: unmatched.join(','), isMultiTranslate: 'true', pageNo: 1, pageSize: 999 });
const nameRecords = nameRes?.records || nameRes?.result?.records || [];
for (const u of nameRecords) {
if (u.username && u.realname) userMap[u.username] = u.realname;
}
}
for (const c of userConfigs) {
const val = c.getValue ? c.getValue() : target[c.field];
const ids = String(val || '').split(',').map((s: string) => s.trim()).filter(Boolean);
target[c.field + 'Names'] = ids.map(id => userMap[id] || id).join('、');
}
}
}
} catch (e) {
console.warn('【Name解析】resolveAll 翻译失败,占位符将显示 ID:', e);
}
}
function selectHandler(field: string) {
const cfg = configs.find(c => c.field === field);
const nameKey = cfg?.type === 'user' ? 'realname' : cfg?.type === 'dept' ? 'departName' : 'label';
return (options: Array<Record<string, any>>) => {
target[field + 'Names'] = options?.length ? options.map(o => o[nameKey] || o.label || '').join('、') : '';
};
}
return { resolveAll, selectHandler };
}