Bläddra i källkod

feat:完成安全组织体系管理左侧树与右侧图的联动

sunqijun 3 veckor sedan
förälder
incheckning
07e736e64a

+ 61 - 3
src/views/production-safety/productionSafetySystem/securityOrganizationalStructure/components/orgChart.vue

@@ -19,9 +19,16 @@
     children?: TreeData[];
   }
 
-  const props = defineProps<{
-    treeData: TreeData;
-  }>();
+  const props = withDefaults(
+    defineProps<{
+      treeData: TreeData;
+      /** 与左侧组织树选中的 orgId 一致(不含 `org-` 前缀),用于同步节点高亮 */
+      highlightOrgId?: string | number | null;
+    }>(),
+    {
+      highlightOrgId: null,
+    },
+  );
 
   const emits = defineEmits<{
     (event: 'node-click', nodeData: any): void;
@@ -32,6 +39,47 @@
   const container = ref<HTMLDivElement | null>(null); // 图表容器引用
   let graph: any = null;
   let pending = false; // 防止并发 initGraph
+  /** 上一次由外部同步高亮的图节点 id(`org-xxx`) */
+  let prevExternalHighlightNodeId: string | null = null;
+
+  function resolveGraphNodeId(raw: string | number | null | undefined): string | null {
+    if (raw === null || raw === undefined) return null;
+    const s = String(raw).trim();
+    if (!s) return null;
+    return s.startsWith('org-') ? s : `org-${s}`;
+  }
+
+  /** 根据左侧选中 orgId 同步节点 selected 状态(与 click-select 的 selected 样式一致) */
+  async function applyExternalHighlight() {
+    if (!graph) return;
+
+    const nextId = resolveGraphNodeId(props.highlightOrgId as string | number | null | undefined);
+
+    if (prevExternalHighlightNodeId && prevExternalHighlightNodeId !== nextId) {
+      try {
+        await graph.setElementState(prevExternalHighlightNodeId, []);
+      } catch {
+        /* 图重建过程中可能无效,忽略 */
+      }
+    }
+
+    if (!nextId) {
+      prevExternalHighlightNodeId = null;
+      return;
+    }
+
+    try {
+      const node = graph.getNodeData(nextId);
+      if (!node) {
+        prevExternalHighlightNodeId = null;
+        return;
+      }
+      await graph.setElementState(nextId, 'selected');
+      prevExternalHighlightNodeId = nextId;
+    } catch {
+      prevExternalHighlightNodeId = null;
+    }
+  }
 
   // 初始化图表
   const initGraph = async () => {
@@ -44,6 +92,7 @@
       graph.destroy();
       graph = null;
     }
+    prevExternalHighlightNodeId = null;
 
     // 等待下一帧,确保销毁完成
     await nextTick();
@@ -135,6 +184,7 @@
 
     // 渲染
     graph.render();
+    await applyExternalHighlight();
 
     // 监听节点点击事件
     graph.on(NodeEvent.CLICK, (evt) => {
@@ -171,6 +221,14 @@
     { deep: true },
   );
 
+  watch(
+    () => props.highlightOrgId,
+    async () => {
+      await nextTick();
+      await applyExternalHighlight();
+    },
+  );
+
   // 生命周期钩子
   onMounted(() => {
     data = treeToGraphData(props.treeData);

+ 10 - 4
src/views/production-safety/productionSafetySystem/securityOrganizationalStructure/securityOrganizationalStructure.vue

@@ -39,7 +39,11 @@
 
         <div class="chart" ref="chartContainerRef">
             <!-- 架构图 -->
-            <OrgChart :treeData="treeData" @node-click="handleNodeClick" />
+            <OrgChart
+              :treeData="treeData"
+              :highlight-org-id="selectedOrgId"
+              @node-click="handleNodeClick"
+            />
             <div class="chart-actions">
               <el-button v-if="!isChartFullscreen" size="small" @click="toggleChartZoom">
                 {{ isChartZoomed ? '恢复布局' : '放大模式' }}
@@ -223,7 +227,9 @@ const position = ref('left')
       const id = nodeData?.id?.replace('org-', '')
       console.log(nodeData, 'canshu')
     selectedTeamId.value = Number(id);
-
+    if (id !== undefined && id !== null && String(id) !== '') {
+      selectedOrgId.value = String(id);
+    }
     teamDetailDrawerRef.value?.drawerShow();
   };
 
@@ -401,7 +407,7 @@ const formatTreeData = (tree)=> {
       // 默认选择第一个组织
       if(res[0].orgId){
         treeNodePreview(res[0])
-        activeName.value = String(res[0].orgId)
+        //activeName.value = String(res[0].orgId)
         selectedOrgId.value = String(res[0].orgId)
         tableQuery.queryParam.classifyName = res[0].orgId
       }
@@ -454,7 +460,7 @@ const formatTreeData = (tree)=> {
   const querySafetyTeamData = (value) => {
     // console.log('查询', value);
     tableQuery.queryParam.classifyName = value.orgId;
-    activeName.value = String(value.orgId)
+    //activeName.value = String(value.orgId)
     selectedOrgId.value = String(value.orgId)
     treeNodePreview(value)
     safetyOrgDetail(value.orgId)