sculp-js 1.13.4 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/cjs/_virtual/_commonjsHelpers.js +3 -3
- package/dist/cjs/array.js +36 -46
- package/dist/cjs/async.js +41 -43
- package/dist/cjs/base64.js +77 -66
- package/dist/cjs/clipboard.js +54 -53
- package/dist/cjs/cloneDeep.js +90 -91
- package/dist/cjs/cookie.js +27 -30
- package/dist/cjs/date.js +101 -98
- package/dist/cjs/dom.js +114 -121
- package/dist/cjs/download.js +77 -78
- package/dist/cjs/easing.js +29 -32
- package/dist/cjs/file.js +147 -152
- package/dist/cjs/func.js +64 -78
- package/dist/cjs/index.js +3 -3
- package/dist/cjs/math.js +32 -38
- package/dist/cjs/node_modules/bezier-easing/src/index.js +35 -23
- package/dist/cjs/number.js +56 -61
- package/dist/cjs/object.js +112 -126
- package/dist/cjs/path.js +39 -43
- package/dist/cjs/qs.js +34 -41
- package/dist/cjs/random.js +31 -34
- package/dist/cjs/string.js +62 -63
- package/dist/cjs/tooltip.js +66 -69
- package/dist/cjs/tree.js +329 -258
- package/dist/cjs/type.js +42 -46
- package/dist/cjs/unique.js +39 -42
- package/dist/cjs/url.js +47 -48
- package/dist/cjs/validator.js +38 -38
- package/dist/cjs/variable.js +27 -21
- package/dist/cjs/watermark.js +78 -67
- package/dist/esm/array.js +36 -46
- package/dist/esm/async.js +41 -43
- package/dist/esm/base64.js +77 -66
- package/dist/esm/clipboard.js +55 -54
- package/dist/esm/cloneDeep.js +90 -91
- package/dist/esm/cookie.js +27 -30
- package/dist/esm/date.js +101 -98
- package/dist/esm/dom.js +114 -121
- package/dist/esm/download.js +78 -79
- package/dist/esm/easing.js +29 -32
- package/dist/esm/file.js +147 -152
- package/dist/esm/func.js +64 -78
- package/dist/esm/index.js +106 -9
- package/dist/esm/math.js +32 -38
- package/dist/esm/number.js +57 -62
- package/dist/esm/object.js +124 -127
- package/dist/esm/path.js +39 -43
- package/dist/esm/qs.js +34 -41
- package/dist/esm/random.js +31 -34
- package/dist/esm/string.js +74 -64
- package/dist/esm/tooltip.js +66 -69
- package/dist/esm/tree.js +329 -260
- package/dist/esm/type.js +68 -47
- package/dist/esm/unique.js +39 -42
- package/dist/esm/url.js +47 -48
- package/dist/esm/validator.js +56 -39
- package/dist/esm/variable.js +27 -21
- package/dist/esm/watermark.js +79 -68
- package/dist/types/tree.d.ts +36 -0
- package/dist/umd/index.min.js +2 -2
- package/package.json +11 -7
package/dist/cjs/tree.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v1.
|
|
2
|
+
* sculp-js v1.14.0
|
|
3
3
|
* (c) 2023-present chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -11,10 +11,10 @@ var type = require('./type.js');
|
|
|
11
11
|
|
|
12
12
|
const defaultFieldOptions = { keyField: 'key', childField: 'children', pidField: 'pid' };
|
|
13
13
|
const defaultSearchTreeOptions = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
childField: 'children',
|
|
15
|
+
nameField: 'name',
|
|
16
|
+
removeEmptyChild: false,
|
|
17
|
+
ignoreCase: true
|
|
18
18
|
};
|
|
19
19
|
/**
|
|
20
20
|
* 树遍历函数(支持continue和break操作), 可用于遍历Array和NodeList类型的数据
|
|
@@ -28,106 +28,177 @@ const defaultSearchTreeOptions = {
|
|
|
28
28
|
}
|
|
29
29
|
* @returns {*}
|
|
30
30
|
*/
|
|
31
|
-
function forEachDeep(
|
|
31
|
+
function forEachDeep(
|
|
32
|
+
tree,
|
|
33
|
+
iterator,
|
|
34
|
+
options = {
|
|
32
35
|
childField: 'children',
|
|
33
36
|
reverse: false,
|
|
34
37
|
breadthFirst: false,
|
|
35
38
|
isDomNode: false
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
39
|
+
}
|
|
40
|
+
) {
|
|
41
|
+
const {
|
|
42
|
+
childField = 'children',
|
|
43
|
+
reverse = false,
|
|
44
|
+
breadthFirst = false,
|
|
45
|
+
isDomNode = false
|
|
46
|
+
} = type.isObject(options) ? options : {};
|
|
47
|
+
let isBreak = false;
|
|
48
|
+
const queue = [];
|
|
49
|
+
const reverseWalk = (arr, parent, level = 0) => {
|
|
50
|
+
for (let index = arr.length - 1; index >= 0; index--) {
|
|
51
|
+
if (isBreak) {
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
const item = arr[index];
|
|
55
|
+
// 广度优先
|
|
56
|
+
if (breadthFirst) {
|
|
57
|
+
queue.push({ item, index, array: arr, tree, parent, level });
|
|
58
|
+
} else {
|
|
59
|
+
const re = iterator(item, index, arr, tree, parent, level);
|
|
60
|
+
if (re === false) {
|
|
61
|
+
isBreak = true;
|
|
62
|
+
break;
|
|
63
|
+
} else if (re === true) {
|
|
64
|
+
continue;
|
|
63
65
|
}
|
|
64
|
-
if (
|
|
65
|
-
|
|
66
|
-
while (queue.length > 0 && !isBreak) {
|
|
67
|
-
const current = queue.shift();
|
|
68
|
-
const { item, index, array, tree, parent, level } = current;
|
|
69
|
-
const re = iterator(item, index, array, tree, parent, level);
|
|
70
|
-
if (re === false) {
|
|
71
|
-
isBreak = true;
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
else if (re === true) {
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
if (item && (isDomNode ? type.isNodeList(item[childField]) : Array.isArray(item[childField]))) {
|
|
78
|
-
reverseWalk(item[childField], item, level + 1);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
66
|
+
if (item && (isDomNode ? type.isNodeList(item[childField]) : Array.isArray(item[childField]))) {
|
|
67
|
+
reverseWalk(item[childField], item, level + 1);
|
|
81
68
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const re = iterator(item, index, arr, tree, parent, level);
|
|
96
|
-
if (re === false) {
|
|
97
|
-
isBreak = true;
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
else if (re === true) {
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
if (item && (isDomNode ? type.isNodeList(item[childField]) : Array.isArray(item[childField]))) {
|
|
104
|
-
walk(item[childField], item, level + 1);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (breadthFirst) {
|
|
72
|
+
// Process queue
|
|
73
|
+
while (queue.length > 0 && !isBreak) {
|
|
74
|
+
const current = queue.shift();
|
|
75
|
+
const { item, index, array, tree, parent, level } = current;
|
|
76
|
+
const re = iterator(item, index, array, tree, parent, level);
|
|
77
|
+
if (re === false) {
|
|
78
|
+
isBreak = true;
|
|
79
|
+
break;
|
|
80
|
+
} else if (re === true) {
|
|
81
|
+
continue;
|
|
107
82
|
}
|
|
108
|
-
if (
|
|
109
|
-
|
|
110
|
-
const current = queue.shift();
|
|
111
|
-
if (!current)
|
|
112
|
-
break;
|
|
113
|
-
const { item, index, array, tree, parent, level } = current;
|
|
114
|
-
const re = iterator(item, index, array, tree, parent, level);
|
|
115
|
-
if (re === false) {
|
|
116
|
-
isBreak = true;
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
else if (re === true) {
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
if (item && (isDomNode ? type.isNodeList(item[childField]) : Array.isArray(item[childField]))) {
|
|
123
|
-
walk(item[childField], item, level + 1);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
83
|
+
if (item && (isDomNode ? type.isNodeList(item[childField]) : Array.isArray(item[childField]))) {
|
|
84
|
+
reverseWalk(item[childField], item, level + 1);
|
|
126
85
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const walk = (arr, parent, level = 0) => {
|
|
90
|
+
for (let index = 0, len = arr.length; index < len; index++) {
|
|
91
|
+
if (isBreak) {
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
const item = arr[index];
|
|
95
|
+
if (breadthFirst) {
|
|
96
|
+
// 广度优先
|
|
97
|
+
queue.push({ item, index: index, array: arr, tree, parent, level });
|
|
98
|
+
} else {
|
|
99
|
+
// 深度优先
|
|
100
|
+
const re = iterator(item, index, arr, tree, parent, level);
|
|
101
|
+
if (re === false) {
|
|
102
|
+
isBreak = true;
|
|
103
|
+
break;
|
|
104
|
+
} else if (re === true) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (item && (isDomNode ? type.isNodeList(item[childField]) : Array.isArray(item[childField]))) {
|
|
108
|
+
walk(item[childField], item, level + 1);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (breadthFirst) {
|
|
113
|
+
while (queue.length > 0 && !isBreak) {
|
|
114
|
+
const current = queue.shift();
|
|
115
|
+
if (!current) break;
|
|
116
|
+
const { item, index, array, tree, parent, level } = current;
|
|
117
|
+
const re = iterator(item, index, array, tree, parent, level);
|
|
118
|
+
if (re === false) {
|
|
119
|
+
isBreak = true;
|
|
120
|
+
break;
|
|
121
|
+
} else if (re === true) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (item && (isDomNode ? type.isNodeList(item[childField]) : Array.isArray(item[childField]))) {
|
|
125
|
+
walk(item[childField], item, level + 1);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
reverse ? reverseWalk(tree, null, 0) : walk(tree, null, 0);
|
|
131
|
+
// @ts-ignore
|
|
132
|
+
tree = null;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* 树查找函数, 可用于查找Array和NodeList类型的数据
|
|
136
|
+
* @param {ArrayLike<V>} tree 树形数据
|
|
137
|
+
* @param {Function} predicate 断言函数
|
|
138
|
+
* @param {options} options 支持定制子元素名称、反向遍历、广度优先遍历,默认{
|
|
139
|
+
childField: 'children',
|
|
140
|
+
reverse: false,
|
|
141
|
+
breadthFirst: false,
|
|
142
|
+
isDomNode: false,
|
|
143
|
+
}
|
|
144
|
+
* @returns {V|null}
|
|
145
|
+
*/
|
|
146
|
+
function findDeep(
|
|
147
|
+
tree,
|
|
148
|
+
predicate,
|
|
149
|
+
options = {
|
|
150
|
+
childField: 'children',
|
|
151
|
+
reverse: false,
|
|
152
|
+
breadthFirst: false,
|
|
153
|
+
isDomNode: false
|
|
154
|
+
}
|
|
155
|
+
) {
|
|
156
|
+
let result = null;
|
|
157
|
+
forEachDeep(
|
|
158
|
+
tree,
|
|
159
|
+
(...args) => {
|
|
160
|
+
if (predicate(...args)) {
|
|
161
|
+
result = args[0];
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
options
|
|
166
|
+
);
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 树过滤函数, 可用于过滤Array和NodeList类型的数据
|
|
171
|
+
* @param {ArrayLike<V>} tree 树形数据
|
|
172
|
+
* @param {Function} predicate 断言函数
|
|
173
|
+
* @param {options} options 支持定制子元素名称、反向遍历、广度优先遍历,默认{
|
|
174
|
+
childField: 'children',
|
|
175
|
+
reverse: false,
|
|
176
|
+
breadthFirst: false,
|
|
177
|
+
isDomNode: false,
|
|
178
|
+
}
|
|
179
|
+
* @returns {V|null}
|
|
180
|
+
*/
|
|
181
|
+
function filterDeep(
|
|
182
|
+
tree,
|
|
183
|
+
predicate,
|
|
184
|
+
options = {
|
|
185
|
+
childField: 'children',
|
|
186
|
+
reverse: false,
|
|
187
|
+
breadthFirst: false,
|
|
188
|
+
isDomNode: false
|
|
189
|
+
}
|
|
190
|
+
) {
|
|
191
|
+
const result = [];
|
|
192
|
+
forEachDeep(
|
|
193
|
+
tree,
|
|
194
|
+
(...args) => {
|
|
195
|
+
if (predicate(...args)) {
|
|
196
|
+
result.push(args[0]);
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
options
|
|
200
|
+
);
|
|
201
|
+
return result;
|
|
131
202
|
}
|
|
132
203
|
/**
|
|
133
204
|
* 创建一个新数组, 深度优先遍历的Map函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
|
|
@@ -141,69 +212,68 @@ function forEachDeep(tree, iterator, options = {
|
|
|
141
212
|
}
|
|
142
213
|
* @returns {any[]} 新的一棵树
|
|
143
214
|
*/
|
|
144
|
-
function mapDeep(
|
|
215
|
+
function mapDeep(
|
|
216
|
+
tree,
|
|
217
|
+
iterator,
|
|
218
|
+
options = {
|
|
145
219
|
childField: 'children',
|
|
146
220
|
reverse: false
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const item = arr[i];
|
|
158
|
-
const re = iterator(item, i, arr, tree, parent, level);
|
|
159
|
-
if (re === false) {
|
|
160
|
-
isBreak = true;
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
else if (re === true) {
|
|
164
|
-
continue;
|
|
165
|
-
}
|
|
166
|
-
newTree.push(object.objectOmit(re, [childField]));
|
|
167
|
-
if (item && Array.isArray(item[childField])) {
|
|
168
|
-
newTree[newTree.length - 1][childField] = [];
|
|
169
|
-
walk(item[childField], item, newTree[newTree.length - 1][childField], level + 1);
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
// children非有效数组时,移除该属性字段
|
|
173
|
-
delete re[childField];
|
|
174
|
-
}
|
|
175
|
-
}
|
|
221
|
+
}
|
|
222
|
+
) {
|
|
223
|
+
const { childField = 'children', reverse = false } = type.isObject(options) ? options : {};
|
|
224
|
+
let isBreak = false;
|
|
225
|
+
const newTree = [];
|
|
226
|
+
const walk = (arr, parent, newTree, level = 0) => {
|
|
227
|
+
if (reverse) {
|
|
228
|
+
for (let i = arr.length - 1; i >= 0; i--) {
|
|
229
|
+
if (isBreak) {
|
|
230
|
+
break;
|
|
176
231
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
if (re === false) {
|
|
185
|
-
isBreak = true;
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
else if (re === true) {
|
|
189
|
-
continue;
|
|
190
|
-
}
|
|
191
|
-
newTree.push(object.objectOmit(re, [childField]));
|
|
192
|
-
if (item && Array.isArray(item[childField])) {
|
|
193
|
-
newTree[newTree.length - 1][childField] = [];
|
|
194
|
-
walk(item[childField], item, newTree[newTree.length - 1][childField], level + 1);
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
// children非有效数组时,移除该属性字段
|
|
198
|
-
delete re[childField];
|
|
199
|
-
}
|
|
200
|
-
}
|
|
232
|
+
const item = arr[i];
|
|
233
|
+
const re = iterator(item, i, arr, tree, parent, level);
|
|
234
|
+
if (re === false) {
|
|
235
|
+
isBreak = true;
|
|
236
|
+
break;
|
|
237
|
+
} else if (re === true) {
|
|
238
|
+
continue;
|
|
201
239
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
240
|
+
newTree.push(object.objectOmit(re, [childField]));
|
|
241
|
+
if (item && Array.isArray(item[childField])) {
|
|
242
|
+
newTree[newTree.length - 1][childField] = [];
|
|
243
|
+
walk(item[childField], item, newTree[newTree.length - 1][childField], level + 1);
|
|
244
|
+
} else {
|
|
245
|
+
// children非有效数组时,移除该属性字段
|
|
246
|
+
delete re[childField];
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
} else {
|
|
250
|
+
for (let i = 0; i < arr.length; i++) {
|
|
251
|
+
if (isBreak) {
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
const item = arr[i];
|
|
255
|
+
const re = iterator(item, i, arr, tree, parent, level);
|
|
256
|
+
if (re === false) {
|
|
257
|
+
isBreak = true;
|
|
258
|
+
break;
|
|
259
|
+
} else if (re === true) {
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
newTree.push(object.objectOmit(re, [childField]));
|
|
263
|
+
if (item && Array.isArray(item[childField])) {
|
|
264
|
+
newTree[newTree.length - 1][childField] = [];
|
|
265
|
+
walk(item[childField], item, newTree[newTree.length - 1][childField], level + 1);
|
|
266
|
+
} else {
|
|
267
|
+
// children非有效数组时,移除该属性字段
|
|
268
|
+
delete re[childField];
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
walk(tree, null, newTree);
|
|
274
|
+
// @ts-ignore
|
|
275
|
+
tree = null;
|
|
276
|
+
return newTree;
|
|
207
277
|
}
|
|
208
278
|
/**
|
|
209
279
|
* 在树中找到 id 为某个值的节点,并返回上游的所有父级节点
|
|
@@ -214,29 +284,30 @@ function mapDeep(tree, iterator, options = {
|
|
|
214
284
|
* @returns {[(number | string)[], V[]]} - 由parentId...childId, parentObject-childObject组成的二维数组
|
|
215
285
|
*/
|
|
216
286
|
function searchTreeById(tree, nodeId, options = { childField: 'children', keyField: 'id' }) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
287
|
+
const { childField = 'children', keyField = 'id' } = type.isObject(options) ? options : {};
|
|
288
|
+
const toFlatArray = (tree, parentId, parent) => {
|
|
289
|
+
return tree.reduce((t, _) => {
|
|
290
|
+
const child = _[childField];
|
|
291
|
+
return [
|
|
292
|
+
...t,
|
|
293
|
+
parentId ? { ..._, parentId, parent } : _,
|
|
294
|
+
...(child && child.length ? toFlatArray(child, _[keyField], _) : [])
|
|
295
|
+
];
|
|
296
|
+
}, []);
|
|
297
|
+
};
|
|
298
|
+
const getIds = flatArray => {
|
|
299
|
+
let child = flatArray.find(_ => _[keyField] === nodeId);
|
|
300
|
+
const { parent, parentId, ...other } = child;
|
|
301
|
+
let ids = [nodeId],
|
|
302
|
+
nodes = [other];
|
|
303
|
+
while (child && child.parentId) {
|
|
304
|
+
ids = [child.parentId, ...ids];
|
|
305
|
+
nodes = [child.parent, ...nodes];
|
|
306
|
+
child = flatArray.find(_ => _[keyField] === child.parentId); // eslint-disable-line
|
|
307
|
+
}
|
|
308
|
+
return [ids, nodes];
|
|
309
|
+
};
|
|
310
|
+
return getIds(toFlatArray(tree));
|
|
240
311
|
}
|
|
241
312
|
/**
|
|
242
313
|
* 扁平化数组转换成树
|
|
@@ -246,26 +317,25 @@ function searchTreeById(tree, nodeId, options = { childField: 'children', keyFie
|
|
|
246
317
|
* @returns {any[]}
|
|
247
318
|
*/
|
|
248
319
|
function formatTree(list, options = defaultFieldOptions) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
treeArr.push(item);
|
|
264
|
-
}
|
|
320
|
+
const { keyField = 'key', childField = 'children', pidField = 'pid' } = type.isObject(options) ? options : {};
|
|
321
|
+
const treeArr = [];
|
|
322
|
+
const sourceMap = {};
|
|
323
|
+
for (let i = 0, len = list.length; i < len; i++) {
|
|
324
|
+
const item = list[i];
|
|
325
|
+
sourceMap[item[keyField]] = item;
|
|
326
|
+
}
|
|
327
|
+
for (let i = 0, len = list.length; i < len; i++) {
|
|
328
|
+
const item = list[i];
|
|
329
|
+
const parent = sourceMap[item[pidField]];
|
|
330
|
+
if (parent) {
|
|
331
|
+
(parent[childField] || (parent[childField] = [])).push(item);
|
|
332
|
+
} else {
|
|
333
|
+
treeArr.push(item);
|
|
265
334
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
335
|
+
}
|
|
336
|
+
// @ts-ignore
|
|
337
|
+
list = null;
|
|
338
|
+
return treeArr;
|
|
269
339
|
}
|
|
270
340
|
/**
|
|
271
341
|
* 树形结构转扁平化
|
|
@@ -275,25 +345,25 @@ function formatTree(list, options = defaultFieldOptions) {
|
|
|
275
345
|
* @returns {any[]}
|
|
276
346
|
*/
|
|
277
347
|
function flatTree(treeList, options = defaultFieldOptions) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
348
|
+
const { keyField = 'key', childField = 'children', pidField = 'pid' } = type.isObject(options) ? options : {};
|
|
349
|
+
let res = [];
|
|
350
|
+
for (let i = 0, len = treeList.length; i < len; i++) {
|
|
351
|
+
const node = treeList[i];
|
|
352
|
+
const item = {
|
|
353
|
+
...node,
|
|
354
|
+
[childField]: [] // 清空子级
|
|
355
|
+
};
|
|
356
|
+
type.objectHas(item, childField) && delete item[childField];
|
|
357
|
+
res.push(item);
|
|
358
|
+
if (node[childField]) {
|
|
359
|
+
const children = node[childField].map(item => ({
|
|
360
|
+
...item,
|
|
361
|
+
[pidField]: node[keyField] || item.pid // 给子级设置pid
|
|
362
|
+
}));
|
|
363
|
+
res = res.concat(flatTree(children, options));
|
|
295
364
|
}
|
|
296
|
-
|
|
365
|
+
}
|
|
366
|
+
return res;
|
|
297
367
|
}
|
|
298
368
|
/**
|
|
299
369
|
* 模糊搜索函数,返回包含搜索字符的节点及其祖先节点, 适用于树型组件的字符过滤功能
|
|
@@ -315,52 +385,53 @@ function flatTree(treeList, options = defaultFieldOptions) {
|
|
|
315
385
|
* @returns {V[]}
|
|
316
386
|
*/
|
|
317
387
|
function fuzzySearchTree(nodes, filterCondition, options = defaultSearchTreeOptions) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
else {
|
|
356
|
-
const { [options.childField]: _, ...other } = node;
|
|
357
|
-
result.push(other);
|
|
358
|
-
}
|
|
388
|
+
if (!type.objectHas(filterCondition, 'filter') && !filterCondition.keyword) {
|
|
389
|
+
return nodes;
|
|
390
|
+
}
|
|
391
|
+
const result = [];
|
|
392
|
+
for (let i = 0, len = nodes.length; i < len; i++) {
|
|
393
|
+
const node = nodes[i];
|
|
394
|
+
// 递归检查子节点是否匹配
|
|
395
|
+
const matchedChildren =
|
|
396
|
+
node[options.childField] && node[options.childField].length > 0
|
|
397
|
+
? fuzzySearchTree(node[options.childField] || [], filterCondition, options)
|
|
398
|
+
: [];
|
|
399
|
+
// 检查当前节点是否匹配或者有匹配的子节点
|
|
400
|
+
if (
|
|
401
|
+
(type.objectHas(filterCondition, 'filter')
|
|
402
|
+
? filterCondition.filter(node)
|
|
403
|
+
: !options.ignoreCase
|
|
404
|
+
? node[options.nameField].includes(filterCondition.keyword)
|
|
405
|
+
: node[options.nameField].toLowerCase().includes(filterCondition.keyword.toLowerCase())) ||
|
|
406
|
+
matchedChildren.length > 0
|
|
407
|
+
) {
|
|
408
|
+
// 将当前节点加入结果中
|
|
409
|
+
if (node[options.childField]) {
|
|
410
|
+
if (matchedChildren.length > 0) {
|
|
411
|
+
result.push({
|
|
412
|
+
...node,
|
|
413
|
+
[options.childField]: matchedChildren // 包含匹配的子节点
|
|
414
|
+
});
|
|
415
|
+
} else if (options.removeEmptyChild) {
|
|
416
|
+
const { [options.childField]: _, ...other } = node;
|
|
417
|
+
result.push(other);
|
|
418
|
+
} else {
|
|
419
|
+
result.push({
|
|
420
|
+
...node,
|
|
421
|
+
[options.childField]: []
|
|
422
|
+
});
|
|
359
423
|
}
|
|
424
|
+
} else {
|
|
425
|
+
const { [options.childField]: _, ...other } = node;
|
|
426
|
+
result.push(other);
|
|
427
|
+
}
|
|
360
428
|
}
|
|
361
|
-
|
|
429
|
+
}
|
|
430
|
+
return result;
|
|
362
431
|
}
|
|
363
432
|
|
|
433
|
+
exports.filterDeep = filterDeep;
|
|
434
|
+
exports.findDeep = findDeep;
|
|
364
435
|
exports.flatTree = flatTree;
|
|
365
436
|
exports.forEachDeep = forEachDeep;
|
|
366
437
|
exports.formatTree = formatTree;
|