Procházet zdrojové kódy

perf(views): 完善"组织架构"组件基本逻辑

wangshun před 2 týdny
rodič
revize
a7c5114f94
1 změnil soubory, kde provedl 84 přidání a 27 odebrání
  1. 84 27
      src/components/OrganizationalStructure.vue

+ 84 - 27
src/components/OrganizationalStructure.vue

@@ -1,27 +1,70 @@
 <script setup lang="ts">
-import { ref } from 'vue';
-
-import type { DataNode } from 'ant-design-vue/es/tree';
-
-const treeStructure = ref<DataNode[]>([
-  {
-    title: '父节点 1',
-    key: '0-0',
-    children: [
-      {
-        title: '子节点 1',
-        key: '0-0-0',
-        children: [
-          { title: '孙子节点 1', key: '0-0-0-0' },
-          { title: '孙子节点 2', key: '0-0-0-1' },
-        ],
-      },
-      { title: '子节点 2', key: '0-0-1' },
-    ],
-  },
-]);
-const expandedKeys = ref<string[]>(['0-0', '0-0-0']); // 初始展开父节点
-const addMenu = () => {};
+import { onMounted, ref } from 'vue';
+
+import { useRequest } from '@/hooks/request';
+import { getSubOrgsByToken } from '@/api';
+
+import type { DataNode, TreeProps } from 'ant-design-vue/es/tree';
+import type { Organization } from '@/types';
+
+const treeStructure = ref<DataNode[]>([]);
+const { handleRequest } = useRequest();
+const expandedKeys = ref<number[]>([]); // 初始展开父节点
+const selectedKeys = ref<number[]>([]); // 选中的节点
+
+const fieldNames: TreeProps['fieldNames'] = {
+  children: 'subOrgs',
+  title: 'orgName',
+  key: 'id',
+};
+
+const emit = defineEmits<{
+  change: [id: number];
+}>();
+const transformTreeData = (data: Organization[]): DataNode[] => {
+  return data.map((item) => ({
+    ...item,
+    key: item.id, // 关键:将 id 映射到 key
+    title: item.orgName,
+    children: item.subOrgs ? transformTreeData(item.subOrgs) : undefined,
+  }));
+};
+
+const getParentIds = (nodes: Organization[]): number[] => {
+  const parentIds: number[] = [];
+
+  const traverse = (node: Organization) => {
+    // 判断是否为有效父节点:存在子节点且非空数组
+    if (node.subOrgs?.length) {
+      parentIds.push(node.id);
+      // 继续遍历子节点
+      node.subOrgs.forEach((child) => traverse(child));
+    }
+  };
+
+  nodes.forEach((node) => traverse(node));
+  return parentIds;
+};
+
+const addMenu = () => {
+  if (selectedKeys.value.length) {
+    emit('change', selectedKeys.value[0]);
+  } else {
+    emit('change', treeStructure.value[0].id);
+    selectedKeys.value.push(treeStructure.value[0].id);
+  }
+};
+
+onMounted(() => {
+  selectedKeys.value = [];
+  handleRequest(async () => {
+    const data = await getSubOrgsByToken();
+    treeStructure.value = transformTreeData(data);
+    expandedKeys.value = getParentIds(data);
+    selectedKeys.value.push(data[0].id);
+    emit('change', data[0].id);
+  });
+});
 </script>
 
 <template>
@@ -30,10 +73,12 @@ const addMenu = () => {};
       <div class="content-text">组织架构</div>
       <ATree
         v-model:expanded-keys="expandedKeys"
+        v-model:selected-keys="selectedKeys"
         :tree-data="treeStructure"
         block-node
-        @check="addMenu"
+        @select="addMenu"
         class="tree-organization"
+        :field-names="fieldNames"
       />
     </div>
   </div>
@@ -41,13 +86,25 @@ const addMenu = () => {};
 
 <style lang="scss" scoped>
 :deep(.content) {
-  .ant-tree .ant-tree-treenode {
-    margin-bottom: 6px;
+  .ant-tree-list-holder-inner > div {
+    display: flex;
+    align-items: center;
+    width: 100%;
+    height: 40px;
+    padding-left: 5px;
+  }
+
+  .ant-tree-list-holder-inner > div > .ant-tree-checkbox {
+    margin-block-start: 0;
+  }
+
+  .ant-tree-list-holder-inner > div > .ant-tree-switcher > span {
+    margin-top: 13px;
   }
 }
 
 .content-text {
-  margin-bottom: 25px;
+  margin-bottom: 16px;
   font-size: 16px;
   font-style: normal;
   font-weight: 600;