@yh-kit/utils 1.18.0 → 1.19.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/dist/utils.js CHANGED
@@ -41,7 +41,7 @@ const b = {
41
41
  t[r[n]] = o;
42
42
  }), t;
43
43
  }
44
- }, M = {
44
+ }, S = {
45
45
  /**
46
46
  * 判断某元素是否在存在于数组中(indexOf方法)
47
47
  * @param arr 数组
@@ -60,7 +60,7 @@ const b = {
60
60
  isExistByIncludes(e, n) {
61
61
  return !e || !n ? !1 : e.includes(n);
62
62
  }
63
- }, S = {
63
+ }, M = {
64
64
  /**
65
65
  * 获取数组中的最大值
66
66
  * @param arr 数组
@@ -312,13 +312,13 @@ const b = {
312
312
  return this.uniqueBySet(o);
313
313
  if (t) {
314
314
  const s = /* @__PURE__ */ new Map();
315
- return o.filter((c) => {
316
- const l = t.map((i) => c[i]).join("|");
317
- return s.has(l) ? !1 : (s.set(l, !0), !0);
315
+ return o.filter((i) => {
316
+ const a = t.map((c) => i[c]).join("|");
317
+ return s.has(a) ? !1 : (s.set(a, !0), !0);
318
318
  });
319
319
  }
320
320
  if (r)
321
- return o.filter((s, c, l) => c === l.findIndex((i) => r(s, i)));
321
+ return o.filter((s, i, a) => i === a.findIndex((c) => r(s, c)));
322
322
  }
323
323
  }, C = {
324
324
  // 数组转对象
@@ -326,17 +326,17 @@ const b = {
326
326
  // 数组去重
327
327
  ...B,
328
328
  // 判断元素是否存在
329
- ...M,
329
+ ...S,
330
330
  // 数组排序
331
331
  ...x,
332
332
  // 获取极值
333
- ...S,
333
+ ...M,
334
334
  // 统计出现次数
335
335
  ...b,
336
336
  // 数组随机打乱-Fisher-Yates算法
337
337
  ...E
338
338
  };
339
- class F {
339
+ class q {
340
340
  /** Base64 编码表 */
341
341
  static BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
342
342
  /**
@@ -349,19 +349,19 @@ class F {
349
349
  * @returns 返回转换后的Blob对象,如果转换失败,则返回null。
350
350
  */
351
351
  static toBlob(n, t = "", r = 512) {
352
- const s = (n.split(",")[1] || n).replace(/-/g, "+").replace(/_/g, "/"), c = "=".repeat((4 - s.length % 4) % 4), l = s + c;
352
+ const s = (n.split(",")[1] || n).replace(/-/g, "+").replace(/_/g, "/"), i = "=".repeat((4 - s.length % 4) % 4), a = s + i;
353
353
  try {
354
- const i = atob(l), h = [];
355
- for (let a = 0; a < i.length; a += r) {
356
- const u = i.slice(a, a + r), f = new Array(u.length);
354
+ const c = atob(a), h = [];
355
+ for (let l = 0; l < c.length; l += r) {
356
+ const u = c.slice(l, l + r), f = new Array(u.length);
357
357
  for (let d = 0; d < u.length; d++)
358
358
  f[d] = u.charCodeAt(d);
359
359
  const p = new Uint8Array(f);
360
360
  h.push(p);
361
361
  }
362
362
  return new Blob(h, { type: t });
363
- } catch (i) {
364
- return console.error("Failed to convert base64 to blob:", i), null;
363
+ } catch (c) {
364
+ return console.error("Failed to convert base64 to blob:", c), null;
365
365
  }
366
366
  }
367
367
  /**
@@ -375,15 +375,15 @@ class F {
375
375
  * @returns 返回一个File对象,包含解码后的数据。
376
376
  */
377
377
  static toFile(n, t = "file.txt", r = "text/plain") {
378
- const s = n.replace(/^data:.+;base64,/, "").replace(/-/g, "+").replace(/_/g, "/"), c = "=".repeat((4 - s.length % 4) % 4), l = s + c, i = atob(l), h = [];
379
- for (let u = 0; u < i.length; u += 512) {
380
- const f = i.slice(u, u + 512), p = new Array(f.length);
378
+ const s = n.replace(/^data:.+;base64,/, "").replace(/-/g, "+").replace(/_/g, "/"), i = "=".repeat((4 - s.length % 4) % 4), a = s + i, c = atob(a), h = [];
379
+ for (let u = 0; u < c.length; u += 512) {
380
+ const f = c.slice(u, u + 512), p = new Array(f.length);
381
381
  for (let d = 0; d < f.length; d++)
382
382
  p[d] = f.charCodeAt(d);
383
383
  h.push(new Uint8Array(p));
384
384
  }
385
- const a = new Blob(h, { type: r });
386
- return new File([a], t, { type: r });
385
+ const l = new Blob(h, { type: r });
386
+ return new File([l], t, { type: r });
387
387
  }
388
388
  /**
389
389
  * base64加密 -- 普通字符串转 Base64 编码
@@ -421,10 +421,10 @@ class F {
421
421
  t.push(224 | o >> 12), t.push(128 | o >> 6 & 63), t.push(128 | o & 63);
422
422
  else {
423
423
  r++;
424
- const s = o, c = n.charCodeAt(r);
425
- if (isNaN(c))
424
+ const s = o, i = n.charCodeAt(r);
425
+ if (isNaN(i))
426
426
  throw new Error("代理对不完整");
427
- o = 65536 + ((s & 1023) << 10) + (c & 1023), t.push(240 | o >> 18), t.push(128 | o >> 12 & 63), t.push(128 | o >> 6 & 63), t.push(128 | o & 63);
427
+ o = 65536 + ((s & 1023) << 10) + (i & 1023), t.push(240 | o >> 18), t.push(128 | o >> 12 & 63), t.push(128 | o >> 6 & 63), t.push(128 | o & 63);
428
428
  }
429
429
  }
430
430
  return t;
@@ -442,11 +442,11 @@ class F {
442
442
  const s = n[r++] & 63;
443
443
  t += String.fromCharCode((o & 31) << 6 | s);
444
444
  } else if (o >= 224 && o < 240) {
445
- const s = n[r++] & 63, c = n[r++] & 63;
446
- t += String.fromCharCode((o & 15) << 12 | s << 6 | c);
445
+ const s = n[r++] & 63, i = n[r++] & 63;
446
+ t += String.fromCharCode((o & 15) << 12 | s << 6 | i);
447
447
  } else if (o >= 240 && o < 248) {
448
- const s = n[r++] & 63, c = n[r++] & 63, l = n[r++] & 63, i = (o & 7) << 18 | s << 12 | c << 6 | l, h = Math.floor((i - 65536) / 1024) + 55296, a = (i - 65536) % 1024 + 56320;
449
- t += String.fromCharCode(h, a);
448
+ const s = n[r++] & 63, i = n[r++] & 63, a = n[r++] & 63, c = (o & 7) << 18 | s << 12 | i << 6 | a, h = Math.floor((c - 65536) / 1024) + 55296, l = (c - 65536) % 1024 + 56320;
449
+ t += String.fromCharCode(h, l);
450
450
  } else
451
451
  t += "�";
452
452
  }
@@ -458,8 +458,8 @@ class F {
458
458
  static _bytesToBase64(n) {
459
459
  let t = "", r = 0;
460
460
  for (; r < n.length; ) {
461
- const o = n[r++], s = r < n.length, c = s ? n[r++] : 0, l = r < n.length, i = l ? n[r++] : 0, h = o >> 2, a = (o & 3) << 4 | c >> 4, u = (c & 15) << 2 | i >> 6, f = i & 63;
462
- s ? l ? t += this.BASE64_CHARS.charAt(h) + this.BASE64_CHARS.charAt(a) + this.BASE64_CHARS.charAt(u) + this.BASE64_CHARS.charAt(f) : t += this.BASE64_CHARS.charAt(h) + this.BASE64_CHARS.charAt(a) + this.BASE64_CHARS.charAt(u) + "=" : t += this.BASE64_CHARS.charAt(h) + this.BASE64_CHARS.charAt(a) + "==";
461
+ const o = n[r++], s = r < n.length, i = s ? n[r++] : 0, a = r < n.length, c = a ? n[r++] : 0, h = o >> 2, l = (o & 3) << 4 | i >> 4, u = (i & 15) << 2 | c >> 6, f = c & 63;
462
+ s ? a ? t += this.BASE64_CHARS.charAt(h) + this.BASE64_CHARS.charAt(l) + this.BASE64_CHARS.charAt(u) + this.BASE64_CHARS.charAt(f) : t += this.BASE64_CHARS.charAt(h) + this.BASE64_CHARS.charAt(l) + this.BASE64_CHARS.charAt(u) + "=" : t += this.BASE64_CHARS.charAt(h) + this.BASE64_CHARS.charAt(l) + "==";
463
463
  }
464
464
  return t;
465
465
  }
@@ -470,27 +470,27 @@ class F {
470
470
  const t = n.length;
471
471
  let r = 0;
472
472
  t >= 2 && (n[t - 1] === "=" && r++, n[t - 2] === "=" && r++);
473
- const o = Math.floor(t * 3 / 4) - r, s = new Array(o), c = new Array(256).fill(-1);
473
+ const o = Math.floor(t * 3 / 4) - r, s = new Array(o), i = new Array(256).fill(-1);
474
474
  for (let h = 0; h < this.BASE64_CHARS.length; h++)
475
- c[this.BASE64_CHARS.charCodeAt(h)] = h;
476
- let l = 0, i = 0;
477
- for (; i < t; ) {
478
- const h = c[n.charCodeAt(i++)], a = c[n.charCodeAt(i++)], u = i < t ? c[n.charCodeAt(i++)] : -1, f = i < t ? c[n.charCodeAt(i++)] : -1;
479
- if (h === -1 || a === -1)
475
+ i[this.BASE64_CHARS.charCodeAt(h)] = h;
476
+ let a = 0, c = 0;
477
+ for (; c < t; ) {
478
+ const h = i[n.charCodeAt(c++)], l = i[n.charCodeAt(c++)], u = c < t ? i[n.charCodeAt(c++)] : -1, f = c < t ? i[n.charCodeAt(c++)] : -1;
479
+ if (h === -1 || l === -1)
480
480
  throw new Error("无效的 Base64 字符");
481
- const p = h << 2 | a >> 4;
482
- if (s[l++] = p, u !== -1) {
483
- const d = (a & 15) << 4 | u >> 2;
484
- if (s[l++] = d, f !== -1) {
481
+ const p = h << 2 | l >> 4;
482
+ if (s[a++] = p, u !== -1) {
483
+ const d = (l & 15) << 4 | u >> 2;
484
+ if (s[a++] = d, f !== -1) {
485
485
  const g = (u & 3) << 6 | f;
486
- s[l++] = g;
486
+ s[a++] = g;
487
487
  }
488
488
  }
489
489
  }
490
490
  return s;
491
491
  }
492
492
  }
493
- const R = {
493
+ const T = {
494
494
  /**
495
495
  * 检查是否为空字符串
496
496
  * @param str 要检查的字符串
@@ -667,7 +667,7 @@ const R = {
667
667
  }
668
668
  }, D = {
669
669
  /**
670
- * 浅拷贝
670
+ * 浅拷贝,使用 for 循环实现浅拷贝
671
671
  * @param source 需要处理的源对象
672
672
  * @returns 浅拷贝后的新对象
673
673
  */
@@ -681,6 +681,22 @@ const R = {
681
681
  n[t] = e[t];
682
682
  return n;
683
683
  },
684
+ /**
685
+ * 浅拷贝,使用 Object.assign({}, source) 实现浅拷贝
686
+ * @param source 需要处理的源对象
687
+ * @returns 浅拷贝后的新对象
688
+ */
689
+ shallowCloneByObjectAssign(e) {
690
+ return Object.assign({}, e);
691
+ },
692
+ /**
693
+ * 浅拷贝,使用 扩展运算符 ...source 实现浅拷贝【更推荐】
694
+ * @param source 需要处理的源对象
695
+ * @returns 浅拷贝后的新对象
696
+ */
697
+ shallowCloneBySpreadOperator(e) {
698
+ return { ...e };
699
+ },
684
700
  /**
685
701
  * 最便捷实现深克隆/拷贝
686
702
  * 存在的问题:
@@ -709,7 +725,7 @@ const R = {
709
725
  throw new Error("空对象不能进行深拷贝");
710
726
  if (n.has(e))
711
727
  return n.get(e);
712
- const t = T.getType(e);
728
+ const t = v.getType(e);
713
729
  let r;
714
730
  switch (t) {
715
731
  case "object":
@@ -742,7 +758,7 @@ const R = {
742
758
  );
743
759
  }), r);
744
760
  }
745
- }, U = {
761
+ }, R = {
746
762
  /**
747
763
  * 函数柯里化
748
764
  * 定义:把一个多参数的函数,转换为一系列的单参数函数,每个函数只处理一个参数。
@@ -791,7 +807,7 @@ const R = {
791
807
  return e.call(n, ...t);
792
808
  };
793
809
  }
794
- }, O = {
810
+ }, U = {
795
811
  /**
796
812
  * 获取变量的类型
797
813
  * @param val 任意变量
@@ -800,11 +816,11 @@ const R = {
800
816
  getType(e) {
801
817
  return Object.prototype.toString.call(e).replace(/\[object\s(\w+)\]/, "$1");
802
818
  }
803
- }, T = {
804
- ...O,
819
+ }, v = {
820
+ ...U,
805
821
  ...D,
806
- ...U
807
- }, P = {
822
+ ...R
823
+ }, V = {
808
824
  /**
809
825
  * 通过传入的name获取cookie的值
810
826
  * @param name cookie的name
@@ -834,7 +850,7 @@ const R = {
834
850
  deleteCookie(e) {
835
851
  this.setCookie(e, "", -1);
836
852
  }
837
- }, q = {
853
+ }, W = {
838
854
  /**
839
855
  * 获取当前时间字符串
840
856
  * @param locales 区域设置。如:'zh-CN','en-US',"chinese"。默认'zh-CN'。
@@ -882,7 +898,7 @@ const R = {
882
898
  r += 31;
883
899
  break;
884
900
  case 2:
885
- R.isLeapYear(e) ? r += 29 : r += 28;
901
+ T.isLeapYear(e) ? r += 29 : r += 28;
886
902
  break;
887
903
  default:
888
904
  r += 30;
@@ -897,29 +913,29 @@ const R = {
897
913
  * @returns 时间字符串
898
914
  */
899
915
  getTimeStringAutoShort2(e, n) {
900
- const t = /* @__PURE__ */ new Date(), r = new Date(e), o = t.getFullYear(), s = t.getMonth() + 1, c = t.getDate(), l = r.getFullYear(), i = r.getMonth() + 1, h = r.getDate();
901
- let a = "";
916
+ const t = /* @__PURE__ */ new Date(), r = new Date(e), o = t.getFullYear(), s = t.getMonth() + 1, i = t.getDate(), a = r.getFullYear(), c = r.getMonth() + 1, h = r.getDate();
917
+ let l = "";
902
918
  const u = n ? " " + this.formatDate(r, "hh:mm") : "";
903
- if (o === l) {
919
+ if (o === a) {
904
920
  const d = t.getTime() - e;
905
- if (s === i && c === h)
906
- d < 60 * 1e3 ? a = "刚刚" : a = this.formatDate(r, "hh:mm");
921
+ if (s === c && i === h)
922
+ d < 60 * 1e3 ? l = "刚刚" : l = this.formatDate(r, "hh:mm");
907
923
  else {
908
924
  const g = /* @__PURE__ */ new Date();
909
925
  g.setDate(g.getDate() - 1);
910
926
  const w = /* @__PURE__ */ new Date();
911
- if (w.setDate(w.getDate() - 2), i === g.getMonth() + 1 && h === g.getDate())
912
- a = "昨天" + u;
913
- else if (i === w.getMonth() + 1 && h === w.getDate())
914
- a = "前天" + u;
927
+ if (w.setDate(w.getDate() - 2), c === g.getMonth() + 1 && h === g.getDate())
928
+ l = "昨天" + u;
929
+ else if (c === w.getMonth() + 1 && h === w.getDate())
930
+ l = "前天" + u;
915
931
  else if (d / 36e5 <= 7 * 24) {
916
932
  const y = new Array(7);
917
- y[0] = "星期日", y[1] = "星期一", y[2] = "星期二", y[3] = "星期三", y[4] = "星期四", y[5] = "星期五", y[6] = "星期六", a = y[r.getDay()] + u;
918
- } else a = this.formatDate(r, "yyyy/M/d") + u;
933
+ y[0] = "星期日", y[1] = "星期一", y[2] = "星期二", y[3] = "星期三", y[4] = "星期四", y[5] = "星期五", y[6] = "星期六", l = y[r.getDay()] + u;
934
+ } else l = this.formatDate(r, "yyyy/M/d") + u;
919
935
  }
920
936
  } else
921
- a = this.formatDate(r, "yyyy/M/d") + u;
922
- return a;
937
+ l = this.formatDate(r, "yyyy/M/d") + u;
938
+ return l;
923
939
  },
924
940
  /**
925
941
  * 格式化日期
@@ -949,7 +965,7 @@ const R = {
949
965
  new RegExp("(" + r + ")").test(n) && (n = n.replace(RegExp.$1, RegExp.$1.length === 1 ? t[r] : ("00" + t[r]).substr(("" + t[r]).length)));
950
966
  return n;
951
967
  }
952
- }, V = {
968
+ }, Y = {
953
969
  /**
954
970
  * 获取元素相对于文档顶部的偏移量(距离)
955
971
  * 处理了SVG元素的特殊情况。
@@ -1020,7 +1036,7 @@ const R = {
1020
1036
  getViewportHeight() {
1021
1037
  return window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
1022
1038
  }
1023
- }, W = {
1039
+ }, z = {
1024
1040
  /**
1025
1041
  * 将blob对象转化成文件并导出到本地
1026
1042
  * @param blob blob对象
@@ -1039,7 +1055,7 @@ const R = {
1039
1055
  const t = document.createElement("a");
1040
1056
  t.href = e, t.download = n, document.body.appendChild(t), t.click(), URL.revokeObjectURL(e), document.body.removeChild(t);
1041
1057
  }
1042
- }, Y = {
1058
+ }, J = {
1043
1059
  /**
1044
1060
  * echarts动画函数
1045
1061
  * @param option echarts配置
@@ -1071,7 +1087,7 @@ const R = {
1071
1087
  });
1072
1088
  });
1073
1089
  }
1074
- }, z = {
1090
+ }, Z = {
1075
1091
  /**
1076
1092
  * 将选中的字母数组从A-Z排序:用于试题选择答案的排序实例
1077
1093
  * @param arr 字母数组
@@ -1083,7 +1099,7 @@ const R = {
1083
1099
  return o < s ? -1 : o > s ? 1 : 0;
1084
1100
  }) : void 0;
1085
1101
  }
1086
- }, J = {
1102
+ }, K = {
1087
1103
  /**
1088
1104
  * 角度(度数)转弧度
1089
1105
  * 在数学和编程里,角度有两种常用单位,分别是度(°)和弧度(rad)。
@@ -1104,13 +1120,13 @@ const R = {
1104
1120
  * @returns 距离值 单位:km
1105
1121
  */
1106
1122
  getDistance(e, n, t, r) {
1107
- const o = this.degrees2Radians(e), s = this.degrees2Radians(t), c = o - s, l = this.degrees2Radians(n) - this.degrees2Radians(r);
1108
- let i = 2 * Math.asin(
1123
+ const o = this.degrees2Radians(e), s = this.degrees2Radians(t), i = o - s, a = this.degrees2Radians(n) - this.degrees2Radians(r);
1124
+ let c = 2 * Math.asin(
1109
1125
  Math.sqrt(
1110
- Math.pow(Math.sin(c / 2), 2) + Math.cos(o) * Math.cos(s) * Math.pow(Math.sin(l / 2), 2)
1126
+ Math.pow(Math.sin(i / 2), 2) + Math.cos(o) * Math.cos(s) * Math.pow(Math.sin(a / 2), 2)
1111
1127
  )
1112
1128
  );
1113
- return i = i * 6378.137, i = Math.round(i * 1e4) / 1e4, i = +i.toFixed(2), console.log("经纬度计算的距离为:" + i), i;
1129
+ return c = c * 6378.137, c = Math.round(c * 1e4) / 1e4, c = +c.toFixed(2), console.log("经纬度计算的距离为:" + c), c;
1114
1130
  },
1115
1131
  /**
1116
1132
  * 计算两个坐标点之间的距离(Haversine公式)
@@ -1128,10 +1144,10 @@ const R = {
1128
1144
  * @returns 距离值
1129
1145
  */
1130
1146
  calculateDistanceByHaversine(e, n, t = "km") {
1131
- const r = this, o = e.longitude ?? e.lng, s = e.latitude ?? e.lat, c = n.longitude ?? n.lng, l = n.latitude ?? n.lat;
1132
- if (o === void 0 || s === void 0 || c === void 0 || l === void 0)
1147
+ const r = this, o = e.longitude ?? e.lng, s = e.latitude ?? e.lat, i = n.longitude ?? n.lng, a = n.latitude ?? n.lat;
1148
+ if (o === void 0 || s === void 0 || i === void 0 || a === void 0)
1133
1149
  throw new Error("无效的坐标格式,缺少经纬度信息");
1134
- const i = 6371, h = r.degrees2Radians(s), a = r.degrees2Radians(l), u = r.degrees2Radians(l - s), f = r.degrees2Radians(c - o), p = Math.sin(u / 2) * Math.sin(u / 2) + Math.cos(h) * Math.cos(a) * Math.sin(f / 2) * Math.sin(f / 2), d = 2 * Math.atan2(Math.sqrt(p), Math.sqrt(1 - p)), g = i * d;
1150
+ const c = 6371, h = r.degrees2Radians(s), l = r.degrees2Radians(a), u = r.degrees2Radians(a - s), f = r.degrees2Radians(i - o), p = Math.sin(u / 2) * Math.sin(u / 2) + Math.cos(h) * Math.cos(l) * Math.sin(f / 2) * Math.sin(f / 2), d = 2 * Math.atan2(Math.sqrt(p), Math.sqrt(1 - p)), g = c * d;
1135
1151
  switch (t) {
1136
1152
  case "m":
1137
1153
  return g * 1e3;
@@ -1159,8 +1175,8 @@ const R = {
1159
1175
  const r = [];
1160
1176
  let o = 0;
1161
1177
  for (let s = 0; s < e.length - 1; s++) {
1162
- const c = this.calculateDistanceByHaversine(e[s], e[s + 1], n);
1163
- r.push(c), o += c;
1178
+ const i = this.calculateDistanceByHaversine(e[s], e[s + 1], n);
1179
+ r.push(i), o += i;
1164
1180
  }
1165
1181
  if (t && e.length > 2) {
1166
1182
  const s = this.calculateDistanceByHaversine(e[e.length - 1], e[0], n);
@@ -1169,7 +1185,7 @@ const R = {
1169
1185
  return { segments: r, total: o };
1170
1186
  }
1171
1187
  };
1172
- class Z {
1188
+ class X {
1173
1189
  /**
1174
1190
  * 转换为标准金额格式(带千分位和两位小数)
1175
1191
  * @param num 要转换的数字
@@ -1199,32 +1215,32 @@ class Z {
1199
1215
  throw new Error("输入不是有效的数字");
1200
1216
  if (t > 9999999999999e-2 || t < -9999999999999e-2)
1201
1217
  throw new Error("输入数字超出范围");
1202
- const r = t < 0, o = Math.abs(t), s = Math.floor(o), c = Math.round((o - s) * 100), l = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"], i = ["", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟"], h = ["角", "分"];
1203
- let a = "", u = s;
1218
+ const r = t < 0, o = Math.abs(t), s = Math.floor(o), i = Math.round((o - s) * 100), a = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"], c = ["", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟"], h = ["角", "分"];
1219
+ let l = "", u = s;
1204
1220
  if (u === 0)
1205
- a = l[0];
1221
+ l = a[0];
1206
1222
  else {
1207
1223
  let d = 0;
1208
1224
  for (; u > 0; ) {
1209
1225
  const g = u % 10;
1210
- g !== 0 ? a = l[g] + i[d] + a : a.charAt(0) !== l[0] && (a = l[g] + a), u = Math.floor(u / 10), d++;
1226
+ g !== 0 ? l = a[g] + c[d] + l : l.charAt(0) !== a[0] && (l = a[g] + l), u = Math.floor(u / 10), d++;
1211
1227
  }
1212
- a = a.replace(/零+/g, "零"), a = a.replace(/零+$/, "");
1228
+ l = l.replace(/零+/g, "零"), l = l.replace(/零+$/, "");
1213
1229
  }
1214
1230
  let f = "";
1215
- if (c > 0) {
1216
- const d = Math.floor(c / 10), g = c % 10;
1217
- d > 0 && (f += l[d] + h[0]), g > 0 && (f += l[g] + h[1]);
1231
+ if (i > 0) {
1232
+ const d = Math.floor(i / 10), g = i % 10;
1233
+ d > 0 && (f += a[d] + h[0]), g > 0 && (f += a[g] + h[1]);
1218
1234
  } else
1219
1235
  f = "整";
1220
- let p = (r ? "负" : "") + a + "圆" + f;
1236
+ let p = (r ? "负" : "") + l + "圆" + f;
1221
1237
  return p === "零圆整" && (p = "零圆"), p;
1222
1238
  } catch (t) {
1223
1239
  return console.error("转换失败:", t), "格式错误";
1224
1240
  }
1225
1241
  }
1226
1242
  }
1227
- const K = {
1243
+ const G = {
1228
1244
  /**
1229
1245
  * 中文姓名脱敏
1230
1246
  * @param name 姓名
@@ -1258,22 +1274,22 @@ const K = {
1258
1274
  ];
1259
1275
  n.compoundSurname && n.compoundSurname.trim().length > 0 && !o.includes(n.compoundSurname) && o.push(n.compoundSurname);
1260
1276
  let s = "";
1261
- o.some((l) => e.startsWith(l)) ? s = o.find((l) => e.startsWith(l)) || "" : s = e[0] || "";
1262
- const c = Math.max(t, s.length);
1263
- if (c >= e.length) return e;
1277
+ o.some((a) => e.startsWith(a)) ? s = o.find((a) => e.startsWith(a)) || "" : s = e[0] || "";
1278
+ const i = Math.max(t, s.length);
1279
+ if (i >= e.length) return e;
1264
1280
  if (r && e.length > 2) {
1265
- const l = e.slice(0, c), i = e.slice(-1), h = e.length - c - 1;
1266
- return `${l}${"*".repeat(h)}${i}`;
1281
+ const a = e.slice(0, i), c = e.slice(-1), h = e.length - i - 1;
1282
+ return `${a}${"*".repeat(h)}${c}`;
1267
1283
  }
1268
- return `${e.slice(0, c)}${"*".repeat(e.length - c)}`;
1284
+ return `${e.slice(0, i)}${"*".repeat(e.length - i)}`;
1269
1285
  }
1270
- }, v = (e) => e > 25 || e < 0 ? "" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[e], j = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1286
+ }, O = (e) => e > 25 || e < 0 ? "" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[e], j = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1271
1287
  __proto__: null,
1272
- toLetter: v
1288
+ toLetter: O
1273
1289
  }, Symbol.toStringTag, { value: "Module" })), L = (e) => e.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","), I = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1274
1290
  __proto__: null,
1275
1291
  toMoney: L
1276
- }, Symbol.toStringTag, { value: "Module" })), X = {
1292
+ }, Symbol.toStringTag, { value: "Module" })), Q = {
1277
1293
  ...j,
1278
1294
  ...I,
1279
1295
  /**
@@ -1284,7 +1300,114 @@ const K = {
1284
1300
  isNumber(e) {
1285
1301
  return typeof e == "number" && !isNaN(e);
1286
1302
  }
1287
- }, G = {
1303
+ }, _ = {
1304
+ /**
1305
+ * 函数防抖
1306
+ * 定义:在事件被触发后,延迟执行某个函数。如果在延迟期间事件再次被触发,则重新计算延迟时间。
1307
+ * 核心:只有当事件停止触发一段时间后,才会执行函数。
1308
+ * 应用场景:搜索框输入、按钮防重复点击、滚动事件防抖、窗口resize事件等。
1309
+ * @param fn 需要防抖的函数
1310
+ * @param delay 防抖延迟时间(毫秒)
1311
+ * @returns 防抖后的函数(返回 Promise,可通过 .then() 获取原函数返回值)
1312
+ */
1313
+ debounce(e, n) {
1314
+ let t = null;
1315
+ return function(...o) {
1316
+ const s = this;
1317
+ return t && (clearTimeout(t), t = null), new Promise((i) => {
1318
+ t = setTimeout(() => {
1319
+ const a = e.apply(s, o);
1320
+ t = null, i(a);
1321
+ }, n);
1322
+ });
1323
+ };
1324
+ }
1325
+ }, H = {
1326
+ /**
1327
+ * 函数节流(时间戳版)
1328
+ * 定义:在指定的时间间隔内,函数最多只执行一次。
1329
+ * 核心:保证函数定期执行,而不是等待事件停止触发。
1330
+ * 实现思路:通过时间戳判断,只有当距离上一次执行的时间超过设定延迟时才执行。
1331
+ * 特点:首次调用会立即执行。
1332
+ * 应用场景:滚动加载、按钮限频、鼠标移动追踪等。
1333
+ * @param fn 要节流的函数
1334
+ * @param delay 时间间隔(毫秒)
1335
+ * @returns 节流后的函数
1336
+ */
1337
+ throttleByTimestamp(e, n) {
1338
+ let t = 0;
1339
+ return function(...o) {
1340
+ const s = this, i = Date.now();
1341
+ return i - t >= n ? (t = i, new Promise((a) => {
1342
+ const c = e.apply(s, o);
1343
+ a(c);
1344
+ })) : Promise.resolve(void 0);
1345
+ };
1346
+ },
1347
+ /**
1348
+ * 函数节流(定时器版)
1349
+ * 定义:在指定的时间间隔内,函数最多只执行一次。
1350
+ * 核心:通过定时器控制函数的执行频率,定时器运行期间的所有调用都会被忽略。
1351
+ * 实现思路:第一次调用时设置定时器,在定时器运行期间忽略所有调用,直到定时器执行完毕后才允许下一次执行。
1352
+ * 特点:首次调用会延迟执行(等待 delay 后)。
1353
+ * 应用场景:按钮防重复提交、防重复请求等。
1354
+ * @param fn 要节流的函数
1355
+ * @param delay 时间间隔(毫秒)
1356
+ * @returns 节流后的函数(返回 Promise,可通过 .then() 获取原函数返回值)
1357
+ */
1358
+ throttleByTimer(e, n) {
1359
+ let t = null;
1360
+ return function(...o) {
1361
+ const s = this;
1362
+ return t ? Promise.resolve(void 0) : new Promise((i) => {
1363
+ t = setTimeout(() => {
1364
+ t = null;
1365
+ const a = e.apply(s, o);
1366
+ i(a);
1367
+ }, n);
1368
+ });
1369
+ };
1370
+ },
1371
+ /**
1372
+ * 函数节流(高级版)
1373
+ * 定义:在指定的时间间隔内,函数最多只执行一次,支持配置执行时机。
1374
+ * 核心:通过配置选项控制函数在时间窗口的开始或结束时执行。
1375
+ * 实现思路:结合时间戳和定时器实现,支持 leading 和 trailing 选项。
1376
+ * 应用场景:滚动加载、搜索建议、鼠标拖拽等。
1377
+ * @param fn 要节流的函数
1378
+ * @param delay 时间间隔(毫秒)
1379
+ * @param options 配置选项
1380
+ * @param options.leading 是否在时间窗口开始时执行,默认 true
1381
+ * @param options.trailing 是否在时间窗口结束时执行,默认 false
1382
+ * @returns 节流后的函数(返回 Promise,可通过 .then() 获取原函数返回值)
1383
+ */
1384
+ throttle(e, n, t = {}) {
1385
+ const { leading: r = !0, trailing: o = !1 } = t;
1386
+ let s = 0, i = null;
1387
+ const a = function(...c) {
1388
+ const h = this, l = Date.now();
1389
+ return r && l - s >= n ? (s = l, new Promise((u) => {
1390
+ const f = e.apply(h, c);
1391
+ u(f);
1392
+ })) : o && !i ? new Promise((u) => {
1393
+ i = setTimeout(
1394
+ () => {
1395
+ s = Date.now(), i = null;
1396
+ const f = e.apply(h, c);
1397
+ u(f);
1398
+ },
1399
+ n - (l - s)
1400
+ );
1401
+ }) : Promise.resolve(void 0);
1402
+ };
1403
+ return a.cancel = function() {
1404
+ i && (clearTimeout(i), i = null), s = 0;
1405
+ }, a;
1406
+ }
1407
+ }, ee = {
1408
+ ..._,
1409
+ ...H
1410
+ }, te = {
1288
1411
  /**
1289
1412
  * 脱敏
1290
1413
  * @param phone 电话号码/手机号码
@@ -1293,7 +1416,7 @@ const K = {
1293
1416
  desensitize(e) {
1294
1417
  return e ? e.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2") || e.slice(0, 3) + "****" + e.slice(7) : "";
1295
1418
  }
1296
- }, Q = {
1419
+ }, ne = {
1297
1420
  /**
1298
1421
  * 生成随机颜色
1299
1422
  * @returns 随机颜色值
@@ -1317,7 +1440,7 @@ const K = {
1317
1440
  uniqueId() {
1318
1441
  return Date.now().toString(36) + Math.random().toString(36).substr(2, 5);
1319
1442
  }
1320
- }, ee = {
1443
+ }, re = {
1321
1444
  /**
1322
1445
  * 验证手机号
1323
1446
  */
@@ -1354,7 +1477,7 @@ const K = {
1354
1477
  * 验证0.01~0.99正则:最多两位小数。0.1、0.10、0.9、0.90
1355
1478
  */
1356
1479
  decimal: /^0\.(0[1-9]|[1-9][0-9]*)$/
1357
- }, te = {
1480
+ }, oe = {
1358
1481
  /**
1359
1482
  * 通过key值获取 localStorage 中存储的某个值
1360
1483
  * @param key 获取的key
@@ -1401,7 +1524,7 @@ const K = {
1401
1524
  removeSession(e) {
1402
1525
  sessionStorage.removeItem(e);
1403
1526
  }
1404
- }, ne = {
1527
+ }, se = {
1405
1528
  /**
1406
1529
  * 判断某元素是否在字符串中-比includes()方法更兼容,includes为ES6新增方法,IE不支持。小程序也不支持
1407
1530
  * @param str 字符串
@@ -1457,8 +1580,8 @@ const K = {
1457
1580
  getMaxTimesAndVal(e) {
1458
1581
  const n = [0, ""], t = {};
1459
1582
  for (let s = 0; s < e.length; s++) {
1460
- const c = e.charAt(s);
1461
- t[c] ? t[c]++ : t[c] = 1;
1583
+ const i = e.charAt(s);
1584
+ t[i] ? t[i]++ : t[i] = 1;
1462
1585
  }
1463
1586
  let r = 1;
1464
1587
  for (const s in t)
@@ -1484,19 +1607,19 @@ const K = {
1484
1607
  throw new Error("开始位置小于0或结束位置超出字符串长度或开始位置大于结束位置");
1485
1608
  return e.slice(0, n) + "*".repeat(t - n + 1) + e.slice(t);
1486
1609
  }
1487
- }, _ = (e) => {
1610
+ }, $ = (e) => {
1488
1611
  const t = new RegExp("[?&]" + e + "=([^&#]*)", "gi").exec(window.location.href);
1489
1612
  return t ? decodeURIComponent(t[1]) : null;
1490
1613
  };
1491
- function H(e) {
1614
+ function k(e) {
1492
1615
  return new URLSearchParams(window.location.search).get(e);
1493
1616
  }
1494
- const $ = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1617
+ const P = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1495
1618
  __proto__: null,
1496
- getQueryInfoByName: _,
1497
- getQueryParam: H
1498
- }, Symbol.toStringTag, { value: "Module" })), re = {
1499
- ...$,
1619
+ getQueryInfoByName: $,
1620
+ getQueryParam: k
1621
+ }, Symbol.toStringTag, { value: "Module" })), ie = {
1622
+ ...P,
1500
1623
  /**
1501
1624
  * 获取当前域名
1502
1625
  * @returns 当前url链接的host信息
@@ -1511,7 +1634,7 @@ const $ = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1511
1634
  getPath() {
1512
1635
  return window.location.pathname;
1513
1636
  }
1514
- }, oe = {
1637
+ }, ce = {
1515
1638
  /**
1516
1639
  * 处理瀑布流数据,使其竖向瀑布流布局呈现横向瀑布流的展现形式。适用于 column-gap: 20rpx; column-count: 2; 布局的瀑布流
1517
1640
  * @param list 瀑布流数据-数组
@@ -1536,39 +1659,40 @@ const $ = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1536
1659
  * @param step 间距
1537
1660
  */
1538
1661
  jsLayout(e, n, t) {
1539
- const r = e.offsetWidth, o = n[0].offsetWidth, s = parseInt((r / o).toString()), c = (r - o * s) / (s - 1), l = [];
1540
- for (let i = 0, h = n.length; i < h; i++) {
1541
- const a = n[i];
1542
- if (i < s)
1543
- a.style.left = (o + c) * i + "px", l[i] = a.offsetHeight;
1662
+ const r = e.offsetWidth, o = n[0].offsetWidth, s = parseInt((r / o).toString()), i = (r - o * s) / (s - 1), a = [];
1663
+ for (let c = 0, h = n.length; c < h; c++) {
1664
+ const l = n[c];
1665
+ if (c < s)
1666
+ l.style.left = (o + i) * c + "px", a[c] = l.offsetHeight;
1544
1667
  else {
1545
- const { index: u, value: f } = C.getMinValueAndIndex(l);
1546
- a.style.left = (o + c) * u + "px", a.style.top = f + t + "px", l[u] = a.offsetHeight + t + f;
1668
+ const { index: u, value: f } = C.getMinValueAndIndex(a);
1669
+ l.style.left = (o + i) * u + "px", l.style.top = f + t + "px", a[u] = l.offsetHeight + t + f;
1547
1670
  }
1548
1671
  }
1549
1672
  }
1550
1673
  };
1551
1674
  export {
1552
- F as Base64Utils,
1553
- Z as MoneyFormatter,
1675
+ q as Base64Utils,
1676
+ X as MoneyFormatter,
1554
1677
  C as arrayUtils,
1555
- R as booleanUtils,
1556
- T as commonUtils,
1557
- P as cookieUtils,
1558
- q as dateUtils,
1559
- V as documentUtils,
1560
- W as downloadUtils,
1561
- Y as echartsUtils,
1562
- z as letterUtils,
1563
- J as mapUtils,
1564
- K as nameUtils,
1565
- X as numberUtils,
1678
+ T as booleanUtils,
1679
+ v as commonUtils,
1680
+ V as cookieUtils,
1681
+ W as dateUtils,
1682
+ Y as documentUtils,
1683
+ z as downloadUtils,
1684
+ J as echartsUtils,
1685
+ Z as letterUtils,
1686
+ K as mapUtils,
1687
+ G as nameUtils,
1688
+ Q as numberUtils,
1566
1689
  m as objectUtils,
1567
- G as phoneUtils,
1568
- Q as randomUtils,
1569
- ee as regexpUtils,
1570
- te as storageUtils,
1571
- ne as stringUtils,
1572
- re as urlUtils,
1573
- oe as waterfallUtils
1690
+ ee as performanceUtils,
1691
+ te as phoneUtils,
1692
+ ne as randomUtils,
1693
+ re as regexpUtils,
1694
+ oe as storageUtils,
1695
+ se as stringUtils,
1696
+ ie as urlUtils,
1697
+ ce as waterfallUtils
1574
1698
  };
@@ -1 +1 @@
1
- (function(f,m){typeof exports=="object"&&typeof module<"u"?m(exports):typeof define=="function"&&define.amd?define(["exports"],m):(f=typeof globalThis<"u"?globalThis:f||self,m(f.yhkitUtils={}))})(this,function(f){"use strict";const M={...{toEnumObj(e,n="value"){if(!e||!e.length)return{};const t={};return e.forEach(r=>{const o=Object.assign({label:r.label,text:r.label},r);t[r[n]]=o}),t}},...{uniqueBySet(e){if(!e)throw new Error("数组不能为空");const n=e;return Array.from(new Set(n))},uniqueByFilter(e){if(!e)throw new Error("数组不能为空");return e.filter((t,r,o)=>r===o.indexOf(t))},uniqueByReduce(e){if(!e)throw new Error("数组不能为空");return e.reduce((t,r)=>(t.includes(r)||t.push(r),t),[])},uniqueByIncludes(e){if(!e)throw new Error("数组不能为空");const n=e,t=[];return n.forEach(r=>{t.includes(r)||t.push(r)}),t},uniqueByFor(e){if(!e)throw new Error("数组不能为空");const n=e,t=[];for(let r=0;r<n.length;r++)t.includes(n[r])||t.push(n[r]);return t},uniqueByKey(e,n){if(!e||!n)throw new Error("数组不能为空或键名不能为空");const t=e,r=new Map;return t.filter(o=>r.has(o[n])?!1:(r.set(o[n],!0),!0))},unique(e,n={}){const{keys:t,compareFn:r}=n;if(!e)throw new Error("数组不能为空");const o=e;if(!t&&!r)return this.uniqueBySet(o);if(t){const s=new Map;return o.filter(c=>{const l=t.map(i=>c[i]).join("|");return s.has(l)?!1:(s.set(l,!0),!0)})}if(r)return o.filter((s,c,l)=>c===l.findIndex(i=>r(s,i)))}},...{isExistByIndexOf(e,n){return!e||!n?!1:e.indexOf(n)!==-1},isExistByIncludes(e,n){return!e||!n?!1:e.includes(n)}},...{sort(e,n="asc"){return e?e.sort((t,r)=>n==="asc"?t>r?1:-1:t<r?1:-1):[]}},...{getMaxValue(e){return e?Math.max(...e):0},getMinValue(e){return e?Math.min(...e):0},getMinValueAndIndex(e){if(e.length===0)return{value:0,index:0};const n={value:e[0],index:0};for(let t=1,r=e.length;t<r;t++){const o=e[t];n.value>o&&(n.value=o,n.index=t)}return n},getMaxValueAndIndex(e){return e.length===0?{value:0,index:0}:e.reduce((n,t,r)=>t<n.value?{value:t,index:r}:n,{value:e[0],index:0})}},...{countOfAppear(e,n){let t=0;for(const r of e)r===n&&t++;return t},indexsOfAppear(e,n){let t=-1;const r=[];do t=e.indexOf(n,t+1),t!==-1&&r.push(t);while(t!==-1);return r}},...{shuffle(e){if(!e)return[];const n=[...e];for(let t=n.length-1;t>0;t--){const r=Math.floor(Math.random()*(t+1));[n[t],n[r]]=[n[r],n[t]]}return n},sample(e,n){if(!e)return[];if(n<=0||n>e.length)throw new Error("抽样次数必须在1次到数组长度之间");const t=[...e];for(let r=0;r<n;r++){const o=Math.floor(Math.random()*(e.length-r))+r;[t[r],t[o]]=[t[o],t[r]]}return t.slice(0,n)},sampleByStart(e,n){if(!e)return[];if(n<=0||n>e.length)throw new Error("抽样次数必须在1次到数组长度之间");const t=[...e];for(let r=n-1;r>=0;r--){const o=Math.floor(Math.random()*(e.length-r))+r;[t[r],t[o]]=[t[o],t[r]]}return t.slice(0,n)},sampleByEnd(e,n){if(!e)return[];if(n<=0||n>e.length)throw new Error("抽样次数必须在1次到数组长度之间");const t=[...e];for(let r=e.length-1;r>=e.length-n;r--){const o=Math.floor(Math.random()*(r+1));[t[r],t[o]]=[t[o],t[r]]}return t.slice(e.length-n)}}};class U{static BASE64_CHARS="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";static toBlob(n,t="",r=512){const s=(n.split(",")[1]||n).replace(/-/g,"+").replace(/_/g,"/"),c="=".repeat((4-s.length%4)%4),l=s+c;try{const i=atob(l),h=[];for(let a=0;a<i.length;a+=r){const u=i.slice(a,a+r),d=new Array(u.length);for(let g=0;g<u.length;g++)d[g]=u.charCodeAt(g);const y=new Uint8Array(d);h.push(y)}return new Blob(h,{type:t})}catch(i){return console.error("Failed to convert base64 to blob:",i),null}}static toFile(n,t="file.txt",r="text/plain"){const s=n.replace(/^data:.+;base64,/,"").replace(/-/g,"+").replace(/_/g,"/"),c="=".repeat((4-s.length%4)%4),l=s+c,i=atob(l),h=[];for(let u=0;u<i.length;u+=512){const d=i.slice(u,u+512),y=new Array(d.length);for(let g=0;g<d.length;g++)y[g]=d.charCodeAt(g);h.push(new Uint8Array(y))}const a=new Blob(h,{type:r});return new File([a],t,{type:r})}static encode(n){if(!n)return"";const t=this._stringToUtf8Bytes(n);return this._bytesToBase64(t)}static decode(n){if(!n)return"";n=n.replace(/\s/g,"");const t=this._base64ToBytes(n);return this._utf8BytesToString(t)}static _stringToUtf8Bytes(n){const t=[];for(let r=0;r<n.length;r++){let o=n.charCodeAt(r);if(o<128)t.push(o);else if(o<2048)t.push(192|o>>6),t.push(128|o&63);else if(o<55296||o>=57344)t.push(224|o>>12),t.push(128|o>>6&63),t.push(128|o&63);else{r++;const s=o,c=n.charCodeAt(r);if(isNaN(c))throw new Error("代理对不完整");o=65536+((s&1023)<<10)+(c&1023),t.push(240|o>>18),t.push(128|o>>12&63),t.push(128|o>>6&63),t.push(128|o&63)}}return t}static _utf8BytesToString(n){let t="",r=0;for(;r<n.length;){const o=n[r++];if(o<128)t+=String.fromCharCode(o);else if(o>=192&&o<224){const s=n[r++]&63;t+=String.fromCharCode((o&31)<<6|s)}else if(o>=224&&o<240){const s=n[r++]&63,c=n[r++]&63;t+=String.fromCharCode((o&15)<<12|s<<6|c)}else if(o>=240&&o<248){const s=n[r++]&63,c=n[r++]&63,l=n[r++]&63,i=(o&7)<<18|s<<12|c<<6|l,h=Math.floor((i-65536)/1024)+55296,a=(i-65536)%1024+56320;t+=String.fromCharCode(h,a)}else t+="�"}return t}static _bytesToBase64(n){let t="",r=0;for(;r<n.length;){const o=n[r++],s=r<n.length,c=s?n[r++]:0,l=r<n.length,i=l?n[r++]:0,h=o>>2,a=(o&3)<<4|c>>4,u=(c&15)<<2|i>>6,d=i&63;s?l?t+=this.BASE64_CHARS.charAt(h)+this.BASE64_CHARS.charAt(a)+this.BASE64_CHARS.charAt(u)+this.BASE64_CHARS.charAt(d):t+=this.BASE64_CHARS.charAt(h)+this.BASE64_CHARS.charAt(a)+this.BASE64_CHARS.charAt(u)+"=":t+=this.BASE64_CHARS.charAt(h)+this.BASE64_CHARS.charAt(a)+"=="}return t}static _base64ToBytes(n){const t=n.length;let r=0;t>=2&&(n[t-1]==="="&&r++,n[t-2]==="="&&r++);const o=Math.floor(t*3/4)-r,s=new Array(o),c=new Array(256).fill(-1);for(let h=0;h<this.BASE64_CHARS.length;h++)c[this.BASE64_CHARS.charCodeAt(h)]=h;let l=0,i=0;for(;i<t;){const h=c[n.charCodeAt(i++)],a=c[n.charCodeAt(i++)],u=i<t?c[n.charCodeAt(i++)]:-1,d=i<t?c[n.charCodeAt(i++)]:-1;if(h===-1||a===-1)throw new Error("无效的 Base64 字符");const y=h<<2|a>>4;if(s[l++]=y,u!==-1){const g=(a&15)<<4|u>>2;if(s[l++]=g,d!==-1){const p=(u&3)<<6|d;s[l++]=p}}}return s}}const S={isEmptyString(e){return typeof e=="string"&&e.trim()===""},isNumber(e){return typeof e=="number"&&!isNaN(e)},isObject(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)},isEmptyObject(e){return e?Object.keys(e).length===0&&e.constructor===Object:!0},isBoolean(e){return typeof e=="boolean"},isArray(e){return Array.isArray(e)},isFunction(e){return typeof e=="function"},isPromise(e){return!!e&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"},isElement(e){return e instanceof Element},isPhone(e){return/^1[3-9]\d{9}$/.test(e)},isEmail(e){return/^[\w.-]+@[\w.-]+\.\w+$/.test(e)},isJSON(e){try{return JSON.parse(e),!0}catch{return!1}},isImageLoaded(e){return e.complete&&e.naturalWidth!==0},isInViewport(e){const n=e.getBoundingClientRect();return n.top>=0&&n.left>=0&&n.bottom<=window.innerHeight&&n.right<=window.innerWidth},isLeapYear(e){return e%4===0&&e%100!==0||e%400===0},isMobile(){return/Mobi|Android|iPhone/i.test(navigator.userAgent)}},b={isEmptyObject(e){return e?Object.keys(e).length===0&&e.constructor===Object:!0},copy(e,n){for(const t in e)n[t]=e[t]},deepCopy(e,n){for(const t in e){const r=e[t];r instanceof Object?(n[t]={},this.deepCopy(r,n[t])):r instanceof Array?(n[t]=[],this.deepCopy(r,n[t])):n[t]=e[t]}}},E={...{getType(e){return Object.prototype.toString.call(e).replace(/\[object\s(\w+)\]/,"$1")}},...{shallowClone(e){if(e===null||typeof e!="object")return e;if(b.isEmptyObject(e))return{};const n={};for(const t in e)n[t]=e[t];return n},deepCloneByJSON(e){return e===null||typeof e!="object"?e:b.isEmptyObject(e)?{}:JSON.parse(JSON.stringify(e))},deepCloneByMap(e,n=new WeakMap){if(e===null||typeof e!="object")return e;if(b.isEmptyObject(e))throw new Error("空对象不能进行深拷贝");if(n.has(e))return n.get(e);const t=E.getType(e);let r;switch(t){case"object":case"array":r=Array.isArray(e)?[]:{};break;case"Date":r=new Date(e);break;case"RegExp":r=new RegExp(e);break;case"Map":r=new Map(e);break;case"Set":r=new Set(e);break;default:return e}return n.set(e,r),t==="Map"?(e.forEach((o,s)=>{r.set(this.deepCloneByMap(s,n),this.deepCloneByMap(o,n))}),r):t==="Set"?(e.forEach(o=>{r.add(this.deepCloneByMap(o,n))}),r):(Reflect.ownKeys(e).forEach(o=>{r[o]=this.deepCloneByMap(e[o],n)}),r)}},...{curry(e){if(typeof e!="function")throw new TypeError("curry: fn must be a function, but got "+typeof e);const n=e.length;return function t(...r){return r.length>=n?e.apply(this,r):function(...o){return t.apply(this,[...r,...o])}}},uncurry(e){return function(n,...t){return e.call(n,...t)}}}},B={getCookie(e){if(!e)return;const n=document.cookie.match(new RegExp("(^| )"+e+"=([^;]+)"));return n?decodeURIComponent(n[2]):null},setCookie(e,n,t=7){const r=new Date;r.setTime(r.getTime()+t*24*60*60*1e3),document.cookie=`${e}=${encodeURIComponent(n)};expires=${r.toUTCString()};path=/`},deleteCookie(e){this.setCookie(e,"",-1)}},C={getTimeString(e,n=!1){return n?new Date().toLocaleString(e,{hour12:!0}):new Date().toLocaleString("chinese",{hour12:!1})},diffDays(e,n){const t=new Date(e).getTime(),r=new Date(n).getTime();return t>r?Math.abs(Math.floor((t-r)/(24*3600*1e3))):Math.abs(Math.floor((r-t)/(24*3600*1e3)))},uniqueId(){return Date.now().toString(36)+Math.random().toString(36).substr(2,5)},getWhichDays(e,n,t){let r=t;for(let o=1;o<n;o++)switch(o){case 1:case 3:case 5:case 7:case 8:case 10:case 12:r+=31;break;case 2:S.isLeapYear(e)?r+=29:r+=28;break;default:r+=30;break}return r},getTimeStringAutoShort2(e,n){const t=new Date,r=new Date(e),o=t.getFullYear(),s=t.getMonth()+1,c=t.getDate(),l=r.getFullYear(),i=r.getMonth()+1,h=r.getDate();let a="";const u=n?" "+this.formatDate(r,"hh:mm"):"";if(o===l){const g=t.getTime()-e;if(s===i&&c===h)g<60*1e3?a="刚刚":a=this.formatDate(r,"hh:mm");else{const p=new Date;p.setDate(p.getDate()-1);const A=new Date;if(A.setDate(A.getDate()-2),i===p.getMonth()+1&&h===p.getDate())a="昨天"+u;else if(i===A.getMonth()+1&&h===A.getDate())a="前天"+u;else if(g/36e5<=7*24){const w=new Array(7);w[0]="星期日",w[1]="星期一",w[2]="星期二",w[3]="星期三",w[4]="星期四",w[5]="星期五",w[6]="星期六",a=w[r.getDay()]+u}else a=this.formatDate(r,"yyyy/M/d")+u}}else a=this.formatDate(r,"yyyy/M/d")+u;return a},formatDate(e,n){const t={"M+":e.getMonth()+1,"d+":e.getDate(),"h+":e.getHours(),"m+":e.getMinutes(),"s+":e.getSeconds(),"q+":Math.floor((e.getMonth()+3)/3),S:e.getMilliseconds()};/(y+)/.test(n)&&(n=n.replace(RegExp.$1,(e.getFullYear()+"").substr(4-RegExp.$1.length)));for(const r in t)new RegExp("("+r+")").test(n)&&(n=n.replace(RegExp.$1,RegExp.$1.length===1?t[r]:("00"+t[r]).substr((""+t[r]).length)));return n}},x={getOffsetTop(e){if(!e)throw new Error("Element is not provided");if(e instanceof SVGElement){const t=e.getBoundingClientRect(),r=window.pageYOffset||document.documentElement.scrollTop;return t.top+r}let n=0;for(;e;)n+=e.offsetTop,e=e.offsetParent;return n},getScrollValue(){const e={scrollLeft:0,scrollTop:0};return e.scrollLeft=document.body.scrollLeft||document.documentElement.scrollLeft,e.scrollTop=document.body.scrollTop||document.documentElement.scrollTop,e},getPageValue(e){e=e||window.event;const n=e.pageX||e.clientX+this.getScrollValue().scrollLeft,t=e.pageY||e.clientY+this.getScrollValue().scrollTop;return{pageX:n,pageY:t}},addEventListener(e,n,t){e.addEventListener?e.addEventListener(n,t):e.attachEvent?e.attachEvent("on"+n,t):e["on"+n]=t},getViewportWidth(){return window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth},getViewportHeight(){return window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight}},R={saveAsBlob(e,n){const t=document.createElement("a"),r=window.URL.createObjectURL(e);t.href=r,t.download=n,document.body.appendChild(t),t.click(),URL.revokeObjectURL(r),document.body.removeChild(t)},saveAsUrl(e,n){const t=document.createElement("a");t.href=e,t.download=n,document.body.appendChild(t),t.click(),URL.revokeObjectURL(e),document.body.removeChild(t)}},D={animate(e,n){let t=-1;const r=e.series[0].data.length;let o;o=setInterval(()=>{n.dispatchAction({type:"downplay",seriesIndex:0,dataIndex:t}),t=(t+1)%r,n.dispatchAction({type:"highlight",seriesIndex:0,dataIndex:t}),n.dispatchAction({type:"showTip",seriesIndex:0,dataIndex:t}),t>r&&(t=0)},2e3),n.on("mouseover",()=>{clearInterval(o),n.dispatchAction({type:"downplay",seriesIndex:0,dataIndex:t})})}},O={sortFromA2Z(e){return e?.length?e.sort((t,r)=>{const o=t.toUpperCase(),s=r.toUpperCase();return o<s?-1:o>s?1:0}):void 0}},T={degrees2Radians(e){return e*Math.PI/180},getDistance(e,n,t,r){const o=this.degrees2Radians(e),s=this.degrees2Radians(t),c=o-s,l=this.degrees2Radians(n)-this.degrees2Radians(r);let i=2*Math.asin(Math.sqrt(Math.pow(Math.sin(c/2),2)+Math.cos(o)*Math.cos(s)*Math.pow(Math.sin(l/2),2)));return i=i*6378.137,i=Math.round(i*1e4)/1e4,i=+i.toFixed(2),console.log("经纬度计算的距离为:"+i),i},calculateDistanceByHaversine(e,n,t="km"){const r=this,o=e.longitude??e.lng,s=e.latitude??e.lat,c=n.longitude??n.lng,l=n.latitude??n.lat;if(o===void 0||s===void 0||c===void 0||l===void 0)throw new Error("无效的坐标格式,缺少经纬度信息");const i=6371,h=r.degrees2Radians(s),a=r.degrees2Radians(l),u=r.degrees2Radians(l-s),d=r.degrees2Radians(c-o),y=Math.sin(u/2)*Math.sin(u/2)+Math.cos(h)*Math.cos(a)*Math.sin(d/2)*Math.sin(d/2),g=2*Math.atan2(Math.sqrt(y),Math.sqrt(1-y)),p=i*g;switch(t){case"m":return p*1e3;case"mi":return p*.621371;case"nmi":return p*.539957;default:return p}},calculateDistancesByHaversine(e,n="km",t=!1){if(e.length<2)return{segments:[],total:0};const r=[];let o=0;for(let s=0;s<e.length-1;s++){const c=this.calculateDistanceByHaversine(e[s],e[s+1],n);r.push(c),o+=c}if(t&&e.length>2){const s=this.calculateDistanceByHaversine(e[e.length-1],e[0],n);r.push(s),o+=s}return{segments:r,total:o}}};class j{static toStandardFormat(n){try{const t=typeof n=="string"?parseFloat(n):n;if(isNaN(t))throw new Error("输入不是有效的数字");if(!isFinite(t))throw new Error("输入是无穷大");return t.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")}catch(t){return console.error("格式化失败:",t),"格式错误"}}static toChineseFormat(n){try{const t=typeof n=="string"?parseFloat(n):n;if(isNaN(t))throw new Error("输入不是有效的数字");if(t>9999999999999e-2||t<-9999999999999e-2)throw new Error("输入数字超出范围");const r=t<0,o=Math.abs(t),s=Math.floor(o),c=Math.round((o-s)*100),l=["零","壹","贰","叁","肆","伍","陆","柒","捌","玖"],i=["","拾","佰","仟","万","拾","佰","仟","亿","拾","佰","仟"],h=["角","分"];let a="",u=s;if(u===0)a=l[0];else{let g=0;for(;u>0;){const p=u%10;p!==0?a=l[p]+i[g]+a:a.charAt(0)!==l[0]&&(a=l[p]+a),u=Math.floor(u/10),g++}a=a.replace(/零+/g,"零"),a=a.replace(/零+$/,"")}let d="";if(c>0){const g=Math.floor(c/10),p=c%10;g>0&&(d+=l[g]+h[0]),p>0&&(d+=l[p]+h[1])}else d="整";let y=(r?"负":"")+a+"圆"+d;return y==="零圆整"&&(y="零圆"),y}catch(t){return console.error("转换失败:",t),"格式错误"}}}const v={desensitizeChineseName(e,n={}){const{keepLength:t=1,keepLast:r=!1}=n;if(!e||e.length===0||e.trim().length===0)throw new Error("姓名不能为空");if(typeof e!="string")throw new Error("姓名必须是字符串");if(e.length<=1)return e;const o=["欧阳","司马","上官","东方","独孤","南宫","闻人","夏侯","诸葛","尉迟","公孙","长孙","宇文","司徒","慕容"];n.compoundSurname&&n.compoundSurname.trim().length>0&&!o.includes(n.compoundSurname)&&o.push(n.compoundSurname);let s="";o.some(l=>e.startsWith(l))?s=o.find(l=>e.startsWith(l))||"":s=e[0]||"";const c=Math.max(t,s.length);if(c>=e.length)return e;if(r&&e.length>2){const l=e.slice(0,c),i=e.slice(-1),h=e.length-c-1;return`${l}${"*".repeat(h)}${i}`}return`${e.slice(0,c)}${"*".repeat(e.length-c)}`}},L={...Object.freeze(Object.defineProperty({__proto__:null,toLetter:e=>e>25||e<0?"":"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[e]},Symbol.toStringTag,{value:"Module"})),...Object.freeze(Object.defineProperty({__proto__:null,toMoney:e=>e.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")},Symbol.toStringTag,{value:"Module"})),isNumber(e){return typeof e=="number"&&!isNaN(e)}},I={desensitize(e){return e?e.replace(/^(\d{3})\d{4}(\d{4})$/,"$1****$2")||e.slice(0,3)+"****"+e.slice(7):""}},_={color:function(){return`#${Math.random().toString(16).slice(2,8)}`},int(e,n){return Math.floor(Math.random()*(n-e+1))+e},uniqueId(){return Date.now().toString(36)+Math.random().toString(36).substr(2,5)}},k={mobile:/^1[3-9]\d{9}$/,email:/^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,chinese:/^[\u4e00-\u9fa5]+$/,english:/^[a-zA-Z]+$/,chineseStart:/^[\u4e00-\u9fa5]+\w*$/,integer:/^\d+$/,integerAndzero:/^(0|[1-9]+[0-9]*)$/,strongPassword:/^(?!.*[\s\p{C}])(?:(?=.*[A-Z])(?=.*[a-z])(?=.*[\d\W])|(?=.*\d)(?=.*[^\w\s])).{8,}$/u,decimal:/^0\.(0[1-9]|[1-9][0-9]*)$/},H={getLocal(e){return localStorage.getItem(e)},setLocal(e,n){localStorage.setItem(e,n)},removeLocal(e){localStorage.removeItem(e)},getSession(e){return sessionStorage.getItem(e)},setSession(e,n){sessionStorage.setItem(e,n)},removeSession(e){sessionStorage.removeItem(e)}},$={isExist(e,n){if(!e||!n)return!1;const t=e.split(",");return console.log("判断某元素是否在字符串中",t.indexOf(n)===-1),t.indexOf(n)!==-1},includes(e,n){return!e||!n?!1:e.includes(n)},isJSON(e){try{return JSON.parse(e),!0}catch{return!1}},indexsOfAppear(e,n){let t=-1;const r=[];do t=e.indexOf(n,t+1),t!==-1&&r.push(t);while(t!==-1);return r},getMaxTimesAndVal(e){const n=[0,""],t={};for(let s=0;s<e.length;s++){const c=e.charAt(s);t[c]?t[c]++:t[c]=1}let r=1;for(const s in t)r<t[s]&&(r=t[s]);const o=[];for(const s in t)r==t[s]&&o.push(s);return n[0]=r,n[1]=o.join(),n},mask(e,n,t){if(!e)throw new Error("字符串为空");if(typeof n!="number"||typeof t!="number")throw new Error("开始位置或结束位置为空");if(n<0||t>e.length||n>t)throw new Error("开始位置小于0或结束位置超出字符串长度或开始位置大于结束位置");return e.slice(0,n)+"*".repeat(t-n+1)+e.slice(t)}},N=e=>{const t=new RegExp("[?&]"+e+"=([^&#]*)","gi").exec(window.location.href);return t?decodeURIComponent(t[1]):null};function F(e){return new URLSearchParams(window.location.search).get(e)}const q={...Object.freeze(Object.defineProperty({__proto__:null,getQueryInfoByName:N,getQueryParam:F},Symbol.toStringTag,{value:"Module"})),getHost(){return window.location.host},getPath(){return window.location.pathname}},P={toList(e,n=2){console.log(e,n);const t={};for(let o=0;o<n;o++)t[o]=[];e.forEach((o,s)=>t[s%n].push(o));const r=[];for(const o in t)r.push(...t[o]);return r},jsLayout(e,n,t){const r=e.offsetWidth,o=n[0].offsetWidth,s=parseInt((r/o).toString()),c=(r-o*s)/(s-1),l=[];for(let i=0,h=n.length;i<h;i++){const a=n[i];if(i<s)a.style.left=(o+c)*i+"px",l[i]=a.offsetHeight;else{const{index:u,value:d}=M.getMinValueAndIndex(l);a.style.left=(o+c)*u+"px",a.style.top=d+t+"px",l[u]=a.offsetHeight+t+d}}}};f.Base64Utils=U,f.MoneyFormatter=j,f.arrayUtils=M,f.booleanUtils=S,f.commonUtils=E,f.cookieUtils=B,f.dateUtils=C,f.documentUtils=x,f.downloadUtils=R,f.echartsUtils=D,f.letterUtils=O,f.mapUtils=T,f.nameUtils=v,f.numberUtils=L,f.objectUtils=b,f.phoneUtils=I,f.randomUtils=_,f.regexpUtils=k,f.storageUtils=H,f.stringUtils=$,f.urlUtils=q,f.waterfallUtils=P,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
1
+ (function(f,w){typeof exports=="object"&&typeof module<"u"?w(exports):typeof define=="function"&&define.amd?define(["exports"],w):(f=typeof globalThis<"u"?globalThis:f||self,w(f.yhkitUtils={}))})(this,function(f){"use strict";const M={...{toEnumObj(e,n="value"){if(!e||!e.length)return{};const t={};return e.forEach(r=>{const o=Object.assign({label:r.label,text:r.label},r);t[r[n]]=o}),t}},...{uniqueBySet(e){if(!e)throw new Error("数组不能为空");const n=e;return Array.from(new Set(n))},uniqueByFilter(e){if(!e)throw new Error("数组不能为空");return e.filter((t,r,o)=>r===o.indexOf(t))},uniqueByReduce(e){if(!e)throw new Error("数组不能为空");return e.reduce((t,r)=>(t.includes(r)||t.push(r),t),[])},uniqueByIncludes(e){if(!e)throw new Error("数组不能为空");const n=e,t=[];return n.forEach(r=>{t.includes(r)||t.push(r)}),t},uniqueByFor(e){if(!e)throw new Error("数组不能为空");const n=e,t=[];for(let r=0;r<n.length;r++)t.includes(n[r])||t.push(n[r]);return t},uniqueByKey(e,n){if(!e||!n)throw new Error("数组不能为空或键名不能为空");const t=e,r=new Map;return t.filter(o=>r.has(o[n])?!1:(r.set(o[n],!0),!0))},unique(e,n={}){const{keys:t,compareFn:r}=n;if(!e)throw new Error("数组不能为空");const o=e;if(!t&&!r)return this.uniqueBySet(o);if(t){const s=new Map;return o.filter(i=>{const l=t.map(c=>i[c]).join("|");return s.has(l)?!1:(s.set(l,!0),!0)})}if(r)return o.filter((s,i,l)=>i===l.findIndex(c=>r(s,c)))}},...{isExistByIndexOf(e,n){return!e||!n?!1:e.indexOf(n)!==-1},isExistByIncludes(e,n){return!e||!n?!1:e.includes(n)}},...{sort(e,n="asc"){return e?e.sort((t,r)=>n==="asc"?t>r?1:-1:t<r?1:-1):[]}},...{getMaxValue(e){return e?Math.max(...e):0},getMinValue(e){return e?Math.min(...e):0},getMinValueAndIndex(e){if(e.length===0)return{value:0,index:0};const n={value:e[0],index:0};for(let t=1,r=e.length;t<r;t++){const o=e[t];n.value>o&&(n.value=o,n.index=t)}return n},getMaxValueAndIndex(e){return e.length===0?{value:0,index:0}:e.reduce((n,t,r)=>t<n.value?{value:t,index:r}:n,{value:e[0],index:0})}},...{countOfAppear(e,n){let t=0;for(const r of e)r===n&&t++;return t},indexsOfAppear(e,n){let t=-1;const r=[];do t=e.indexOf(n,t+1),t!==-1&&r.push(t);while(t!==-1);return r}},...{shuffle(e){if(!e)return[];const n=[...e];for(let t=n.length-1;t>0;t--){const r=Math.floor(Math.random()*(t+1));[n[t],n[r]]=[n[r],n[t]]}return n},sample(e,n){if(!e)return[];if(n<=0||n>e.length)throw new Error("抽样次数必须在1次到数组长度之间");const t=[...e];for(let r=0;r<n;r++){const o=Math.floor(Math.random()*(e.length-r))+r;[t[r],t[o]]=[t[o],t[r]]}return t.slice(0,n)},sampleByStart(e,n){if(!e)return[];if(n<=0||n>e.length)throw new Error("抽样次数必须在1次到数组长度之间");const t=[...e];for(let r=n-1;r>=0;r--){const o=Math.floor(Math.random()*(e.length-r))+r;[t[r],t[o]]=[t[o],t[r]]}return t.slice(0,n)},sampleByEnd(e,n){if(!e)return[];if(n<=0||n>e.length)throw new Error("抽样次数必须在1次到数组长度之间");const t=[...e];for(let r=e.length-1;r>=e.length-n;r--){const o=Math.floor(Math.random()*(r+1));[t[r],t[o]]=[t[o],t[r]]}return t.slice(e.length-n)}}};class U{static BASE64_CHARS="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";static toBlob(n,t="",r=512){const s=(n.split(",")[1]||n).replace(/-/g,"+").replace(/_/g,"/"),i="=".repeat((4-s.length%4)%4),l=s+i;try{const c=atob(l),h=[];for(let a=0;a<c.length;a+=r){const u=c.slice(a,a+r),d=new Array(u.length);for(let g=0;g<u.length;g++)d[g]=u.charCodeAt(g);const y=new Uint8Array(d);h.push(y)}return new Blob(h,{type:t})}catch(c){return console.error("Failed to convert base64 to blob:",c),null}}static toFile(n,t="file.txt",r="text/plain"){const s=n.replace(/^data:.+;base64,/,"").replace(/-/g,"+").replace(/_/g,"/"),i="=".repeat((4-s.length%4)%4),l=s+i,c=atob(l),h=[];for(let u=0;u<c.length;u+=512){const d=c.slice(u,u+512),y=new Array(d.length);for(let g=0;g<d.length;g++)y[g]=d.charCodeAt(g);h.push(new Uint8Array(y))}const a=new Blob(h,{type:r});return new File([a],t,{type:r})}static encode(n){if(!n)return"";const t=this._stringToUtf8Bytes(n);return this._bytesToBase64(t)}static decode(n){if(!n)return"";n=n.replace(/\s/g,"");const t=this._base64ToBytes(n);return this._utf8BytesToString(t)}static _stringToUtf8Bytes(n){const t=[];for(let r=0;r<n.length;r++){let o=n.charCodeAt(r);if(o<128)t.push(o);else if(o<2048)t.push(192|o>>6),t.push(128|o&63);else if(o<55296||o>=57344)t.push(224|o>>12),t.push(128|o>>6&63),t.push(128|o&63);else{r++;const s=o,i=n.charCodeAt(r);if(isNaN(i))throw new Error("代理对不完整");o=65536+((s&1023)<<10)+(i&1023),t.push(240|o>>18),t.push(128|o>>12&63),t.push(128|o>>6&63),t.push(128|o&63)}}return t}static _utf8BytesToString(n){let t="",r=0;for(;r<n.length;){const o=n[r++];if(o<128)t+=String.fromCharCode(o);else if(o>=192&&o<224){const s=n[r++]&63;t+=String.fromCharCode((o&31)<<6|s)}else if(o>=224&&o<240){const s=n[r++]&63,i=n[r++]&63;t+=String.fromCharCode((o&15)<<12|s<<6|i)}else if(o>=240&&o<248){const s=n[r++]&63,i=n[r++]&63,l=n[r++]&63,c=(o&7)<<18|s<<12|i<<6|l,h=Math.floor((c-65536)/1024)+55296,a=(c-65536)%1024+56320;t+=String.fromCharCode(h,a)}else t+="�"}return t}static _bytesToBase64(n){let t="",r=0;for(;r<n.length;){const o=n[r++],s=r<n.length,i=s?n[r++]:0,l=r<n.length,c=l?n[r++]:0,h=o>>2,a=(o&3)<<4|i>>4,u=(i&15)<<2|c>>6,d=c&63;s?l?t+=this.BASE64_CHARS.charAt(h)+this.BASE64_CHARS.charAt(a)+this.BASE64_CHARS.charAt(u)+this.BASE64_CHARS.charAt(d):t+=this.BASE64_CHARS.charAt(h)+this.BASE64_CHARS.charAt(a)+this.BASE64_CHARS.charAt(u)+"=":t+=this.BASE64_CHARS.charAt(h)+this.BASE64_CHARS.charAt(a)+"=="}return t}static _base64ToBytes(n){const t=n.length;let r=0;t>=2&&(n[t-1]==="="&&r++,n[t-2]==="="&&r++);const o=Math.floor(t*3/4)-r,s=new Array(o),i=new Array(256).fill(-1);for(let h=0;h<this.BASE64_CHARS.length;h++)i[this.BASE64_CHARS.charCodeAt(h)]=h;let l=0,c=0;for(;c<t;){const h=i[n.charCodeAt(c++)],a=i[n.charCodeAt(c++)],u=c<t?i[n.charCodeAt(c++)]:-1,d=c<t?i[n.charCodeAt(c++)]:-1;if(h===-1||a===-1)throw new Error("无效的 Base64 字符");const y=h<<2|a>>4;if(s[l++]=y,u!==-1){const g=(a&15)<<4|u>>2;if(s[l++]=g,d!==-1){const p=(u&3)<<6|d;s[l++]=p}}}return s}}const S={isEmptyString(e){return typeof e=="string"&&e.trim()===""},isNumber(e){return typeof e=="number"&&!isNaN(e)},isObject(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)},isEmptyObject(e){return e?Object.keys(e).length===0&&e.constructor===Object:!0},isBoolean(e){return typeof e=="boolean"},isArray(e){return Array.isArray(e)},isFunction(e){return typeof e=="function"},isPromise(e){return!!e&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"},isElement(e){return e instanceof Element},isPhone(e){return/^1[3-9]\d{9}$/.test(e)},isEmail(e){return/^[\w.-]+@[\w.-]+\.\w+$/.test(e)},isJSON(e){try{return JSON.parse(e),!0}catch{return!1}},isImageLoaded(e){return e.complete&&e.naturalWidth!==0},isInViewport(e){const n=e.getBoundingClientRect();return n.top>=0&&n.left>=0&&n.bottom<=window.innerHeight&&n.right<=window.innerWidth},isLeapYear(e){return e%4===0&&e%100!==0||e%400===0},isMobile(){return/Mobi|Android|iPhone/i.test(navigator.userAgent)}},b={isEmptyObject(e){return e?Object.keys(e).length===0&&e.constructor===Object:!0},copy(e,n){for(const t in e)n[t]=e[t]},deepCopy(e,n){for(const t in e){const r=e[t];r instanceof Object?(n[t]={},this.deepCopy(r,n[t])):r instanceof Array?(n[t]=[],this.deepCopy(r,n[t])):n[t]=e[t]}}},E={...{getType(e){return Object.prototype.toString.call(e).replace(/\[object\s(\w+)\]/,"$1")}},...{shallowClone(e){if(e===null||typeof e!="object")return e;if(b.isEmptyObject(e))return{};const n={};for(const t in e)n[t]=e[t];return n},shallowCloneByObjectAssign(e){return Object.assign({},e)},shallowCloneBySpreadOperator(e){return{...e}},deepCloneByJSON(e){return e===null||typeof e!="object"?e:b.isEmptyObject(e)?{}:JSON.parse(JSON.stringify(e))},deepCloneByMap(e,n=new WeakMap){if(e===null||typeof e!="object")return e;if(b.isEmptyObject(e))throw new Error("空对象不能进行深拷贝");if(n.has(e))return n.get(e);const t=E.getType(e);let r;switch(t){case"object":case"array":r=Array.isArray(e)?[]:{};break;case"Date":r=new Date(e);break;case"RegExp":r=new RegExp(e);break;case"Map":r=new Map(e);break;case"Set":r=new Set(e);break;default:return e}return n.set(e,r),t==="Map"?(e.forEach((o,s)=>{r.set(this.deepCloneByMap(s,n),this.deepCloneByMap(o,n))}),r):t==="Set"?(e.forEach(o=>{r.add(this.deepCloneByMap(o,n))}),r):(Reflect.ownKeys(e).forEach(o=>{r[o]=this.deepCloneByMap(e[o],n)}),r)}},...{curry(e){if(typeof e!="function")throw new TypeError("curry: fn must be a function, but got "+typeof e);const n=e.length;return function t(...r){return r.length>=n?e.apply(this,r):function(...o){return t.apply(this,[...r,...o])}}},uncurry(e){return function(n,...t){return e.call(n,...t)}}}},B={getCookie(e){if(!e)return;const n=document.cookie.match(new RegExp("(^| )"+e+"=([^;]+)"));return n?decodeURIComponent(n[2]):null},setCookie(e,n,t=7){const r=new Date;r.setTime(r.getTime()+t*24*60*60*1e3),document.cookie=`${e}=${encodeURIComponent(n)};expires=${r.toUTCString()};path=/`},deleteCookie(e){this.setCookie(e,"",-1)}},C={getTimeString(e,n=!1){return n?new Date().toLocaleString(e,{hour12:!0}):new Date().toLocaleString("chinese",{hour12:!1})},diffDays(e,n){const t=new Date(e).getTime(),r=new Date(n).getTime();return t>r?Math.abs(Math.floor((t-r)/(24*3600*1e3))):Math.abs(Math.floor((r-t)/(24*3600*1e3)))},uniqueId(){return Date.now().toString(36)+Math.random().toString(36).substr(2,5)},getWhichDays(e,n,t){let r=t;for(let o=1;o<n;o++)switch(o){case 1:case 3:case 5:case 7:case 8:case 10:case 12:r+=31;break;case 2:S.isLeapYear(e)?r+=29:r+=28;break;default:r+=30;break}return r},getTimeStringAutoShort2(e,n){const t=new Date,r=new Date(e),o=t.getFullYear(),s=t.getMonth()+1,i=t.getDate(),l=r.getFullYear(),c=r.getMonth()+1,h=r.getDate();let a="";const u=n?" "+this.formatDate(r,"hh:mm"):"";if(o===l){const g=t.getTime()-e;if(s===c&&i===h)g<60*1e3?a="刚刚":a=this.formatDate(r,"hh:mm");else{const p=new Date;p.setDate(p.getDate()-1);const A=new Date;if(A.setDate(A.getDate()-2),c===p.getMonth()+1&&h===p.getDate())a="昨天"+u;else if(c===A.getMonth()+1&&h===A.getDate())a="前天"+u;else if(g/36e5<=7*24){const m=new Array(7);m[0]="星期日",m[1]="星期一",m[2]="星期二",m[3]="星期三",m[4]="星期四",m[5]="星期五",m[6]="星期六",a=m[r.getDay()]+u}else a=this.formatDate(r,"yyyy/M/d")+u}}else a=this.formatDate(r,"yyyy/M/d")+u;return a},formatDate(e,n){const t={"M+":e.getMonth()+1,"d+":e.getDate(),"h+":e.getHours(),"m+":e.getMinutes(),"s+":e.getSeconds(),"q+":Math.floor((e.getMonth()+3)/3),S:e.getMilliseconds()};/(y+)/.test(n)&&(n=n.replace(RegExp.$1,(e.getFullYear()+"").substr(4-RegExp.$1.length)));for(const r in t)new RegExp("("+r+")").test(n)&&(n=n.replace(RegExp.$1,RegExp.$1.length===1?t[r]:("00"+t[r]).substr((""+t[r]).length)));return n}},x={getOffsetTop(e){if(!e)throw new Error("Element is not provided");if(e instanceof SVGElement){const t=e.getBoundingClientRect(),r=window.pageYOffset||document.documentElement.scrollTop;return t.top+r}let n=0;for(;e;)n+=e.offsetTop,e=e.offsetParent;return n},getScrollValue(){const e={scrollLeft:0,scrollTop:0};return e.scrollLeft=document.body.scrollLeft||document.documentElement.scrollLeft,e.scrollTop=document.body.scrollTop||document.documentElement.scrollTop,e},getPageValue(e){e=e||window.event;const n=e.pageX||e.clientX+this.getScrollValue().scrollLeft,t=e.pageY||e.clientY+this.getScrollValue().scrollTop;return{pageX:n,pageY:t}},addEventListener(e,n,t){e.addEventListener?e.addEventListener(n,t):e.attachEvent?e.attachEvent("on"+n,t):e["on"+n]=t},getViewportWidth(){return window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth},getViewportHeight(){return window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight}},T={saveAsBlob(e,n){const t=document.createElement("a"),r=window.URL.createObjectURL(e);t.href=r,t.download=n,document.body.appendChild(t),t.click(),URL.revokeObjectURL(r),document.body.removeChild(t)},saveAsUrl(e,n){const t=document.createElement("a");t.href=e,t.download=n,document.body.appendChild(t),t.click(),URL.revokeObjectURL(e),document.body.removeChild(t)}},D={animate(e,n){let t=-1;const r=e.series[0].data.length;let o;o=setInterval(()=>{n.dispatchAction({type:"downplay",seriesIndex:0,dataIndex:t}),t=(t+1)%r,n.dispatchAction({type:"highlight",seriesIndex:0,dataIndex:t}),n.dispatchAction({type:"showTip",seriesIndex:0,dataIndex:t}),t>r&&(t=0)},2e3),n.on("mouseover",()=>{clearInterval(o),n.dispatchAction({type:"downplay",seriesIndex:0,dataIndex:t})})}},v={sortFromA2Z(e){return e?.length?e.sort((t,r)=>{const o=t.toUpperCase(),s=r.toUpperCase();return o<s?-1:o>s?1:0}):void 0}},O={degrees2Radians(e){return e*Math.PI/180},getDistance(e,n,t,r){const o=this.degrees2Radians(e),s=this.degrees2Radians(t),i=o-s,l=this.degrees2Radians(n)-this.degrees2Radians(r);let c=2*Math.asin(Math.sqrt(Math.pow(Math.sin(i/2),2)+Math.cos(o)*Math.cos(s)*Math.pow(Math.sin(l/2),2)));return c=c*6378.137,c=Math.round(c*1e4)/1e4,c=+c.toFixed(2),console.log("经纬度计算的距离为:"+c),c},calculateDistanceByHaversine(e,n,t="km"){const r=this,o=e.longitude??e.lng,s=e.latitude??e.lat,i=n.longitude??n.lng,l=n.latitude??n.lat;if(o===void 0||s===void 0||i===void 0||l===void 0)throw new Error("无效的坐标格式,缺少经纬度信息");const c=6371,h=r.degrees2Radians(s),a=r.degrees2Radians(l),u=r.degrees2Radians(l-s),d=r.degrees2Radians(i-o),y=Math.sin(u/2)*Math.sin(u/2)+Math.cos(h)*Math.cos(a)*Math.sin(d/2)*Math.sin(d/2),g=2*Math.atan2(Math.sqrt(y),Math.sqrt(1-y)),p=c*g;switch(t){case"m":return p*1e3;case"mi":return p*.621371;case"nmi":return p*.539957;default:return p}},calculateDistancesByHaversine(e,n="km",t=!1){if(e.length<2)return{segments:[],total:0};const r=[];let o=0;for(let s=0;s<e.length-1;s++){const i=this.calculateDistanceByHaversine(e[s],e[s+1],n);r.push(i),o+=i}if(t&&e.length>2){const s=this.calculateDistanceByHaversine(e[e.length-1],e[0],n);r.push(s),o+=s}return{segments:r,total:o}}};class R{static toStandardFormat(n){try{const t=typeof n=="string"?parseFloat(n):n;if(isNaN(t))throw new Error("输入不是有效的数字");if(!isFinite(t))throw new Error("输入是无穷大");return t.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")}catch(t){return console.error("格式化失败:",t),"格式错误"}}static toChineseFormat(n){try{const t=typeof n=="string"?parseFloat(n):n;if(isNaN(t))throw new Error("输入不是有效的数字");if(t>9999999999999e-2||t<-9999999999999e-2)throw new Error("输入数字超出范围");const r=t<0,o=Math.abs(t),s=Math.floor(o),i=Math.round((o-s)*100),l=["零","壹","贰","叁","肆","伍","陆","柒","捌","玖"],c=["","拾","佰","仟","万","拾","佰","仟","亿","拾","佰","仟"],h=["角","分"];let a="",u=s;if(u===0)a=l[0];else{let g=0;for(;u>0;){const p=u%10;p!==0?a=l[p]+c[g]+a:a.charAt(0)!==l[0]&&(a=l[p]+a),u=Math.floor(u/10),g++}a=a.replace(/零+/g,"零"),a=a.replace(/零+$/,"")}let d="";if(i>0){const g=Math.floor(i/10),p=i%10;g>0&&(d+=l[g]+h[0]),p>0&&(d+=l[p]+h[1])}else d="整";let y=(r?"负":"")+a+"圆"+d;return y==="零圆整"&&(y="零圆"),y}catch(t){return console.error("转换失败:",t),"格式错误"}}}const j={desensitizeChineseName(e,n={}){const{keepLength:t=1,keepLast:r=!1}=n;if(!e||e.length===0||e.trim().length===0)throw new Error("姓名不能为空");if(typeof e!="string")throw new Error("姓名必须是字符串");if(e.length<=1)return e;const o=["欧阳","司马","上官","东方","独孤","南宫","闻人","夏侯","诸葛","尉迟","公孙","长孙","宇文","司徒","慕容"];n.compoundSurname&&n.compoundSurname.trim().length>0&&!o.includes(n.compoundSurname)&&o.push(n.compoundSurname);let s="";o.some(l=>e.startsWith(l))?s=o.find(l=>e.startsWith(l))||"":s=e[0]||"";const i=Math.max(t,s.length);if(i>=e.length)return e;if(r&&e.length>2){const l=e.slice(0,i),c=e.slice(-1),h=e.length-i-1;return`${l}${"*".repeat(h)}${c}`}return`${e.slice(0,i)}${"*".repeat(e.length-i)}`}},L={...Object.freeze(Object.defineProperty({__proto__:null,toLetter:e=>e>25||e<0?"":"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[e]},Symbol.toStringTag,{value:"Module"})),...Object.freeze(Object.defineProperty({__proto__:null,toMoney:e=>e.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")},Symbol.toStringTag,{value:"Module"})),isNumber(e){return typeof e=="number"&&!isNaN(e)}},I={...{debounce(e,n){let t=null;return function(...o){const s=this;return t&&(clearTimeout(t),t=null),new Promise(i=>{t=setTimeout(()=>{const l=e.apply(s,o);t=null,i(l)},n)})}}},...{throttleByTimestamp(e,n){let t=0;return function(...o){const s=this,i=Date.now();return i-t>=n?(t=i,new Promise(l=>{const c=e.apply(s,o);l(c)})):Promise.resolve(void 0)}},throttleByTimer(e,n){let t=null;return function(...o){const s=this;return t?Promise.resolve(void 0):new Promise(i=>{t=setTimeout(()=>{t=null;const l=e.apply(s,o);i(l)},n)})}},throttle(e,n,t={}){const{leading:r=!0,trailing:o=!1}=t;let s=0,i=null;const l=function(...c){const h=this,a=Date.now();return r&&a-s>=n?(s=a,new Promise(u=>{const d=e.apply(h,c);u(d)})):o&&!i?new Promise(u=>{i=setTimeout(()=>{s=Date.now(),i=null;const d=e.apply(h,c);u(d)},n-(a-s))}):Promise.resolve(void 0)};return l.cancel=function(){i&&(clearTimeout(i),i=null),s=0},l}}},_={desensitize(e){return e?e.replace(/^(\d{3})\d{4}(\d{4})$/,"$1****$2")||e.slice(0,3)+"****"+e.slice(7):""}},k={color:function(){return`#${Math.random().toString(16).slice(2,8)}`},int(e,n){return Math.floor(Math.random()*(n-e+1))+e},uniqueId(){return Date.now().toString(36)+Math.random().toString(36).substr(2,5)}},H={mobile:/^1[3-9]\d{9}$/,email:/^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,chinese:/^[\u4e00-\u9fa5]+$/,english:/^[a-zA-Z]+$/,chineseStart:/^[\u4e00-\u9fa5]+\w*$/,integer:/^\d+$/,integerAndzero:/^(0|[1-9]+[0-9]*)$/,strongPassword:/^(?!.*[\s\p{C}])(?:(?=.*[A-Z])(?=.*[a-z])(?=.*[\d\W])|(?=.*\d)(?=.*[^\w\s])).{8,}$/u,decimal:/^0\.(0[1-9]|[1-9][0-9]*)$/},P={getLocal(e){return localStorage.getItem(e)},setLocal(e,n){localStorage.setItem(e,n)},removeLocal(e){localStorage.removeItem(e)},getSession(e){return sessionStorage.getItem(e)},setSession(e,n){sessionStorage.setItem(e,n)},removeSession(e){sessionStorage.removeItem(e)}},$={isExist(e,n){if(!e||!n)return!1;const t=e.split(",");return console.log("判断某元素是否在字符串中",t.indexOf(n)===-1),t.indexOf(n)!==-1},includes(e,n){return!e||!n?!1:e.includes(n)},isJSON(e){try{return JSON.parse(e),!0}catch{return!1}},indexsOfAppear(e,n){let t=-1;const r=[];do t=e.indexOf(n,t+1),t!==-1&&r.push(t);while(t!==-1);return r},getMaxTimesAndVal(e){const n=[0,""],t={};for(let s=0;s<e.length;s++){const i=e.charAt(s);t[i]?t[i]++:t[i]=1}let r=1;for(const s in t)r<t[s]&&(r=t[s]);const o=[];for(const s in t)r==t[s]&&o.push(s);return n[0]=r,n[1]=o.join(),n},mask(e,n,t){if(!e)throw new Error("字符串为空");if(typeof n!="number"||typeof t!="number")throw new Error("开始位置或结束位置为空");if(n<0||t>e.length||n>t)throw new Error("开始位置小于0或结束位置超出字符串长度或开始位置大于结束位置");return e.slice(0,n)+"*".repeat(t-n+1)+e.slice(t)}},N=e=>{const t=new RegExp("[?&]"+e+"=([^&#]*)","gi").exec(window.location.href);return t?decodeURIComponent(t[1]):null};function F(e){return new URLSearchParams(window.location.search).get(e)}const q={...Object.freeze(Object.defineProperty({__proto__:null,getQueryInfoByName:N,getQueryParam:F},Symbol.toStringTag,{value:"Module"})),getHost(){return window.location.host},getPath(){return window.location.pathname}},V={toList(e,n=2){console.log(e,n);const t={};for(let o=0;o<n;o++)t[o]=[];e.forEach((o,s)=>t[s%n].push(o));const r=[];for(const o in t)r.push(...t[o]);return r},jsLayout(e,n,t){const r=e.offsetWidth,o=n[0].offsetWidth,s=parseInt((r/o).toString()),i=(r-o*s)/(s-1),l=[];for(let c=0,h=n.length;c<h;c++){const a=n[c];if(c<s)a.style.left=(o+i)*c+"px",l[c]=a.offsetHeight;else{const{index:u,value:d}=M.getMinValueAndIndex(l);a.style.left=(o+i)*u+"px",a.style.top=d+t+"px",l[u]=a.offsetHeight+t+d}}}};f.Base64Utils=U,f.MoneyFormatter=R,f.arrayUtils=M,f.booleanUtils=S,f.commonUtils=E,f.cookieUtils=B,f.dateUtils=C,f.documentUtils=x,f.downloadUtils=T,f.echartsUtils=D,f.letterUtils=v,f.mapUtils=O,f.nameUtils=j,f.numberUtils=L,f.objectUtils=b,f.performanceUtils=I,f.phoneUtils=_,f.randomUtils=k,f.regexpUtils=H,f.storageUtils=P,f.stringUtils=$,f.urlUtils=q,f.waterfallUtils=V,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yh-kit/utils",
3
3
  "private": false,
4
- "version": "1.18.0",
4
+ "version": "1.19.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist",
@@ -1,10 +1,22 @@
1
1
  declare const _default: {
2
2
  /**
3
- * 浅拷贝
3
+ * 浅拷贝,使用 for 循环实现浅拷贝
4
4
  * @param source 需要处理的源对象
5
5
  * @returns 浅拷贝后的新对象
6
6
  */
7
7
  shallowClone(source: object): object;
8
+ /**
9
+ * 浅拷贝,使用 Object.assign({}, source) 实现浅拷贝
10
+ * @param source 需要处理的源对象
11
+ * @returns 浅拷贝后的新对象
12
+ */
13
+ shallowCloneByObjectAssign(source: object): object;
14
+ /**
15
+ * 浅拷贝,使用 扩展运算符 ...source 实现浅拷贝【更推荐】
16
+ * @param source 需要处理的源对象
17
+ * @returns 浅拷贝后的新对象
18
+ */
19
+ shallowCloneBySpreadOperator(source: object): {};
8
20
  /**
9
21
  * 最便捷实现深克隆/拷贝
10
22
  * 存在的问题:
@@ -5,6 +5,8 @@ export declare const commonUtils: {
5
5
  readonly curry: (fn: Function) => (this: unknown, ...args: unknown[]) => any;
6
6
  readonly uncurry: (fn: Function) => (context: unknown, ...args: unknown[]) => any;
7
7
  readonly shallowClone: (source: object) => object;
8
+ readonly shallowCloneByObjectAssign: (source: object) => object;
9
+ readonly shallowCloneBySpreadOperator: (source: object) => {};
8
10
  readonly deepCloneByJSON: (source: unknown) => any;
9
11
  readonly deepCloneByMap: <T>(source: T, map?: WeakMap<object, unknown>) => unknown;
10
12
  readonly getType: (val: unknown) => string;
package/types/index.d.ts CHANGED
@@ -13,6 +13,7 @@ export * from "./money";
13
13
  export * from "./name";
14
14
  export * from "./number";
15
15
  export * from "./object";
16
+ export * from "./performance";
16
17
  export * from "./phone";
17
18
  export * from "./random";
18
19
  export * from "./regexp";
@@ -0,0 +1,13 @@
1
+ declare const _default: {
2
+ /**
3
+ * 函数防抖
4
+ * 定义:在事件被触发后,延迟执行某个函数。如果在延迟期间事件再次被触发,则重新计算延迟时间。
5
+ * 核心:只有当事件停止触发一段时间后,才会执行函数。
6
+ * 应用场景:搜索框输入、按钮防重复点击、滚动事件防抖、窗口resize事件等。
7
+ * @param fn 需要防抖的函数
8
+ * @param delay 防抖延迟时间(毫秒)
9
+ * @returns 防抖后的函数(返回 Promise,可通过 .then() 获取原函数返回值)
10
+ */
11
+ debounce(fn: Function, delay: number): (this: unknown, ...args: unknown[]) => Promise<unknown>;
12
+ };
13
+ export default _default;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * 性能优化工具函数
3
+ */
4
+ export declare const performanceUtils: {
5
+ readonly throttleByTimestamp: (fn: Function, delay: number) => (this: unknown, ...args: unknown[]) => Promise<unknown>;
6
+ readonly throttleByTimer: (fn: Function, delay: number) => (this: unknown, ...args: unknown[]) => Promise<unknown>;
7
+ readonly throttle: (fn: Function, delay: number, options?: import("./throttle").ThrottleOptions) => {
8
+ (this: unknown, ...args: unknown[]): Promise<unknown>;
9
+ cancel(): void;
10
+ };
11
+ readonly debounce: (fn: Function, delay: number) => (this: unknown, ...args: unknown[]) => Promise<unknown>;
12
+ };
@@ -0,0 +1,51 @@
1
+ /** 节流选项 */
2
+ export interface ThrottleOptions {
3
+ /** 是否在时间窗口开始时执行,默认 true ,即使用时间戳实现方式,首次调用会立即执行 */
4
+ leading?: boolean;
5
+ /** 是否在时间窗口结束时执行,默认 false 。如果为 true,会使用定时器实现方式,首次调用也会延迟执行 */
6
+ trailing?: boolean;
7
+ }
8
+ declare const _default: {
9
+ /**
10
+ * 函数节流(时间戳版)
11
+ * 定义:在指定的时间间隔内,函数最多只执行一次。
12
+ * 核心:保证函数定期执行,而不是等待事件停止触发。
13
+ * 实现思路:通过时间戳判断,只有当距离上一次执行的时间超过设定延迟时才执行。
14
+ * 特点:首次调用会立即执行。
15
+ * 应用场景:滚动加载、按钮限频、鼠标移动追踪等。
16
+ * @param fn 要节流的函数
17
+ * @param delay 时间间隔(毫秒)
18
+ * @returns 节流后的函数
19
+ */
20
+ throttleByTimestamp(fn: Function, delay: number): (this: unknown, ...args: unknown[]) => Promise<unknown>;
21
+ /**
22
+ * 函数节流(定时器版)
23
+ * 定义:在指定的时间间隔内,函数最多只执行一次。
24
+ * 核心:通过定时器控制函数的执行频率,定时器运行期间的所有调用都会被忽略。
25
+ * 实现思路:第一次调用时设置定时器,在定时器运行期间忽略所有调用,直到定时器执行完毕后才允许下一次执行。
26
+ * 特点:首次调用会延迟执行(等待 delay 后)。
27
+ * 应用场景:按钮防重复提交、防重复请求等。
28
+ * @param fn 要节流的函数
29
+ * @param delay 时间间隔(毫秒)
30
+ * @returns 节流后的函数(返回 Promise,可通过 .then() 获取原函数返回值)
31
+ */
32
+ throttleByTimer(fn: Function, delay: number): (this: unknown, ...args: unknown[]) => Promise<unknown>;
33
+ /**
34
+ * 函数节流(高级版)
35
+ * 定义:在指定的时间间隔内,函数最多只执行一次,支持配置执行时机。
36
+ * 核心:通过配置选项控制函数在时间窗口的开始或结束时执行。
37
+ * 实现思路:结合时间戳和定时器实现,支持 leading 和 trailing 选项。
38
+ * 应用场景:滚动加载、搜索建议、鼠标拖拽等。
39
+ * @param fn 要节流的函数
40
+ * @param delay 时间间隔(毫秒)
41
+ * @param options 配置选项
42
+ * @param options.leading 是否在时间窗口开始时执行,默认 true
43
+ * @param options.trailing 是否在时间窗口结束时执行,默认 false
44
+ * @returns 节流后的函数(返回 Promise,可通过 .then() 获取原函数返回值)
45
+ */
46
+ throttle(fn: Function, delay: number, options?: ThrottleOptions): {
47
+ (this: unknown, ...args: unknown[]): Promise<unknown>;
48
+ cancel(): void;
49
+ };
50
+ };
51
+ export default _default;