diff --git a/src/components/Form/src/jeecg/components/JSelectUser.vue b/src/components/Form/src/jeecg/components/JSelectUser.vue index 4418dd2..2967082 100644 --- a/src/components/Form/src/jeecg/components/JSelectUser.vue +++ b/src/components/Form/src/jeecg/components/JSelectUser.vue @@ -56,7 +56,7 @@ }, //update-end---author:wangshuai ---date:20230703 for:【QQYUN-5685】5、离职人员可以选自己------------ }, - emits: ['options-change', 'change', 'update:value'], + emits: ['options-change', 'change', 'select', 'update:value'], setup(props, { emit }) { const emitData = ref(); //注册model @@ -99,6 +99,15 @@ } }); + /** + * 监听selectOptions变化,对外暴露选中的 option 对象 + */ + watch(selectOptions, () => { + if (selectOptions.value) { + emit('select', toRaw(unref(selectOptions)), toRaw(unref(selectValues))); + } + }); + /** * 监听selectValues变化 */ diff --git a/src/composables/useSelectNameResolver.ts b/src/composables/useSelectNameResolver.ts new file mode 100644 index 0000000..3b5f1cf --- /dev/null +++ b/src/composables/useSelectNameResolver.ts @@ -0,0 +1,108 @@ +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 { + const map: Record = {}; + 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, + 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(); + 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(); + 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 = {}; + + // 先按 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>) => { + target[field + 'Names'] = options?.length ? options.map(o => o[nameKey] || o.label || '').join('、') : ''; + }; + } + + return { resolveAll, selectHandler }; +} diff --git a/src/views/bg/xispeak/components/BgXiSpeakBPMForm.vue b/src/views/bg/xispeak/components/BgXiSpeakBPMForm.vue index 35b5a5f..90bcdcd 100644 --- a/src/views/bg/xispeak/components/BgXiSpeakBPMForm.vue +++ b/src/views/bg/xispeak/components/BgXiSpeakBPMForm.vue @@ -266,7 +266,7 @@