Ver código fonte

fix(岗位调动): 机构名称优先取接口返回值,缺失时用快照与组织单查补全

lihaiting 1 dia atrás
pai
commit
bf17580aea

+ 92 - 31
src/views/bpm/handleTask/components/positionTransfer/positionTransferDetail.vue

@@ -77,7 +77,7 @@
 
 <script>
 import { getUserChangeById } from '@/api/main';
-import { listOrganizations, adaptEmployee, getEmployeeById } from '@/api/organization';
+import { listOrganizations, getOrganization, adaptEmployee, getEmployeeById } from '@/api/organization';
 import { getDictByCode } from '@/api/sys';
 import { parseAttachmentIds } from '@/utils/attachment';
 
@@ -136,6 +136,7 @@ const empty = () => ({
   contractPeriod: '',
   // 变更信息
   targetLegalId: null,
+  targetLegalName: '',
   targetDeptId: null,
   targetDept: '',
   positionSequence: '',
@@ -260,22 +261,28 @@ export default {
       this.loading = true;
       try {
         const record = await getUserChangeById(id);
-        // 异动单只带 userId:并行补查员工档案与组织列表
-        const [employee] = await Promise.all([
-          this.fetchEmployee(record),
-          this.loadOrganizations(),
-          this.loadPositionNatureOptions()
-        ]);
-        this.form = this.mapForm(record, employee);
+        // 主数据先行渲染,补查(员工/组织/字典)失败不阻断、不清空
+        this.form = this.mapForm(record, null);
         // 兼容多种附件字段来源(attachmentIds / approvalDocumentFileId 等)
         this.approvalFileIds = parseAttachmentIds(record);
+        try {
+          // 异动单只带 userId:并行补查员工档案与组织列表
+          const [employee] = await Promise.all([
+            this.fetchEmployee(record),
+            this.loadOrganizations(),
+            this.loadPositionNatureOptions()
+          ]);
+          this.form = this.mapForm(record, employee);
+        } catch (error) {
+          // 补查失败:保留已解析的主数据继续展示
+        }
+        // 组织树查不到机构名时,按 id 单查补全
+        this.ensureLegalName(this.form.targetLegalId);
       } catch (error) {
         this.form = empty();
         this.approvalFileIds = [];
-        if (process.env.NODE_ENV !== 'production') {
-          // eslint-disable-next-line no-console
-          console.warn('[PositionTransferDetail] 加载岗位变更单失败:', error);
-        }
+        // eslint-disable-next-line no-console
+        console.warn('[PositionTransferDetail] 加载岗位变更单失败:', error);
       } finally {
         this.loading = false;
       }
@@ -296,21 +303,28 @@ export default {
     async loadOrganizations() {
       try {
         const res = await listOrganizations();
-        const list = Array.isArray(res)
+        const raw = Array.isArray(res)
           ? res
           : (res && (res.list || res.records || res.rows)) || [];
-        this.orgList = list
-          .filter(item => item && item.id != null && item.id !== '')
-          .map(item => ({
-            id: String(item.id),
-            name: item.name || '',
-            parentId:
-              item.parentId != null && item.parentId !== ''
-                ? String(item.parentId)
-                : '',
-            type: item.type
-          }))
-          .filter(item => item.name);
+        // getGroupList 返回树形(含 children),需递归展开为平铺列表
+        const flat = [];
+        const walk = nodes => {
+          (Array.isArray(nodes) ? nodes : []).forEach(item => {
+            if (!item || item.id == null || item.id === '') return;
+            flat.push({
+              id: String(item.id),
+              name: item.name || '',
+              parentId:
+                item.parentId != null && item.parentId !== ''
+                  ? String(item.parentId)
+                  : '',
+              type: item.type
+            });
+            if (item.children && item.children.length) walk(item.children);
+          });
+        };
+        walk(raw);
+        this.orgList = flat.filter(item => item.name);
       } catch (error) {
         this.orgList = [];
       }
@@ -409,9 +423,29 @@ export default {
           .filter(Boolean)
           .map(toDateStr)
           .join(' 至 '),
-        // 变更信息
-        targetLegalId: first(record.targetLegalId) || null,
-        targetDeptId: first(record.targetDeptId) || null,
+        // 变更信息:机构来自 beforeSnapshot / afterSnapshot(接口无顶层机构字段)
+        targetLegalId: first(
+          record.targetLegalId,
+          record.targetOrganizationId,
+          record.toOrganizationId,
+          record.toLegalId,
+          record.organizationId,
+          record.legalEntityId,
+          after.legalId,
+          before.legalId
+        ) || null,
+        // 机构名:接口/快照直接返回的名字优先,避免依赖组织树回显
+        targetLegalName: first(
+          record.targetLegalName,
+          record.targetOrganizationName,
+          record.toLegalName,
+          record.toOrganizationName,
+          record.organizationName,
+          record.legalEntityName,
+          after.legalName,
+          before.legalName
+        ) || '',
+        targetDeptId: first(record.targetDeptId, after.deptId, before.deptId) || null,
         targetDept: first(
           record.targetDeptName,
           record.targetDept,
@@ -467,13 +501,15 @@ export default {
       if (explicit) return explicit;
       return onlineDocumentTemplateId ? 'online' : 'offline';
     },
-    /** 员工所属机构:档案机构 → 部门上溯顶层机构 */
+    /** 员工所属机构:档案机构 → 快照机构 → 部门上溯顶层机构 */
     resolveOriginLegal(record, employee) {
       const emp = employee || {};
+      const before = parseSnapshot(record && record.beforeSnapshot);
       const explicit = first(
         emp.company,
         emp.legalEntity,
-        emp.raw && emp.raw.groupName
+        emp.raw && emp.raw.groupName,
+        before.legalName
       );
       if (explicit) return explicit;
       const legalId = this.findLegalIdByDept(
@@ -501,13 +537,38 @@ export default {
       );
       return (legal && legal.id) || node.id;
     },
-    /** 机构名称:组织列表优先,缺失时按部门上溯,兜底原始 id */
+    /** 机构名称:接口直接返回的机构名优先,其次组织树查询,兜底原始 id */
     legalName(id) {
+      if (this.form.targetLegalName) return this.form.targetLegalName;
       const target =
         id == null || id === '' ? this.findLegalIdByDept(this.form.targetDeptId) : id;
       if (target == null || target === '') return '-';
       const node = this.orgList.find(item => String(item.id) === String(target));
       return (node && node.name) || String(target);
+    },
+    /** 组织树查不到机构名时,按 id 单查补全(不阻塞渲染) */
+    async ensureLegalName(id) {
+      if (id == null || id === '' || this.form.targetLegalName) return;
+      if (this.orgList.some(item => String(item.id) === String(id))) return;
+      try {
+        const node = await getOrganization(id);
+        if (node && node.name) {
+          this.orgList = [
+            ...this.orgList,
+            {
+              id: String(node.id != null ? node.id : id),
+              name: node.name,
+              parentId:
+                node.parentId != null && node.parentId !== ''
+                  ? String(node.parentId)
+                  : '',
+              type: node.type
+            }
+          ];
+        }
+      } catch (error) {
+        // 单查失败不影响其它字段展示
+      }
     }
   }
 };