|
@@ -1,27 +1,70 @@
|
|
<script setup lang="ts">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<template>
|
|
<template>
|
|
@@ -30,10 +73,12 @@ const addMenu = () => {};
|
|
<div class="content-text">组织架构</div>
|
|
<div class="content-text">组织架构</div>
|
|
<ATree
|
|
<ATree
|
|
v-model:expanded-keys="expandedKeys"
|
|
v-model:expanded-keys="expandedKeys"
|
|
|
|
+ v-model:selected-keys="selectedKeys"
|
|
:tree-data="treeStructure"
|
|
:tree-data="treeStructure"
|
|
block-node
|
|
block-node
|
|
- @check="addMenu"
|
|
|
|
|
|
+ @select="addMenu"
|
|
class="tree-organization"
|
|
class="tree-organization"
|
|
|
|
+ :field-names="fieldNames"
|
|
/>
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@@ -41,13 +86,25 @@ const addMenu = () => {};
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
:deep(.content) {
|
|
: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 {
|
|
.content-text {
|
|
- margin-bottom: 25px;
|
|
|
|
|
|
+ margin-bottom: 16px;
|
|
font-size: 16px;
|
|
font-size: 16px;
|
|
font-style: normal;
|
|
font-style: normal;
|
|
font-weight: 600;
|
|
font-weight: 600;
|