sculp-js 1.3.1 → 1.4.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.
Files changed (52) hide show
  1. package/README.md +8 -7
  2. package/lib/cjs/array.js +1 -1
  3. package/lib/cjs/async.js +1 -1
  4. package/lib/cjs/clipboard.js +1 -1
  5. package/lib/cjs/cookie.js +1 -1
  6. package/lib/cjs/date.js +28 -42
  7. package/lib/cjs/dom.js +1 -1
  8. package/lib/cjs/download.js +1 -1
  9. package/lib/cjs/easing.js +1 -1
  10. package/lib/cjs/file.js +1 -1
  11. package/lib/cjs/func.js +1 -1
  12. package/lib/cjs/index.js +3 -1
  13. package/lib/cjs/number.js +1 -1
  14. package/lib/cjs/object.js +1 -1
  15. package/lib/cjs/path.js +1 -1
  16. package/lib/cjs/qs.js +1 -1
  17. package/lib/cjs/random.js +1 -1
  18. package/lib/cjs/string.js +1 -1
  19. package/lib/cjs/tooltip.js +1 -1
  20. package/lib/cjs/tree.js +84 -7
  21. package/lib/cjs/type.js +1 -1
  22. package/lib/cjs/unique.js +1 -1
  23. package/lib/cjs/url.js +1 -1
  24. package/lib/cjs/watermark.js +1 -1
  25. package/lib/cjs/we-decode.js +1 -1
  26. package/lib/es/array.js +1 -1
  27. package/lib/es/async.js +1 -1
  28. package/lib/es/clipboard.js +1 -1
  29. package/lib/es/cookie.js +1 -1
  30. package/lib/es/date.js +28 -42
  31. package/lib/es/dom.js +1 -1
  32. package/lib/es/download.js +1 -1
  33. package/lib/es/easing.js +1 -1
  34. package/lib/es/file.js +1 -1
  35. package/lib/es/func.js +1 -1
  36. package/lib/es/index.js +2 -2
  37. package/lib/es/number.js +1 -1
  38. package/lib/es/object.js +1 -1
  39. package/lib/es/path.js +1 -1
  40. package/lib/es/qs.js +1 -1
  41. package/lib/es/random.js +1 -1
  42. package/lib/es/string.js +1 -1
  43. package/lib/es/tooltip.js +1 -1
  44. package/lib/es/tree.js +83 -8
  45. package/lib/es/type.js +1 -1
  46. package/lib/es/unique.js +1 -1
  47. package/lib/es/url.js +1 -1
  48. package/lib/es/watermark.js +1 -1
  49. package/lib/es/we-decode.js +1 -1
  50. package/lib/index.d.ts +26 -5
  51. package/lib/umd/index.js +111 -48
  52. package/package.json +2 -1
package/README.md CHANGED
@@ -34,8 +34,8 @@
34
34
  - forEachDeep 高性能的深度优先遍历函数, 支持continue、break,可定制id、children
35
35
  - forEachMap 高性能的深度优先遍历的Map函数, 支持continue、break,可定制id、children
36
36
  - searchTreeById 在树中找到 id 为某个值的节点,并返回上游的所有父级节点
37
- - buildTree 根据 id 与 parentId 从对象数组中构建对应的树
38
37
  - formatTree 高性能的数组转树函数
38
+ - fuzzySearchTree 模糊搜索函数,返回包含搜索字符的节点及其祖先节点的树
39
39
 
40
40
  - Object
41
41
 
@@ -54,7 +54,7 @@
54
54
 
55
55
  - stringCamelCase
56
56
  - stringKebabCase
57
- - getStrWidthPx
57
+ - getStrWidthPx (web)
58
58
 
59
59
  - Unique
60
60
 
@@ -69,18 +69,19 @@
69
69
  - calculateDate
70
70
  - calculateDateTime
71
71
 
72
- - Download
72
+ - Download (web)
73
73
 
74
74
  - downloadURL
75
75
  - downloadHref
76
76
  - downloadBlob
77
77
  - downloadData
78
78
 
79
- - File
79
+ - File (web)
80
80
 
81
81
  - chooseLocalFile
82
+ - compressImg 压缩图片
82
83
 
83
- - Dom
84
+ - Dom (web)
84
85
 
85
86
  - hasClass
86
87
  - addClass
@@ -89,11 +90,11 @@
89
90
  - getStyle
90
91
  - getComputedCssVal
91
92
 
92
- - Watermark
93
+ - Watermark (web)
93
94
 
94
95
  - genCanvasWM
95
96
 
96
- - Clipboard
97
+ - Clipboard (web)
97
98
  - copyText
98
99
 
99
100
  ## Install
package/lib/cjs/array.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/async.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/cookie.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/date.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -163,64 +163,50 @@ function formatDate(value, format = 'YYYY-MM-DD HH:mm:ss') {
163
163
  }
164
164
  /**
165
165
  * 计算向前或向后N天的具体日期
166
- * @param {string} strDate - 参考日期
166
+ * @param {DateValue} originDate - 参考日期
167
167
  * @param {number} n - 正数:向后推算;负数:向前推算
168
168
  * @param {string} sep - 日期格式的分隔符
169
169
  * @returns {string} 计算后的目标日期
170
170
  */
171
- function calculateDate(strDate, n, sep = '-') {
172
- //strDate 为字符串日期 如:'2019-01-01' n为你要传入的参数,当前为0,前一天为-1,后一天为1
173
- const dateArr = strDate.split(sep); //这边给定一个特定时间
174
- const newDate = new Date(+dateArr[0], +dateArr[1] - 1, +dateArr[2]);
175
- const befminuts = newDate.getTime() + 1000 * 60 * 60 * 24 * parseInt(String(n)); //计算前几天用减,计算后几天用加,最后一个就是多少天的数量
176
- const beforeDat = new Date();
177
- beforeDat.setTime(befminuts);
178
- const befMonth = beforeDat.getMonth() + 1;
179
- const mon = befMonth >= 10 ? befMonth : '0' + befMonth;
180
- const befDate = beforeDat.getDate();
181
- const da = befDate >= 10 ? befDate : '0' + befDate;
182
- const finalNewDate = beforeDat.getFullYear() + '-' + mon + '-' + da;
171
+ function calculateDate(originDate, n, sep = '-') {
172
+ //originDate 为字符串日期 如:'2019-01-01' n为你要传入的参数,当前为0,前一天为-1,后一天为1
173
+ const date = new Date(originDate); //这边给定一个特定时间
174
+ const newDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
175
+ const millisecondGap = newDate.getTime() + 1000 * 60 * 60 * 24 * parseInt(String(n)); //计算前几天用减,计算后几天用加,最后一个就是多少天的数量
176
+ const targetDate = new Date(millisecondGap);
177
+ const finalNewDate = targetDate.getFullYear() +
178
+ sep +
179
+ String(targetDate.getMonth() + 1).padStart(2, '0') +
180
+ '-' +
181
+ String(targetDate.getDate()).padStart(2, '0');
183
182
  return finalNewDate;
184
183
  }
185
184
  /**
186
- * 计算向前或向后N天的具体时间日期
185
+ * 计算向前或向后N天的具体日期时间
186
+ * @param {DateValue} originDateTime - 参考日期时间
187
187
  * @param {number} n - 正数:向后推算;负数:向前推算
188
188
  * @param {string} dateSep - 日期分隔符
189
189
  * @param {string} timeSep - 时间分隔符
190
190
  * @returns {string} 转换后的目标日期时间
191
191
  */
192
- function calculateDateTime(n, dateSep = '-', timeSep = ':') {
193
- const date = new Date();
194
- const separator1 = '-';
195
- const separator2 = ':';
196
- let year = date.getFullYear();
197
- let month = date.getMonth() + 1;
198
- let strDate = date.getDate() + n;
199
- if (strDate > new Date(year, month, 0).getDate()) {
200
- month += 1;
201
- strDate -= new Date(year, month, 0).getDate();
202
- if (month > 12) {
203
- year += 1;
204
- month = 1;
205
- }
206
- }
207
- if (month >= 1 && month <= 9) {
208
- month = '0' + month;
209
- }
210
- if (strDate >= 0 && strDate <= 9) {
211
- strDate = '0' + strDate;
212
- }
213
- return (year +
192
+ function calculateDateTime(originDateTime, n, dateSep = '-', timeSep = ':') {
193
+ const date = new Date(originDateTime);
194
+ const separator1 = dateSep;
195
+ const separator2 = timeSep;
196
+ const dateTime = new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
197
+ const millisecondGap = dateTime.getTime() + 1000 * 60 * 60 * 24 * parseInt(String(n)); //计算前几天用减,计算后几天用加,最后一个就是多少天的数量
198
+ const targetDateTime = new Date(millisecondGap);
199
+ return (targetDateTime.getFullYear() +
214
200
  separator1 +
215
- month +
201
+ String(targetDateTime.getMonth() + 1).padStart(2, '0') +
216
202
  separator1 +
217
- strDate +
203
+ String(targetDateTime.getDate()).padStart(2, '0') +
218
204
  ' ' +
219
- date.getHours() +
205
+ String(targetDateTime.getHours()).padStart(2, '0') +
220
206
  separator2 +
221
- date.getMinutes() +
207
+ String(targetDateTime.getMinutes()).padStart(2, '0') +
222
208
  separator2 +
223
- date.getSeconds());
209
+ String(targetDateTime.getSeconds()).padStart(2, '0'));
224
210
  }
225
211
 
226
212
  exports.calculateDate = calculateDate;
package/lib/cjs/dom.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/easing.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/file.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/func.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -131,9 +131,11 @@ exports.uniqueNumber = unique.uniqueNumber;
131
131
  exports.uniqueString = unique.uniqueString;
132
132
  exports.tooltipEvent = tooltip.tooltipEvent;
133
133
  exports.buildTree = tree.buildTree;
134
+ exports.flatTree = tree.flatTree;
134
135
  exports.forEachDeep = tree.forEachDeep;
135
136
  exports.forEachMap = tree.forEachMap;
136
137
  exports.formatTree = tree.formatTree;
138
+ exports.fuzzySearchTree = tree.fuzzySearchTree;
137
139
  exports.searchTreeById = tree.searchTreeById;
138
140
  exports.weAppJwtDecode = weDecode.weAppJwtDecode;
139
141
  exports.weAtob = weDecode.weAtob;
package/lib/cjs/number.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/object.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/path.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/qs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/random.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/string.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/tree.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -7,6 +7,11 @@
7
7
  'use strict';
8
8
 
9
9
  const defaultFieldOptions = { keyField: 'key', childField: 'children', pidField: 'pid' };
10
+ const defaultSearchTreeOptions = {
11
+ childField: 'children',
12
+ nameField: 'name',
13
+ ignoreEmptyChild: false
14
+ };
10
15
  /**
11
16
  * 深度优先遍历函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
12
17
  * @param {ArrayLike<V>} tree 树形数据
@@ -70,9 +75,9 @@ function forEachDeep(tree, iterator, children = 'children', isReverse = false) {
70
75
  * @returns {any[]} 新的一棵树
71
76
  */
72
77
  function forEachMap(tree, iterator, children = 'children', isReverse = false) {
73
- let level = 0, isBreak = false;
78
+ let isBreak = false;
74
79
  const newTree = [];
75
- const walk = (arr, parent, newTree) => {
80
+ const walk = (arr, parent, newTree, level = 0) => {
76
81
  if (isReverse) {
77
82
  for (let i = arr.length - 1; i >= 0; i--) {
78
83
  if (isBreak) {
@@ -89,10 +94,9 @@ function forEachMap(tree, iterator, children = 'children', isReverse = false) {
89
94
  newTree.push(re);
90
95
  // @ts-ignore
91
96
  if (arr[i] && Array.isArray(arr[i][children])) {
92
- ++level;
93
97
  newTree[newTree.length - 1][children] = [];
94
98
  // @ts-ignore
95
- walk(arr[i][children], arr[i], newTree[newTree.length - 1][children]);
99
+ walk(arr[i][children], arr[i], newTree[newTree.length - 1][children], level + 1);
96
100
  }
97
101
  else {
98
102
  // children非有效数组时,移除该属性字段
@@ -116,10 +120,9 @@ function forEachMap(tree, iterator, children = 'children', isReverse = false) {
116
120
  newTree.push(re);
117
121
  // @ts-ignore
118
122
  if (arr[i] && Array.isArray(arr[i][children])) {
119
- ++level;
120
123
  newTree[newTree.length - 1][children] = [];
121
124
  // @ts-ignore
122
- walk(arr[i][children], arr[i], newTree[newTree.length - 1][children]);
125
+ walk(arr[i][children], arr[i], newTree[newTree.length - 1][children], level + 1);
123
126
  }
124
127
  else {
125
128
  // children非有效数组时,移除该属性字段
@@ -273,9 +276,83 @@ function formatTree(list, options = defaultFieldOptions) {
273
276
  });
274
277
  return treeArr;
275
278
  }
279
+ /**
280
+ * 树形结构转扁平化
281
+ * @param {any} treeList
282
+ * @param {IFieldOptions} options
283
+ * @return {*}
284
+ */
285
+ function flatTree(treeList, options = defaultFieldOptions) {
286
+ const { childField, keyField, pidField } = options;
287
+ return treeList.reduce((res, node) => {
288
+ const item = {
289
+ ...node,
290
+ [childField]: [] // 清空子级
291
+ };
292
+ item.hasOwnProperty([childField]) && delete item[childField];
293
+ res.push(item);
294
+ if (node[childField]) {
295
+ const children = node[childField].map(item => ({
296
+ ...item,
297
+ [pidField]: node[keyField] || item.pid // 给子级设置pid
298
+ }));
299
+ res = res.concat(flatTree(children, options));
300
+ }
301
+ return res;
302
+ }, []);
303
+ }
304
+ /**
305
+ * 模糊搜索函数,返回包含搜索字符的节点及其祖先节点, 适用于树型组件的字符过滤功能
306
+ * @param {any[]} nodes
307
+ * @param {string} query
308
+ * @param {ISearchTreeOpts} options
309
+ * @return {any[]}
310
+ */
311
+ function fuzzySearchTree(nodes, query, options = defaultSearchTreeOptions) {
312
+ const result = [];
313
+ for (const node of nodes) {
314
+ // 递归检查子节点是否匹配
315
+ const matchedChildren = node[options.childField] && node[options.childField].length > 0
316
+ ? fuzzySearchTree(node[options.childField] || [], query, options)
317
+ : [];
318
+ // 检查当前节点是否匹配或者有匹配的子节点
319
+ if (node[options.nameField].toLowerCase().includes(query.toLowerCase()) || matchedChildren.length > 0) {
320
+ // 将当前节点加入结果中
321
+ if (node[options.childField]) {
322
+ if (matchedChildren.length > 0) {
323
+ result.push({
324
+ ...node,
325
+ [options.childField]: matchedChildren // 包含匹配的子节点
326
+ });
327
+ }
328
+ else if (options.ignoreEmptyChild) {
329
+ node[options.childField] && delete node[options.childField];
330
+ result.push({
331
+ ...node
332
+ });
333
+ }
334
+ else {
335
+ result.push({
336
+ ...node,
337
+ ...{ [options.childField]: [] }
338
+ });
339
+ }
340
+ }
341
+ else {
342
+ node[options.childField] && delete node[options.childField];
343
+ result.push({
344
+ ...node
345
+ });
346
+ }
347
+ }
348
+ }
349
+ return result;
350
+ }
276
351
 
277
352
  exports.buildTree = buildTree;
353
+ exports.flatTree = flatTree;
278
354
  exports.forEachDeep = forEachDeep;
279
355
  exports.forEachMap = forEachMap;
280
356
  exports.formatTree = formatTree;
357
+ exports.fuzzySearchTree = fuzzySearchTree;
281
358
  exports.searchTreeById = searchTreeById;
package/lib/cjs/type.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/unique.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/cjs/url.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/array.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/async.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/cookie.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/date.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -161,64 +161,50 @@ function formatDate(value, format = 'YYYY-MM-DD HH:mm:ss') {
161
161
  }
162
162
  /**
163
163
  * 计算向前或向后N天的具体日期
164
- * @param {string} strDate - 参考日期
164
+ * @param {DateValue} originDate - 参考日期
165
165
  * @param {number} n - 正数:向后推算;负数:向前推算
166
166
  * @param {string} sep - 日期格式的分隔符
167
167
  * @returns {string} 计算后的目标日期
168
168
  */
169
- function calculateDate(strDate, n, sep = '-') {
170
- //strDate 为字符串日期 如:'2019-01-01' n为你要传入的参数,当前为0,前一天为-1,后一天为1
171
- const dateArr = strDate.split(sep); //这边给定一个特定时间
172
- const newDate = new Date(+dateArr[0], +dateArr[1] - 1, +dateArr[2]);
173
- const befminuts = newDate.getTime() + 1000 * 60 * 60 * 24 * parseInt(String(n)); //计算前几天用减,计算后几天用加,最后一个就是多少天的数量
174
- const beforeDat = new Date();
175
- beforeDat.setTime(befminuts);
176
- const befMonth = beforeDat.getMonth() + 1;
177
- const mon = befMonth >= 10 ? befMonth : '0' + befMonth;
178
- const befDate = beforeDat.getDate();
179
- const da = befDate >= 10 ? befDate : '0' + befDate;
180
- const finalNewDate = beforeDat.getFullYear() + '-' + mon + '-' + da;
169
+ function calculateDate(originDate, n, sep = '-') {
170
+ //originDate 为字符串日期 如:'2019-01-01' n为你要传入的参数,当前为0,前一天为-1,后一天为1
171
+ const date = new Date(originDate); //这边给定一个特定时间
172
+ const newDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
173
+ const millisecondGap = newDate.getTime() + 1000 * 60 * 60 * 24 * parseInt(String(n)); //计算前几天用减,计算后几天用加,最后一个就是多少天的数量
174
+ const targetDate = new Date(millisecondGap);
175
+ const finalNewDate = targetDate.getFullYear() +
176
+ sep +
177
+ String(targetDate.getMonth() + 1).padStart(2, '0') +
178
+ '-' +
179
+ String(targetDate.getDate()).padStart(2, '0');
181
180
  return finalNewDate;
182
181
  }
183
182
  /**
184
- * 计算向前或向后N天的具体时间日期
183
+ * 计算向前或向后N天的具体日期时间
184
+ * @param {DateValue} originDateTime - 参考日期时间
185
185
  * @param {number} n - 正数:向后推算;负数:向前推算
186
186
  * @param {string} dateSep - 日期分隔符
187
187
  * @param {string} timeSep - 时间分隔符
188
188
  * @returns {string} 转换后的目标日期时间
189
189
  */
190
- function calculateDateTime(n, dateSep = '-', timeSep = ':') {
191
- const date = new Date();
192
- const separator1 = '-';
193
- const separator2 = ':';
194
- let year = date.getFullYear();
195
- let month = date.getMonth() + 1;
196
- let strDate = date.getDate() + n;
197
- if (strDate > new Date(year, month, 0).getDate()) {
198
- month += 1;
199
- strDate -= new Date(year, month, 0).getDate();
200
- if (month > 12) {
201
- year += 1;
202
- month = 1;
203
- }
204
- }
205
- if (month >= 1 && month <= 9) {
206
- month = '0' + month;
207
- }
208
- if (strDate >= 0 && strDate <= 9) {
209
- strDate = '0' + strDate;
210
- }
211
- return (year +
190
+ function calculateDateTime(originDateTime, n, dateSep = '-', timeSep = ':') {
191
+ const date = new Date(originDateTime);
192
+ const separator1 = dateSep;
193
+ const separator2 = timeSep;
194
+ const dateTime = new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
195
+ const millisecondGap = dateTime.getTime() + 1000 * 60 * 60 * 24 * parseInt(String(n)); //计算前几天用减,计算后几天用加,最后一个就是多少天的数量
196
+ const targetDateTime = new Date(millisecondGap);
197
+ return (targetDateTime.getFullYear() +
212
198
  separator1 +
213
- month +
199
+ String(targetDateTime.getMonth() + 1).padStart(2, '0') +
214
200
  separator1 +
215
- strDate +
201
+ String(targetDateTime.getDate()).padStart(2, '0') +
216
202
  ' ' +
217
- date.getHours() +
203
+ String(targetDateTime.getHours()).padStart(2, '0') +
218
204
  separator2 +
219
- date.getMinutes() +
205
+ String(targetDateTime.getMinutes()).padStart(2, '0') +
220
206
  separator2 +
221
- date.getSeconds());
207
+ String(targetDateTime.getSeconds()).padStart(2, '0'));
222
208
  }
223
209
 
224
210
  export { calculateDate, calculateDateTime, dateParse, dateToEnd, dateToStart, formatDate, isValidDate };
package/lib/es/dom.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/easing.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/file.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/func.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -24,5 +24,5 @@ export { STRING_POOL, randomNumber, randomString, randomUuid } from './random.js
24
24
  export { HEX_POOL, formatNumber, numberAbbr, numberToHex } from './number.js';
25
25
  export { UNIQUE_NUMBER_SAFE_LENGTH, uniqueNumber, uniqueString } from './unique.js';
26
26
  export { tooltipEvent } from './tooltip.js';
27
- export { buildTree, forEachDeep, forEachMap, formatTree, searchTreeById } from './tree.js';
27
+ export { buildTree, flatTree, forEachDeep, forEachMap, formatTree, fuzzySearchTree, searchTreeById } from './tree.js';
28
28
  export { weAppJwtDecode, weAtob, weBtoa } from './we-decode.js';
package/lib/es/number.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/object.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/path.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/qs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/random.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/string.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/tooltip.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/tree.js CHANGED
@@ -1,10 +1,15 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
6
6
 
7
7
  const defaultFieldOptions = { keyField: 'key', childField: 'children', pidField: 'pid' };
8
+ const defaultSearchTreeOptions = {
9
+ childField: 'children',
10
+ nameField: 'name',
11
+ ignoreEmptyChild: false
12
+ };
8
13
  /**
9
14
  * 深度优先遍历函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
10
15
  * @param {ArrayLike<V>} tree 树形数据
@@ -68,9 +73,9 @@ function forEachDeep(tree, iterator, children = 'children', isReverse = false) {
68
73
  * @returns {any[]} 新的一棵树
69
74
  */
70
75
  function forEachMap(tree, iterator, children = 'children', isReverse = false) {
71
- let level = 0, isBreak = false;
76
+ let isBreak = false;
72
77
  const newTree = [];
73
- const walk = (arr, parent, newTree) => {
78
+ const walk = (arr, parent, newTree, level = 0) => {
74
79
  if (isReverse) {
75
80
  for (let i = arr.length - 1; i >= 0; i--) {
76
81
  if (isBreak) {
@@ -87,10 +92,9 @@ function forEachMap(tree, iterator, children = 'children', isReverse = false) {
87
92
  newTree.push(re);
88
93
  // @ts-ignore
89
94
  if (arr[i] && Array.isArray(arr[i][children])) {
90
- ++level;
91
95
  newTree[newTree.length - 1][children] = [];
92
96
  // @ts-ignore
93
- walk(arr[i][children], arr[i], newTree[newTree.length - 1][children]);
97
+ walk(arr[i][children], arr[i], newTree[newTree.length - 1][children], level + 1);
94
98
  }
95
99
  else {
96
100
  // children非有效数组时,移除该属性字段
@@ -114,10 +118,9 @@ function forEachMap(tree, iterator, children = 'children', isReverse = false) {
114
118
  newTree.push(re);
115
119
  // @ts-ignore
116
120
  if (arr[i] && Array.isArray(arr[i][children])) {
117
- ++level;
118
121
  newTree[newTree.length - 1][children] = [];
119
122
  // @ts-ignore
120
- walk(arr[i][children], arr[i], newTree[newTree.length - 1][children]);
123
+ walk(arr[i][children], arr[i], newTree[newTree.length - 1][children], level + 1);
121
124
  }
122
125
  else {
123
126
  // children非有效数组时,移除该属性字段
@@ -271,5 +274,77 @@ function formatTree(list, options = defaultFieldOptions) {
271
274
  });
272
275
  return treeArr;
273
276
  }
277
+ /**
278
+ * 树形结构转扁平化
279
+ * @param {any} treeList
280
+ * @param {IFieldOptions} options
281
+ * @return {*}
282
+ */
283
+ function flatTree(treeList, options = defaultFieldOptions) {
284
+ const { childField, keyField, pidField } = options;
285
+ return treeList.reduce((res, node) => {
286
+ const item = {
287
+ ...node,
288
+ [childField]: [] // 清空子级
289
+ };
290
+ item.hasOwnProperty([childField]) && delete item[childField];
291
+ res.push(item);
292
+ if (node[childField]) {
293
+ const children = node[childField].map(item => ({
294
+ ...item,
295
+ [pidField]: node[keyField] || item.pid // 给子级设置pid
296
+ }));
297
+ res = res.concat(flatTree(children, options));
298
+ }
299
+ return res;
300
+ }, []);
301
+ }
302
+ /**
303
+ * 模糊搜索函数,返回包含搜索字符的节点及其祖先节点, 适用于树型组件的字符过滤功能
304
+ * @param {any[]} nodes
305
+ * @param {string} query
306
+ * @param {ISearchTreeOpts} options
307
+ * @return {any[]}
308
+ */
309
+ function fuzzySearchTree(nodes, query, options = defaultSearchTreeOptions) {
310
+ const result = [];
311
+ for (const node of nodes) {
312
+ // 递归检查子节点是否匹配
313
+ const matchedChildren = node[options.childField] && node[options.childField].length > 0
314
+ ? fuzzySearchTree(node[options.childField] || [], query, options)
315
+ : [];
316
+ // 检查当前节点是否匹配或者有匹配的子节点
317
+ if (node[options.nameField].toLowerCase().includes(query.toLowerCase()) || matchedChildren.length > 0) {
318
+ // 将当前节点加入结果中
319
+ if (node[options.childField]) {
320
+ if (matchedChildren.length > 0) {
321
+ result.push({
322
+ ...node,
323
+ [options.childField]: matchedChildren // 包含匹配的子节点
324
+ });
325
+ }
326
+ else if (options.ignoreEmptyChild) {
327
+ node[options.childField] && delete node[options.childField];
328
+ result.push({
329
+ ...node
330
+ });
331
+ }
332
+ else {
333
+ result.push({
334
+ ...node,
335
+ ...{ [options.childField]: [] }
336
+ });
337
+ }
338
+ }
339
+ else {
340
+ node[options.childField] && delete node[options.childField];
341
+ result.push({
342
+ ...node
343
+ });
344
+ }
345
+ }
346
+ }
347
+ return result;
348
+ }
274
349
 
275
- export { buildTree, forEachDeep, forEachMap, formatTree, searchTreeById };
350
+ export { buildTree, flatTree, forEachDeep, forEachMap, formatTree, fuzzySearchTree, searchTreeById };
package/lib/es/type.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/unique.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/url.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/index.d.ts CHANGED
@@ -160,20 +160,21 @@ declare function dateToEnd(value: DateValue): Date;
160
160
  declare function formatDate(value: DateValue, format?: string): string;
161
161
  /**
162
162
  * 计算向前或向后N天的具体日期
163
- * @param {string} strDate - 参考日期
163
+ * @param {DateValue} originDate - 参考日期
164
164
  * @param {number} n - 正数:向后推算;负数:向前推算
165
165
  * @param {string} sep - 日期格式的分隔符
166
166
  * @returns {string} 计算后的目标日期
167
167
  */
168
- declare function calculateDate(strDate: string, n: number, sep?: string): string;
168
+ declare function calculateDate(originDate: DateValue, n: number, sep?: string): string;
169
169
  /**
170
- * 计算向前或向后N天的具体时间日期
170
+ * 计算向前或向后N天的具体日期时间
171
+ * @param {DateValue} originDateTime - 参考日期时间
171
172
  * @param {number} n - 正数:向后推算;负数:向前推算
172
173
  * @param {string} dateSep - 日期分隔符
173
174
  * @param {string} timeSep - 时间分隔符
174
175
  * @returns {string} 转换后的目标日期时间
175
176
  */
176
- declare function calculateDateTime(n: number, dateSep?: string, timeSep?: string): string;
177
+ declare function calculateDateTime(originDateTime: DateValue, n: number, dateSep?: string, timeSep?: string): string;
177
178
 
178
179
  type EasingName = 'ease' | 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out' | string;
179
180
 
@@ -708,6 +709,11 @@ interface IFieldOptions {
708
709
  childField: string;
709
710
  pidField: string;
710
711
  }
712
+ interface ISearchTreeOpts {
713
+ childField: string;
714
+ nameField: string;
715
+ ignoreEmptyChild: boolean;
716
+ }
711
717
  /**
712
718
  * 深度优先遍历函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
713
719
  * @param {ArrayLike<V>} tree 树形数据
@@ -786,6 +792,21 @@ declare function buildTree<ID extends string, PID extends string, T extends {
786
792
  * @returns {any[]}
787
793
  */
788
794
  declare function formatTree(list: any[], options?: IFieldOptions): any[];
795
+ /**
796
+ * 树形结构转扁平化
797
+ * @param {any} treeList
798
+ * @param {IFieldOptions} options
799
+ * @return {*}
800
+ */
801
+ declare function flatTree(treeList: any[], options?: IFieldOptions): any[];
802
+ /**
803
+ * 模糊搜索函数,返回包含搜索字符的节点及其祖先节点, 适用于树型组件的字符过滤功能
804
+ * @param {any[]} nodes
805
+ * @param {string} query
806
+ * @param {ISearchTreeOpts} options
807
+ * @return {any[]}
808
+ */
809
+ declare function fuzzySearchTree(nodes: any[], query: string, options?: ISearchTreeOpts): any[];
789
810
 
790
811
  /**
791
812
  * 字符串编码成Base64 (适用于任何环境,包括小程序)
@@ -801,4 +822,4 @@ declare function weBtoa(string: string): string;
801
822
  declare function weAtob(string: string): string;
802
823
  declare function weAppJwtDecode(token: any, options: any): any;
803
824
 
804
- export { type AnyArray, type AnyFunc, type AnyObject, type ArrayElements, type DateObj, type DateValue, type DebounceFunc, type FileType, HEX_POOL, type ICanvasWM, type ICompressOptions, type IFieldOptions, type ITreeConf, type IdLike, type LooseParamValue, type LooseParams, type ObjectAssignItem, type OnceFunc, type Params, type PartialDeep, type RandomString, type ReadyCallback, type Replacer, STRING_ARABIC_NUMERALS, STRING_LOWERCASE_ALPHA, STRING_POOL, STRING_UPPERCASE_ALPHA, type SetStyle, type SmoothScrollOptions, type Style, type ThrottleFunc, UNIQUE_NUMBER_SAFE_LENGTH, type UniqueString, type Url, type WithChildren, addClass, arrayEach, arrayEachAsync, arrayInsertBefore, arrayLike, arrayRemove, asyncMap, buildTree, calculateDate, calculateDateTime, chooseLocalFile, cloneDeep, compressImg, cookieDel, cookieGet, cookieSet, copyText, dateParse, dateToEnd, dateToStart, debounce, downloadBlob, downloadData, downloadHref, downloadURL, forEachDeep, forEachMap, formatDate, formatNumber, formatTree, genCanvasWM, getComputedCssVal, getGlobal, getStrWidthPx, getStyle, hasClass, isArray, isBigInt, isBoolean, isDate, isDomReady, isError, isFunction, isNaN, isNull, isNullOrUnDef, isNumber, isObject, isPlainObject, isPrimitive, isRegExp, isString, isSymbol, isUndefined, isValidDate, numberAbbr, numberToHex, objectAssign, objectEach, objectEachAsync, objectFill, objectGet, objectHas, objectMap, objectAssign as objectMerge, objectOmit, objectPick, onDomReady, once, pathJoin, pathNormalize, qsParse, qsStringify, randomNumber, randomString, randomUuid, removeClass, searchTreeById, setGlobal, setStyle, smoothScroll, stringAssign, stringCamelCase, stringEscapeHtml, stringFill, stringFormat, stringKebabCase, supportCanvas, throttle, tooltipEvent, typeIs, uniqueNumber, uniqueString, urlDelParams, urlParse, urlSetParams, urlStringify, wait, weAppJwtDecode, weAtob, weBtoa };
825
+ export { type AnyArray, type AnyFunc, type AnyObject, type ArrayElements, type DateObj, type DateValue, type DebounceFunc, type FileType, HEX_POOL, type ICanvasWM, type ICompressOptions, type IFieldOptions, type ISearchTreeOpts, type ITreeConf, type IdLike, type LooseParamValue, type LooseParams, type ObjectAssignItem, type OnceFunc, type Params, type PartialDeep, type RandomString, type ReadyCallback, type Replacer, STRING_ARABIC_NUMERALS, STRING_LOWERCASE_ALPHA, STRING_POOL, STRING_UPPERCASE_ALPHA, type SetStyle, type SmoothScrollOptions, type Style, type ThrottleFunc, UNIQUE_NUMBER_SAFE_LENGTH, type UniqueString, type Url, type WithChildren, addClass, arrayEach, arrayEachAsync, arrayInsertBefore, arrayLike, arrayRemove, asyncMap, buildTree, calculateDate, calculateDateTime, chooseLocalFile, cloneDeep, compressImg, cookieDel, cookieGet, cookieSet, copyText, dateParse, dateToEnd, dateToStart, debounce, downloadBlob, downloadData, downloadHref, downloadURL, flatTree, forEachDeep, forEachMap, formatDate, formatNumber, formatTree, fuzzySearchTree, genCanvasWM, getComputedCssVal, getGlobal, getStrWidthPx, getStyle, hasClass, isArray, isBigInt, isBoolean, isDate, isDomReady, isError, isFunction, isNaN, isNull, isNullOrUnDef, isNumber, isObject, isPlainObject, isPrimitive, isRegExp, isString, isSymbol, isUndefined, isValidDate, numberAbbr, numberToHex, objectAssign, objectEach, objectEachAsync, objectFill, objectGet, objectHas, objectMap, objectAssign as objectMerge, objectOmit, objectPick, onDomReady, once, pathJoin, pathNormalize, qsParse, qsStringify, randomNumber, randomString, randomUuid, removeClass, searchTreeById, setGlobal, setStyle, smoothScroll, stringAssign, stringCamelCase, stringEscapeHtml, stringFill, stringFormat, stringKebabCase, supportCanvas, throttle, tooltipEvent, typeIs, uniqueNumber, uniqueString, urlDelParams, urlParse, urlSetParams, urlStringify, wait, weAppJwtDecode, weAtob, weBtoa };
package/lib/umd/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.3.0
2
+ * sculp-js v1.4.0
3
3
  * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -913,64 +913,50 @@
913
913
  }
914
914
  /**
915
915
  * 计算向前或向后N天的具体日期
916
- * @param {string} strDate - 参考日期
916
+ * @param {DateValue} originDate - 参考日期
917
917
  * @param {number} n - 正数:向后推算;负数:向前推算
918
918
  * @param {string} sep - 日期格式的分隔符
919
919
  * @returns {string} 计算后的目标日期
920
920
  */
921
- function calculateDate(strDate, n, sep = '-') {
922
- //strDate 为字符串日期 如:'2019-01-01' n为你要传入的参数,当前为0,前一天为-1,后一天为1
923
- const dateArr = strDate.split(sep); //这边给定一个特定时间
924
- const newDate = new Date(+dateArr[0], +dateArr[1] - 1, +dateArr[2]);
925
- const befminuts = newDate.getTime() + 1000 * 60 * 60 * 24 * parseInt(String(n)); //计算前几天用减,计算后几天用加,最后一个就是多少天的数量
926
- const beforeDat = new Date();
927
- beforeDat.setTime(befminuts);
928
- const befMonth = beforeDat.getMonth() + 1;
929
- const mon = befMonth >= 10 ? befMonth : '0' + befMonth;
930
- const befDate = beforeDat.getDate();
931
- const da = befDate >= 10 ? befDate : '0' + befDate;
932
- const finalNewDate = beforeDat.getFullYear() + '-' + mon + '-' + da;
921
+ function calculateDate(originDate, n, sep = '-') {
922
+ //originDate 为字符串日期 如:'2019-01-01' n为你要传入的参数,当前为0,前一天为-1,后一天为1
923
+ const date = new Date(originDate); //这边给定一个特定时间
924
+ const newDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
925
+ const millisecondGap = newDate.getTime() + 1000 * 60 * 60 * 24 * parseInt(String(n)); //计算前几天用减,计算后几天用加,最后一个就是多少天的数量
926
+ const targetDate = new Date(millisecondGap);
927
+ const finalNewDate = targetDate.getFullYear() +
928
+ sep +
929
+ String(targetDate.getMonth() + 1).padStart(2, '0') +
930
+ '-' +
931
+ String(targetDate.getDate()).padStart(2, '0');
933
932
  return finalNewDate;
934
933
  }
935
934
  /**
936
- * 计算向前或向后N天的具体时间日期
935
+ * 计算向前或向后N天的具体日期时间
936
+ * @param {DateValue} originDateTime - 参考日期时间
937
937
  * @param {number} n - 正数:向后推算;负数:向前推算
938
938
  * @param {string} dateSep - 日期分隔符
939
939
  * @param {string} timeSep - 时间分隔符
940
940
  * @returns {string} 转换后的目标日期时间
941
941
  */
942
- function calculateDateTime(n, dateSep = '-', timeSep = ':') {
943
- const date = new Date();
944
- const separator1 = '-';
945
- const separator2 = ':';
946
- let year = date.getFullYear();
947
- let month = date.getMonth() + 1;
948
- let strDate = date.getDate() + n;
949
- if (strDate > new Date(year, month, 0).getDate()) {
950
- month += 1;
951
- strDate -= new Date(year, month, 0).getDate();
952
- if (month > 12) {
953
- year += 1;
954
- month = 1;
955
- }
956
- }
957
- if (month >= 1 && month <= 9) {
958
- month = '0' + month;
959
- }
960
- if (strDate >= 0 && strDate <= 9) {
961
- strDate = '0' + strDate;
962
- }
963
- return (year +
942
+ function calculateDateTime(originDateTime, n, dateSep = '-', timeSep = ':') {
943
+ const date = new Date(originDateTime);
944
+ const separator1 = dateSep;
945
+ const separator2 = timeSep;
946
+ const dateTime = new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
947
+ const millisecondGap = dateTime.getTime() + 1000 * 60 * 60 * 24 * parseInt(String(n)); //计算前几天用减,计算后几天用加,最后一个就是多少天的数量
948
+ const targetDateTime = new Date(millisecondGap);
949
+ return (targetDateTime.getFullYear() +
964
950
  separator1 +
965
- month +
951
+ String(targetDateTime.getMonth() + 1).padStart(2, '0') +
966
952
  separator1 +
967
- strDate +
953
+ String(targetDateTime.getDate()).padStart(2, '0') +
968
954
  ' ' +
969
- date.getHours() +
955
+ String(targetDateTime.getHours()).padStart(2, '0') +
970
956
  separator2 +
971
- date.getMinutes() +
957
+ String(targetDateTime.getMinutes()).padStart(2, '0') +
972
958
  separator2 +
973
- date.getSeconds());
959
+ String(targetDateTime.getSeconds()).padStart(2, '0'));
974
960
  }
975
961
 
976
962
  /**
@@ -2043,6 +2029,11 @@
2043
2029
  const tooltipEvent = { handleMouseEnter, handleMouseLeave };
2044
2030
 
2045
2031
  const defaultFieldOptions = { keyField: 'key', childField: 'children', pidField: 'pid' };
2032
+ const defaultSearchTreeOptions = {
2033
+ childField: 'children',
2034
+ nameField: 'name',
2035
+ ignoreEmptyChild: false
2036
+ };
2046
2037
  /**
2047
2038
  * 深度优先遍历函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
2048
2039
  * @param {ArrayLike<V>} tree 树形数据
@@ -2106,9 +2097,9 @@
2106
2097
  * @returns {any[]} 新的一棵树
2107
2098
  */
2108
2099
  function forEachMap(tree, iterator, children = 'children', isReverse = false) {
2109
- let level = 0, isBreak = false;
2100
+ let isBreak = false;
2110
2101
  const newTree = [];
2111
- const walk = (arr, parent, newTree) => {
2102
+ const walk = (arr, parent, newTree, level = 0) => {
2112
2103
  if (isReverse) {
2113
2104
  for (let i = arr.length - 1; i >= 0; i--) {
2114
2105
  if (isBreak) {
@@ -2125,10 +2116,9 @@
2125
2116
  newTree.push(re);
2126
2117
  // @ts-ignore
2127
2118
  if (arr[i] && Array.isArray(arr[i][children])) {
2128
- ++level;
2129
2119
  newTree[newTree.length - 1][children] = [];
2130
2120
  // @ts-ignore
2131
- walk(arr[i][children], arr[i], newTree[newTree.length - 1][children]);
2121
+ walk(arr[i][children], arr[i], newTree[newTree.length - 1][children], level + 1);
2132
2122
  }
2133
2123
  else {
2134
2124
  // children非有效数组时,移除该属性字段
@@ -2152,10 +2142,9 @@
2152
2142
  newTree.push(re);
2153
2143
  // @ts-ignore
2154
2144
  if (arr[i] && Array.isArray(arr[i][children])) {
2155
- ++level;
2156
2145
  newTree[newTree.length - 1][children] = [];
2157
2146
  // @ts-ignore
2158
- walk(arr[i][children], arr[i], newTree[newTree.length - 1][children]);
2147
+ walk(arr[i][children], arr[i], newTree[newTree.length - 1][children], level + 1);
2159
2148
  }
2160
2149
  else {
2161
2150
  // children非有效数组时,移除该属性字段
@@ -2309,6 +2298,78 @@
2309
2298
  });
2310
2299
  return treeArr;
2311
2300
  }
2301
+ /**
2302
+ * 树形结构转扁平化
2303
+ * @param {any} treeList
2304
+ * @param {IFieldOptions} options
2305
+ * @return {*}
2306
+ */
2307
+ function flatTree(treeList, options = defaultFieldOptions) {
2308
+ const { childField, keyField, pidField } = options;
2309
+ return treeList.reduce((res, node) => {
2310
+ const item = {
2311
+ ...node,
2312
+ [childField]: [] // 清空子级
2313
+ };
2314
+ item.hasOwnProperty([childField]) && delete item[childField];
2315
+ res.push(item);
2316
+ if (node[childField]) {
2317
+ const children = node[childField].map(item => ({
2318
+ ...item,
2319
+ [pidField]: node[keyField] || item.pid // 给子级设置pid
2320
+ }));
2321
+ res = res.concat(flatTree(children, options));
2322
+ }
2323
+ return res;
2324
+ }, []);
2325
+ }
2326
+ /**
2327
+ * 模糊搜索函数,返回包含搜索字符的节点及其祖先节点, 适用于树型组件的字符过滤功能
2328
+ * @param {any[]} nodes
2329
+ * @param {string} query
2330
+ * @param {ISearchTreeOpts} options
2331
+ * @return {any[]}
2332
+ */
2333
+ function fuzzySearchTree(nodes, query, options = defaultSearchTreeOptions) {
2334
+ const result = [];
2335
+ for (const node of nodes) {
2336
+ // 递归检查子节点是否匹配
2337
+ const matchedChildren = node[options.childField] && node[options.childField].length > 0
2338
+ ? fuzzySearchTree(node[options.childField] || [], query, options)
2339
+ : [];
2340
+ // 检查当前节点是否匹配或者有匹配的子节点
2341
+ if (node[options.nameField].toLowerCase().includes(query.toLowerCase()) || matchedChildren.length > 0) {
2342
+ // 将当前节点加入结果中
2343
+ if (node[options.childField]) {
2344
+ if (matchedChildren.length > 0) {
2345
+ result.push({
2346
+ ...node,
2347
+ [options.childField]: matchedChildren // 包含匹配的子节点
2348
+ });
2349
+ }
2350
+ else if (options.ignoreEmptyChild) {
2351
+ node[options.childField] && delete node[options.childField];
2352
+ result.push({
2353
+ ...node
2354
+ });
2355
+ }
2356
+ else {
2357
+ result.push({
2358
+ ...node,
2359
+ ...{ [options.childField]: [] }
2360
+ });
2361
+ }
2362
+ }
2363
+ else {
2364
+ node[options.childField] && delete node[options.childField];
2365
+ result.push({
2366
+ ...node
2367
+ });
2368
+ }
2369
+ }
2370
+ }
2371
+ return result;
2372
+ }
2312
2373
 
2313
2374
  exports.HEX_POOL = HEX_POOL;
2314
2375
  exports.STRING_ARABIC_NUMERALS = STRING_ARABIC_NUMERALS;
@@ -2341,11 +2402,13 @@
2341
2402
  exports.downloadData = downloadData;
2342
2403
  exports.downloadHref = downloadHref;
2343
2404
  exports.downloadURL = downloadURL;
2405
+ exports.flatTree = flatTree;
2344
2406
  exports.forEachDeep = forEachDeep;
2345
2407
  exports.forEachMap = forEachMap;
2346
2408
  exports.formatDate = formatDate;
2347
2409
  exports.formatNumber = formatNumber;
2348
2410
  exports.formatTree = formatTree;
2411
+ exports.fuzzySearchTree = fuzzySearchTree;
2349
2412
  exports.genCanvasWM = genCanvasWM;
2350
2413
  exports.getComputedCssVal = getComputedCssVal;
2351
2414
  exports.getGlobal = getGlobal;
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "sculp-js",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "packageManager": "npm@8.19.2",
5
5
  "description": "js工具库",
6
6
  "scripts": {
7
7
  "prepare": "husky install",
8
8
  "build": "rollup --bundleConfigAsCjs --config rollup.config.js",
9
+ "build:core": "BUILD_TARGET=core rollup --bundleConfigAsCjs --config rollup.config.js",
9
10
  "build:terser": "node scripts/build.js",
10
11
  "test:unit": "jest",
11
12
  "test": "jest --coverage",