util-helpers 4.14.0 → 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.0";
540
+ var version = "4.15.0";
541
541
 
542
542
  /**
543
543
  * 打印警告信息
@@ -2704,9 +2704,10 @@
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
+ * @param {'spread'|'self'} [nodeAssign='spread'] 节点赋值方式。spread表示使用展开运算符创建新值,self表示使用自身对象。
2710
2711
  * @returns {import('./transformFieldNames.type.js').TransformFieldNames<D, F, C>}
2711
2712
  * @example
2712
2713
  *
@@ -2727,7 +2728,8 @@
2727
2728
  * const newOptions4 = transformFieldNames(options3, {label: 'name', value: 'code', children: 'childs'}, 'childs');
2728
2729
  * // [{value: '1', label: 'one'},{value:'2', label:'two', children: [{value: '2-1', label:'two-one'}]}]
2729
2730
  */
2730
- function transformFieldNames(data, fieldNames, childrenFieldName) {
2731
+ function transformFieldNames(data, fieldNames, childrenField) {
2732
+ var nodeAssign = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'spread';
2731
2733
  if (!Array.isArray(data)) {
2732
2734
  return data;
2733
2735
  }
@@ -2748,15 +2750,15 @@
2748
2750
  if (!isObject(item)) {
2749
2751
  return item;
2750
2752
  }
2751
- var newItem = _objectSpread2({}, item);
2753
+ var newItem = nodeAssign === 'spread' ? _objectSpread2({}, item) : item;
2752
2754
  /** @type {Array.<string>} */
2753
2755
  var delKeys = [];
2754
2756
 
2755
2757
  // 树形数据子节点
2756
2758
  // @ts-ignore
2757
- if (childrenFieldName && Array.isArray(newItem[childrenFieldName]) && newItem[childrenFieldName].length > 0) {
2759
+ if (childrenField && Array.isArray(newItem[childrenField]) && newItem[childrenField].length > 0) {
2758
2760
  // @ts-ignore
2759
- newItem[childrenFieldName] = recusion(newItem[childrenFieldName].slice());
2761
+ newItem[childrenField] = recusion(newItem[childrenField].slice());
2760
2762
  }
2761
2763
 
2762
2764
  // 替换字段名
@@ -2831,6 +2833,7 @@
2831
2833
  * @param {string} [options.parentField='pid'] 当前数据的父级字段名称
2832
2834
  * @param {string} [options.childrenField='children'] 子级字段名称
2833
2835
  * @param {'none'|'null'|'array'} [options.emptyChildrenValue='none'] 子级为空时的值,none表示删除该子级,null表示为null,array表示为[]。
2836
+ * @param {'spread'|'self'} [options.nodeAssign='spread'] 节点赋值方式。spread表示使用展开运算符创建新值,self表示使用自身对象。
2834
2837
  * @returns {R[]} 树结构
2835
2838
  * @example
2836
2839
  *
@@ -2860,7 +2863,9 @@
2860
2863
  _options$childrenFiel2 = options.childrenField,
2861
2864
  childrenField = _options$childrenFiel2 === void 0 ? 'children' : _options$childrenFiel2,
2862
2865
  _options$emptyChildre2 = options.emptyChildrenValue,
2863
- emptyChildrenValue = _options$emptyChildre2 === void 0 ? 'none' : _options$emptyChildre2;
2866
+ emptyChildrenValue = _options$emptyChildre2 === void 0 ? 'none' : _options$emptyChildre2,
2867
+ _options$nodeAssign = options.nodeAssign,
2868
+ nodeAssign = _options$nodeAssign === void 0 ? 'spread' : _options$nodeAssign;
2864
2869
 
2865
2870
  /** @type {R[]} */
2866
2871
  var tree = [];
@@ -2869,7 +2874,7 @@
2869
2874
  var record = {};
2870
2875
  list.forEach(function (item) {
2871
2876
  if (isObject(item)) {
2872
- var newItem = _objectSpread2({}, item);
2877
+ var newItem = nodeAssign === 'spread' ? _objectSpread2({}, item) : item;
2873
2878
 
2874
2879
  /** @type {string} */
2875
2880
  var id = newItem[keyField];
@@ -2951,140 +2956,60 @@
2951
2956
  }
2952
2957
 
2953
2958
  /**
2954
- * 查找树结构数据节点
2959
+ * 过滤/筛选树节点。<br/><br/>如果某节点被过滤掉,它的子节点也一并抛弃
2955
2960
  *
2956
2961
  * @static
2957
- * @alias module:Other.findTreeNode
2958
- * @since 4.14.0
2962
+ * @alias module:Processor.filterTree
2963
+ * @since 4.15.0
2959
2964
  * @template {any} T
2960
2965
  * @template {(item: T) => boolean} F
2961
2966
  * @param {T[]} tree 树结构数据
2962
- * @param {F} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy 将返回该节点
2967
+ * @param {F} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy ,结果将包含该节点
2963
2968
  * @param {string} [childrenField='children'] 子级字段名
2964
- * @returns {T|undefined}
2969
+ * @param {'spread'|'self'} [nodeAssign='spread'] 节点赋值方式。spread表示使用展开运算符创建新值,self表示使用自身对象。
2970
+ * @returns {T[]}
2965
2971
  * @example
2966
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" }] }];
2967
2973
  *
2968
- * findTreeNode(menus, item=>item.id === '2');
2969
- * // {"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"}]}]
2970
2976
  *
2971
- * findTreeNode(menus, item=>item.id === '7');
2972
- * // {"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}
2977
+ * // 如果某节点被过滤掉,它的子节点也一并抛弃
2978
+ * filterTree(menus, item=>item.id === '7');
2979
+ * // []
2973
2980
  *
2974
- * findTreeNode(menus, item=>item.id === 'not found');
2975
- * // undefined
2981
+ * filterTree(menus, item=>item.id === 'not found');
2982
+ * // []
2976
2983
  */
2977
- function findTreeNode(tree, predicate) {
2984
+ function filterTree(tree, predicate) {
2978
2985
  var childrenField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
2979
- var stack = [];
2980
-
2981
- /** @type {T|undefined} */
2982
- var node;
2983
- var _iterator = _createForOfIteratorHelper(tree),
2984
- _step;
2985
- try {
2986
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
2987
- var item = _step.value;
2988
- stack.push(item);
2989
- while (stack.length) {
2990
- /** @type {T} */
2991
- // @ts-ignore
2992
- var temp = stack.pop();
2993
- if (predicate(temp)) {
2994
- node = temp;
2995
- break;
2996
- }
2997
-
2998
- /** @type {T[]} */
2999
- // @ts-ignore
3000
- var children = temp[childrenField] || [];
3001
- stack.push.apply(stack, _toConsumableArray(children));
3002
- }
3003
- if (node) {
3004
- break;
3005
- }
3006
- }
3007
- } catch (err) {
3008
- _iterator.e(err);
3009
- } finally {
3010
- _iterator.f();
2986
+ var nodeAssign = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'spread';
2987
+ if (!Array.isArray(tree)) {
2988
+ return tree;
3011
2989
  }
3012
- return node;
3013
- }
3014
-
3015
- /**
3016
- * 内部实现
3017
- *
3018
- * @private
3019
- * @template {any} T
3020
- * @template {(item: T) => boolean} F
3021
- * @param {T[]} tree 树结构数据
3022
- * @param {F} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy 将返回包含该节点的所有父级节点
3023
- * @param {string} [childrenField='children'] 子级字段名
3024
- * @param {T[]} [path=[]] 当前遍历路径
3025
- * @returns {T[]}
3026
- */
3027
- function internalFindTreeSelect(tree, predicate) {
3028
- var childrenField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
3029
- var path = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
3030
- if (!tree) {
3031
- return [];
3032
- }
3033
- var _iterator = _createForOfIteratorHelper(tree),
3034
- _step;
3035
- try {
3036
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
3037
- var item = _step.value;
3038
- path.push(item);
3039
- if (predicate(item)) {
3040
- return path;
3041
- }
3042
2990
 
2991
+ /** @type {T[]} */
2992
+ var result = [];
2993
+ tree.forEach(function (item) {
2994
+ var newItem = item;
2995
+ if (isObject(item)) {
3043
2996
  // @ts-ignore
3044
- 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} */
3045
3002
  // @ts-ignore
3046
- var findChildren = internalFindTreeSelect(item[childrenField], predicate, childrenField, path);
3047
- if (findChildren.length > 0) {
3048
- 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);
3049
3007
  }
3050
3008
  }
3051
- path.pop();
3009
+ result.push(newItem);
3052
3010
  }
3053
- } catch (err) {
3054
- _iterator.e(err);
3055
- } finally {
3056
- _iterator.f();
3057
- }
3058
- return [];
3059
- }
3060
-
3061
- /**
3062
- * 查找包含当前节点的所有父级节点
3063
- *
3064
- * @static
3065
- * @alias module:Other.findTreeSelect
3066
- * @since 4.14.0
3067
- * @template {any} T
3068
- * @template {(item: T) => boolean} F
3069
- * @param {T[]} tree 树结构数据
3070
- * @param {F} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy 将返回包含该节点的所有父级节点
3071
- * @param {string} [childrenField='children'] 子级字段名
3072
- * @returns {T[]}
3073
- * @example
3074
- * 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" }] }];
3075
- *
3076
- * findTreeSelect(menus, item => item.id === '2');
3077
- * // [{"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"}]}]}]
3078
- *
3079
- * findTreeSelect(menus, item => item.id === '7');
3080
- * // [{"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"}]
3081
- *
3082
- * findTreeSelect(menus, item => item.id === 'not found');
3083
- * // []
3084
- */
3085
- function findTreeSelect(tree, predicate) {
3086
- var childrenField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
3087
- return internalFindTreeSelect(tree, predicate, childrenField);
3011
+ });
3012
+ return result;
3088
3013
  }
3089
3014
 
3090
3015
  /**
@@ -3308,7 +3233,7 @@
3308
3233
  });
3309
3234
  }
3310
3235
 
3311
- // 参考了: 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
3312
3237
 
3313
3238
  /**
3314
3239
  * 计算输入框的值格式化后光标位置
@@ -3316,8 +3241,6 @@
3316
3241
  * @static
3317
3242
  * @alias module:Other.calculateCursorPosition
3318
3243
  * @since 4.6.0
3319
- * @see 格式化手机号码 {@link https://doly-dev.github.io/util-helpers/module-Processor.html#.formatMobile|formatMobile}
3320
- * @see 格式化银行卡号 {@link https://doly-dev.github.io/util-helpers/module-Processor.html#.formatBankCard|formatBankCard}
3321
3244
  * @see h5示例 {@link https://2950v9.csb.app/|点击查看}
3322
3245
  * @see react示例 {@link https://33ccy9.csb.app/|点击查看}
3323
3246
  * @param {number} prevPos 赋值前的光标位置,onChange/onInput的光标位置 e.target.selectionEnd
@@ -3443,12 +3366,220 @@
3443
3366
  return len;
3444
3367
  }
3445
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
+
3446
3575
  exports.blobToDataURL = blobToDataURL;
3447
3576
  exports.bytesToSize = bytesToSize;
3448
3577
  exports.calculateCursorPosition = calculateCursorPosition;
3449
3578
  exports.dataURLToBlob = dataURLToBlob;
3450
3579
  exports.divide = divide;
3580
+ exports.filterTree = filterTree;
3451
3581
  exports.findTreeNode = findTreeNode;
3582
+ exports.findTreeNodes = findTreeNodes;
3452
3583
  exports.findTreeSelect = findTreeSelect;
3453
3584
  exports.formatBankCard = formatBankCard;
3454
3585
  exports.formatMobile = formatMobile;