bowen
2023-10-12 f87e07840217af1bb059200eba04100e44c5d783
提交 | 用户 | age
d21578 1 import type { InsertNodeParams, KeyType, FieldNames, TreeItem } from '../types/tree';
e8ccdc 2 import type { Ref, ComputedRef } from 'vue';
72b42d 3 import type { TreeDataItem } from 'ant-design-vue/es/tree/Tree';
e8ccdc 4
V 5 import { cloneDeep } from 'lodash-es';
6 import { unref } from 'vue';
7 import { forEach } from '/@/utils/helper/treeHelper';
8
52257f 9 export function useTree(treeDataRef: Ref<TreeDataItem[]>, getFieldNames: ComputedRef<FieldNames>) {
cd8e92 10   function getAllKeys(list?: TreeDataItem[]) {
V 11     const keys: string[] = [];
12     const treeData = list || unref(treeDataRef);
52257f 13     const { key: keyField, children: childrenField } = unref(getFieldNames);
cd8e92 14     if (!childrenField || !keyField) return keys;
V 15
16     for (let index = 0; index < treeData.length; index++) {
17       const node = treeData[index];
18       keys.push(node[keyField]!);
19       const children = node[childrenField];
20       if (children && children.length) {
21         keys.push(...(getAllKeys(children) as string[]));
22       }
23     }
52257f 24     return keys as KeyType[];
cd8e92 25   }
3fcfac 26
ddd189 27   // get keys that can be checked and selected
28   function getEnabledKeys(list?: TreeDataItem[]) {
29     const keys: string[] = [];
30     const treeData = list || unref(treeDataRef);
52257f 31     const { key: keyField, children: childrenField } = unref(getFieldNames);
ddd189 32     if (!childrenField || !keyField) return keys;
33
34     for (let index = 0; index < treeData.length; index++) {
35       const node = treeData[index];
36       node.disabled !== true && node.selectable !== false && keys.push(node[keyField]!);
37       const children = node[childrenField];
38       if (children && children.length) {
39         keys.push(...(getEnabledKeys(children) as string[]));
40       }
41     }
52257f 42     return keys as KeyType[];
ddd189 43   }
cd8e92 44
52257f 45   function getChildrenKeys(nodeKey: string | number, list?: TreeDataItem[]) {
V 46     const keys: KeyType[] = [];
f70754 47     const treeData = list || unref(treeDataRef);
52257f 48     const { key: keyField, children: childrenField } = unref(getFieldNames);
f70754 49     if (!childrenField || !keyField) return keys;
50     for (let index = 0; index < treeData.length; index++) {
51       const node = treeData[index];
52       const children = node[childrenField];
53       if (nodeKey === node[keyField]) {
54         keys.push(node[keyField]!);
55         if (children && children.length) {
56           keys.push(...(getAllKeys(children) as string[]));
57         }
58       } else {
59         if (children && children.length) {
60           keys.push(...getChildrenKeys(nodeKey, children));
61         }
62       }
63     }
52257f 64     return keys as KeyType[];
f70754 65   }
66
72b42d 67   // Update node
f87e07 68   function updateNodeByKey(key: string, node: Omit<TreeDataItem, 'key'>, list?: TreeDataItem[]) {
e8ccdc 69     if (!key) return;
V 70     const treeData = list || unref(treeDataRef);
52257f 71     const { key: keyField, children: childrenField } = unref(getFieldNames);
e8ccdc 72
V 73     if (!childrenField || !keyField) return;
74
75     for (let index = 0; index < treeData.length; index++) {
76       const element: any = treeData[index];
77       const children = element[childrenField];
78
79       if (element[keyField] === key) {
80         treeData[index] = { ...treeData[index], ...node };
81         break;
82       } else if (children && children.length) {
83         updateNodeByKey(key, node, element[childrenField]);
84       }
85     }
86   }
87
72b42d 88   // Expand the specified level
V 89   function filterByLevel(level = 1, list?: TreeDataItem[], currentLevel = 1) {
e8ccdc 90     if (!level) {
V 91       return [];
92     }
93     const res: (string | number)[] = [];
94     const data = list || unref(treeDataRef) || [];
95     for (let index = 0; index < data.length; index++) {
f79cae 96       const item = data[index];
e8ccdc 97
52257f 98       const { key: keyField, children: childrenField } = unref(getFieldNames);
e8ccdc 99       const key = keyField ? item[keyField] : '';
V 100       const children = childrenField ? item[childrenField] : [];
101       res.push(key);
102       if (children && children.length && currentLevel < level) {
103         currentLevel += 1;
104         res.push(...filterByLevel(level, children, currentLevel));
105       }
106     }
107     return res as string[] | number[];
108   }
109
110   /**
111    * 添加节点
112    */
113   function insertNodeByKey({ parentKey = null, node, push = 'push' }: InsertNodeParams) {
114     const treeData: any = cloneDeep(unref(treeDataRef));
115     if (!parentKey) {
116       treeData[push](node);
117       treeDataRef.value = treeData;
118       return;
119     }
52257f 120     const { key: keyField, children: childrenField } = unref(getFieldNames);
e8ccdc 121     if (!childrenField || !keyField) return;
V 122
123     forEach(treeData, (treeItem) => {
124       if (treeItem[keyField] === parentKey) {
125         treeItem[childrenField] = treeItem[childrenField] || [];
126         treeItem[childrenField][push](node);
d97aa9 127         return true;
e8ccdc 128       }
V 129     });
130     treeDataRef.value = treeData;
131   }
d97aa9 132   /**
B 133    * 批量添加节点
134    */
135   function insertNodesByKey({ parentKey = null, list, push = 'push' }: InsertNodeParams) {
136     const treeData: any = cloneDeep(unref(treeDataRef));
137     if (!list || list.length < 1) {
138       return;
139     }
140     if (!parentKey) {
141       for (let i = 0; i < list.length; i++) {
142         treeData[push](list[i]);
143       }
cfbd5e 144       treeDataRef.value = treeData;
Z 145       return;
d97aa9 146     } else {
52257f 147       const { key: keyField, children: childrenField } = unref(getFieldNames);
d97aa9 148       if (!childrenField || !keyField) return;
e8ccdc 149
d97aa9 150       forEach(treeData, (treeItem) => {
B 151         if (treeItem[keyField] === parentKey) {
152           treeItem[childrenField] = treeItem[childrenField] || [];
153           for (let i = 0; i < list.length; i++) {
154             treeItem[childrenField][push](list[i]);
155           }
156           treeDataRef.value = treeData;
157           return true;
158         }
159       });
160     }
161   }
72b42d 162   // Delete node
V 163   function deleteNodeByKey(key: string, list?: TreeDataItem[]) {
e8ccdc 164     if (!key) return;
V 165     const treeData = list || unref(treeDataRef);
52257f 166     const { key: keyField, children: childrenField } = unref(getFieldNames);
e8ccdc 167     if (!childrenField || !keyField) return;
V 168
169     for (let index = 0; index < treeData.length; index++) {
170       const element: any = treeData[index];
171       const children = element[childrenField];
172
173       if (element[keyField] === key) {
174         treeData.splice(index, 1);
175         break;
176       } else if (children && children.length) {
177         deleteNodeByKey(key, element[childrenField]);
178       }
179     }
180   }
5ad93c 181
C 182   // Get selected node
183   function getSelectedNode(key: KeyType, list?: TreeItem[], selectedNode?: TreeItem | null) {
184     if (!key && key !== 0) return null;
185     const treeData = list || unref(treeDataRef);
8d218e 186     const { key: keyField, children: childrenField } = unref(getFieldNames);
f87e07 187     if (!keyField) return null;
5ad93c 188     treeData.forEach((item) => {
C 189       if (selectedNode?.key || selectedNode?.key === 0) return selectedNode;
8d218e 190       if (item[keyField] === key) {
5ad93c 191         selectedNode = item;
C 192         return;
193       }
8d218e 194       if (item[childrenField!] && item[childrenField!].length) {
J 195         selectedNode = getSelectedNode(key, item[childrenField!], selectedNode);
5ad93c 196       }
C 197     });
198     return selectedNode || null;
199   }
d97aa9 200   return {
B 201     deleteNodeByKey,
202     insertNodeByKey,
203     insertNodesByKey,
204     filterByLevel,
205     updateNodeByKey,
206     getAllKeys,
f70754 207     getChildrenKeys,
ddd189 208     getEnabledKeys,
5ad93c 209     getSelectedNode,
d97aa9 210   };
e8ccdc 211 }