From 4df8b3e31d7af6e34a0904f59deb703ddfccd421 Mon Sep 17 00:00:00 2001 From: wsm <8454518+new-twice@user.noreply.gitee.com> Date: Wed, 1 Jul 2026 11:07:18 +0000 Subject: [PATCH] =?UTF-8?q?!74=20fix(bpm):=20=E4=BF=AE=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E4=BA=BA=E7=BB=84=E4=BB=B6=20Name=20=E7=BF=BB=E8=AF=91?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E9=94=99=E8=AF=AF=E5=AD=97=E6=AE=B5=E5=8F=8A?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E9=A1=BA=E5=BA=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(bpm): 修复选人组件 Name 翻译使用错误字段及查询顺序问题 * feat(bpm): 默认审批意见改为完全由后端节点配置驱动,移除所有写死模板 * fix(bpm): 修复节点默认审批意见配置 UI 绑定错误,支持 extraVars 变量解析 * feat(bpm): 新增条件变量默认审批意见,支持按流程变量值动态预填审批意见 --- .../Form/src/jeecg/components/JSelectUser.vue | 11 +- src/composables/useSelectNameResolver.ts | 108 ++++++++++++++ .../xispeak/components/BgXiSpeakBPMForm.vue | 14 +- .../components/DqInspectTaskBPMForm.vue | 140 +++++++++--------- .../myHandleTask/content/MyHandleContent.vue | 27 +++- .../content/TaskHandleInnerContent.vue | 32 +++- .../processNode/ProcessNodeList.vue | 4 +- .../processNode/ProcessNodeModal.vue | 46 +++++- .../processNode/process.node.data.ts | 25 ++++ .../processNodeAuth/NodeAuthEasyModal.vue | 1 + 10 files changed, 326 insertions(+), 82 deletions(-) create mode 100644 src/composables/useSelectNameResolver.ts 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 @@