@yh-kit/utils 1.5.0 → 1.6.1

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
@@ -1,22 +1,22 @@
1
- const b = (t) => {
2
- if (!t || !t.length) return {};
3
- const e = {};
4
- return t.forEach((r) => {
5
- const o = Object.assign({ label: r.label, text: r.label }, r);
6
- e[r == null ? void 0 : r.value] = o;
7
- }), e;
8
- }, y = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1
+ const y = (e) => {
2
+ if (!e || !e.length) return {};
3
+ const r = {};
4
+ return e.forEach((t) => {
5
+ const n = Object.assign({ label: t.label, text: t.label }, t);
6
+ r[t == null ? void 0 : t.value] = n;
7
+ }), r;
8
+ }, b = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
9
9
  __proto__: null,
10
- toEnumObj: b
11
- }, Symbol.toStringTag, { value: "Module" })), A = Object.assign(
10
+ toEnumObj: y
11
+ }, Symbol.toStringTag, { value: "Module" })), L = Object.assign(
12
12
  {
13
13
  /**
14
14
  * 数组去重
15
15
  * @param arr 数组
16
16
  * @returns 去重后的数组
17
17
  */
18
- unique(t) {
19
- return t ? Array.from(new Set(t)) : [];
18
+ unique(e) {
19
+ return e ? Array.from(new Set(e)) : [];
20
20
  },
21
21
  /**
22
22
  * 判断某元素是否在数组中
@@ -24,8 +24,8 @@ const b = (t) => {
24
24
  * @param element 查询元素
25
25
  * @returns 是否存在。true 存在;false 不存在
26
26
  */
27
- isExist(t, e) {
28
- return !t || !e ? !1 : t.indexOf(e) !== -1;
27
+ isExist(e, r) {
28
+ return !e || !r ? !1 : e.indexOf(r) !== -1;
29
29
  },
30
30
  /**
31
31
  * 统计数组中某元素出现的次数:对于大型数组,手动循环的性能略优于 filter 和 reduce。
@@ -33,11 +33,25 @@ const b = (t) => {
33
33
  * @param target 目标元素
34
34
  * @returns 出现次数
35
35
  */
36
- countOfAppear(t, e) {
37
- let r = 0;
38
- for (const o of t)
39
- o === e && r++;
40
- return r;
36
+ countOfAppear(e, r) {
37
+ let t = 0;
38
+ for (const n of e)
39
+ n === r && t++;
40
+ return t;
41
+ },
42
+ /**
43
+ * 查找某个元素在数组中重复出现的位置
44
+ * @param array 数组
45
+ * @param element 元素
46
+ * @returns 位置数组
47
+ */
48
+ indexsOfAppear(e, r) {
49
+ let t = -1;
50
+ const n = [];
51
+ do
52
+ t = e.indexOf(r, t + 1), t !== -1 && n.push(t);
53
+ while (t !== -1);
54
+ return n;
41
55
  },
42
56
  /**
43
57
  * 数组排序-默认升序
@@ -45,8 +59,8 @@ const b = (t) => {
45
59
  * @param order 排序方式:asc 升序;desc 降序
46
60
  * @returns 排序后的数组
47
61
  */
48
- sort(t, e = "asc") {
49
- return t ? t.sort((r, o) => e === "asc" ? r > o ? 1 : -1 : r < o ? 1 : -1) : [];
62
+ sort(e, r = "asc") {
63
+ return e ? e.sort((t, n) => r === "asc" ? t > n ? 1 : -1 : t < n ? 1 : -1) : [];
50
64
  },
51
65
  /**
52
66
  * 数组乱序(洗牌算法)
@@ -59,20 +73,36 @@ const b = (t) => {
59
73
  * @param arr 数组
60
74
  * @returns
61
75
  */
62
- shuffle(t) {
63
- if (!t)
76
+ shuffle(e) {
77
+ if (!e)
64
78
  return [];
65
- for (let e = t.length - 1; e > 0; e--) {
66
- const r = Math.floor(Math.random() * (e + 1));
67
- [t[e], t[r]] = [t[r], t[e]];
79
+ for (let r = e.length - 1; r > 0; r--) {
80
+ const t = Math.floor(Math.random() * (r + 1));
81
+ [e[r], e[t]] = [e[t], e[r]];
68
82
  }
69
- return t;
83
+ return e;
84
+ },
85
+ /**
86
+ * 获取数组中的最大值
87
+ * @param arr 数组
88
+ * @returns 最大值
89
+ */
90
+ getMaxValue(e) {
91
+ return e ? Math.max(...e) : 0;
92
+ },
93
+ /**
94
+ * 获取数组中的最小值
95
+ * @param arr 数组
96
+ * @returns 最小值
97
+ */
98
+ getMinValue(e) {
99
+ return e ? Math.min(...e) : 0;
70
100
  }
71
101
  },
72
102
  {
73
- ...y
103
+ ...b
74
104
  }
75
- ), j = {
105
+ ), A = {
76
106
  /**
77
107
  * 将Base64编码的字符串转换为Blob对象。
78
108
  * Blob对象用于表示二进制大型对象,可以在浏览器环境中处理大文件或二进制数据。
@@ -82,18 +112,18 @@ const b = (t) => {
82
112
  * @param sliceSize 可选参数,表示分片大小,默认为512字节。用于控制每次处理的Base64字符串长度,以优化大文件的处理。
83
113
  * @returns 返回转换后的Blob对象,如果转换失败,则返回null。
84
114
  */
85
- toBlob(t, e = "", r = 512) {
86
- const s = (t.split(",")[1] || t).replace(/-/g, "+").replace(/_/g, "/"), l = "=".repeat((4 - s.length % 4) % 4), d = s + l;
115
+ toBlob(e, r = "", t = 512) {
116
+ const o = (e.split(",")[1] || e).replace(/-/g, "+").replace(/_/g, "/"), s = "=".repeat((4 - o.length % 4) % 4), c = o + s;
87
117
  try {
88
- const i = atob(d), g = [];
89
- for (let u = 0; u < i.length; u += r) {
90
- const n = i.slice(u, u + r), a = new Array(n.length);
91
- for (let c = 0; c < n.length; c++)
92
- a[c] = n.charCodeAt(c);
93
- const f = new Uint8Array(a);
94
- g.push(f);
118
+ const i = atob(c), l = [];
119
+ for (let h = 0; h < i.length; h += t) {
120
+ const a = i.slice(h, h + t), d = new Array(a.length);
121
+ for (let u = 0; u < a.length; u++)
122
+ d[u] = a.charCodeAt(u);
123
+ const f = new Uint8Array(d);
124
+ l.push(f);
95
125
  }
96
- return new Blob(g, { type: e });
126
+ return new Blob(l, { type: r });
97
127
  } catch (i) {
98
128
  return console.error("Failed to convert base64 to blob:", i), null;
99
129
  }
@@ -108,73 +138,73 @@ const b = (t) => {
108
138
  * @param mimeType MIME类型,默认为"text/plain"。
109
139
  * @returns 返回一个File对象,包含解码后的数据。
110
140
  */
111
- toFile(t, e = "file.txt", r = "text/plain") {
112
- const s = t.replace(/^data:.+;base64,/, "").replace(/-/g, "+").replace(/_/g, "/"), l = "=".repeat((4 - s.length % 4) % 4), d = s + l, i = atob(d), g = [];
113
- for (let n = 0; n < i.length; n += 512) {
114
- const a = i.slice(n, n + 512), f = new Array(a.length);
115
- for (let c = 0; c < a.length; c++)
116
- f[c] = a.charCodeAt(c);
117
- g.push(new Uint8Array(f));
141
+ toFile(e, r = "file.txt", t = "text/plain") {
142
+ const o = e.replace(/^data:.+;base64,/, "").replace(/-/g, "+").replace(/_/g, "/"), s = "=".repeat((4 - o.length % 4) % 4), c = o + s, i = atob(c), l = [];
143
+ for (let a = 0; a < i.length; a += 512) {
144
+ const d = i.slice(a, a + 512), f = new Array(d.length);
145
+ for (let u = 0; u < d.length; u++)
146
+ f[u] = d.charCodeAt(u);
147
+ l.push(new Uint8Array(f));
118
148
  }
119
- const u = new Blob(g, { type: r });
120
- return new File([u], e, { type: r });
149
+ const h = new Blob(l, { type: t });
150
+ return new File([h], r, { type: t });
121
151
  }
122
- }, x = {
152
+ }, m = {
123
153
  /**
124
154
  * 检查是否为空字符串
125
155
  * @param str 要检查的字符串
126
156
  * @returns 如果字符串为空,则返回 true,否则返回 false
127
157
  */
128
- isEmptyString(t) {
129
- return typeof t == "string" && t.trim() === "";
158
+ isEmptyString(e) {
159
+ return typeof e == "string" && e.trim() === "";
130
160
  },
131
161
  /**
132
162
  * 判断是否为数字
133
163
  * @param val 要检查的值
134
164
  * @returns 如果值是数字,则返回 true,否则返回 false
135
165
  */
136
- isNumber(t) {
137
- return typeof t == "number" && !isNaN(t);
166
+ isNumber(e) {
167
+ return typeof e == "number" && !isNaN(e);
138
168
  },
139
169
  /**
140
170
  * 判断是否为对象
141
171
  * @param val 要检查的值
142
172
  * @returns 如果值是对象,则返回 true,否则返回 false
143
173
  */
144
- isObject(t) {
145
- return t !== null && typeof t == "object" && !Array.isArray(t);
174
+ isObject(e) {
175
+ return e !== null && typeof e == "object" && !Array.isArray(e);
146
176
  },
147
177
  /**
148
178
  * 判断对象是否为空
149
179
  * @param obj 要检查的对象
150
180
  * @returns 如果对象为空,则返回 true,否则返回 false
151
181
  */
152
- isEmptyObject(t) {
153
- return t ? Object.keys(t).length === 0 && t.constructor === Object : !0;
182
+ isEmptyObject(e) {
183
+ return e ? Object.keys(e).length === 0 && e.constructor === Object : !0;
154
184
  },
155
185
  /**
156
186
  * 判断是否为布尔值
157
187
  * @param val 要检查的值
158
188
  * @returns 如果值是布尔值,则返回 true,否则返回 false
159
189
  */
160
- isBoolean(t) {
161
- return typeof t == "boolean";
190
+ isBoolean(e) {
191
+ return typeof e == "boolean";
162
192
  },
163
193
  /**
164
194
  * 判断是否为数组
165
195
  * @param val 要检查的值
166
196
  * @returns 如果值是数组,则返回 true,否则返回 false
167
197
  */
168
- isArray(t) {
169
- return Array.isArray(t);
198
+ isArray(e) {
199
+ return Array.isArray(e);
170
200
  },
171
201
  /**
172
202
  * 判断是否为函数
173
203
  * @param val 要检查的值
174
204
  * @returns
175
205
  */
176
- isFunction(t) {
177
- return typeof t == "function";
206
+ isFunction(e) {
207
+ return typeof e == "function";
178
208
  },
179
209
  /**
180
210
  * 判断是否为 Promise 对象
@@ -182,41 +212,41 @@ const b = (t) => {
182
212
  * @returns 如果对象是 Promise 对象,则返回 true,否则返回 false
183
213
  */
184
214
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
185
- isPromise(t) {
186
- return !!t && (typeof t == "object" || typeof t == "function") && typeof t.then == "function";
215
+ isPromise(e) {
216
+ return !!e && (typeof e == "object" || typeof e == "function") && typeof e.then == "function";
187
217
  },
188
218
  /**
189
219
  * 判断是否为 DOM 元素
190
220
  * @param obj 要检查的对象
191
221
  * @returns 如果对象是 DOM 元素,则返回 true,否则返回 false
192
222
  */
193
- isElement(t) {
194
- return t instanceof Element;
223
+ isElement(e) {
224
+ return e instanceof Element;
195
225
  },
196
226
  /**
197
227
  * 判断手机号格式(中国)
198
228
  * @param str 手机号字符串
199
229
  * @returns true 表示手机号格式正确,false 表示手机号格式错误
200
230
  */
201
- isPhone(t) {
202
- return /^1[3-9]\d{9}$/.test(t);
231
+ isPhone(e) {
232
+ return /^1[3-9]\d{9}$/.test(e);
203
233
  },
204
234
  /**
205
235
  * 判断邮箱格式
206
236
  * @param str 邮箱字符串
207
237
  * @returns true 表示邮箱格式正确,false 表示邮箱格式错误
208
238
  */
209
- isEmail(t) {
210
- return /^[\w.-]+@[\w.-]+\.\w+$/.test(t);
239
+ isEmail(e) {
240
+ return /^[\w.-]+@[\w.-]+\.\w+$/.test(e);
211
241
  },
212
242
  /**
213
243
  * 判断字符串是否为 JSON
214
244
  * @param str 字符串
215
245
  * @returns true 表示是 JSON,false 表示不是 JSON
216
246
  */
217
- isJSON(t) {
247
+ isJSON(e) {
218
248
  try {
219
- return JSON.parse(t), !0;
249
+ return JSON.parse(e), !0;
220
250
  } catch {
221
251
  return !1;
222
252
  }
@@ -229,17 +259,17 @@ const b = (t) => {
229
259
  * const img = new Image();
230
260
  * img.src = "URL_ADDRESS * img.src = "https://example.com/image.jpg";
231
261
  */
232
- isImageLoaded(t) {
233
- return t.complete && t.naturalWidth !== 0;
262
+ isImageLoaded(e) {
263
+ return e.complete && e.naturalWidth !== 0;
234
264
  },
235
265
  /**
236
266
  * 判断元素是否在可视区域内
237
267
  * @param el 元素对象
238
268
  * @returns true 表示元素在可视区域内,false 表示元素不在可视区域内
239
269
  */
240
- isInViewport(t) {
241
- const e = t.getBoundingClientRect();
242
- return e.top >= 0 && e.left >= 0 && e.bottom <= window.innerHeight && e.right <= window.innerWidth;
270
+ isInViewport(e) {
271
+ const r = e.getBoundingClientRect();
272
+ return r.top >= 0 && r.left >= 0 && r.bottom <= window.innerHeight && r.right <= window.innerWidth;
243
273
  },
244
274
  /**
245
275
  * 判断是否为闰年
@@ -253,8 +283,8 @@ const b = (t) => {
253
283
  * isLeapYear(2025); // false
254
284
  * isLeapYear(2024); // true
255
285
  */
256
- isLeapYear(t) {
257
- return t % 4 === 0 && t % 100 !== 0 || t % 400 === 0;
286
+ isLeapYear(e) {
287
+ return e % 4 === 0 && e % 100 !== 0 || e % 400 === 0;
258
288
  },
259
289
  /**
260
290
  * 判断是否为移动端
@@ -263,16 +293,16 @@ const b = (t) => {
263
293
  isMobile() {
264
294
  return /Mobi|Android|iPhone/i.test(navigator.userAgent);
265
295
  }
266
- }, C = {
296
+ }, v = {
267
297
  /**
268
298
  * 通过传入的name获取cookie的值
269
299
  * @param name cookie的name
270
300
  * @returns cookie的值
271
301
  */
272
- getCookie(t) {
273
- if (!t) return;
274
- const e = document.cookie.match(new RegExp("(^| )" + t + "=([^;]+)"));
275
- return e ? decodeURIComponent(e[2]) : null;
302
+ getCookie(e) {
303
+ if (!e) return;
304
+ const r = document.cookie.match(new RegExp("(^| )" + e + "=([^;]+)"));
305
+ return r ? decodeURIComponent(r[2]) : null;
276
306
  },
277
307
  /**
278
308
  * 设置 cookie
@@ -281,27 +311,27 @@ const b = (t) => {
281
311
  * @param days cookie的过期时间,默认7天。如果为0,则表示cookie在会话结束时过期。如果为负数,则表示cookie已过期。
282
312
  * @returns void
283
313
  */
284
- setCookie(t, e, r = 7) {
285
- const o = /* @__PURE__ */ new Date();
286
- o.setTime(o.getTime() + r * 24 * 60 * 60 * 1e3), document.cookie = `${t}=${encodeURIComponent(e)};expires=${o.toUTCString()};path=/`;
314
+ setCookie(e, r, t = 7) {
315
+ const n = /* @__PURE__ */ new Date();
316
+ n.setTime(n.getTime() + t * 24 * 60 * 60 * 1e3), document.cookie = `${e}=${encodeURIComponent(r)};expires=${n.toUTCString()};path=/`;
287
317
  },
288
318
  /**
289
319
  * 删除cookie
290
320
  * @param name cookie的name
291
321
  * @returns void
292
322
  */
293
- deleteCookie(t) {
294
- this.setCookie(t, "", -1);
323
+ deleteCookie(e) {
324
+ this.setCookie(e, "", -1);
295
325
  }
296
- }, _ = {
326
+ }, R = {
297
327
  /**
298
328
  * 获取当前时间字符串
299
329
  * @param locales 区域设置。如:'zh-CN','en-US',"chinese"。默认'zh-CN'。
300
330
  * @param hour12 是否使用12小时制。默认false,使用24小时制。
301
331
  * @returns 当前时间的字符串。如:'2025/5/27 16:54:45'
302
332
  */
303
- getTimeString(t, e = !1) {
304
- return e ? (/* @__PURE__ */ new Date()).toLocaleString(t, { hour12: !0 }) : (/* @__PURE__ */ new Date()).toLocaleString("chinese", { hour12: !1 });
333
+ getTimeString(e, r = !1) {
334
+ return r ? (/* @__PURE__ */ new Date()).toLocaleString(e, { hour12: !0 }) : (/* @__PURE__ */ new Date()).toLocaleString("chinese", { hour12: !1 });
305
335
  },
306
336
  /**
307
337
  * 计算两个日期相差天数
@@ -309,9 +339,9 @@ const b = (t) => {
309
339
  * @param date2 日期2
310
340
  * @returns 相差天数
311
341
  */
312
- diffDays(t, e) {
313
- const r = new Date(t).getTime(), o = new Date(e).getTime();
314
- return r > o ? Math.abs(Math.floor((r - o) / (24 * 3600 * 1e3))) : Math.abs(Math.floor((o - r) / (24 * 3600 * 1e3)));
342
+ diffDays(e, r) {
343
+ const t = new Date(e).getTime(), n = new Date(r).getTime();
344
+ return t > n ? Math.abs(Math.floor((t - n) / (24 * 3600 * 1e3))) : Math.abs(Math.floor((n - t) / (24 * 3600 * 1e3)));
315
345
  },
316
346
  /**
317
347
  * 生成唯一ID(时间戳+随机数)
@@ -319,65 +349,217 @@ const b = (t) => {
319
349
  */
320
350
  uniqueId() {
321
351
  return Date.now().toString(36) + Math.random().toString(36).substr(2, 5);
322
- }
323
- }, N = {
352
+ },
324
353
  /**
325
- * 将blob对象转化成文件并导出到本地
326
- * @param blob blob对象
327
- * @param filename 文件名
328
- */
329
- saveAsBlob(t, e) {
330
- const r = document.createElement("a"), o = window.URL.createObjectURL(t);
331
- r.href = o, r.download = e, document.body.appendChild(r), r.click(), URL.revokeObjectURL(o), document.body.removeChild(r);
354
+ * 获取指定日期是当年的第几天
355
+ * @param year 年份
356
+ * @param month 月份 数字:1-12;1:代表一月;12:代表十二月
357
+ * @param day 日期
358
+ * @returns 当年的第几天
359
+ */
360
+ getWhichDays(e, r, t) {
361
+ let n = t;
362
+ for (let o = 1; o < r; o++)
363
+ switch (o) {
364
+ case 1:
365
+ case 3:
366
+ case 5:
367
+ case 7:
368
+ case 8:
369
+ case 10:
370
+ case 12:
371
+ n += 31;
372
+ break;
373
+ case 2:
374
+ m.isLeapYear(e) ? n += 29 : n += 28;
375
+ break;
376
+ default:
377
+ n += 30;
378
+ break;
379
+ }
380
+ return n;
332
381
  }
333
- }, B = {
382
+ }, j = {
334
383
  /**
335
384
  * 获取元素相对于文档顶部的偏移量(距离)
336
385
  * 处理了SVG元素的特殊情况。
337
386
  * @param el 元素
338
387
  * @returns 偏移量(距离值)
339
388
  */
340
- getOffsetTop(t) {
341
- if (!t)
389
+ getOffsetTop(e) {
390
+ if (!e)
342
391
  throw new Error("Element is not provided");
343
- if (t instanceof SVGElement) {
344
- const r = t.getBoundingClientRect(), o = window.pageYOffset || document.documentElement.scrollTop;
345
- return r.top + o;
392
+ if (e instanceof SVGElement) {
393
+ const t = e.getBoundingClientRect(), n = window.pageYOffset || document.documentElement.scrollTop;
394
+ return t.top + n;
346
395
  }
347
- let e = 0;
348
- for (; t; )
349
- e += t.offsetTop, t = t.offsetParent;
350
- return e;
396
+ let r = 0;
397
+ for (; e; )
398
+ r += e.offsetTop, e = e.offsetParent;
399
+ return r;
400
+ },
401
+ /**
402
+ * 获取文档的滚动值
403
+ * @returns 包含滚动值的对象 { scrollLeft: 水平滚动值, scrollTop: 垂直滚动值 }
404
+ */
405
+ getScrollValue() {
406
+ const e = {
407
+ scrollLeft: 0,
408
+ scrollTop: 0
409
+ };
410
+ return e.scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft, e.scrollTop = document.body.scrollTop || document.documentElement.scrollTop, e;
411
+ },
412
+ /**
413
+ * 获取鼠标事件的页面坐标
414
+ * 已解决pageX、pageY兼容性问题
415
+ * e.pageX = e.clientX + 页面滚动的横向距离 ;
416
+ * e.pageY = e.clientY + 页面滚动的纵向距离 ;
417
+ * @param e 鼠标事件
418
+ * @returns 包含页面坐标的对象 { pageX: 水平页面坐标, pageY: 垂直页面坐标 }
419
+ */
420
+ getPageValue(e) {
421
+ e = e || window.event;
422
+ const r = e.pageX || e.clientX + this.getScrollValue().scrollLeft, t = e.pageY || e.clientY + this.getScrollValue().scrollTop;
423
+ return {
424
+ pageX: r,
425
+ pageY: t
426
+ };
427
+ },
428
+ /**
429
+ * 给元素添加事件监听器 - 判断并处理了监听事件的兼容性问题
430
+ * 实例应用: addEventListenerFn(btn, 'click', function(){})
431
+ * @param element 元素
432
+ * @param eventName 事件名称
433
+ * @param fn 事件处理函数
434
+ */
435
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
436
+ addEventListener(e, r, t) {
437
+ e.addEventListener ? e.addEventListener(r, t) : e.attachEvent ? e.attachEvent("on" + r, t) : e["on" + r] = t;
351
438
  }
352
- }, I = {
439
+ }, C = {
440
+ /**
441
+ * 将blob对象转化成文件并导出到本地
442
+ * @param blob blob对象
443
+ * @param filename 文件名
444
+ */
445
+ saveAsBlob(e, r) {
446
+ const t = document.createElement("a"), n = window.URL.createObjectURL(e);
447
+ t.href = n, t.download = r, document.body.appendChild(t), t.click(), URL.revokeObjectURL(n), document.body.removeChild(t);
448
+ }
449
+ }, k = {
353
450
  /**
354
451
  * 将选中的字母数组从A-Z排序:用于试题选择答案的排序实例
355
452
  * @param arr 字母数组
356
453
  * @returns
357
454
  */
358
- sortFromA2Z(t) {
359
- return t != null && t.length ? t.sort((r, o) => {
360
- const s = r.toUpperCase(), l = o.toUpperCase();
361
- return s < l ? -1 : s > l ? 1 : 0;
455
+ sortFromA2Z(e) {
456
+ return e != null && e.length ? e.sort((t, n) => {
457
+ const o = t.toUpperCase(), s = n.toUpperCase();
458
+ return o < s ? -1 : o > s ? 1 : 0;
362
459
  }) : void 0;
363
460
  }
461
+ }, B = {
462
+ /**
463
+ * 角度(度数)转弧度
464
+ * 在数学和编程里,角度有两种常用单位,分别是度(°)和弧度(rad)。
465
+ * 1 个完整的圆周,用角度表示是 360°,用弧度表示则是 2π rad。
466
+ * 角度和弧度的换算关系为:弧度 = 角度 × π / 180。
467
+ * @param degrees 度数。单位:°
468
+ * @returns 弧度值
469
+ */
470
+ degrees2Radians(e) {
471
+ return e * Math.PI / 180;
472
+ },
473
+ /**
474
+ * 根据经纬度计算距离【弃用】
475
+ * @param userLat 用户纬度
476
+ * @param userLng 用户经度
477
+ * @param targetLat 目标纬度
478
+ * @param targetLng 目标经度
479
+ * @returns 距离值 单位:km
480
+ */
481
+ getDistance(e, r, t, n) {
482
+ const o = this.degrees2Radians(e), s = this.degrees2Radians(t), c = o - s, i = this.degrees2Radians(r) - this.degrees2Radians(n);
483
+ let l = 2 * Math.asin(
484
+ Math.sqrt(
485
+ Math.pow(Math.sin(c / 2), 2) + Math.cos(o) * Math.cos(s) * Math.pow(Math.sin(i / 2), 2)
486
+ )
487
+ );
488
+ return l = l * 6378.137, l = Math.round(l * 1e4) / 1e4, l = +l.toFixed(2), console.log("经纬度计算的距离为:" + l), l;
489
+ },
490
+ /**
491
+ * 计算两个坐标点之间的距离(Haversine公式)
492
+ * Haversine公式:
493
+ * a = sin²(Δlat/2) + cos(lat1)·cos(lat2)·sin²(Δlon/2) 其中:
494
+ * lat1, lat2: 两点的纬度(弧度)
495
+ * Δlat: 两点纬度之差(弧度)
496
+ * Δlon: 两点经度之差(弧度)
497
+ * c = 2·atan2(√a, √(1−a))
498
+ * d = R·c 其中:
499
+ * R: 地球半径(平均约 6371km)
500
+ * @param point1 坐标点1
501
+ * @param point2 坐标点2
502
+ * @param unit 距离单位,默认单位为千米。可选值:km(千米)、m(米)、mi(英里)、nmi(海里)
503
+ * @returns 距离值
504
+ */
505
+ calculateDistanceByHaversine(e, r, t = "km") {
506
+ const n = this, o = e.longitude ?? e.lng, s = e.latitude ?? e.lat, c = r.longitude ?? r.lng, i = r.latitude ?? r.lat;
507
+ if (o === void 0 || s === void 0 || c === void 0 || i === void 0)
508
+ throw new Error("无效的坐标格式,缺少经纬度信息");
509
+ const l = 6371, h = n.degrees2Radians(s), a = n.degrees2Radians(i), d = n.degrees2Radians(i - s), f = n.degrees2Radians(c - o), u = Math.sin(d / 2) * Math.sin(d / 2) + Math.cos(h) * Math.cos(a) * Math.sin(f / 2) * Math.sin(f / 2), p = 2 * Math.atan2(Math.sqrt(u), Math.sqrt(1 - u)), g = l * p;
510
+ switch (t) {
511
+ case "m":
512
+ return g * 1e3;
513
+ // 米
514
+ case "mi":
515
+ return g * 0.621371;
516
+ // 英里
517
+ case "nmi":
518
+ return g * 0.539957;
519
+ // 海里
520
+ default:
521
+ return g;
522
+ }
523
+ },
524
+ /**
525
+ * 计算多个坐标点之间的总距离(Haversine公式)
526
+ * @param points 坐标点数组
527
+ * @param unit 距离单位,默认单位为千米。可选值:km(千米)、m(米)、mi(英里)、nmi(海里)
528
+ * @param closed 是否闭合路径,默认不闭合
529
+ * @returns 距离结果对象。包含每个距离段的数组(segments)和总距离(total)。
530
+ */
531
+ calculateDistancesByHaversine(e, r = "km", t = !1) {
532
+ if (e.length < 2)
533
+ return { segments: [], total: 0 };
534
+ const n = [];
535
+ let o = 0;
536
+ for (let s = 0; s < e.length - 1; s++) {
537
+ const c = this.calculateDistanceByHaversine(e[s], e[s + 1], r);
538
+ n.push(c), o += c;
539
+ }
540
+ if (t && e.length > 2) {
541
+ const s = this.calculateDistanceByHaversine(e[e.length - 1], e[0], r);
542
+ n.push(s), o += s;
543
+ }
544
+ return { segments: n, total: o };
545
+ }
364
546
  };
365
- class L {
547
+ class T {
366
548
  /**
367
549
  * 转换为标准金额格式(带千分位和两位小数)
368
550
  * @param num 要转换的数字
369
551
  * @returns 格式化后的字符串
370
552
  */
371
- static toStandardFormat(e) {
553
+ static toStandardFormat(r) {
372
554
  try {
373
- const r = typeof e == "string" ? parseFloat(e) : e;
374
- if (isNaN(r))
555
+ const t = typeof r == "string" ? parseFloat(r) : r;
556
+ if (isNaN(t))
375
557
  throw new Error("输入不是有效的数字");
376
- if (!isFinite(r))
558
+ if (!isFinite(t))
377
559
  throw new Error("输入是无穷大");
378
- return r.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
379
- } catch (r) {
380
- return console.error("格式化失败:", r), "格式错误";
560
+ return t.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
561
+ } catch (t) {
562
+ return console.error("格式化失败:", t), "格式错误";
381
563
  }
382
564
  }
383
565
  /**
@@ -385,74 +567,96 @@ class L {
385
567
  * @param num 要转换的数字
386
568
  * @returns 中文大写金额字符串
387
569
  */
388
- static toChineseFormat(e) {
570
+ static toChineseFormat(r) {
389
571
  try {
390
- const r = typeof e == "string" ? parseFloat(e) : e;
391
- if (isNaN(r))
572
+ const t = typeof r == "string" ? parseFloat(r) : r;
573
+ if (isNaN(t))
392
574
  throw new Error("输入不是有效的数字");
393
- if (r > 9999999999999e-2 || r < -9999999999999e-2)
575
+ if (t > 9999999999999e-2 || t < -9999999999999e-2)
394
576
  throw new Error("输入数字超出范围");
395
- const o = r < 0, s = Math.abs(r), l = Math.floor(s), d = Math.round((s - l) * 100), i = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"], g = ["", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟"], u = ["角", "分"];
396
- let n = "", a = l;
397
- if (a === 0)
398
- n = i[0];
577
+ const n = t < 0, o = Math.abs(t), s = Math.floor(o), c = Math.round((o - s) * 100), i = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"], l = ["", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟"], h = ["角", "分"];
578
+ let a = "", d = s;
579
+ if (d === 0)
580
+ a = i[0];
399
581
  else {
400
- let h = 0;
401
- for (; a > 0; ) {
402
- const p = a % 10;
403
- p !== 0 ? n = i[p] + g[h] + n : n.charAt(0) !== i[0] && (n = i[p] + n), a = Math.floor(a / 10), h++;
582
+ let p = 0;
583
+ for (; d > 0; ) {
584
+ const g = d % 10;
585
+ g !== 0 ? a = i[g] + l[p] + a : a.charAt(0) !== i[0] && (a = i[g] + a), d = Math.floor(d / 10), p++;
404
586
  }
405
- n = n.replace(/零+/g, "零"), n = n.replace(/零+$/, "");
587
+ a = a.replace(/零+/g, "零"), a = a.replace(/零+$/, "");
406
588
  }
407
589
  let f = "";
408
- if (d > 0) {
409
- const h = Math.floor(d / 10), p = d % 10;
410
- h > 0 && (f += i[h] + u[0]), p > 0 && (f += i[p] + u[1]);
590
+ if (c > 0) {
591
+ const p = Math.floor(c / 10), g = c % 10;
592
+ p > 0 && (f += i[p] + h[0]), g > 0 && (f += i[g] + h[1]);
411
593
  } else
412
594
  f = "整";
413
- let c = (o ? "负" : "") + n + "圆" + f;
414
- return c === "零圆整" && (c = "零圆"), c;
415
- } catch (r) {
416
- return console.error("转换失败:", r), "格式错误";
595
+ let u = (n ? "负" : "") + a + "圆" + f;
596
+ return u === "零圆整" && (u = "零圆"), u;
597
+ } catch (t) {
598
+ return console.error("转换失败:", t), "格式错误";
417
599
  }
418
600
  }
419
601
  }
420
- const m = (t) => t > 25 || t < 0 ? "" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[t], w = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
602
+ const w = (e) => e > 25 || e < 0 ? "" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[e], M = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
421
603
  __proto__: null,
422
- toLetter: m
423
- }, Symbol.toStringTag, { value: "Module" })), S = (t) => t.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","), O = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
604
+ toLetter: w
605
+ }, Symbol.toStringTag, { value: "Module" })), S = (e) => e.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","), O = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
424
606
  __proto__: null,
425
607
  toMoney: S
426
- }, Symbol.toStringTag, { value: "Module" })), T = {
427
- ...w,
608
+ }, Symbol.toStringTag, { value: "Module" })), _ = {
609
+ ...M,
428
610
  ...O,
429
611
  /**
430
612
  * 判断是否为数字
431
613
  * @param val 待判断的值
432
614
  * @returns 是否为数字。true 是;false 否
433
615
  */
434
- isNumber(t) {
435
- return typeof t == "number" && !isNaN(t);
616
+ isNumber(e) {
617
+ return typeof e == "number" && !isNaN(e);
436
618
  }
437
- }, v = {
619
+ }, I = {
438
620
  /**
439
621
  * 判断对象是否为空
440
622
  * @param obj 对象
441
623
  * @returns 是否为空。true 为空;false 不为空
442
624
  */
443
- isEmptyObject(t) {
444
- return t ? Object.keys(t).length === 0 && t.constructor === Object : !0;
625
+ isEmptyObject(e) {
626
+ return e ? Object.keys(e).length === 0 && e.constructor === Object : !0;
627
+ },
628
+ /**
629
+ * 复制对象【对象的浅拷贝 把obj1的成员,复制给obj2】
630
+ * @param obj1 源对象
631
+ * @param obj2 目标对象
632
+ */
633
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
634
+ copy(e, r) {
635
+ for (const t in e)
636
+ r[t] = e[t];
637
+ },
638
+ /**
639
+ * 对象的深拷贝 把o1 的成员,复制给o2
640
+ * @param o1
641
+ * @param o2
642
+ */
643
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
644
+ deepCopy(e, r) {
645
+ for (const t in e) {
646
+ const n = e[t];
647
+ n instanceof Object ? (r[t] = {}, this.deepCopy(n, r[t])) : n instanceof Array ? (r[t] = [], this.deepCopy(n, r[t])) : r[t] = e[t];
648
+ }
445
649
  }
446
- }, F = {
650
+ }, N = {
447
651
  /**
448
652
  * 脱敏
449
653
  * @param phone 电话号码/手机号码
450
654
  * @returns 脱敏后的电话号码/手机号码
451
655
  */
452
- desensitize(t) {
453
- return t ? t.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2") || t.slice(0, 3) + "****" + t.slice(7) : "";
656
+ desensitize(e) {
657
+ return e ? e.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2") || e.slice(0, 3) + "****" + e.slice(7) : "";
454
658
  }
455
- }, P = {
659
+ }, D = {
456
660
  /**
457
661
  * 生成随机颜色
458
662
  * @returns 随机颜色值
@@ -466,8 +670,8 @@ const m = (t) => t > 25 || t < 0 ? "" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[t], w = /*
466
670
  * @param max 最大值
467
671
  * @returns 随机数
468
672
  */
469
- int(t, e) {
470
- return Math.floor(Math.random() * (e - t + 1)) + t;
673
+ int(e, r) {
674
+ return Math.floor(Math.random() * (r - e + 1)) + e;
471
675
  },
472
676
  /**
473
677
  * 生成唯一ID(时间戳+随机数)
@@ -476,65 +680,65 @@ const m = (t) => t > 25 || t < 0 ? "" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[t], w = /*
476
680
  uniqueId() {
477
681
  return Date.now().toString(36) + Math.random().toString(36).substr(2, 5);
478
682
  }
479
- }, k = {
683
+ }, P = {
480
684
  /**
481
685
  * 通过key值获取 localStorage 中存储的某个值
482
686
  * @param key 获取的key
483
687
  * @returns 获取的值
484
688
  */
485
- getLocal(t) {
486
- return localStorage.getItem(t);
689
+ getLocal(e) {
690
+ return localStorage.getItem(e);
487
691
  },
488
692
  /**
489
693
  * 设置localStorage中的某个值
490
694
  * @param key 设置的key
491
695
  * @param value 设置的value
492
696
  */
493
- setLocal(t, e) {
494
- localStorage.setItem(t, e);
697
+ setLocal(e, r) {
698
+ localStorage.setItem(e, r);
495
699
  },
496
700
  /**
497
701
  * 删除localStorage中的某个值
498
702
  * @param key 删除的key
499
703
  */
500
- removeLocal(t) {
501
- localStorage.removeItem(t);
704
+ removeLocal(e) {
705
+ localStorage.removeItem(e);
502
706
  },
503
707
  /**
504
708
  * 通过key值获取 sessionStorage 中存储的某个值
505
709
  * @param key 获取的key
506
710
  * @returns 获取的值
507
711
  */
508
- getSession(t) {
509
- return sessionStorage.getItem(t);
712
+ getSession(e) {
713
+ return sessionStorage.getItem(e);
510
714
  },
511
715
  /**
512
716
  * 设置sessionStorage中的某个值
513
717
  * @param key 设置的key
514
718
  * @param value 设置的value
515
719
  */
516
- setSession(t, e) {
517
- sessionStorage.setItem(t, e);
720
+ setSession(e, r) {
721
+ sessionStorage.setItem(e, r);
518
722
  },
519
723
  /**
520
724
  * 删除sessionStorage中的某个值
521
725
  * @param key 删除的key
522
726
  */
523
- removeSession(t) {
524
- sessionStorage.removeItem(t);
727
+ removeSession(e) {
728
+ sessionStorage.removeItem(e);
525
729
  }
526
- }, R = {
730
+ }, F = {
527
731
  /**
528
732
  * 判断某元素是否在字符串中-比includes()方法更兼容,includes为ES6新增方法,IE不支持。小程序也不支持
529
733
  * @param str 字符串
530
734
  * @param element 查询元素
531
735
  * @returns 是否存在。true 存在;false 不存在
532
736
  */
533
- isExist(t, e) {
534
- if (!t || !e)
737
+ isExist(e, r) {
738
+ if (!e || !r)
535
739
  return !1;
536
- const r = t.split(",");
537
- return console.log("判断某元素是否在字符串中", r.indexOf(e) === -1), r.indexOf(e) !== -1;
740
+ const t = e.split(",");
741
+ return console.log("判断某元素是否在字符串中", t.indexOf(r) === -1), t.indexOf(r) !== -1;
538
742
  },
539
743
  /**
540
744
  * 判断某元素是否在字符串中-比isExist()方法更高效。
@@ -542,34 +746,67 @@ const m = (t) => t > 25 || t < 0 ? "" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[t], w = /*
542
746
  * @param element 查询元素
543
747
  * @returns 是否存在。true 存在;false 不存在
544
748
  */
545
- includes(t, e) {
546
- return !t || !e ? !1 : t.includes(e);
749
+ includes(e, r) {
750
+ return !e || !r ? !1 : e.includes(r);
547
751
  },
548
752
  /**
549
753
  * 判断字符串是否为 JSON
550
754
  * @param str 字符串
551
755
  * @returns
552
756
  */
553
- isJSON(t) {
757
+ isJSON(e) {
554
758
  try {
555
- return JSON.parse(t), !0;
759
+ return JSON.parse(e), !0;
556
760
  } catch {
557
761
  return !1;
558
762
  }
763
+ },
764
+ /**
765
+ * 查找某个元素在字符串中重复出现的位置
766
+ * @param _string 字符串
767
+ * @param element 元素
768
+ * @returns 位置数组
769
+ */
770
+ indexsOfAppear(e, r) {
771
+ let t = -1;
772
+ const n = [];
773
+ do
774
+ t = e.indexOf(r, t + 1), t !== -1 && n.push(t);
775
+ while (t !== -1);
776
+ return n;
777
+ },
778
+ /**
779
+ * 获取字符串中出现次数最多的字符和次数
780
+ * @param string 字符串
781
+ * @returns 数组,第一个元素为出现次数,第二个元素为出现次数最多的字符
782
+ */
783
+ getMaxTimesAndVal(e) {
784
+ const r = [0, ""], t = {};
785
+ for (let s = 0; s < e.length; s++) {
786
+ const c = e.charAt(s);
787
+ t[c] ? t[c]++ : t[c] = 1;
788
+ }
789
+ let n = 1;
790
+ for (const s in t)
791
+ n < t[s] && (n = t[s]);
792
+ const o = [];
793
+ for (const s in t)
794
+ n == t[s] && o.push(s);
795
+ return r[0] = n, r[1] = o.join(), r;
559
796
  }
560
- }, U = (t) => {
561
- const r = new RegExp("[?&]" + t + "=([^&#]*)", "i").exec(window.location.href);
562
- return r ? decodeURIComponent(r[1]) : null;
797
+ }, U = (e) => {
798
+ const t = new RegExp("[?&]" + e + "=([^&#]*)", "i").exec(window.location.href);
799
+ return t ? decodeURIComponent(t[1]) : null;
563
800
  };
564
- function M(t) {
565
- return new URLSearchParams(window.location.search).get(t);
801
+ function E(e) {
802
+ return new URLSearchParams(window.location.search).get(e);
566
803
  }
567
- const E = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
804
+ const x = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
568
805
  __proto__: null,
569
806
  getQueryInfoByName: U,
570
- getQueryParam: M
571
- }, Symbol.toStringTag, { value: "Module" })), $ = {
572
- ...E,
807
+ getQueryParam: E
808
+ }, Symbol.toStringTag, { value: "Module" })), V = {
809
+ ...x,
573
810
  /**
574
811
  * 获取当前域名
575
812
  * @returns 当前url链接的host信息
@@ -584,41 +821,42 @@ const E = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
584
821
  getPath() {
585
822
  return window.location.pathname;
586
823
  }
587
- }, D = {
824
+ }, $ = {
588
825
  /**
589
826
  * 处理瀑布流数据,使其适合瀑布流布局展示
590
827
  * @param list 瀑布流数据-数组
591
828
  * @param columnsNum 需要展示的列数
592
829
  * @returns 适合瀑布流布局的数组
593
830
  */
594
- toList(t, e = 2) {
595
- console.log(t, e);
596
- const r = {};
597
- for (let s = 0; s < e; s++)
598
- r[s] = [];
599
- t.forEach((s, l) => r[l % e].push(s));
600
- const o = [];
601
- for (const s in r)
602
- o.push(...r[s]);
603
- return o;
831
+ toList(e, r = 2) {
832
+ console.log(e, r);
833
+ const t = {};
834
+ for (let o = 0; o < r; o++)
835
+ t[o] = [];
836
+ e.forEach((o, s) => t[s % r].push(o));
837
+ const n = [];
838
+ for (const o in t)
839
+ n.push(...t[o]);
840
+ return n;
604
841
  }
605
842
  };
606
843
  export {
607
- L as MoneyFormatter,
608
- A as arrayUtils,
609
- j as base64Utils,
610
- x as booleanUtils,
611
- C as cookieUtils,
612
- _ as dateUtils,
613
- N as downloadUtils,
614
- B as elementUtils,
615
- I as letterUtils,
616
- T as numberUtils,
617
- v as objectUtils,
618
- F as phoneUtils,
619
- P as randomUtils,
620
- k as storageUtils,
621
- R as stringUtils,
622
- $ as urlUtils,
623
- D as waterfallUtils
844
+ T as MoneyFormatter,
845
+ L as arrayUtils,
846
+ A as base64Utils,
847
+ m as booleanUtils,
848
+ v as cookieUtils,
849
+ R as dateUtils,
850
+ j as documentUtils,
851
+ C as downloadUtils,
852
+ k as letterUtils,
853
+ B as mapUtils,
854
+ _ as numberUtils,
855
+ I as objectUtils,
856
+ N as phoneUtils,
857
+ D as randomUtils,
858
+ P as storageUtils,
859
+ F as stringUtils,
860
+ V as urlUtils,
861
+ $ as waterfallUtils
624
862
  };