util-helpers 4.14.1 → 4.15.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 CHANGED
@@ -53,6 +53,7 @@ formatBankCard('6228480402564890018', { spaceMark: '-' }); // 6228-4804-0256-489
53
53
  - [blobToDataURL](https://doly-dev.github.io/util-helpers/module-Processor.html#.blobToDataURL) - 将 Blob 或 File 对象转成 data:URL 格式的 Base64 字符串
54
54
  - [bytesToSize](https://doly-dev.github.io/util-helpers/module-Processor.html#.bytesToSize) - 字节转换为存储单位
55
55
  - [dataURLToBlob](https://doly-dev.github.io/util-helpers/module-Processor.html#.dataURLToBlob) - 将 DataURL 转为 Blob 对象
56
+ - [filterTree](https://doly-dev.github.io/util-helpers/module-Processor.html#.filterTree) - 过滤树节点
56
57
  - [formatMoney](https://doly-dev.github.io/util-helpers/module-Processor.html#.formatMoney) - 格式化金额
57
58
  - [formatMobile](https://doly-dev.github.io/util-helpers/module-Processor.html#.formatMobile) - 格式化手机号码
58
59
  - [formatBankCard](https://doly-dev.github.io/util-helpers/module-Processor.html#.formatBankCard) - 格式化银行卡
@@ -92,6 +93,7 @@ formatBankCard('6228480402564890018', { spaceMark: '-' }); // 6228-4804-0256-489
92
93
  - 其他
93
94
  - [calculateCursorPosition](https://doly-dev.github.io/util-helpers/module-Other.html#.calculateCursorPosition) - 计算光标位置
94
95
  - [findTreeNode](https://doly-dev.github.io/util-helpers/module-Other.html#.findTreeNode) - 查找树结构数据节点
96
+ - [findTreeNodes](https://doly-dev.github.io/util-helpers/module-Other.html#.findTreeNodes) - 查找树结构数据多个节点
95
97
  - [findTreeSelect](https://doly-dev.github.io/util-helpers/module-Other.html#.findTreeSelect) - 查找包含当前节点的所有父级节点
96
98
  - [randomString](https://doly-dev.github.io/util-helpers/module-Other.html#.randomString) - 随机字符串
97
99
  - [strlen](https://doly-dev.github.io/util-helpers/module-Other.html#.strlen) - 字符长度
@@ -103,13 +105,15 @@ formatBankCard('6228480402564890018', { spaceMark: '-' }); // 6228-4804-0256-489
103
105
  - [query-string] - URL 解析、序列化
104
106
  - [qs] - URL 查询字符串解析和序列化库
105
107
  - [js-cookie] - 一个简单,轻量级的 JavaScript API,用于处理 cookie
106
- - [moment] - 一个轻量级 JavaScript 日期库,用于解析,验证,操作和格式化日期
108
+ - [store2] - 丰富了 localStorage 和 sessionStorage 功能(JSON,命名空间,扩展等)
107
109
  - [dayjs] - 一个轻量的处理时间和日期的 JavaScript 库,和 Moment.js 的 API 设计保持完全一样
110
+ - [date-fns] - 提供了最全面、简单且一致的工具集,用于在浏览器和 Node.js 中操作 JavaScript 日期
111
+ - [moment] - 一个轻量级 JavaScript 日期库,用于解析,验证,操作和格式化日期
112
+ - [ms] - 将各种时间格式转换为毫秒
108
113
  - [axios] - 基于 Promise 的 HTTP 客户端,用于浏览器和 node.js
109
114
  - [jsencrypt] - 用于执行 OpenSSL RSA 加密,解密和密钥生成的 Javascript 库
110
115
  - [crypto-js] - 加密标准的 JavaScript 库
111
116
  - [tinycolor2] - JavaScript 颜色工具,用于 JavaScript 中的颜色处理和转换
112
- - [store2] - 丰富了 localStorage 和 sessionStorage 功能(JSON,命名空间,扩展等)
113
117
  - [uuid] - 生成通用唯一识别码(Universally Unique Identifier)
114
118
  - [JSZip] - 创建、读取和编辑 zip 文件
115
119
  - [ua-parser-js] - 用于从用户代理数据中检测浏览器、引擎、操作系统、CPU 和设备类型/型号
@@ -120,6 +124,8 @@ formatBankCard('6228480402564890018', { spaceMark: '-' }); // 6228-4804-0256-489
120
124
  [js-cookie]: https://www.npmjs.com/package/js-cookie
121
125
  [moment]: https://www.npmjs.com/package/moment
122
126
  [dayjs]: https://www.npmjs.com/package/dayjs
127
+ [date-fns]: https://www.npmjs.com/package/date-fns
128
+ [ms]: https://www.npmjs.com/package/ms
123
129
  [axios]: https://www.npmjs.com/package/axios
124
130
  [jsencrypt]: https://www.npmjs.com/package/jsencrypt
125
131
  [crypto-js]: https://www.npmjs.com/package/crypto-js
@@ -537,7 +537,7 @@
537
537
  }
538
538
 
539
539
  // eslint-disable-next-line no-undef
540
- var version = "4.14.1";
540
+ var version = "4.15.0";
541
541
 
542
542
  /**
543
543
  * 打印警告信息
@@ -2704,9 +2704,9 @@
2704
2704
  * @template {*} D
2705
2705
  * @template {Record<string, keyof D>} F
2706
2706
  * @template {string} C
2707
- * @param {D[]} data 对象数组。如果是树结构数据,需要指定第三个参数 childrenFieldName
2707
+ * @param {D[]} data 对象数组。如果是树结构数据,需要指定第三个参数 childrenField
2708
2708
  * @param {F} fieldNames 字段名映射
2709
- * @param {C} [childrenFieldName] 子级数据字段名
2709
+ * @param {C} [childrenField] 子级数据字段名
2710
2710
  * @param {'spread'|'self'} [nodeAssign='spread'] 节点赋值方式。spread表示使用展开运算符创建新值,self表示使用自身对象。
2711
2711
  * @returns {import('./transformFieldNames.type.js').TransformFieldNames<D, F, C>}
2712
2712
  * @example
@@ -2728,7 +2728,7 @@
2728
2728
  * const newOptions4 = transformFieldNames(options3, {label: 'name', value: 'code', children: 'childs'}, 'childs');
2729
2729
  * // [{value: '1', label: 'one'},{value:'2', label:'two', children: [{value: '2-1', label:'two-one'}]}]
2730
2730
  */
2731
- function transformFieldNames(data, fieldNames, childrenFieldName) {
2731
+ function transformFieldNames(data, fieldNames, childrenField) {
2732
2732
  var nodeAssign = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'spread';
2733
2733
  if (!Array.isArray(data)) {
2734
2734
  return data;
@@ -2756,9 +2756,9 @@
2756
2756
 
2757
2757
  // 树形数据子节点
2758
2758
  // @ts-ignore
2759
- if (childrenFieldName && Array.isArray(newItem[childrenFieldName]) && newItem[childrenFieldName].length > 0) {
2759
+ if (childrenField && Array.isArray(newItem[childrenField]) && newItem[childrenField].length > 0) {
2760
2760
  // @ts-ignore
2761
- newItem[childrenFieldName] = recusion(newItem[childrenFieldName].slice());
2761
+ newItem[childrenField] = recusion(newItem[childrenField].slice());
2762
2762
  }
2763
2763
 
2764
2764
  // 替换字段名
@@ -2956,140 +2956,60 @@
2956
2956
  }
2957
2957
 
2958
2958
  /**
2959
- * 查找树结构数据节点
2959
+ * 过滤/筛选树节点。<br/><br/>如果某节点被过滤掉,它的子节点也一并抛弃
2960
2960
  *
2961
2961
  * @static
2962
- * @alias module:Other.findTreeNode
2963
- * @since 4.14.0
2962
+ * @alias module:Processor.filterTree
2963
+ * @since 4.15.0
2964
2964
  * @template {any} T
2965
2965
  * @template {(item: T) => boolean} F
2966
2966
  * @param {T[]} tree 树结构数据
2967
- * @param {F} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy 将返回该节点
2967
+ * @param {F} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy ,结果将包含该节点
2968
2968
  * @param {string} [childrenField='children'] 子级字段名
2969
- * @returns {T|undefined}
2969
+ * @param {'spread'|'self'} [nodeAssign='spread'] 节点赋值方式。spread表示使用展开运算符创建新值,self表示使用自身对象。
2970
+ * @returns {T[]}
2970
2971
  * @example
2971
2972
  * const menus = [{ "id": "1", "name": "首页", "code": "trade", "pid": null }, { "id": "2", "name": "交易管理", "code": "trade", "pid": null, "children": [{ "id": "3", "name": "交易查询", "code": "trade-1", "pid": "2", "children": [{ "id": "4", "name": "交易查询-查询操作", "code": "trade-1-1", "pid": "3" }] }] }, { "id": "5", "name": "权限管理", "code": "authorization", "pid": null, "children": [{ "id": "6", "name": "角色管理", "code": "authorization-1", "pid": "5" }, { "id": "7", "name": "用户管理", "code": "authorization-2", "pid": "5" }] }];
2972
2973
  *
2973
- * findTreeNode(menus, item=>item.id === '2');
2974
- * // {"id":"2","name":"交易管理","code":"trade","pid":null,"children":[{"id":"3","name":"交易查询","code":"trade-1","pid":"2","children":[{"id":"4","name":"交易查询-查询操作","code":"trade-1-1","pid":"3"}]}]}
2974
+ * filterTree(menus, item=>item.name.indexOf('管理') > -1);
2975
+ * // [{"id":"2","name":"交易管理","code":"trade","pid":null,"children":[]},{"id":"5","name":"权限管理","code":"authorization","pid":null,"children":[{"id":"6","name":"角色管理","code":"authorization-1","pid":"5"},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]}]
2975
2976
  *
2976
- * findTreeNode(menus, item=>item.id === '7');
2977
- * // {"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}
2978
- *
2979
- * findTreeNode(menus, item=>item.id === 'not found');
2980
- * // undefined
2981
- */
2982
- function findTreeNode(tree, predicate) {
2983
- var childrenField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
2984
- var stack = [];
2985
-
2986
- /** @type {T|undefined} */
2987
- var node;
2988
- var _iterator = _createForOfIteratorHelper(tree),
2989
- _step;
2990
- try {
2991
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
2992
- var item = _step.value;
2993
- stack.push(item);
2994
- while (stack.length) {
2995
- /** @type {T} */
2996
- // @ts-ignore
2997
- var temp = stack.pop();
2998
- if (predicate(temp)) {
2999
- node = temp;
3000
- break;
3001
- }
3002
-
3003
- /** @type {T[]} */
3004
- // @ts-ignore
3005
- var children = temp[childrenField] || [];
3006
- stack.push.apply(stack, _toConsumableArray(children));
3007
- }
3008
- if (node) {
3009
- break;
3010
- }
3011
- }
3012
- } catch (err) {
3013
- _iterator.e(err);
3014
- } finally {
3015
- _iterator.f();
3016
- }
3017
- return node;
3018
- }
3019
-
3020
- /**
3021
- * 内部实现
2977
+ * // 如果某节点被过滤掉,它的子节点也一并抛弃
2978
+ * filterTree(menus, item=>item.id === '7');
2979
+ * // []
3022
2980
  *
3023
- * @private
3024
- * @template {any} T
3025
- * @template {(item: T) => boolean} F
3026
- * @param {T[]} tree 树结构数据
3027
- * @param {F} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy 将返回包含该节点的所有父级节点
3028
- * @param {string} [childrenField='children'] 子级字段名
3029
- * @param {T[]} [path=[]] 当前遍历路径
3030
- * @returns {T[]}
2981
+ * filterTree(menus, item=>item.id === 'not found');
2982
+ * // []
3031
2983
  */
3032
- function internalFindTreeSelect(tree, predicate) {
2984
+ function filterTree(tree, predicate) {
3033
2985
  var childrenField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
3034
- var path = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
3035
- if (!tree) {
3036
- return [];
2986
+ var nodeAssign = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'spread';
2987
+ if (!Array.isArray(tree)) {
2988
+ return tree;
3037
2989
  }
3038
- var _iterator = _createForOfIteratorHelper(tree),
3039
- _step;
3040
- try {
3041
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
3042
- var item = _step.value;
3043
- path.push(item);
3044
- if (predicate(item)) {
3045
- return path;
3046
- }
3047
2990
 
2991
+ /** @type {T[]} */
2992
+ var result = [];
2993
+ tree.forEach(function (item) {
2994
+ var newItem = item;
2995
+ if (isObject(item)) {
3048
2996
  // @ts-ignore
3049
- if (isObject(item) && Array.isArray(item[childrenField]) && item[childrenField].length > 0) {
2997
+ newItem = nodeAssign === 'spread' ? _objectSpread2({}, item) : item;
2998
+ }
2999
+ if (predicate(newItem)) {
3000
+ if (isObject(newItem)) {
3001
+ /** @type {T[]|undefined} */
3050
3002
  // @ts-ignore
3051
- var findChildren = internalFindTreeSelect(item[childrenField], predicate, childrenField, path);
3052
- if (findChildren.length > 0) {
3053
- return findChildren;
3003
+ var childs = newItem[childrenField];
3004
+ if (Array.isArray(childs) && childs.length > 0) {
3005
+ // @ts-ignore
3006
+ newItem[childrenField] = filterTree(childs, predicate, childrenField, nodeAssign);
3054
3007
  }
3055
3008
  }
3056
- path.pop();
3009
+ result.push(newItem);
3057
3010
  }
3058
- } catch (err) {
3059
- _iterator.e(err);
3060
- } finally {
3061
- _iterator.f();
3062
- }
3063
- return [];
3064
- }
3065
-
3066
- /**
3067
- * 查找包含当前节点的所有父级节点
3068
- *
3069
- * @static
3070
- * @alias module:Other.findTreeSelect
3071
- * @since 4.14.0
3072
- * @template {any} T
3073
- * @template {(item: T) => boolean} F
3074
- * @param {T[]} tree 树结构数据
3075
- * @param {F} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy 将返回包含该节点的所有父级节点
3076
- * @param {string} [childrenField='children'] 子级字段名
3077
- * @returns {T[]}
3078
- * @example
3079
- * const menus = [{ "id": "1", "name": "首页", "code": "trade", "pid": null }, { "id": "2", "name": "交易管理", "code": "trade", "pid": null, "children": [{ "id": "3", "name": "交易查询", "code": "trade-1", "pid": "2", "children": [{ "id": "4", "name": "交易查询-查询操作", "code": "trade-1-1", "pid": "3" }] }] }, { "id": "5", "name": "权限管理", "code": "authorization", "pid": null, "children": [{ "id": "6", "name": "角色管理", "code": "authorization-1", "pid": "5" }, { "id": "7", "name": "用户管理", "code": "authorization-2", "pid": "5" }] }];
3080
- *
3081
- * findTreeSelect(menus, item => item.id === '2');
3082
- * // [{"id":"2","name":"交易管理","code":"trade","pid":null,"children":[{"id":"3","name":"交易查询","code":"trade-1","pid":"2","children":[{"id":"4","name":"交易查询-查询操作","code":"trade-1-1","pid":"3"}]}]}]
3083
- *
3084
- * findTreeSelect(menus, item => item.id === '7');
3085
- * // [{"id":"5","name":"权限管理","code":"authorization","pid":null,"children":[{"id":"6","name":"角色管理","code":"authorization-1","pid":"5"},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]
3086
- *
3087
- * findTreeSelect(menus, item => item.id === 'not found');
3088
- * // []
3089
- */
3090
- function findTreeSelect(tree, predicate) {
3091
- var childrenField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
3092
- return internalFindTreeSelect(tree, predicate, childrenField);
3011
+ });
3012
+ return result;
3093
3013
  }
3094
3014
 
3095
3015
  /**
@@ -3313,7 +3233,7 @@
3313
3233
  });
3314
3234
  }
3315
3235
 
3316
- // 参考了: https://github.com/ant-design/ant-design-mobile/blob/v2/components/input-item/index.tsx#L240
3236
+ // ref: https://github.com/ant-design/ant-design-mobile/blob/v2/components/input-item/index.tsx#L240
3317
3237
 
3318
3238
  /**
3319
3239
  * 计算输入框的值格式化后光标位置
@@ -3321,8 +3241,6 @@
3321
3241
  * @static
3322
3242
  * @alias module:Other.calculateCursorPosition
3323
3243
  * @since 4.6.0
3324
- * @see 格式化手机号码 {@link https://doly-dev.github.io/util-helpers/module-Processor.html#.formatMobile|formatMobile}
3325
- * @see 格式化银行卡号 {@link https://doly-dev.github.io/util-helpers/module-Processor.html#.formatBankCard|formatBankCard}
3326
3244
  * @see h5示例 {@link https://2950v9.csb.app/|点击查看}
3327
3245
  * @see react示例 {@link https://33ccy9.csb.app/|点击查看}
3328
3246
  * @param {number} prevPos 赋值前的光标位置,onChange/onInput的光标位置 e.target.selectionEnd
@@ -3448,12 +3366,220 @@
3448
3366
  return len;
3449
3367
  }
3450
3368
 
3369
+ /**
3370
+ * 查找树结构数据节点
3371
+ *
3372
+ * @static
3373
+ * @alias module:Other.findTreeNode
3374
+ * @since 4.14.0
3375
+ * @template {any} T
3376
+ * @template {(item: T) => boolean} F
3377
+ * @param {T[]} tree 树结构数据
3378
+ * @param {F} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy ,将返回该节点
3379
+ * @param {string} [childrenField='children'] 子级字段名
3380
+ * @returns {T|undefined}
3381
+ * @example
3382
+ * const menus = [{ "id": "1", "name": "首页", "code": "trade", "pid": null }, { "id": "2", "name": "交易管理", "code": "trade", "pid": null, "children": [{ "id": "3", "name": "交易查询", "code": "trade-1", "pid": "2", "children": [{ "id": "4", "name": "交易查询-查询操作", "code": "trade-1-1", "pid": "3" }] }] }, { "id": "5", "name": "权限管理", "code": "authorization", "pid": null, "children": [{ "id": "6", "name": "角色管理", "code": "authorization-1", "pid": "5" }, { "id": "7", "name": "用户管理", "code": "authorization-2", "pid": "5" }] }];
3383
+ *
3384
+ * findTreeNode(menus, item=>item.id === '2');
3385
+ * // {"id":"2","name":"交易管理","code":"trade","pid":null,"children":[{"id":"3","name":"交易查询","code":"trade-1","pid":"2","children":[{"id":"4","name":"交易查询-查询操作","code":"trade-1-1","pid":"3"}]}]}
3386
+ *
3387
+ * findTreeNode(menus, item=>item.id === '7');
3388
+ * // {"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}
3389
+ *
3390
+ * findTreeNode(menus, item=>item.id === 'not found');
3391
+ * // undefined
3392
+ */
3393
+ function findTreeNode(tree, predicate) {
3394
+ var childrenField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
3395
+ var stack = [];
3396
+
3397
+ /** @type {T|undefined} */
3398
+ var node;
3399
+ var _iterator = _createForOfIteratorHelper(tree),
3400
+ _step;
3401
+ try {
3402
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
3403
+ var item = _step.value;
3404
+ stack.push(item);
3405
+ while (stack.length) {
3406
+ /** @type {T} */
3407
+ // @ts-ignore
3408
+ var temp = stack.pop();
3409
+ if (predicate(temp)) {
3410
+ node = temp;
3411
+ break;
3412
+ }
3413
+ if (isObject(temp)) {
3414
+ /** @type {T[]} */
3415
+ // @ts-ignore
3416
+ var childs = temp[childrenField];
3417
+ if (Array.isArray(childs) && childs.length > 0) {
3418
+ stack.push.apply(stack, _toConsumableArray(childs));
3419
+ }
3420
+ }
3421
+ }
3422
+ if (node) {
3423
+ break;
3424
+ }
3425
+ }
3426
+ } catch (err) {
3427
+ _iterator.e(err);
3428
+ } finally {
3429
+ _iterator.f();
3430
+ }
3431
+ return node;
3432
+ }
3433
+
3434
+ /**
3435
+ * 查找树结构数据多个节点
3436
+ *
3437
+ * @static
3438
+ * @alias module:Other.findTreeNodes
3439
+ * @since 4.15.0
3440
+ * @template {any} T
3441
+ * @template {(item: T) => boolean} F
3442
+ * @param {T[]} tree 树结构数据
3443
+ * @param {F} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy ,返回结果将包含该节点
3444
+ * @param {string} [childrenField='children'] 子级字段名
3445
+ * @returns {T[]}
3446
+ * @example
3447
+ * const menus = [{ "id": "1", "name": "首页", "code": "trade", "pid": null }, { "id": "2", "name": "交易管理", "code": "trade", "pid": null, "children": [{ "id": "3", "name": "交易查询", "code": "trade-1", "pid": "2", "children": [{ "id": "4", "name": "交易查询-查询操作", "code": "trade-1-1", "pid": "3" }] }] }, { "id": "5", "name": "权限管理", "code": "authorization", "pid": null, "children": [{ "id": "6", "name": "角色管理", "code": "authorization-1", "pid": "5" }, { "id": "7", "name": "用户管理", "code": "authorization-2", "pid": "5" }] }];
3448
+ *
3449
+ * findTreeNodes(menus, item=>item.id === '2');
3450
+ * // [{"id":"2","name":"交易管理","code":"trade","pid":null,"children":[{"id":"3","name":"交易查询","code":"trade-1","pid":"2","children":[{"id":"4","name":"交易查询-查询操作","code":"trade-1-1","pid":"3"}]}]}]
3451
+ *
3452
+ * findTreeNodes(menus, item=>item.name.indexOf('管理') > -1);
3453
+ * // [{"id":"2","name":"交易管理","code":"trade","pid":null,"children":[{"id":"3","name":"交易查询","code":"trade-1","pid":"2","children":[{"id":"4","name":"交易查询-查询操作","code":"trade-1-1","pid":"3"}]}]},{"id":"5","name":"权限管理","code":"authorization","pid":null,"children":[{"id":"6","name":"角色管理","code":"authorization-1","pid":"5"},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"},{"id":"6","name":"角色管理","code":"authorization-1","pid":"5"}]
3454
+ *
3455
+ * findTreeNodes(menus, item=>item.id === '1' || item.id === '7');
3456
+ * // [{"id":"1","name":"首页","code":"trade","pid":null},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]
3457
+ *
3458
+ * findTreeNodes(menus, item=>item.id === 'not found');
3459
+ * // []
3460
+ */
3461
+ function findTreeNodes(tree, predicate) {
3462
+ var childrenField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
3463
+ var stack = [];
3464
+
3465
+ /** @type {T[]} */
3466
+ var nodes = [];
3467
+ var _iterator = _createForOfIteratorHelper(tree),
3468
+ _step;
3469
+ try {
3470
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
3471
+ var item = _step.value;
3472
+ stack.push(item);
3473
+ while (stack.length) {
3474
+ /** @type {T} */
3475
+ // @ts-ignore
3476
+ var temp = stack.pop();
3477
+ if (predicate(temp)) {
3478
+ nodes.push(temp);
3479
+ }
3480
+ if (isObject(temp)) {
3481
+ /** @type {T[]} */
3482
+ // @ts-ignore
3483
+ var childs = temp[childrenField];
3484
+ if (Array.isArray(childs) && childs.length > 0) {
3485
+ stack.push.apply(stack, _toConsumableArray(childs));
3486
+ }
3487
+ }
3488
+ }
3489
+ }
3490
+ } catch (err) {
3491
+ _iterator.e(err);
3492
+ } finally {
3493
+ _iterator.f();
3494
+ }
3495
+ return nodes;
3496
+ }
3497
+
3498
+ /**
3499
+ * 内部实现
3500
+ *
3501
+ * @private
3502
+ * @template {any} T
3503
+ * @template {(item: T) => boolean} F
3504
+ * @param {T[]} tree 树结构数据
3505
+ * @param {F} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy 将返回包含该节点的所有父级节点
3506
+ * @param {string} [childrenField='children'] 子级字段名
3507
+ * @param {T[]} [path=[]] 当前遍历路径
3508
+ * @returns {T[]}
3509
+ */
3510
+ function internalFindTreeSelect(tree, predicate) {
3511
+ var childrenField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
3512
+ var path = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
3513
+ if (!tree) {
3514
+ return [];
3515
+ }
3516
+ var _iterator = _createForOfIteratorHelper(tree),
3517
+ _step;
3518
+ try {
3519
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
3520
+ var item = _step.value;
3521
+ path.push(item);
3522
+ if (predicate(item)) {
3523
+ return path;
3524
+ }
3525
+ if (isObject(item)) {
3526
+ /** @type {T[]} */
3527
+ // @ts-ignore
3528
+ var childs = item[childrenField];
3529
+ if (Array.isArray(childs) && childs.length > 0) {
3530
+ var findChildren = internalFindTreeSelect(childs, predicate, childrenField, path);
3531
+ if (findChildren.length > 0) {
3532
+ return findChildren;
3533
+ }
3534
+ }
3535
+ }
3536
+ path.pop();
3537
+ }
3538
+ } catch (err) {
3539
+ _iterator.e(err);
3540
+ } finally {
3541
+ _iterator.f();
3542
+ }
3543
+ return [];
3544
+ }
3545
+
3546
+ /**
3547
+ * 查找包含当前节点的所有父级节点
3548
+ *
3549
+ * @static
3550
+ * @alias module:Other.findTreeSelect
3551
+ * @since 4.14.0
3552
+ * @template {any} T
3553
+ * @template {(item: T) => boolean} F
3554
+ * @param {T[]} tree 树结构数据
3555
+ * @param {F} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy 将返回包含该节点的所有父级节点
3556
+ * @param {string} [childrenField='children'] 子级字段名
3557
+ * @returns {T[]}
3558
+ * @example
3559
+ * const menus = [{ "id": "1", "name": "首页", "code": "trade", "pid": null }, { "id": "2", "name": "交易管理", "code": "trade", "pid": null, "children": [{ "id": "3", "name": "交易查询", "code": "trade-1", "pid": "2", "children": [{ "id": "4", "name": "交易查询-查询操作", "code": "trade-1-1", "pid": "3" }] }] }, { "id": "5", "name": "权限管理", "code": "authorization", "pid": null, "children": [{ "id": "6", "name": "角色管理", "code": "authorization-1", "pid": "5" }, { "id": "7", "name": "用户管理", "code": "authorization-2", "pid": "5" }] }];
3560
+ *
3561
+ * findTreeSelect(menus, item => item.id === '2');
3562
+ * // [{"id":"2","name":"交易管理","code":"trade","pid":null,"children":[{"id":"3","name":"交易查询","code":"trade-1","pid":"2","children":[{"id":"4","name":"交易查询-查询操作","code":"trade-1-1","pid":"3"}]}]}]
3563
+ *
3564
+ * findTreeSelect(menus, item => item.id === '7');
3565
+ * // [{"id":"5","name":"权限管理","code":"authorization","pid":null,"children":[{"id":"6","name":"角色管理","code":"authorization-1","pid":"5"},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]
3566
+ *
3567
+ * findTreeSelect(menus, item => item.id === 'not found');
3568
+ * // []
3569
+ */
3570
+ function findTreeSelect(tree, predicate) {
3571
+ var childrenField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
3572
+ return internalFindTreeSelect(tree, predicate, childrenField);
3573
+ }
3574
+
3451
3575
  exports.blobToDataURL = blobToDataURL;
3452
3576
  exports.bytesToSize = bytesToSize;
3453
3577
  exports.calculateCursorPosition = calculateCursorPosition;
3454
3578
  exports.dataURLToBlob = dataURLToBlob;
3455
3579
  exports.divide = divide;
3580
+ exports.filterTree = filterTree;
3456
3581
  exports.findTreeNode = findTreeNode;
3582
+ exports.findTreeNodes = findTreeNodes;
3457
3583
  exports.findTreeSelect = findTreeSelect;
3458
3584
  exports.formatBankCard = formatBankCard;
3459
3585
  exports.formatMobile = formatMobile;