@qy_better_lib/core 0.1.2 → 0.1.4

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.
@@ -0,0 +1,2945 @@
1
+ # QY Better Lib Core - 工具函数文档
2
+
3
+ 本文档详细介绍了 QY Better Lib Core 包中的工具函数,包括功能描述、参数说明、返回类型和使用示例。
4
+
5
+ ## 工具函数分类
6
+
7
+ ### 1. 类型检查工具 (is.ts)
8
+
9
+ #### is_array
10
+ - **功能**: 检查值是否为数组
11
+ - **参数**: `val: any` - 要检查的值
12
+ - **返回类型**: `boolean` - 是否为数组
13
+ - **示例**:
14
+ ```typescript
15
+ import { is_array } from '@qy_better_lib/core';
16
+
17
+ is_array([]); // true
18
+ is_array({}); // false
19
+ ```
20
+
21
+ #### is_object
22
+ - **功能**: 检查值是否为对象
23
+ - **参数**: `val: any` - 要检查的值
24
+ - **返回类型**: `boolean` - 是否为对象
25
+ - **示例**:
26
+ ```typescript
27
+ import { is_object } from '@qy_better_lib/core';
28
+
29
+ is_object({}); // true
30
+ is_object([]); // false
31
+ ```
32
+
33
+ #### is_string
34
+ - **功能**: 检查值是否为字符串
35
+ - **参数**: `val: any` - 要检查的值
36
+ - **返回类型**: `boolean` - 是否为字符串
37
+ - **示例**:
38
+ ```typescript
39
+ import { is_string } from '@qy_better_lib/core';
40
+
41
+ is_string('hello'); // true
42
+ is_string(123); // false
43
+ ```
44
+
45
+ #### is_number
46
+ - **功能**: 检查值是否为数字
47
+ - **参数**: `val: any` - 要检查的值
48
+ - **返回类型**: `boolean` - 是否为数字
49
+ - **示例**:
50
+ ```typescript
51
+ import { is_number } from '@qy_better_lib/core';
52
+
53
+ is_number(123); // true
54
+ is_number('123'); // false
55
+ ```
56
+
57
+ #### is_function
58
+ - **功能**: 检查值是否为函数
59
+ - **参数**: `val: any` - 要检查的值
60
+ - **返回类型**: `boolean` - 是否为函数
61
+ - **示例**:
62
+ ```typescript
63
+ import { is_function } from '@qy_better_lib/core';
64
+
65
+ is_function(() => {}); // true
66
+ is_function({}); // false
67
+ ```
68
+
69
+ #### is_boolean
70
+ - **功能**: 检查值是否为布尔值
71
+ - **参数**: `val: any` - 要检查的值
72
+ - **返回类型**: `boolean` - 是否为布尔值
73
+ - **示例**:
74
+ ```typescript
75
+ import { is_boolean } from '@qy_better_lib/core';
76
+
77
+ is_boolean(true); // true
78
+ is_boolean('true'); // false
79
+ ```
80
+
81
+ #### is_null
82
+ - **功能**: 检查值是否为 null
83
+ - **参数**: `val: any` - 要检查的值
84
+ - **返回类型**: `boolean` - 是否为 null
85
+ - **示例**:
86
+ ```typescript
87
+ import { is_null } from '@qy_better_lib/core';
88
+
89
+ is_null(null); // true
90
+ is_null(undefined); // false
91
+ ```
92
+
93
+ #### is_undefined
94
+ - **功能**: 检查值是否为 undefined
95
+ - **参数**: `val: any` - 要检查的值
96
+ - **返回类型**: `boolean` - 是否为 undefined
97
+ - **示例**:
98
+ ```typescript
99
+ import { is_undefined } from '@qy_better_lib/core';
100
+
101
+ is_undefined(undefined); // true
102
+ is_undefined(null); // false
103
+ ```
104
+
105
+ #### is_empty
106
+ - **功能**: 检查值是否为空
107
+ - **参数**: `val: any` - 要检查的值
108
+ - **返回类型**: `boolean` - 是否为空
109
+ - **示例**:
110
+ ```typescript
111
+ import { is_empty } from '@qy_better_lib/core';
112
+
113
+ is_empty([]); // true
114
+ is_empty(''); // true
115
+ is_empty({}); // true
116
+ is_empty(null); // true
117
+ is_empty(undefined); // true
118
+ is_empty(0); // false
119
+ ```
120
+
121
+ #### is_date
122
+ - **功能**: 检查值是否为日期对象
123
+ - **参数**: `val: any` - 要检查的值
124
+ - **返回类型**: `boolean` - 是否为日期对象
125
+ - **示例**:
126
+ ```typescript
127
+ import { is_date } from '@qy_better_lib/core';
128
+
129
+ is_date(new Date()); // true
130
+ is_date('2023-01-01'); // false
131
+ ```
132
+
133
+ #### is_reg_exp
134
+ - **功能**: 检查值是否为正则表达式
135
+ - **参数**: `val: any` - 要检查的值
136
+ - **返回类型**: `boolean` - 是否为正则表达式
137
+ - **示例**:
138
+ ```typescript
139
+ import { is_reg_exp } from '@qy_better_lib/core';
140
+
141
+ is_reg_exp(/test/); // true
142
+ is_reg_exp('test'); // false
143
+ ```
144
+
145
+ #### is_error
146
+ - **功能**: 检查值是否为错误对象
147
+ - **参数**: `val: any` - 要检查的值
148
+ - **返回类型**: `boolean` - 是否为错误对象
149
+ - **示例**:
150
+ ```typescript
151
+ import { is_error } from '@qy_better_lib/core';
152
+
153
+ is_error(new Error('error')); // true
154
+ is_error('error'); // false
155
+ ```
156
+
157
+ #### is_promise
158
+ - **功能**: 检查值是否为 Promise 对象
159
+ - **参数**: `val: any` - 要检查的值
160
+ - **返回类型**: `boolean` - 是否为 Promise 对象
161
+ - **示例**:
162
+ ```typescript
163
+ import { is_promise } from '@qy_better_lib/core';
164
+
165
+ is_promise(new Promise(() => {})); // true
166
+ is_promise({}); // false
167
+ ```
168
+
169
+ #### is_element
170
+ - **功能**: 检查值是否为 DOM 元素
171
+ - **参数**: `val: any` - 要检查的值
172
+ - **返回类型**: `boolean` - 是否为 DOM 元素
173
+ - **示例**:
174
+ ```typescript
175
+ import { is_element } from '@qy_better_lib/core';
176
+
177
+ is_element(document.createElement('div')); // true
178
+ is_element({}); // false
179
+ ```
180
+
181
+ #### is_plain_object
182
+ - **功能**: 是否为纯粹的对象(排除数组、null等)
183
+ - **参数**: `val: any` - 要检查的值
184
+ - **返回类型**: `boolean` - 是否为纯粹的对象
185
+ - **示例**:
186
+ ```typescript
187
+ import { is_plain_object } from '@qy_better_lib/core';
188
+
189
+ is_plain_object({}); // true
190
+ is_plain_object([]); // false
191
+ is_plain_object(null); // false
192
+ ```
193
+
194
+ #### is_valid_date
195
+ - **功能**: 是否为有效的日期
196
+ - **参数**: `val: any` - 要检查的值
197
+ - **返回类型**: `boolean` - 是否为有效的日期
198
+ - **示例**:
199
+ ```typescript
200
+ import { is_valid_date } from '@qy_better_lib/core';
201
+
202
+ is_valid_date(new Date()); // true
203
+ is_valid_date(new Date('invalid')); // false
204
+ ```
205
+
206
+ #### is_truthy
207
+ - **功能**: 是否为真值
208
+ - **参数**: `val: any` - 要检查的值
209
+ - **返回类型**: `boolean` - 是否为真值
210
+ - **示例**:
211
+ ```typescript
212
+ import { is_truthy } from '@qy_better_lib/core';
213
+
214
+ is_truthy(1); // true
215
+ is_truthy('hello'); // true
216
+ is_truthy(false); // false
217
+ ```
218
+
219
+ #### is_falsy
220
+ - **功能**: 是否为假值
221
+ - **参数**: `val: any` - 要检查的值
222
+ - **返回类型**: `boolean` - 是否为假值
223
+ - **示例**:
224
+ ```typescript
225
+ import { is_falsy } from '@qy_better_lib/core';
226
+
227
+ is_falsy(false); // true
228
+ is_falsy(0); // true
229
+ is_falsy(''); // true
230
+ is_falsy('hello'); // false
231
+ ```
232
+
233
+ #### is_string_number
234
+ - **功能**: 是否为字符串数值
235
+ - **参数**: `val: any` - 要检查的值
236
+ - **返回类型**: `boolean` - 是否为字符串数值
237
+ - **示例**:
238
+ ```typescript
239
+ import { is_string_number } from '@qy_better_lib/core';
240
+
241
+ is_string_number('123'); // true
242
+ is_string_number('abc'); // false
243
+ ```
244
+
245
+ #### is_mobile
246
+ - **功能**: 是否为手机号(国内手机号)
247
+ - **参数**: `str: string` - 要检查的字符串
248
+ - **返回类型**: `boolean` - 是否为手机号
249
+ - **示例**:
250
+ ```typescript
251
+ import { is_mobile } from '@qy_better_lib/core';
252
+
253
+ is_mobile('13800138000'); // true
254
+ is_mobile('12345678901'); // false
255
+ ```
256
+
257
+ #### is_email
258
+ - **功能**: 是否为邮箱地址
259
+ - **参数**: `str: string` - 要检查的字符串
260
+ - **返回类型**: `boolean` - 是否为邮箱地址
261
+ - **示例**:
262
+ ```typescript
263
+ import { is_email } from '@qy_better_lib/core';
264
+
265
+ is_email('test@example.com'); // true
266
+ is_email('invalid'); // false
267
+ ```
268
+
269
+ #### is_url
270
+ - **功能**: 是否为URL地址
271
+ - **参数**: `str: string` - 要检查的字符串
272
+ - **返回类型**: `boolean` - 是否为URL地址
273
+ - **示例**:
274
+ ```typescript
275
+ import { is_url } from '@qy_better_lib/core';
276
+
277
+ is_url('https://example.com'); // true
278
+ is_url('invalid'); // false
279
+ ```
280
+
281
+ #### is_hex_color
282
+ - **功能**: 是否为十六进制颜色值
283
+ - **参数**: `str: string` - 要检查的字符串
284
+ - **返回类型**: `boolean` - 是否为十六进制颜色值
285
+ - **示例**:
286
+ ```typescript
287
+ import { is_hex_color } from '@qy_better_lib/core';
288
+
289
+ is_hex_color('#ff0000'); // true
290
+ is_hex_color('#fff'); // true
291
+ is_hex_color('red'); // false
292
+ ```
293
+
294
+ #### is_ip
295
+ - **功能**: 是否为有效IP地址
296
+ - **参数**: `val: string` - 要检查的字符串
297
+ - **返回类型**: `boolean` - 是否为有效IP地址
298
+ - **示例**:
299
+ ```typescript
300
+ import { is_ip } from '@qy_better_lib/core';
301
+
302
+ is_ip('192.168.1.1'); // true
303
+ is_ip('256.0.0.1'); // false
304
+ ```
305
+
306
+ #### is_port
307
+ - **功能**: 是否为有效端口
308
+ - **参数**: `val: string` - 要检查的字符串
309
+ - **返回类型**: `boolean` - 是否为有效端口
310
+ - **示例**:
311
+ ```typescript
312
+ import { is_port } from '@qy_better_lib/core';
313
+
314
+ is_port('8080'); // true
315
+ is_port('65536'); // false
316
+ ```
317
+
318
+ #### is_client
319
+ - **功能**: 检查是否在客户端环境
320
+ - **返回类型**: `boolean` - 是否在客户端环境
321
+ - **示例**:
322
+ ```typescript
323
+ import { is_client } from '@qy_better_lib/core';
324
+
325
+ if (is_client) {
326
+ // 客户端环境代码
327
+ }
328
+ ```
329
+
330
+ #### is_server
331
+ - **功能**: 检查是否在服务端环境
332
+ - **返回类型**: `boolean` - 是否在服务端环境
333
+ - **示例**:
334
+ ```typescript
335
+ import { is_server } from '@qy_better_lib/core';
336
+
337
+ if (is_server) {
338
+ // 服务端环境代码
339
+ }
340
+ ```
341
+
342
+ ### 2. 数字处理工具 (number.ts)
343
+
344
+ #### format_currency
345
+ - **功能**: 格式化货币
346
+ - **参数**:
347
+ - `value: number` - 要格式化的数值
348
+ - `currency: string` - 货币符号,默认 '¥'
349
+ - `decimals: number` - 小数位数,默认 2
350
+ - `decimalSeparator: string` - 小数分隔符,默认 '.'
351
+ - `thousandSeparator: string` - 千位分隔符,默认 ','
352
+ - **返回类型**: `string` - 格式化后的货币字符串
353
+ - **示例**:
354
+ ```typescript
355
+ import { format_currency } from '@qy_better_lib/core';
356
+
357
+ format_currency(1234.56); // ¥1,234.56
358
+ format_currency(1234.56, '$'); // $1,234.56
359
+ ```
360
+
361
+ #### format_number
362
+ - **功能**: 格式化数字
363
+ - **参数**:
364
+ - `value: number` - 要格式化的数值
365
+ - `decimals: number` - 小数位数,默认 0
366
+ - `decimalSeparator: string` - 小数分隔符,默认 '.'
367
+ - `thousandSeparator: string` - 千位分隔符,默认 ','
368
+ - **返回类型**: `string` - 格式化后的数字字符串
369
+ - **示例**:
370
+ ```typescript
371
+ import { format_number } from '@qy_better_lib/core';
372
+
373
+ format_number(1234.56, 2); // 1,234.56
374
+ format_number(1234, 0); // 1,234
375
+ ```
376
+
377
+ #### to_percentage
378
+ - **功能**: 将数字转换为百分比
379
+ - **参数**:
380
+ - `value: number` - 要转换的数值
381
+ - `decimals: number` - 小数位数,默认 2
382
+ - `multiply: boolean` - 是否乘以 100,默认 true
383
+ - **返回类型**: `string` - 格式化后的百分比字符串
384
+ - **示例**:
385
+ ```typescript
386
+ import { to_percentage } from '@qy_better_lib/core';
387
+
388
+ to_percentage(0.1234); // 12.34%
389
+ to_percentage(12.34, 1, false); // 12.3%
390
+ ```
391
+
392
+ #### clamp
393
+ - **功能**: 限制数字在指定范围内
394
+ - **参数**:
395
+ - `value: number` - 要限制的值
396
+ - `min: number` - 最小值
397
+ - `max: number` - 最大值
398
+ - **返回类型**: `number` - 限制后的值
399
+ - **示例**:
400
+ ```typescript
401
+ import { clamp } from '@qy_better_lib/core';
402
+
403
+ clamp(5, 0, 10); // 5
404
+ clamp(-5, 0, 10); // 0
405
+ clamp(15, 0, 10); // 10
406
+ ```
407
+
408
+ #### is_even
409
+ - **功能**: 检查数字是否为偶数
410
+ - **参数**: `value: number` - 要检查的数字
411
+ - **返回类型**: `boolean` - 是否为偶数
412
+ - **示例**:
413
+ ```typescript
414
+ import { is_even } from '@qy_better_lib/core';
415
+
416
+ is_even(2); // true
417
+ is_even(3); // false
418
+ ```
419
+
420
+ #### is_odd
421
+ - **功能**: 检查数字是否为奇数
422
+ - **参数**: `value: number` - 要检查的数字
423
+ - **返回类型**: `boolean` - 是否为奇数
424
+ - **示例**:
425
+ ```typescript
426
+ import { is_odd } from '@qy_better_lib/core';
427
+
428
+ is_odd(3); // true
429
+ is_odd(2); // false
430
+ ```
431
+
432
+ #### get_integer_part
433
+ - **功能**: 获取数字的整数部分
434
+ - **参数**: `value: number` - 要处理的数字
435
+ - **返回类型**: `number` - 整数部分
436
+ - **示例**:
437
+ ```typescript
438
+ import { get_integer_part } from '@qy_better_lib/core';
439
+
440
+ get_integer_part(123.45); // 123
441
+ get_integer_part(-123.45); // -123
442
+ ```
443
+
444
+ #### get_decimal_part
445
+ - **功能**: 获取数字的小数部分
446
+ - **参数**: `value: number` - 要处理的数字
447
+ - **返回类型**: `number` - 小数部分
448
+ - **示例**:
449
+ ```typescript
450
+ import { get_decimal_part } from '@qy_better_lib/core';
451
+
452
+ get_decimal_part(123.45); // 0.45
453
+ get_decimal_part(-123.45); // 0.45
454
+ ```
455
+
456
+ #### round
457
+ - **功能**: 四舍五入数字
458
+ - **参数**:
459
+ - `value: number` - 要四舍五入的数字
460
+ - `decimals: number` - 小数位数,默认 0
461
+ - **返回类型**: `number` - 四舍五入后的数字
462
+ - **示例**:
463
+ ```typescript
464
+ import { round } from '@qy_better_lib/core';
465
+
466
+ round(123.45); // 123
467
+ round(123.45, 1); // 123.5
468
+ ```
469
+
470
+ #### ceil
471
+ - **功能**: 向上取整数字
472
+ - **参数**: `value: number` - 要向上取整的数字
473
+ - **返回类型**: `number` - 向上取整后的数字
474
+ - **示例**:
475
+ ```typescript
476
+ import { ceil } from '@qy_better_lib/core';
477
+
478
+ ceil(123.1); // 124
479
+ ceil(-123.9); // -123
480
+ ```
481
+
482
+ #### floor
483
+ - **功能**: 向下取整数字
484
+ - **参数**: `value: number` - 要向下取整的数字
485
+ - **返回类型**: `number` - 向下取整后的数字
486
+ - **示例**:
487
+ ```typescript
488
+ import { floor } from '@qy_better_lib/core';
489
+
490
+ floor(123.9); // 123
491
+ floor(-123.1); // -124
492
+ ```
493
+
494
+ #### thousand_separator
495
+ - **功能**: 数字转成千分位
496
+ - **参数**: `num: any` - 数字或数字字符串
497
+ - **返回类型**: `string` - 千分位格式的字符串
498
+ - **示例**:
499
+ ```typescript
500
+ import { thousand_separator } from '@qy_better_lib/core';
501
+
502
+ thousand_separator(1234567); // "1,234,567"
503
+ thousand_separator('1234567'); // "1,234,567"
504
+ ```
505
+
506
+ #### to_number
507
+ - **功能**: 转换成数值
508
+ - **参数**: `num: any` - 源
509
+ - **返回类型**: `number` - 转换后的数值
510
+ - **示例**:
511
+ ```typescript
512
+ import { to_number } from '@qy_better_lib/core';
513
+
514
+ to_number(123); // 123
515
+ to_number('123'); // 123
516
+ to_number('invalid'); // NaN
517
+ ```
518
+
519
+ #### to_fixed
520
+ - **功能**: 保留小数点
521
+ - **参数**:
522
+ - `num: any` - 数字或数字字符串
523
+ - `fixed: number` - 小数位数
524
+ - **返回类型**: `number` - 保留小数点后的数值
525
+ - **示例**:
526
+ ```typescript
527
+ import { to_fixed } from '@qy_better_lib/core';
528
+
529
+ to_fixed(123.456, 2); // 123.46
530
+ to_fixed('123.456', 1); // 123.5
531
+ ```
532
+
533
+ #### calculate_percentage
534
+ - **功能**: 计算百分比
535
+ - **参数**:
536
+ - `current: number` - 当前值
537
+ - `total: number` - 总值
538
+ - `fixed: number` - 小数位数,默认 2
539
+ - **返回类型**: `number` - 百分比值
540
+ - **示例**:
541
+ ```typescript
542
+ import { calculate_percentage } from '@qy_better_lib/core';
543
+
544
+ calculate_percentage(50, 200); // 25
545
+ calculate_percentage(25, 100, 1); // 25
546
+ ```
547
+
548
+ ### 3. 日期时间工具 (date.ts)
549
+
550
+ #### format_date
551
+ - **功能**: 格式化日期时间
552
+ - **参数**:
553
+ - `date: Date | string | number` - 日期时间对象或字符串
554
+ - `format: string` - 格式化模板,默认 "YYYY-MM-DD HH:mm:ss"
555
+ - **返回类型**: `string` - 格式化后的日期时间字符串
556
+ - **示例**:
557
+ ```typescript
558
+ import { format_date } from '@qy_better_lib/core';
559
+
560
+ format_date(new Date()); // 2023-12-31 23:59:59
561
+ format_date(new Date(), 'YYYY-MM-DD'); // 2023-12-31
562
+ ```
563
+
564
+ #### get_date_time_range
565
+ - **功能**: 根据当前时间获取指定类型的时间范围
566
+ - **参数**:
567
+ - `type: DateRangeType` - 范围类型 ('d' | 'w' | 'M' | 'Q' | 'y' | 'h' | 'm' | 's')
568
+ - `increment: number` - 增量,默认 -1
569
+ - `format: string` - 日期时间显示格式,默认 "YYYY-MM-DD HH:mm:ss"
570
+ - `span: boolean` - 是否跨越范围类型,默认 false
571
+ - **返回类型**: `[string, string]` - [开始日期时间, 截止日期时间]
572
+ - **示例**:
573
+ ```typescript
574
+ import { get_date_time_range } from '@qy_better_lib/core';
575
+
576
+ // 获取昨天的时间范围
577
+ const [start, end] = get_date_time_range('d', -1);
578
+ console.log(start, end); // 2023-12-30 00:00:00 2023-12-31 23:59:59
579
+ ```
580
+
581
+ #### get_date_diff
582
+ - **功能**: 计算两个日期之间的时间差
583
+ - **参数**:
584
+ - `date1: Date | string | number` - 第一个日期
585
+ - `date2: Date | string | number` - 第二个日期
586
+ - `unit: string` - 时间单位,默认 "day"
587
+ - **返回类型**: `number` - 时间差
588
+ - **示例**:
589
+ ```typescript
590
+ import { get_date_diff } from '@qy_better_lib/core';
591
+
592
+ const date1 = '2023-12-31';
593
+ const date2 = '2023-12-25';
594
+ get_date_diff(date1, date2); // 6
595
+ ```
596
+
597
+ #### add_date
598
+ - **功能**: 添加时间
599
+ - **参数**:
600
+ - `date: Date | string | number` - 基础日期
601
+ - `value: number` - 增加的值
602
+ - `unit: string` - 时间单位
603
+ - `format: string` - 格式化模板,默认不格式化
604
+ - **返回类型**: `Date | string` - 增加后的日期或格式化后的字符串
605
+ - **示例**:
606
+ ```typescript
607
+ import { add_date } from '@qy_better_lib/core';
608
+
609
+ // 添加7天
610
+ add_date(new Date(), 7, 'day'); // 7天后的日期对象
611
+ add_date(new Date(), 7, 'day', 'YYYY-MM-DD'); // 格式化后的日期字符串
612
+ ```
613
+
614
+ #### subtract_date
615
+ - **功能**: 减去时间
616
+ - **参数**:
617
+ - `date: Date | string | number` - 基础日期
618
+ - `value: number` - 减少的值
619
+ - `unit: string` - 时间单位
620
+ - `format: string` - 格式化模板,默认不格式化
621
+ - **返回类型**: `Date | string` - 减少后的日期或格式化后的字符串
622
+ - **示例**:
623
+ ```typescript
624
+ import { subtract_date } from '@qy_better_lib/core';
625
+
626
+ // 减去7天
627
+ subtract_date(new Date(), 7, 'day'); // 7天前的日期对象
628
+ subtract_date(new Date(), 7, 'day', 'YYYY-MM-DD'); // 格式化后的日期字符串
629
+ ```
630
+
631
+ #### is_weekday
632
+ - **功能**: 判断是否为工作日
633
+ - **参数**: `date: Date | string | number` - 日期
634
+ - **返回类型**: `boolean` - 是否为工作日
635
+ - **示例**:
636
+ ```typescript
637
+ import { is_weekday } from '@qy_better_lib/core';
638
+
639
+ is_weekday('2023-12-31'); // true (周日)
640
+ is_weekday('2024-01-01'); // false (周一)
641
+ ```
642
+
643
+ #### is_weekend
644
+ - **功能**: 判断是否为周末
645
+ - **参数**: `date: Date | string | number` - 日期
646
+ - **返回类型**: `boolean` - 是否为周末
647
+ - **示例**:
648
+ ```typescript
649
+ import { is_weekend } from '@qy_better_lib/core';
650
+
651
+ is_weekend('2023-12-30'); // true (周六)
652
+ is_weekend('2023-12-29'); // false (周五)
653
+ ```
654
+
655
+ #### get_relative_time
656
+ - **功能**: 获取相对时间描述
657
+ - **参数**: `date: Date | string | number` - 日期
658
+ - **返回类型**: `string` - 相对时间描述
659
+ - **示例**:
660
+ ```typescript
661
+ import { get_relative_time } from '@qy_better_lib/core';
662
+
663
+ // 假设当前时间是2023-12-31
664
+ get_relative_time('2023-12-31 23:50:00'); // 刚刚
665
+ get_relative_time('2023-12-31 22:00:00'); // 1小时前
666
+ ```
667
+
668
+ #### format_timestamp_diff
669
+ - **功能**: 将时间戳差值转换成可读格式
670
+ - **参数**:
671
+ - `timestamp_diff: number` - 时间戳差值(毫秒)
672
+ - `format: TimeDiffFormatType` - 格式类型,默认 'zh'
673
+ - **返回类型**: `string` - 格式化后的时间差字符串
674
+ - **示例**:
675
+ ```typescript
676
+ import { format_timestamp_diff } from '@qy_better_lib/core';
677
+
678
+ // 1天2小时3分钟4秒
679
+ const diff = 1 * 24 * 60 * 60 * 1000 + 2 * 60 * 60 * 1000 + 3 * 60 * 1000 + 4 * 1000;
680
+ format_timestamp_diff(diff); // 1天2时3分4秒
681
+ format_timestamp_diff(diff, 'en'); // 1D2H3M4S
682
+ ```
683
+
684
+ ### 4. 对象操作工具 (object.ts)
685
+
686
+ #### deep_clone
687
+ - **功能**: 深拷贝对象
688
+ - **参数**: `obj: any` - 要拷贝的对象
689
+ - **返回类型**: `any` - 拷贝后的新对象
690
+ - **示例**:
691
+ ```typescript
692
+ import { deep_clone } from '@qy_better_lib/core';
693
+
694
+ const obj = { a: 1, b: { c: 2 } };
695
+ const cloned = deep_clone(obj);
696
+ cloned.b.c = 3;
697
+ console.log(obj.b.c); // 2
698
+ ```
699
+
700
+ #### deep_assign
701
+ - **功能**: 深度合并多个对象
702
+ - **参数**: `...args: any[]` - 要合并的对象列表
703
+ - **返回类型**: `any` - 合并后的对象
704
+ - **示例**:
705
+ ```typescript
706
+ import { deep_assign } from '@qy_better_lib/core';
707
+
708
+ const obj1 = { a: 1, b: { c: 2 } };
709
+ const obj2 = { b: { d: 3 }, e: 4 };
710
+ const merged = deep_assign(obj1, obj2);
711
+ console.log(merged); // { a: 1, b: { c: 2, d: 3 }, e: 4 }
712
+ ```
713
+
714
+ #### deep_equal
715
+ - **功能**: 深度比较两个对象值是否一致
716
+ - **参数**:
717
+ - `a: any` - 第一个对象
718
+ - `b: any` - 第二个对象
719
+ - **返回类型**: `boolean` - 是否相等
720
+ - **示例**:
721
+ ```typescript
722
+ import { deep_equal } from '@qy_better_lib/core';
723
+
724
+ const obj1 = { a: 1, b: { c: 2 } };
725
+ const obj2 = { a: 1, b: { c: 2 } };
726
+ const obj3 = { a: 1, b: { c: 3 } };
727
+
728
+ deep_equal(obj1, obj2); // true
729
+ deep_equal(obj1, obj3); // false
730
+ ```
731
+
732
+ #### is_empty_object
733
+ - **功能**: 检查对象是否为空
734
+ - **参数**: `obj: any` - 要检查的对象
735
+ - **返回类型**: `boolean` - 是否为空对象
736
+ - **示例**:
737
+ ```typescript
738
+ import { is_empty_object } from '@qy_better_lib/core';
739
+
740
+ is_empty_object({}); // true
741
+ is_empty_object({ a: 1 }); // false
742
+ ```
743
+
744
+ #### pick
745
+ - **功能**: 从对象中提取指定属性
746
+ - **参数**:
747
+ - `obj: any` - 源对象
748
+ - `keys: string[]` - 要提取的属性名数组
749
+ - **返回类型**: `Record<string, any>` - 提取后的新对象
750
+ - **示例**:
751
+ ```typescript
752
+ import { pick } from '@qy_better_lib/core';
753
+
754
+ const obj = { a: 1, b: 2, c: 3 };
755
+ const picked = pick(obj, ['a', 'c']);
756
+ console.log(picked); // { a: 1, c: 3 }
757
+ ```
758
+
759
+ #### omit
760
+ - **功能**: 从对象中排除指定属性
761
+ - **参数**:
762
+ - `obj: any` - 源对象
763
+ - `keys: string[]` - 要排除的属性名数组
764
+ - **返回类型**: `Record<string, any>` - 排除后的新对象
765
+ - **示例**:
766
+ ```typescript
767
+ import { omit } from '@qy_better_lib/core';
768
+
769
+ const obj = { a: 1, b: 2, c: 3 };
770
+ const omitted = omit(obj, ['b']);
771
+ console.log(omitted); // { a: 1, c: 3 }
772
+ ```
773
+
774
+ #### flatten_object
775
+ - **功能**: 将嵌套对象扁平化为一维对象
776
+ - **参数**:
777
+ - `obj: any` - 源对象
778
+ - `prefix: string` - 前缀,默认 ''
779
+ - **返回类型**: `Record<string, any>` - 扁平化后的对象
780
+ - **示例**:
781
+ ```typescript
782
+ import { flatten_object } from '@qy_better_lib/core';
783
+
784
+ const obj = { a: 1, b: { c: 2, d: { e: 3 } } };
785
+ const flattened = flatten_object(obj);
786
+ console.log(flattened); // { a: 1, 'b.c': 2, 'b.d.e': 3 }
787
+ ```
788
+
789
+ #### unflatten_object
790
+ - **功能**: 将扁平对象转换为嵌套对象
791
+ - **参数**: `obj: any` - 扁平对象
792
+ - **返回类型**: `Record<string, any>` - 嵌套对象
793
+ - **示例**:
794
+ ```typescript
795
+ import { unflatten_object } from '@qy_better_lib/core';
796
+
797
+ const obj = { a: 1, 'b.c': 2, 'b.d.e': 3 };
798
+ const unflattened = unflatten_object(obj);
799
+ console.log(unflattened); // { a: 1, b: { c: 2, d: { e: 3 } } }
800
+ ```
801
+
802
+ #### get_object_value
803
+ - **功能**: 根据路径获取对象值
804
+ - **参数**:
805
+ - `obj: any` - 源对象
806
+ - `path: string` - 路径字符串,如 "a.b.c"
807
+ - `defaultValue: any` - 默认值,默认 undefined
808
+ - **返回类型**: `any` - 获取的值或默认值
809
+ - **示例**:
810
+ ```typescript
811
+ import { get_object_value } from '@qy_better_lib/core';
812
+
813
+ const obj = { a: 1, b: { c: 2, d: { e: 3 } } };
814
+ get_object_value(obj, 'a'); // 1
815
+ get_object_value(obj, 'b.c'); // 2
816
+ get_object_value(obj, 'b.d.e'); // 3
817
+ get_object_value(obj, 'b.f', 'default'); // 'default'
818
+ ```
819
+
820
+ #### set_object_value
821
+ - **功能**: 根据路径设置对象值
822
+ - **参数**:
823
+ - `obj: any` - 源对象
824
+ - `path: string` - 路径字符串,如 "a.b.c"
825
+ - `value: any` - 要设置的值
826
+ - **返回类型**: `Record<string, any>` - 修改后的对象
827
+ - **示例**:
828
+ ```typescript
829
+ import { set_object_value } from '@qy_better_lib/core';
830
+
831
+ const obj = { a: 1, b: { c: 2 } };
832
+ set_object_value(obj, 'b.d.e', 3);
833
+ console.log(obj); // { a: 1, b: { c: 2, d: { e: 3 } } }
834
+ ```
835
+
836
+ #### merge_objects
837
+ - **功能**: 浅合并多个对象
838
+ - **参数**: `...args: any[]` - 要合并的对象列表
839
+ - **返回类型**: `Record<string, any>` - 合并后的对象
840
+ - **示例**:
841
+ ```typescript
842
+ import { merge_objects } from '@qy_better_lib/core';
843
+
844
+ const obj1 = { a: 1, b: 2 };
845
+ const obj2 = { b: 3, c: 4 };
846
+ const merged = merge_objects(obj1, obj2);
847
+ console.log(merged); // { a: 1, b: 3, c: 4 }
848
+ ```
849
+
850
+ #### diff_objects
851
+ - **功能**: 比较两个对象的差异
852
+ - **参数**:
853
+ - `obj1: any` - 第一个对象
854
+ - `obj2: any` - 第二个对象
855
+ - **返回类型**: `Record<string, any>` - 差异对象
856
+ - **示例**:
857
+ ```typescript
858
+ import { diff_objects } from '@qy_better_lib/core';
859
+
860
+ const obj1 = { a: 1, b: 2, c: 3 };
861
+ const obj2 = { a: 1, b: 4, d: 5 };
862
+ const diff = diff_objects(obj1, obj2);
863
+ console.log(diff); // { b: { oldValue: 2, newValue: 4 }, c: { oldValue: 3, newValue: undefined }, d: { oldValue: undefined, newValue: 5 } }
864
+ ```
865
+
866
+ ### 5. 随机值生成工具 (random.ts)
867
+
868
+ #### generate_id
869
+ - **功能**: 生成[0-10000]的随机数,针对数据小量使用
870
+ - **返回类型**: `number` - 随机数
871
+ - **示例**:
872
+ ```typescript
873
+ import { generate_id } from '@qy_better_lib/core';
874
+
875
+ generate_id(); // 生成0-10000之间的随机数
876
+ ```
877
+
878
+ #### get_random_int
879
+ - **功能**: 生成[0-max]的随机数
880
+ - **参数**: `max: number` - 最大值
881
+ - **返回类型**: `number` - 随机数
882
+ - **示例**:
883
+ ```typescript
884
+ import { get_random_int } from '@qy_better_lib/core';
885
+
886
+ get_random_int(10); // 生成0-10之间的随机整数
887
+ ```
888
+
889
+ #### get_random_int_range
890
+ - **功能**: 生成指定范围的随机整数
891
+ - **参数**:
892
+ - `min: number` - 最小值
893
+ - `max: number` - 最大值
894
+ - **返回类型**: `number` - 随机整数
895
+ - **示例**:
896
+ ```typescript
897
+ import { get_random_int_range } from '@qy_better_lib/core';
898
+
899
+ get_random_int_range(1, 10); // 生成1-10之间的随机整数
900
+ ```
901
+
902
+ #### get_random_float
903
+ - **功能**: 生成随机浮点数
904
+ - **参数**:
905
+ - `min: number` - 最小值
906
+ - `max: number` - 最大值
907
+ - `decimalPlaces: number` - 小数位数,默认 2
908
+ - **返回类型**: `number` - 随机浮点数
909
+ - **示例**:
910
+ ```typescript
911
+ import { get_random_float } from '@qy_better_lib/core';
912
+
913
+ get_random_float(1, 10, 2); // 生成1-10之间的随机小数,保留2位小数
914
+ ```
915
+
916
+ #### generate_guid
917
+ - **功能**: 生成GUID/UUID
918
+ - **返回类型**: `string` - GUID/UUID字符串
919
+ - **示例**:
920
+ ```typescript
921
+ import { generate_guid } from '@qy_better_lib/core';
922
+
923
+ generate_guid(); // 生成一个随机GUID/UUID
924
+ ```
925
+
926
+ #### generate_string
927
+ - **功能**: 生成随机字符串
928
+ - **返回类型**: `string` - 随机字符串
929
+ - **示例**:
930
+ ```typescript
931
+ import { generate_string } from '@qy_better_lib/core';
932
+
933
+ generate_string(); // 生成一个随机字符串
934
+ ```
935
+
936
+ #### generate_random_string
937
+ - **功能**: 生成指定长度的随机字符串
938
+ - **参数**:
939
+ - `length: number` - 字符串长度
940
+ - `chars: string` - 可选字符集,默认包含大小写字母和数字
941
+ - **返回类型**: `string` - 随机字符串
942
+ - **示例**:
943
+ ```typescript
944
+ import { generate_random_string } from '@qy_better_lib/core';
945
+
946
+ generate_random_string(10); // 生成10位随机字符串
947
+ generate_random_string(8, 'ABCDEFG'); // 生成8位只包含指定字符的随机字符串
948
+ ```
949
+
950
+ #### get_random_boolean
951
+ - **功能**: 生成随机布尔值
952
+ - **返回类型**: `boolean` - 随机布尔值
953
+ - **示例**:
954
+ ```typescript
955
+ import { get_random_boolean } from '@qy_better_lib/core';
956
+
957
+ get_random_boolean(); // 50%概率为true
958
+ ```
959
+
960
+ #### get_random_element
961
+ - **功能**: 从数组中随机选择一个元素
962
+ - **参数**: `array: T[]` - 源数组
963
+ - **返回类型**: `T | undefined` - 随机选中的元素
964
+ - **示例**:
965
+ ```typescript
966
+ import { get_random_element } from '@qy_better_lib/core';
967
+
968
+ const array = ['a', 'b', 'c', 'd'];
969
+ get_random_element(array); // 随机返回数组中的一个元素
970
+ ```
971
+
972
+ #### get_random_elements
973
+ - **功能**: 从数组中随机选择多个元素
974
+ - **参数**:
975
+ - `array: T[]` - 源数组
976
+ - `count: number` - 选择数量
977
+ - **返回类型**: `T[]` - 随机选中的元素数组
978
+ - **示例**:
979
+ ```typescript
980
+ import { get_random_elements } from '@qy_better_lib/core';
981
+
982
+ const array = ['a', 'b', 'c', 'd'];
983
+ get_random_elements(array, 2); // 随机返回数组中的2个元素
984
+ ```
985
+
986
+ #### generate_random_color
987
+ - **功能**: 生成随机颜色
988
+ - **返回类型**: `string` - 随机颜色的十六进制值
989
+ - **示例**:
990
+ ```typescript
991
+ import { generate_random_color } from '@qy_better_lib/core';
992
+
993
+ generate_random_color(); // 生成一个随机十六进制颜色
994
+ ```
995
+
996
+ #### generate_random_number_string
997
+ - **功能**: 生成指定长度的随机数字字符串
998
+ - **参数**: `length: number` - 字符串长度
999
+ - **返回类型**: `string` - 随机数字字符串
1000
+ - **示例**:
1001
+ ```typescript
1002
+ import { generate_random_number_string } from '@qy_better_lib/core';
1003
+
1004
+ generate_random_number_string(6); // 生成6位随机数字字符串
1005
+ ```
1006
+
1007
+ #### generate_random_password
1008
+ - **功能**: 生成随机密码
1009
+ - **参数**: `length: number` - 密码长度,默认 8
1010
+ - **返回类型**: `string` - 随机密码
1011
+ - **示例**:
1012
+ ```typescript
1013
+ import { generate_random_password } from '@qy_better_lib/core';
1014
+
1015
+ generate_random_password(); // 生成8位随机密码
1016
+ generate_random_password(12); // 生成12位随机密码
1017
+ ```
1018
+
1019
+ #### generate_random_phone
1020
+ - **功能**: 生成随机手机号
1021
+ - **返回类型**: `string` - 随机手机号
1022
+ - **示例**:
1023
+ ```typescript
1024
+ import { generate_random_phone } from '@qy_better_lib/core';
1025
+
1026
+ generate_random_phone(); // 生成一个随机手机号
1027
+ ```
1028
+
1029
+ #### generate_random_email
1030
+ - **功能**: 生成随机邮箱
1031
+ - **返回类型**: `string` - 随机邮箱
1032
+ - **示例**:
1033
+ ```typescript
1034
+ import { generate_random_email } from '@qy_better_lib/core';
1035
+
1036
+ generate_random_email(); // 生成一个随机邮箱
1037
+ ```
1038
+
1039
+ #### generate_random_url
1040
+ - **功能**: 生成随机URL
1041
+ - **返回类型**: `string` - 随机URL
1042
+ - **示例**:
1043
+ ```typescript
1044
+ import { generate_random_url } from '@qy_better_lib/core';
1045
+
1046
+ generate_random_url(); // 生成一个随机URL
1047
+ ```
1048
+
1049
+ #### shuffle_array
1050
+ - **功能**: 打乱数组顺序
1051
+ - **参数**: `array: T[]` - 源数组
1052
+ - **返回类型**: `T[]` - 打乱后的新数组
1053
+ - **示例**:
1054
+ ```typescript
1055
+ import { shuffle_array } from '@qy_better_lib/core';
1056
+
1057
+ const array = [1, 2, 3, 4, 5];
1058
+ const shuffled = shuffle_array(array); // 打乱数组顺序
1059
+ ```
1060
+
1061
+ ### 6. 函数工具 (share.ts)
1062
+
1063
+ #### debounce
1064
+ - **功能**: 防抖函数
1065
+ - **参数**:
1066
+ - `fn: Function` - 要执行的函数
1067
+ - `delay: number` - 延迟时间,默认 200ms
1068
+ - `immediate: boolean` - 是否立即执行,默认 false
1069
+ - **返回类型**: `Function` - 防抖处理后的函数
1070
+ - **示例**:
1071
+ ```typescript
1072
+ import { debounce } from '@qy_better_lib/core';
1073
+
1074
+ // 防抖处理的搜索函数
1075
+ const debouncedSearch = debounce((keyword) => {
1076
+ console.log('搜索:', keyword);
1077
+ }, 300);
1078
+
1079
+ // 频繁调用时,只会在最后一次调用后300ms执行
1080
+ debouncedSearch('关键词1');
1081
+ debouncedSearch('关键词2');
1082
+ debouncedSearch('关键词3'); // 只有这次会执行
1083
+ ```
1084
+
1085
+ #### throttle
1086
+ - **功能**: 节流函数
1087
+ - **参数**:
1088
+ - `fn: Function` - 要执行的函数
1089
+ - `interval: number` - 时间间隔,默认 200ms
1090
+ - `options: object` - 配置选项
1091
+ - **返回类型**: `Function` - 节流处理后的函数
1092
+ - **示例**:
1093
+ ```typescript
1094
+ import { throttle } from '@qy_better_lib/core';
1095
+
1096
+ // 节流处理的滚动函数
1097
+ const throttledScroll = throttle(() => {
1098
+ console.log('滚动事件');
1099
+ }, 100);
1100
+
1101
+ // 滚动时,每100ms执行一次
1102
+ window.addEventListener('scroll', throttledScroll);
1103
+ ```
1104
+
1105
+ #### curry
1106
+ - **功能**: 柯里化函数
1107
+ - **参数**: `fn: Function` - 要柯里化的函数
1108
+ - **返回类型**: `Function` - 柯里化后的函数
1109
+ - **示例**:
1110
+ ```typescript
1111
+ import { curry } from '@qy_better_lib/core';
1112
+
1113
+ const add = (a, b, c) => a + b + c;
1114
+ const curriedAdd = curry(add);
1115
+
1116
+ curriedAdd(1)(2)(3); // 6
1117
+ curriedAdd(1, 2)(3); // 6
1118
+ curriedAdd(1)(2, 3); // 6
1119
+ ```
1120
+
1121
+ #### compose
1122
+ - **功能**: 函数组合
1123
+ - **参数**: `...fns: Function[]` - 要组合的函数列表
1124
+ - **返回类型**: `Function` - 组合后的函数
1125
+ - **示例**:
1126
+ ```typescript
1127
+ import { compose } from '@qy_better_lib/core';
1128
+
1129
+ const add1 = x => x + 1;
1130
+ const multiply2 = x => x * 2;
1131
+ const subtract3 = x => x - 3;
1132
+
1133
+ const composed = compose(subtract3, multiply2, add1);
1134
+ composed(5); // ((5 + 1) * 2) - 3 = 9
1135
+ ```
1136
+
1137
+ #### pipe
1138
+ - **功能**: 管道函数
1139
+ - **参数**: `...fns: Function[]` - 要管道的函数列表
1140
+ - **返回类型**: `Function` - 管道后的函数
1141
+ - **示例**:
1142
+ ```typescript
1143
+ import { pipe } from '@qy_better_lib/core';
1144
+
1145
+ const add1 = x => x + 1;
1146
+ const multiply2 = x => x * 2;
1147
+ const subtract3 = x => x - 3;
1148
+
1149
+ const piped = pipe(add1, multiply2, subtract3);
1150
+ piped(5); // ((5 + 1) * 2) - 3 = 9
1151
+ ```
1152
+
1153
+ #### delay_execution
1154
+ - **功能**: 延迟执行函数
1155
+ - **参数**:
1156
+ - `fn: Function` - 要执行的函数
1157
+ - `delay: number` - 延迟时间,默认 1000ms
1158
+ - **返回类型**: `Promise<any>` - 执行结果的Promise
1159
+ - **示例**:
1160
+ ```typescript
1161
+ import { delay_execution } from '@qy_better_lib/core';
1162
+
1163
+ async function example() {
1164
+ console.log('开始');
1165
+ await delay_execution(() => {
1166
+ console.log('延迟执行');
1167
+ }, 2000);
1168
+ console.log('结束');
1169
+ }
1170
+
1171
+ example(); // 开始 -> 2秒后 -> 延迟执行 -> 结束
1172
+ ```
1173
+
1174
+ #### retry
1175
+ - **功能**: 重试函数
1176
+ - **参数**:
1177
+ - `fn: Function` - 要执行的函数
1178
+ - `options: object` - 配置选项
1179
+ - **返回类型**: `Promise<any>` - 执行结果的Promise
1180
+ - **示例**:
1181
+ ```typescript
1182
+ import { retry } from '@qy_better_lib/core';
1183
+
1184
+ async function example() {
1185
+ const result = await retry(async () => {
1186
+ // 可能会失败的操作
1187
+ if (Math.random() > 0.5) {
1188
+ throw new Error('失败');
1189
+ }
1190
+ return '成功';
1191
+ }, {
1192
+ maxAttempts: 3,
1193
+ delay: 1000
1194
+ });
1195
+ console.log(result);
1196
+ }
1197
+
1198
+ example();
1199
+ ```
1200
+
1201
+ #### once
1202
+ - **功能**: 一次性函数
1203
+ - **参数**: `fn: Function` - 要执行的函数
1204
+ - **返回类型**: `Function` - 一次性函数
1205
+ - **示例**:
1206
+ ```typescript
1207
+ import { once } from '@qy_better_lib/core';
1208
+
1209
+ const initialize = once(() => {
1210
+ console.log('初始化');
1211
+ return '初始化完成';
1212
+ });
1213
+
1214
+ initialize(); // 初始化
1215
+ initialize(); // 无输出
1216
+ initialize(); // 无输出
1217
+ ```
1218
+
1219
+ #### memoize
1220
+ - **功能**: 记忆化函数
1221
+ - **参数**:
1222
+ - `fn: Function` - 要记忆化的函数
1223
+ - `keyGenerator: Function` - 缓存键生成函数
1224
+ - **返回类型**: `Function` - 记忆化后的函数
1225
+ - **示例**:
1226
+ ```typescript
1227
+ import { memoize } from '@qy_better_lib/core';
1228
+
1229
+ // 记忆化的计算函数
1230
+ const memoizedCalculate = memoize((a, b) => {
1231
+ console.log('计算中...');
1232
+ return a + b;
1233
+ });
1234
+
1235
+ console.log(memoizedCalculate(1, 2)); // 计算中... 3
1236
+ console.log(memoizedCalculate(1, 2)); // 直接返回缓存结果 3
1237
+ console.log(memoizedCalculate(2, 3)); // 计算中... 5
1238
+ ```
1239
+
1240
+ #### batch_execution
1241
+ - **功能**: 批量执行函数
1242
+ - **参数**:
1243
+ - `fns: Function[]` - 要执行的函数数组
1244
+ - `parallel: boolean` - 是否并行执行,默认 true
1245
+ - **返回类型**: `Promise<any[]>` - 执行结果的Promise数组
1246
+ - **示例**:
1247
+ ```typescript
1248
+ import { batch_execution } from '@qy_better_lib/core';
1249
+
1250
+ async function example() {
1251
+ const fns = [
1252
+ () => Promise.resolve(1),
1253
+ () => Promise.resolve(2),
1254
+ () => Promise.resolve(3)
1255
+ ];
1256
+
1257
+ const results = await batch_execution(fns);
1258
+ console.log(results); // [1, 2, 3]
1259
+ }
1260
+
1261
+ example();
1262
+ ```
1263
+
1264
+ #### timeout
1265
+ - **功能**: 超时控制函数
1266
+ - **参数**:
1267
+ - `fn: Function` - 要执行的函数
1268
+ - `timeout: number` - 超时时间,默认 3000ms
1269
+ - `message: string` - 超时消息,默认 '操作超时'
1270
+ - **返回类型**: `Promise<any>` - 执行结果的Promise
1271
+ - **示例**:
1272
+ ```typescript
1273
+ import { timeout } from '@qy_better_lib/core';
1274
+
1275
+ async function example() {
1276
+ try {
1277
+ const result = await timeout(async () => {
1278
+ // 模拟长时间操作
1279
+ await new Promise(resolve => setTimeout(resolve, 5000));
1280
+ return '成功';
1281
+ }, 3000);
1282
+ console.log(result);
1283
+ } catch (error) {
1284
+ console.log(error.message); // 操作超时
1285
+ }
1286
+ }
1287
+
1288
+ example();
1289
+ ```
1290
+
1291
+ ### 7. 存储工具 (storage.ts)
1292
+
1293
+ #### get_token
1294
+ - **功能**: 获取用户token,包含过期时间判断
1295
+ - **返回类型**: `any | null` - token值或null
1296
+ - **示例**:
1297
+ ```typescript
1298
+ import { get_token } from '@qy_better_lib/core';
1299
+
1300
+ const token = get_token();
1301
+ console.log(token);
1302
+ ```
1303
+
1304
+ #### set_token
1305
+ - **功能**: 设置用户token,有效期默认七天
1306
+ - **参数**:
1307
+ - `value: any` - token值
1308
+ - `expires: number` - 过期时间(秒),默认7天
1309
+ - **示例**:
1310
+ ```typescript
1311
+ import { set_token } from '@qy_better_lib/core';
1312
+
1313
+ set_token('abc123'); // 默认7天过期
1314
+ set_token('abc123', 3600); // 1小时过期
1315
+ ```
1316
+
1317
+ #### remove_token
1318
+ - **功能**: 移除token
1319
+ - **示例**:
1320
+ ```typescript
1321
+ import { remove_token } from '@qy_better_lib/core';
1322
+
1323
+ remove_token();
1324
+ ```
1325
+
1326
+ #### set_storage
1327
+ - **功能**: 设置缓存
1328
+ - **参数**:
1329
+ - `key: string` - 缓存键
1330
+ - `value: any` - 缓存值
1331
+ - `type: 'local' | 'session'` - 存储类型,默认'local'
1332
+ - **示例**:
1333
+ ```typescript
1334
+ import { set_storage } from '@qy_better_lib/core';
1335
+
1336
+ // 设置localStorage
1337
+ set_storage('user', { name: '张三', age: 20 });
1338
+
1339
+ // 设置sessionStorage
1340
+ set_storage('token', 'abc123', 'session');
1341
+ ```
1342
+
1343
+ #### get_storage
1344
+ - **功能**: 获取缓存
1345
+ - **参数**:
1346
+ - `key: string` - 缓存键
1347
+ - `type: 'local' | 'session'` - 存储类型,默认'local'
1348
+ - **返回类型**: `any` - 缓存值或null
1349
+ - **示例**:
1350
+ ```typescript
1351
+ import { get_storage } from '@qy_better_lib/core';
1352
+
1353
+ // 获取localStorage
1354
+ const user = get_storage('user');
1355
+ console.log(user); // { name: '张三', age: 20 }
1356
+
1357
+ // 获取sessionStorage
1358
+ const token = get_storage('token', 'session');
1359
+ console.log(token); // 'abc123'
1360
+ ```
1361
+
1362
+ #### remove_storage
1363
+ - **功能**: 删除指定key的缓存
1364
+ - **参数**:
1365
+ - `key: string` - 缓存键
1366
+ - `type: 'local' | 'session'` - 存储类型,默认'local'
1367
+ - **示例**:
1368
+ ```typescript
1369
+ import { remove_storage } from '@qy_better_lib/core';
1370
+
1371
+ // 移除localStorage
1372
+ remove_storage('user');
1373
+
1374
+ // 移除sessionStorage
1375
+ remove_storage('token', 'session');
1376
+ ```
1377
+
1378
+ #### clear_storage
1379
+ - **功能**: 清除所有缓存
1380
+ - **参数**: `type: 'local' | 'session'` - 存储类型,默认'local'
1381
+ - **示例**:
1382
+ ```typescript
1383
+ import { clear_storage } from '@qy_better_lib/core';
1384
+
1385
+ // 清空localStorage
1386
+ clear_storage();
1387
+
1388
+ // 清空sessionStorage
1389
+ clear_storage('session');
1390
+ ```
1391
+
1392
+ #### set_storage_with_expiry
1393
+ - **功能**: 设置带过期时间的缓存
1394
+ - **参数**:
1395
+ - `key: string` - 缓存键
1396
+ - `value: any` - 缓存值
1397
+ - `expiry: number` - 过期时间(秒)
1398
+ - `type: 'local' | 'session'` - 存储类型,默认'local'
1399
+ - **示例**:
1400
+ ```typescript
1401
+ import { set_storage_with_expiry } from '@qy_better_lib/core';
1402
+
1403
+ // 设置1小时过期的缓存
1404
+ set_storage_with_expiry('user', { name: '张三', age: 20 }, 3600);
1405
+ ```
1406
+
1407
+ #### get_storage_with_expiry
1408
+ - **功能**: 获取带过期时间的缓存
1409
+ - **参数**:
1410
+ - `key: string` - 缓存键
1411
+ - `type: 'local' | 'session'` - 存储类型,默认'local'
1412
+ - **返回类型**: `any` - 缓存值或null
1413
+ - **示例**:
1414
+ ```typescript
1415
+ import { get_storage_with_expiry } from '@qy_better_lib/core';
1416
+
1417
+ const user = get_storage_with_expiry('user');
1418
+ console.log(user);
1419
+ ```
1420
+
1421
+ #### has_storage
1422
+ - **功能**: 检查缓存是否存在
1423
+ - **参数**:
1424
+ - `key: string` - 缓存键
1425
+ - `type: 'local' | 'session'` - 存储类型,默认'local'
1426
+ - **返回类型**: `boolean` - 是否存在
1427
+ - **示例**:
1428
+ ```typescript
1429
+ import { has_storage } from '@qy_better_lib/core';
1430
+
1431
+ const hasUser = has_storage('user');
1432
+ console.log(hasUser);
1433
+ ```
1434
+
1435
+ #### get_all_storage_keys
1436
+ - **功能**: 获取所有缓存键
1437
+ - **参数**: `type: 'local' | 'session'` - 存储类型,默认'local'
1438
+ - **返回类型**: `string[]` - 缓存键数组
1439
+ - **示例**:
1440
+ ```typescript
1441
+ import { get_all_storage_keys } from '@qy_better_lib/core';
1442
+
1443
+ const keys = get_all_storage_keys();
1444
+ console.log(keys);
1445
+ ```
1446
+
1447
+ #### clear_expired_storage
1448
+ - **功能**: 清除过期的缓存
1449
+ - **参数**: `type: 'local' | 'session'` - 存储类型,默认'local'
1450
+ - **返回类型**: `number` - 清除的缓存数量
1451
+ - **示例**:
1452
+ ```typescript
1453
+ import { clear_expired_storage } from '@qy_better_lib/core';
1454
+
1455
+ const count = clear_expired_storage();
1456
+ console.log(`清除了${count}个过期缓存`);
1457
+ ```
1458
+
1459
+ #### encrypt_storage
1460
+ - **功能**: 加密存储敏感数据
1461
+ - **参数**:
1462
+ - `key: string` - 缓存键
1463
+ - `value: any` - 缓存值
1464
+ - `type: 'local' | 'session'` - 存储类型,默认'local'
1465
+ - **示例**:
1466
+ ```typescript
1467
+ import { encrypt_storage } from '@qy_better_lib/core';
1468
+
1469
+ // 加密存储用户信息
1470
+ encrypt_storage('user', { name: '张三', age: 20 });
1471
+ ```
1472
+
1473
+ #### decrypt_storage
1474
+ - **功能**: 解密获取敏感数据
1475
+ - **参数**:
1476
+ - `key: string` - 缓存键
1477
+ - `type: 'local' | 'session'` - 存储类型,默认'local'
1478
+ - **返回类型**: `any` - 解密后的数据或null
1479
+ - **示例**:
1480
+ ```typescript
1481
+ import { decrypt_storage } from '@qy_better_lib/core';
1482
+
1483
+ // 解密获取用户信息
1484
+ const user = decrypt_storage('user');
1485
+ console.log(user); // { name: '张三', age: 20 }
1486
+ ```
1487
+
1488
+ #### set_batch_storage
1489
+ - **功能**: 批量设置缓存
1490
+ - **参数**:
1491
+ - `items: Array<{ key: string; value: any }>` - 缓存项数组
1492
+ - `type: 'local' | 'session'` - 存储类型,默认'local'
1493
+ - **示例**:
1494
+ ```typescript
1495
+ import { set_batch_storage } from '@qy_better_lib/core';
1496
+
1497
+ set_batch_storage([
1498
+ { key: 'user', value: { name: '张三', age: 20 } },
1499
+ { key: 'token', value: 'abc123' }
1500
+ ]);
1501
+ ```
1502
+
1503
+ #### get_batch_storage
1504
+ - **功能**: 批量获取缓存
1505
+ - **参数**:
1506
+ - `keys: string[]` - 缓存键数组
1507
+ - `type: 'local' | 'session'` - 存储类型,默认'local'
1508
+ - **返回类型**: `Record<string, any>` - 缓存值对象
1509
+ - **示例**:
1510
+ ```typescript
1511
+ import { get_batch_storage } from '@qy_better_lib/core';
1512
+
1513
+ const data = get_batch_storage(['user', 'token']);
1514
+ console.log(data.user);
1515
+ console.log(data.token);
1516
+ ```
1517
+
1518
+ #### remove_batch_storage
1519
+ - **功能**: 批量删除缓存
1520
+ - **参数**:
1521
+ - `keys: string[]` - 缓存键数组
1522
+ - `type: 'local' | 'session'` - 存储类型,默认'local'
1523
+ - **示例**:
1524
+ ```typescript
1525
+ import { remove_batch_storage } from '@qy_better_lib/core';
1526
+
1527
+ remove_batch_storage(['user', 'token']);
1528
+ ```
1529
+
1530
+ ### 8. DOM 操作工具 (dom.ts)
1531
+
1532
+ #### get_parent_by_class
1533
+ - **功能**: 根据类名获取父元素
1534
+ - **参数**:
1535
+ - `dom: Element | null` - DOM元素
1536
+ - `class_name: string` - CSS类名
1537
+ - **返回类型**: `Element | null` - DOM元素或null
1538
+ - **示例**:
1539
+ ```typescript
1540
+ import { get_parent_by_class } from '@qy_better_lib/core';
1541
+
1542
+ const childElement = document.getElementById('child');
1543
+ const parentElement = get_parent_by_class(childElement, 'parent-class');
1544
+ console.log(parentElement);
1545
+ ```
1546
+
1547
+ #### scroll_footer
1548
+ - **功能**: 滚动到底部
1549
+ - **参数**:
1550
+ - `dom_id: string` - 元素ID
1551
+ - `behavior: boolean` - 开启滚动动画,默认true
1552
+ - **示例**:
1553
+ ```typescript
1554
+ import { scroll_footer } from '@qy_better_lib/core';
1555
+
1556
+ // 滚动到ID为container的元素底部
1557
+ scroll_footer('container');
1558
+ ```
1559
+
1560
+ #### get_element
1561
+ - **功能**: 根据选择器获取元素
1562
+ - **参数**:
1563
+ - `selector: string` - 选择器
1564
+ - `context: Element | Document` - 上下文元素,默认为document
1565
+ - **返回类型**: `Element | null` - DOM元素或null
1566
+ - **示例**:
1567
+ ```typescript
1568
+ import { get_element } from '@qy_better_lib/core';
1569
+
1570
+ // 通过选择器获取元素
1571
+ const element = get_element('#container');
1572
+
1573
+ // 在指定上下文中获取元素
1574
+ const parentElement = get_element('.parent');
1575
+ const childElement = get_element('.child', parentElement);
1576
+ ```
1577
+
1578
+ #### get_elements
1579
+ - **功能**: 根据选择器获取多个元素
1580
+ - **参数**:
1581
+ - `selector: string` - 选择器
1582
+ - `context: Element | Document` - 上下文元素,默认为document
1583
+ - **返回类型**: `Element[]` - DOM元素数组
1584
+ - **示例**:
1585
+ ```typescript
1586
+ import { get_elements } from '@qy_better_lib/core';
1587
+
1588
+ // 获取所有段落元素
1589
+ const paragraphs = get_elements('p');
1590
+ console.log(paragraphs.length);
1591
+ ```
1592
+
1593
+ #### add_class
1594
+ - **功能**: 添加类名
1595
+ - **参数**:
1596
+ - `element: Element | null` - DOM元素
1597
+ - `class_name: string` - 类名
1598
+ - **示例**:
1599
+ ```typescript
1600
+ import { add_class } from '@qy_better_lib/core';
1601
+
1602
+ const element = document.getElementById('container');
1603
+ add_class(element, 'active');
1604
+ ```
1605
+
1606
+ #### remove_class
1607
+ - **功能**: 移除类名
1608
+ - **参数**:
1609
+ - `element: Element | null` - DOM元素
1610
+ - `class_name: string` - 类名
1611
+ - **示例**:
1612
+ ```typescript
1613
+ import { remove_class } from '@qy_better_lib/core';
1614
+
1615
+ const element = document.getElementById('container');
1616
+ remove_class(element, 'active');
1617
+ ```
1618
+
1619
+ #### toggle_class
1620
+ - **功能**: 切换类名
1621
+ - **参数**:
1622
+ - `element: Element | null` - DOM元素
1623
+ - `class_name: string` - 类名
1624
+ - **返回类型**: `boolean` - 是否添加了类名
1625
+ - **示例**:
1626
+ ```typescript
1627
+ import { toggle_class } from '@qy_better_lib/core';
1628
+
1629
+ const element = document.getElementById('container');
1630
+ const isActive = toggle_class(element, 'active');
1631
+ console.log(isActive); // 切换后的状态
1632
+ ```
1633
+
1634
+ #### has_class
1635
+ - **功能**: 检查是否包含类名
1636
+ - **参数**:
1637
+ - `element: Element | null` - DOM元素
1638
+ - `class_name: string` - 类名
1639
+ - **返回类型**: `boolean` - 是否包含类名
1640
+ - **示例**:
1641
+ ```typescript
1642
+ import { has_class } from '@qy_better_lib/core';
1643
+
1644
+ const element = document.getElementById('container');
1645
+ const hasActive = has_class(element, 'active');
1646
+ console.log(hasActive);
1647
+ ```
1648
+
1649
+ #### get_style
1650
+ - **功能**: 获取元素样式
1651
+ - **参数**:
1652
+ - `element: Element | null` - DOM元素
1653
+ - `property: string` - CSS属性名
1654
+ - **返回类型**: `string` - CSS属性值
1655
+ - **示例**:
1656
+ ```typescript
1657
+ import { get_style } from '@qy_better_lib/core';
1658
+
1659
+ const element = document.getElementById('container');
1660
+ const color = get_style(element, 'color');
1661
+ console.log(color);
1662
+ ```
1663
+
1664
+ #### set_style
1665
+ - **功能**: 设置元素样式
1666
+ - **参数**:
1667
+ - `element: Element | null` - DOM元素
1668
+ - `property: string` - CSS属性名
1669
+ - `value: string` - CSS属性值
1670
+ - **示例**:
1671
+ ```typescript
1672
+ import { set_style } from '@qy_better_lib/core';
1673
+
1674
+ const element = document.getElementById('container');
1675
+ set_style(element, 'color', 'red');
1676
+ set_style(element, 'fontSize', '16px');
1677
+ ```
1678
+
1679
+ #### set_styles
1680
+ - **功能**: 设置元素多个样式
1681
+ - **参数**:
1682
+ - `element: Element | null` - DOM元素
1683
+ - `styles: Record<string, string>` - 样式对象
1684
+ - **示例**:
1685
+ ```typescript
1686
+ import { set_styles } from '@qy_better_lib/core';
1687
+
1688
+ const element = document.getElementById('container');
1689
+ set_styles(element, {
1690
+ color: 'red',
1691
+ fontSize: '16px',
1692
+ backgroundColor: '#f0f0f0'
1693
+ });
1694
+ ```
1695
+
1696
+ #### get_attribute
1697
+ - **功能**: 获取元素属性
1698
+ - **参数**:
1699
+ - `element: Element | null` - DOM元素
1700
+ - `attribute: string` - 属性名
1701
+ - **返回类型**: `string` - 属性值
1702
+ - **示例**:
1703
+ ```typescript
1704
+ import { get_attribute } from '@qy_better_lib/core';
1705
+
1706
+ const element = document.getElementById('link');
1707
+ const href = get_attribute(element, 'href');
1708
+ console.log(href);
1709
+ ```
1710
+
1711
+ #### set_attribute
1712
+ - **功能**: 设置元素属性
1713
+ - **参数**:
1714
+ - `element: Element | null` - DOM元素
1715
+ - `attribute: string` - 属性名
1716
+ - `value: string` - 属性值
1717
+ - **示例**:
1718
+ ```typescript
1719
+ import { set_attribute } from '@qy_better_lib/core';
1720
+
1721
+ const element = document.getElementById('link');
1722
+ set_attribute(element, 'href', 'https://example.com');
1723
+ ```
1724
+
1725
+ #### remove_attribute
1726
+ - **功能**: 移除元素属性
1727
+ - **参数**:
1728
+ - `element: Element | null` - DOM元素
1729
+ - `attribute: string` - 属性名
1730
+ - **示例**:
1731
+ ```typescript
1732
+ import { remove_attribute } from '@qy_better_lib/core';
1733
+
1734
+ const element = document.getElementById('link');
1735
+ remove_attribute(element, 'href');
1736
+ ```
1737
+
1738
+ #### on
1739
+ - **功能**: 绑定事件
1740
+ - **参数**:
1741
+ - `element: Element | Window | Document | null` - DOM元素、窗口或文档
1742
+ - `event: string` - 事件名
1743
+ - `handler: EventListener` - 事件处理函数
1744
+ - `options: AddEventListenerOptions` - 事件选项
1745
+ - **示例**:
1746
+ ```typescript
1747
+ import { on } from '@qy_better_lib/core';
1748
+
1749
+ const button = document.getElementById('button');
1750
+ on(button, 'click', () => {
1751
+ console.log('Button clicked');
1752
+ });
1753
+ ```
1754
+
1755
+ #### off
1756
+ - **功能**: 解绑事件
1757
+ - **参数**:
1758
+ - `element: Element | Window | Document | null` - DOM元素、窗口或文档
1759
+ - `event: string` - 事件名
1760
+ - `handler: EventListener` - 事件处理函数
1761
+ - `options: EventListenerOptions` - 事件选项
1762
+ - **示例**:
1763
+ ```typescript
1764
+ import { off } from '@qy_better_lib/core';
1765
+
1766
+ const button = document.getElementById('button');
1767
+ const handleClick = () => {
1768
+ console.log('Button clicked');
1769
+ };
1770
+
1771
+ on(button, 'click', handleClick);
1772
+ // 解绑事件
1773
+ off(button, 'click', handleClick);
1774
+ ```
1775
+
1776
+ #### create_element
1777
+ - **功能**: 创建元素
1778
+ - **参数**:
1779
+ - `tag_name: string` - 标签名
1780
+ - `options: object` - 元素选项
1781
+ - **返回类型**: `Element` - 创建的DOM元素
1782
+ - **示例**:
1783
+ ```typescript
1784
+ import { create_element } from '@qy_better_lib/core';
1785
+
1786
+ // 创建带有类名和样式的元素
1787
+ const element = create_element('div', {
1788
+ class_name: 'container',
1789
+ style: {
1790
+ color: 'red',
1791
+ fontSize: '16px'
1792
+ },
1793
+ attributes: {
1794
+ 'data-id': '123'
1795
+ },
1796
+ text: 'Hello World'
1797
+ });
1798
+
1799
+ document.body.appendChild(element);
1800
+ ```
1801
+
1802
+ #### get_element_rect
1803
+ - **功能**: 获取元素位置和尺寸
1804
+ - **参数**: `element: Element | null` - DOM元素
1805
+ - **返回类型**: `DOMRect | null` - 元素位置和尺寸信息
1806
+ - **示例**:
1807
+ ```typescript
1808
+ import { get_element_rect } from '@qy_better_lib/core';
1809
+
1810
+ const element = document.getElementById('container');
1811
+ const rect = get_element_rect(element);
1812
+ if (rect) {
1813
+ console.log(rect.width, rect.height, rect.top, rect.left);
1814
+ }
1815
+ ```
1816
+
1817
+ #### get_element_position
1818
+ - **功能**: 获取元素相对于文档的位置
1819
+ - **参数**: `element: Element | null` - DOM元素
1820
+ - **返回类型**: `{ top: number; left: number } | null` - 元素位置信息
1821
+ - **示例**:
1822
+ ```typescript
1823
+ import { get_element_position } from '@qy_better_lib/core';
1824
+
1825
+ const element = document.getElementById('container');
1826
+ const position = get_element_position(element);
1827
+ if (position) {
1828
+ console.log(position.top, position.left);
1829
+ }
1830
+ ```
1831
+
1832
+ #### get_element_size
1833
+ - **功能**: 获取元素尺寸
1834
+ - **参数**: `element: Element | null` - DOM元素
1835
+ - **返回类型**: `{ width: number; height: number } | null` - 元素尺寸信息
1836
+ - **示例**:
1837
+ ```typescript
1838
+ import { get_element_size } from '@qy_better_lib/core';
1839
+
1840
+ const element = document.getElementById('container');
1841
+ const size = get_element_size(element);
1842
+ if (size) {
1843
+ console.log(size.width, size.height);
1844
+ }
1845
+ ```
1846
+
1847
+ #### scroll_to_element
1848
+ - **功能**: 滚动到指定元素
1849
+ - **参数**:
1850
+ - `element: Element | null` - DOM元素
1851
+ - `options: object` - 滚动选项
1852
+ - **示例**:
1853
+ ```typescript
1854
+ import { scroll_to_element } from '@qy_better_lib/core';
1855
+
1856
+ const targetElement = document.getElementById('target');
1857
+ // 滚动到指定元素
1858
+ scroll_to_element(targetElement, {
1859
+ behavior: 'smooth',
1860
+ offsetTop: 100 // 顶部偏移量
1861
+ });
1862
+ ```
1863
+
1864
+ #### is_in_viewport
1865
+ - **功能**: 检查元素是否在视口中
1866
+ - **参数**: `element: Element | null` - DOM元素
1867
+ - **返回类型**: `boolean` - 是否在视口中
1868
+ - **示例**:
1869
+ ```typescript
1870
+ import { is_in_viewport } from '@qy_better_lib/core';
1871
+
1872
+ const element = document.getElementById('container');
1873
+ const inViewport = is_in_viewport(element);
1874
+ console.log(inViewport);
1875
+ ```
1876
+
1877
+ #### is_completely_in_viewport
1878
+ - **功能**: 检查元素是否完全在视口中
1879
+ - **参数**: `element: Element | null` - DOM元素
1880
+ - **返回类型**: `boolean` - 是否完全在视口中
1881
+ - **示例**:
1882
+ ```typescript
1883
+ import { is_completely_in_viewport } from '@qy_better_lib/core';
1884
+
1885
+ const element = document.getElementById('container');
1886
+ const completelyInViewport = is_completely_in_viewport(element);
1887
+ console.log(completelyInViewport);
1888
+ ```
1889
+
1890
+ #### get_window_size
1891
+ - **功能**: 获取窗口尺寸
1892
+ - **返回类型**: `{ width: number; height: number }` - 窗口尺寸信息
1893
+ - **示例**:
1894
+ ```typescript
1895
+ import { get_window_size } from '@qy_better_lib/core';
1896
+
1897
+ const windowSize = get_window_size();
1898
+ console.log(windowSize.width, windowSize.height);
1899
+ ```
1900
+
1901
+ #### get_document_size
1902
+ - **功能**: 获取文档尺寸
1903
+ - **返回类型**: `{ width: number; height: number }` - 文档尺寸信息
1904
+ - **示例**:
1905
+ ```typescript
1906
+ import { get_document_size } from '@qy_better_lib/core';
1907
+
1908
+ const documentSize = get_document_size();
1909
+ console.log(documentSize.width, documentSize.height);
1910
+ ```
1911
+
1912
+ ### 9. 颜色处理工具 (color.ts)
1913
+
1914
+ #### mix
1915
+ - **功能**: 过渡颜色生成
1916
+ - **参数**:
1917
+ - `color1: string` - 第一个颜色
1918
+ - `color2: string` - 第二个颜色
1919
+ - `weight: number` - 混合权重 (0-1)
1920
+ - **返回类型**: `string` - 混合后的颜色
1921
+ - **示例**:
1922
+ ```typescript
1923
+ import { mix } from '@qy_better_lib/core';
1924
+
1925
+ const mixedColor = mix('#ff0000', '#0000ff', 0.5);
1926
+ console.log(mixedColor); // 混合后的紫色
1927
+ ```
1928
+
1929
+ #### get_rgb
1930
+ - **功能**: HEX转成RGB字符串
1931
+ - **参数**: `color: string` - HEX颜色值
1932
+ - **返回类型**: `string` - RGB字符串 "r,g,b"
1933
+ - **示例**:
1934
+ ```typescript
1935
+ import { get_rgb } from '@qy_better_lib/core';
1936
+
1937
+ const rgbString = get_rgb('#ff0000');
1938
+ console.log(rgbString); // "255,0,0"
1939
+ ```
1940
+
1941
+ #### hex_to_rgb
1942
+ - **功能**: HEX转成RGB对象
1943
+ - **参数**: `hex: string` - HEX颜色值
1944
+ - **返回类型**: `{ r: number; g: number; b: number } | null` - RGB对象
1945
+ - **示例**:
1946
+ ```typescript
1947
+ import { hex_to_rgb } from '@qy_better_lib/core';
1948
+
1949
+ const rgb = hex_to_rgb('#ff0000');
1950
+ console.log(rgb); // { r: 255, g: 0, b: 0 }
1951
+ ```
1952
+
1953
+ #### rgb_to_hex
1954
+ - **功能**: RGB转成HEX
1955
+ - **参数**:
1956
+ - `r: number` - 红色通道值 (0-255)
1957
+ - `g: number` - 绿色通道值 (0-255)
1958
+ - `b: number` - 蓝色通道值 (0-255)
1959
+ - **返回类型**: `string` - HEX颜色值
1960
+ - **示例**:
1961
+ ```typescript
1962
+ import { rgb_to_hex } from '@qy_better_lib/core';
1963
+
1964
+ const hex = rgb_to_hex(255, 0, 0);
1965
+ console.log(hex); // #ff0000
1966
+ ```
1967
+
1968
+ #### rgba_to_hex
1969
+ - **功能**: RGBA转成HEX
1970
+ - **参数**:
1971
+ - `r: number` - 红色通道值 (0-255)
1972
+ - `g: number` - 绿色通道值 (0-255)
1973
+ - `b: number` - 蓝色通道值 (0-255)
1974
+ - `a: number` - 透明度值 (0-1)
1975
+ - **返回类型**: `string` - HEX颜色值
1976
+ - **示例**:
1977
+ ```typescript
1978
+ import { rgba_to_hex } from '@qy_better_lib/core';
1979
+
1980
+ const hex = rgba_to_hex(255, 0, 0, 0.5);
1981
+ console.log(hex); // #ff0000
1982
+ ```
1983
+
1984
+ #### lighten
1985
+ - **功能**: 使颜色变亮
1986
+ - **参数**:
1987
+ - `color: string` - HEX颜色值
1988
+ - `amount: number` - 变亮程度 (0-1)
1989
+ - **返回类型**: `string` - 变亮后的HEX颜色值
1990
+ - **示例**:
1991
+ ```typescript
1992
+ import { lighten } from '@qy_better_lib/core';
1993
+
1994
+ const lightColor = lighten('#ff0000', 0.2);
1995
+ console.log(lightColor); // 变亮后的红色
1996
+ ```
1997
+
1998
+ #### darken
1999
+ - **功能**: 使颜色变暗
2000
+ - **参数**:
2001
+ - `color: string` - HEX颜色值
2002
+ - `amount: number` - 变暗程度 (0-1)
2003
+ - **返回类型**: `string` - 变暗后的HEX颜色值
2004
+ - **示例**:
2005
+ ```typescript
2006
+ import { darken } from '@qy_better_lib/core';
2007
+
2008
+ const darkColor = darken('#ff0000', 0.2);
2009
+ console.log(darkColor); // 变暗后的红色
2010
+ ```
2011
+
2012
+ #### is_light
2013
+ - **功能**: 判断颜色是否为亮色
2014
+ - **参数**: `color: string` - HEX颜色值
2015
+ - **返回类型**: `boolean` - 是否为亮色
2016
+ - **示例**:
2017
+ ```typescript
2018
+ import { is_light } from '@qy_better_lib/core';
2019
+
2020
+ const isLight = is_light('#ffffff');
2021
+ console.log(isLight); // true
2022
+ ```
2023
+
2024
+ #### is_dark
2025
+ - **功能**: 判断颜色是否为暗色
2026
+ - **参数**: `color: string` - HEX颜色值
2027
+ - **返回类型**: `boolean` - 是否为暗色
2028
+ - **示例**:
2029
+ ```typescript
2030
+ import { is_dark } from '@qy_better_lib/core';
2031
+
2032
+ const isDark = is_dark('#000000');
2033
+ console.log(isDark); // true
2034
+ ```
2035
+
2036
+ #### get_contrast_color
2037
+ - **功能**: 获取与给定颜色对比度高的颜色(黑或白)
2038
+ - **参数**: `color: string` - HEX颜色值
2039
+ - **返回类型**: `string` - 对比度高的颜色 (#000000 或 #FFFFFF)
2040
+ - **示例**:
2041
+ ```typescript
2042
+ import { get_contrast_color } from '@qy_better_lib/core';
2043
+
2044
+ const contrastColor = get_contrast_color('#ff0000');
2045
+ console.log(contrastColor); // #000000
2046
+ ```
2047
+
2048
+ ### 10. ECharts 图表工具 (echarts.ts)
2049
+
2050
+ #### auto_size
2051
+ - **功能**: ECharts图表字体、间距自适应
2052
+ - **参数**:
2053
+ - `size: number` - 原始尺寸
2054
+ - `deflate_width: number` - 基准宽度,默认 1920
2055
+ - **返回类型**: `number` - 自适应后的尺寸
2056
+ - **示例**:
2057
+ ```typescript
2058
+ import { auto_size } from '@qy_better_lib/core';
2059
+
2060
+ const fontSize = auto_size(14); // 根据屏幕宽度自适应的字体大小
2061
+ ```
2062
+
2063
+ #### get_chart_gradient_color
2064
+ - **功能**: ECharts线性渐变颜色
2065
+ - **参数**:
2066
+ - `type: 'v' | 'h'` - 渐变类型,'v'为垂直渐变,'h'为水平渐变
2067
+ - `start_color: string` - 起始颜色
2068
+ - `end_color: string` - 结束颜色
2069
+ - **返回类型**: `object` - 渐变配置对象
2070
+ - **示例**:
2071
+ ```typescript
2072
+ import { get_chart_gradient_color } from '@qy_better_lib/core';
2073
+
2074
+ const gradient = get_chart_gradient_color('v', '#ff0000', '#0000ff');
2075
+ ```
2076
+
2077
+ #### init_chart
2078
+ - **功能**: 初始化ECharts图表
2079
+ - **参数**:
2080
+ - `container: HTMLElement | string` - 容器元素或容器ID
2081
+ - `options: object` - 图表配置项
2082
+ - `renderer: 'canvas' | 'svg'` - 渲染方式,默认 'canvas'
2083
+ - **返回类型**: `Promise<object>` - ECharts实例
2084
+ - **示例**:
2085
+ ```typescript
2086
+ import { init_chart } from '@qy_better_lib/core';
2087
+
2088
+ async function example() {
2089
+ const chart = await init_chart('chart-container', {
2090
+ title: {
2091
+ text: '示例图表'
2092
+ },
2093
+ series: [{
2094
+ type: 'bar',
2095
+ data: [1, 2, 3, 4, 5]
2096
+ }]
2097
+ });
2098
+ }
2099
+ ```
2100
+
2101
+ #### destroy_chart
2102
+ - **功能**: 销毁ECharts图表
2103
+ - **参数**: `chart: object` - ECharts实例
2104
+ - **返回类型**: `void`
2105
+ - **示例**:
2106
+ ```typescript
2107
+ import { destroy_chart } from '@qy_better_lib/core';
2108
+
2109
+ destroy_chart(chart);
2110
+ ```
2111
+
2112
+ #### update_chart
2113
+ - **功能**: 更新ECharts图表配置
2114
+ - **参数**:
2115
+ - `chart: object` - ECharts实例
2116
+ - `options: object` - 图表配置项
2117
+ - **返回类型**: `void`
2118
+ - **示例**:
2119
+ ```typescript
2120
+ import { update_chart } from '@qy_better_lib/core';
2121
+
2122
+ update_chart(chart, {
2123
+ series: [{
2124
+ data: [6, 7, 8, 9, 10]
2125
+ }]
2126
+ });
2127
+ ```
2128
+
2129
+ #### resize_chart
2130
+ - **功能**: 调整ECharts图表大小
2131
+ - **参数**: `chart: object` - ECharts实例
2132
+ - **返回类型**: `void`
2133
+ - **示例**:
2134
+ ```typescript
2135
+ import { resize_chart } from '@qy_better_lib/core';
2136
+
2137
+ resize_chart(chart);
2138
+ ```
2139
+
2140
+ #### make_chart_responsive
2141
+ - **功能**: 为ECharts图表添加响应式处理
2142
+ - **参数**:
2143
+ - `chart: object` - ECharts实例
2144
+ - `debounce_time: number` - 防抖时间,默认 200ms
2145
+ - **返回类型**: `Function` - 清理函数
2146
+ - **示例**:
2147
+ ```typescript
2148
+ import { make_chart_responsive } from '@qy_better_lib/core';
2149
+
2150
+ const cleanup = make_chart_responsive(chart);
2151
+ // 当需要清理时调用
2152
+ // cleanup();
2153
+ ```
2154
+
2155
+ #### generate_chart_colors
2156
+ - **功能**: 生成ECharts颜色数组
2157
+ - **参数**:
2158
+ - `count: number` - 颜色数量
2159
+ - `base_colors: string[]` - 基础颜色数组,默认使用ECharts默认颜色
2160
+ - **返回类型**: `string[]` - 颜色数组
2161
+ - **示例**:
2162
+ ```typescript
2163
+ import { generate_chart_colors } from '@qy_better_lib/core';
2164
+
2165
+ const colors = generate_chart_colors(5);
2166
+ ```
2167
+
2168
+ #### format_chart_label
2169
+ - **功能**: 格式化ECharts数据标签
2170
+ - **参数**:
2171
+ - `value: any` - 数值
2172
+ - `formatter: Function | string` - 格式化函数或格式化模板
2173
+ - **返回类型**: `string` - 格式化后的值
2174
+ - **示例**:
2175
+ ```typescript
2176
+ import { format_chart_label } from '@qy_better_lib/core';
2177
+
2178
+ const label = format_chart_label(100, '{value}元'); // 100元
2179
+ ```
2180
+
2181
+ #### merge_chart_options
2182
+ - **功能**: 合并ECharts配置项
2183
+ - **参数**:
2184
+ - `defaultOption: object` - 默认配置项
2185
+ - `customOption: object` - 自定义配置项
2186
+ - **返回类型**: `object` - 合并后的配置项
2187
+ - **示例**:
2188
+ ```typescript
2189
+ import { merge_chart_options } from '@qy_better_lib/core';
2190
+
2191
+ const options = merge_chart_options(defaultOptions, customOptions);
2192
+ ```
2193
+
2194
+ #### add_chart_listener
2195
+ - **功能**: 为ECharts图表添加事件监听器
2196
+ - **参数**:
2197
+ - `chart: object` - ECharts实例
2198
+ - `eventName: string` - 事件名称
2199
+ - `handler: Function` - 事件处理函数
2200
+ - **返回类型**: `void`
2201
+ - **示例**:
2202
+ ```typescript
2203
+ import { add_chart_listener } from '@qy_better_lib/core';
2204
+
2205
+ add_chart_listener(chart, 'click', (params) => {
2206
+ console.log('图表点击:', params);
2207
+ });
2208
+ ```
2209
+
2210
+ #### remove_chart_listener
2211
+ - **功能**: 移除ECharts图表事件监听器
2212
+ - **参数**:
2213
+ - `chart: object` - ECharts实例
2214
+ - `eventName: string` - 事件名称
2215
+ - `handler: Function` - 事件处理函数
2216
+ - **返回类型**: `void`
2217
+ - **示例**:
2218
+ ```typescript
2219
+ import { remove_chart_listener } from '@qy_better_lib/core';
2220
+
2221
+ remove_chart_listener(chart, 'click', handler);
2222
+ ```
2223
+
2224
+ #### export_chart_image
2225
+ - **功能**: 导出ECharts图表为图片
2226
+ - **参数**:
2227
+ - `chart: object` - ECharts实例
2228
+ - `options: object` - 导出选项
2229
+ - **返回类型**: `string` - 图片URL
2230
+ - **示例**:
2231
+ ```typescript
2232
+ import { export_chart_image } from '@qy_better_lib/core';
2233
+
2234
+ const imageUrl = export_chart_image(chart, {
2235
+ type: 'png',
2236
+ file_name: 'chart'
2237
+ });
2238
+ ```
2239
+
2240
+ #### is_echarts_loaded
2241
+ - **功能**: 检查ECharts是否已加载
2242
+ - **返回类型**: `boolean` - 是否已加载
2243
+ - **示例**:
2244
+ ```typescript
2245
+ import { is_echarts_loaded } from '@qy_better_lib/core';
2246
+
2247
+ if (is_echarts_loaded()) {
2248
+ // ECharts已加载
2249
+ }
2250
+ ```
2251
+
2252
+ #### resize_charts
2253
+ - **功能**: 批量调整ECharts图表大小
2254
+ - **参数**: `charts: object[]` - 图表实例数组
2255
+ - **返回类型**: `void`
2256
+ - **示例**:
2257
+ ```typescript
2258
+ import { resize_charts } from '@qy_better_lib/core';
2259
+
2260
+ resize_charts([chart1, chart2]);
2261
+ ```
2262
+
2263
+ #### destroy_charts
2264
+ - **功能**: 批量销毁ECharts图表
2265
+ - **参数**: `charts: object[]` - 图表实例数组
2266
+ - **返回类型**: `void`
2267
+ - **示例**:
2268
+ ```typescript
2269
+ import { destroy_charts } from '@qy_better_lib/core';
2270
+
2271
+ destroy_charts([chart1, chart2]);
2272
+ ```
2273
+
2274
+ #### sort_chart_data
2275
+ - **功能**: 数据排序函数
2276
+ - **参数**:
2277
+ - `data: any[]` - 原始数据数组
2278
+ - `sort_key: string` - 排序字段名
2279
+ - `order: 'asc' | 'desc'` - 排序顺序,默认 'asc'
2280
+ - **返回类型**: `any[]` - 排序后的数据数组
2281
+ - **示例**:
2282
+ ```typescript
2283
+ import { sort_chart_data } from '@qy_better_lib/core';
2284
+
2285
+ const sortedData = sort_chart_data(data, 'value', 'desc');
2286
+ ```
2287
+
2288
+ #### group_chart_data
2289
+ - **功能**: 数据分组函数
2290
+ - **参数**:
2291
+ - `data: any[]` - 原始数据数组
2292
+ - `group_key: string` - 分组字段名
2293
+ - **返回类型**: `Record<string, any[]>` - 分组后的数据对象
2294
+ - **示例**:
2295
+ ```typescript
2296
+ import { group_chart_data } from '@qy_better_lib/core';
2297
+
2298
+ const groupedData = group_chart_data(data, 'category');
2299
+ ```
2300
+
2301
+ #### aggregate_chart_data
2302
+ - **功能**: 数据聚合函数
2303
+ - **参数**:
2304
+ - `data: any[]` - 原始数据数组
2305
+ - `group_key: string` - 分组字段名
2306
+ - `value_key: string` - 数值字段名
2307
+ - `aggregator: Function` - 聚合函数,默认求和
2308
+ - **返回类型**: `any[]` - 聚合后的数据数组
2309
+ - **示例**:
2310
+ ```typescript
2311
+ import { aggregate_chart_data } from '@qy_better_lib/core';
2312
+
2313
+ const aggregatedData = aggregate_chart_data(data, 'category', 'value');
2314
+ ```
2315
+
2316
+ ### 11. 文件操作工具 (file.ts)
2317
+
2318
+ #### download_file
2319
+ - **功能**: 下载文件
2320
+ - **参数**:
2321
+ - `path: string` - 文件路径
2322
+ - `name?: string` - 文件名
2323
+ - **示例**:
2324
+ ```typescript
2325
+ import { download_file } from '@qy_better_lib/core';
2326
+
2327
+ // 下载文件
2328
+ download_file({ path: 'https://example.com/file.pdf', name: 'document.pdf' });
2329
+ ```
2330
+
2331
+ #### download_files
2332
+ - **功能**: 批量下载文件
2333
+ - **参数**: `file_list: any[]` - 文件列表,每个元素包含url和name属性
2334
+ - **示例**:
2335
+ ```typescript
2336
+ import { download_files } from '@qy_better_lib/core';
2337
+
2338
+ // 批量下载文件
2339
+ download_files([
2340
+ { url: 'https://example.com/file1.pdf', name: 'file1.pdf' },
2341
+ { url: 'https://example.com/file2.pdf', name: 'file2.pdf' }
2342
+ ]);
2343
+ ```
2344
+
2345
+ #### to_base64
2346
+ - **功能**: 将file转换成base64
2347
+ - **参数**: `file: Blob` - 文件对象
2348
+ - **返回类型**: `Promise<string | undefined>` - base64字符串
2349
+ - **示例**:
2350
+ ```typescript
2351
+ import { to_base64 } from '@qy_better_lib/core';
2352
+
2353
+ async function example() {
2354
+ const file = document.querySelector('input[type="file"]').files[0];
2355
+ const base64 = await to_base64(file);
2356
+ console.log(base64);
2357
+ }
2358
+ ```
2359
+
2360
+ #### read_file
2361
+ - **功能**: 读取文件内容
2362
+ - **参数**:
2363
+ - `file: Blob` - 文件对象
2364
+ - `encoding: string` - 编码方式,默认为 UTF-8
2365
+ - **返回类型**: `Promise<string | undefined>` - 文件内容
2366
+ - **示例**:
2367
+ ```typescript
2368
+ import { read_file } from '@qy_better_lib/core';
2369
+
2370
+ async function example() {
2371
+ const file = document.querySelector('input[type="file"]').files[0];
2372
+ const content = await read_file(file);
2373
+ console.log(content);
2374
+ }
2375
+ ```
2376
+
2377
+ #### get_file_extension
2378
+ - **功能**: 获取文件扩展名
2379
+ - **参数**: `file_name: string` - 文件名
2380
+ - **返回类型**: `string` - 文件扩展名
2381
+ - **示例**:
2382
+ ```typescript
2383
+ import { get_file_extension } from '@qy_better_lib/core';
2384
+
2385
+ const ext = get_file_extension('example.jpg'); // 'jpg'
2386
+ ```
2387
+
2388
+ #### get_file_name_without_extension
2389
+ - **功能**: 获取不带扩展名的文件名
2390
+ - **参数**: `file_name: string` - 文件名
2391
+ - **返回类型**: `string` - 不带扩展名的文件名
2392
+ - **示例**:
2393
+ ```typescript
2394
+ import { get_file_name_without_extension } from '@qy_better_lib/core';
2395
+
2396
+ const name = get_file_name_without_extension('example.jpg'); // 'example'
2397
+ ```
2398
+
2399
+ #### validate_file_size
2400
+ - **功能**: 验证文件大小
2401
+ - **参数**:
2402
+ - `file: File` - 文件对象
2403
+ - `max_size: number` - 最大文件大小(字节)
2404
+ - **返回类型**: `boolean` - 是否符合大小要求
2405
+ - **示例**:
2406
+ ```typescript
2407
+ import { validate_file_size } from '@qy_better_lib/core';
2408
+
2409
+ const file = document.querySelector('input[type="file"]').files[0];
2410
+ const isValid = validate_file_size(file, 1024 * 1024); // 1MB
2411
+ console.log(isValid);
2412
+ ```
2413
+
2414
+ #### validate_file_type
2415
+ - **功能**: 验证文件类型
2416
+ - **参数**:
2417
+ - `file: File` - 文件对象
2418
+ - `allowed_types: string[]` - 允许的文件类型数组
2419
+ - **返回类型**: `boolean` - 是否符合类型要求
2420
+ - **示例**:
2421
+ ```typescript
2422
+ import { validate_file_type } from '@qy_better_lib/core';
2423
+
2424
+ const file = document.querySelector('input[type="file"]').files[0];
2425
+ const isValid = validate_file_type(file, ['jpg', 'png', 'gif']);
2426
+ console.log(isValid);
2427
+ ```
2428
+
2429
+ #### create_file_from_blob
2430
+ - **功能**: 从 Blob 创建文件
2431
+ - **参数**:
2432
+ - `blob: Blob` - Blob 对象
2433
+ - `file_name: string` - 文件名
2434
+ - `mime_type: string` - MIME 类型
2435
+ - **返回类型**: `File` - 文件对象
2436
+ - **示例**:
2437
+ ```typescript
2438
+ import { create_file_from_blob } from '@qy_better_lib/core';
2439
+
2440
+ const blob = new Blob(['Hello'], { type: 'text/plain' });
2441
+ const file = create_file_from_blob(blob, 'example.txt', 'text/plain');
2442
+ ```
2443
+
2444
+ #### download_text_file
2445
+ - **功能**: 下载文本文件
2446
+ - **参数**:
2447
+ - `content: string` - 文件内容
2448
+ - `file_name: string` - 文件名
2449
+ - `mime_type: string` - MIME 类型,默认为 text/plain
2450
+ - **示例**:
2451
+ ```typescript
2452
+ import { download_text_file } from '@qy_better_lib/core';
2453
+
2454
+ // 下载文本文件
2455
+ download_text_file('Hello World', 'example.txt');
2456
+ ```
2457
+
2458
+ #### compress_image
2459
+ - **功能**: 压缩图片文件
2460
+ - **参数**:
2461
+ - `file: File` - 图片文件
2462
+ - `max_width: number` - 最大宽度,默认 800
2463
+ - `max_height: number` - 最大高度,默认 800
2464
+ - `quality: number` - 压缩质量,0-1之间,默认 0.8
2465
+ - **返回类型**: `Promise<File | undefined>` - 压缩后的文件
2466
+ - **示例**:
2467
+ ```typescript
2468
+ import { compress_image } from '@qy_better_lib/core';
2469
+
2470
+ async function example() {
2471
+ const file = document.querySelector('input[type="file"]').files[0];
2472
+ const compressedFile = await compress_image(file, 1024, 1024, 0.7);
2473
+ console.log(compressedFile);
2474
+ }
2475
+ ```
2476
+
2477
+ #### get_file_info
2478
+ - **功能**: 获取文件信息
2479
+ - **参数**: `file: File` - 文件对象
2480
+ - **返回类型**: `object` - 文件信息对象
2481
+ - **示例**:
2482
+ ```typescript
2483
+ import { get_file_info } from '@qy_better_lib/core';
2484
+
2485
+ const file = document.querySelector('input[type="file"]').files[0];
2486
+ const info = get_file_info(file);
2487
+ console.log(info);
2488
+ ```
2489
+
2490
+ #### generate_unique_file_name
2491
+ - **功能**: 生成唯一的文件名
2492
+ - **参数**: `original_name: string` - 原始文件名
2493
+ - **返回类型**: `string` - 唯一的文件名
2494
+ - **示例**:
2495
+ ```typescript
2496
+ import { generate_unique_file_name } from '@qy_better_lib/core';
2497
+
2498
+ const uniqueName = generate_unique_file_name('example.jpg');
2499
+ console.log(uniqueName);
2500
+ ```
2501
+
2502
+ ### 12. 树形数据工具 (tree.ts)
2503
+
2504
+ #### tree_flat
2505
+ - **功能**: 树形数据扁平化处理
2506
+ - **参数**:
2507
+ - `data: TreeNode[]` - 树形数据数组
2508
+ - `key: string` - key属性,默认"key"
2509
+ - `children: string` - children属性,默认"children"
2510
+ - **返回类型**: `Record<string, TreeNode>` - 扁平化的树形数据映射
2511
+ - **示例**:
2512
+ ```typescript
2513
+ import { tree_flat } from '@qy_better_lib/core';
2514
+
2515
+ const tree = [
2516
+ {
2517
+ key: '1',
2518
+ name: '节点1',
2519
+ children: [
2520
+ { key: '1-1', name: '节点1-1' }
2521
+ ]
2522
+ }
2523
+ ];
2524
+ const flattened = tree_flat(tree);
2525
+ console.log(flattened); // { '1': { ... }, '1-1': { ... } }
2526
+ ```
2527
+
2528
+ #### build_tree
2529
+ - **功能**: 从扁平化数据构建树形结构
2530
+ - **参数**:
2531
+ - `data: TreeNode[]` - 扁平化数据数组
2532
+ - `key: string` - key属性,默认"key"
2533
+ - `parent_key: string` - 父节点key属性,默认"parentId"
2534
+ - `children: string` - children属性,默认"children"
2535
+ - **返回类型**: `TreeNode[]` - 树形数据
2536
+ - **示例**:
2537
+ ```typescript
2538
+ import { build_tree } from '@qy_better_lib/core';
2539
+
2540
+ const data = [
2541
+ { key: '1', name: '节点1', parentId: null },
2542
+ { key: '1-1', name: '节点1-1', parentId: '1' }
2543
+ ];
2544
+ const tree = build_tree(data);
2545
+ console.log(tree);
2546
+ ```
2547
+
2548
+ #### traverse_tree_depth_first
2549
+ - **功能**: 深度优先遍历树形数据
2550
+ - **参数**:
2551
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2552
+ - `callback: (node: TreeNode, depth: number) => boolean | void` - 回调函数,返回false可中断遍历
2553
+ - `children: string` - children属性,默认"children"
2554
+ - **返回类型**: `boolean` - 是否提前中断了遍历
2555
+ - **示例**:
2556
+ ```typescript
2557
+ import { traverse_tree_depth_first } from '@qy_better_lib/core';
2558
+
2559
+ traverse_tree_depth_first(tree, (node, depth) => {
2560
+ console.log('深度:', depth, '节点:', node.name);
2561
+ // 返回 false 可中断遍历
2562
+ });
2563
+ ```
2564
+
2565
+ #### traverse_tree_breadth_first
2566
+ - **功能**: 广度优先遍历树形数据
2567
+ - **参数**:
2568
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2569
+ - `callback: (node: TreeNode, depth: number) => boolean | void` - 回调函数,返回false可中断遍历
2570
+ - `children: string` - children属性,默认"children"
2571
+ - **返回类型**: `boolean` - 是否提前中断了遍历
2572
+ - **示例**:
2573
+ ```typescript
2574
+ import { traverse_tree_breadth_first } from '@qy_better_lib/core';
2575
+
2576
+ traverse_tree_breadth_first(tree, (node, depth) => {
2577
+ console.log('深度:', depth, '节点:', node.name);
2578
+ });
2579
+ ```
2580
+
2581
+ #### find_tree_node
2582
+ - **功能**: 根据条件查找树形节点
2583
+ - **参数**:
2584
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2585
+ - `predicate: (node: TreeNode) => boolean` - 条件函数
2586
+ - `children: string` - children属性,默认"children"
2587
+ - **返回类型**: `TreeNode | null` - 找到的节点或null
2588
+ - **示例**:
2589
+ ```typescript
2590
+ import { find_tree_node } from '@qy_better_lib/core';
2591
+
2592
+ const node = find_tree_node(tree, (node) => node.name === '节点1-1');
2593
+ console.log(node);
2594
+ ```
2595
+
2596
+ #### find_tree_node_by_key
2597
+ - **功能**: 根据key查找树形节点
2598
+ - **参数**:
2599
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2600
+ - `key_value: any` - key值
2601
+ - `key: string` - key属性,默认"key"
2602
+ - `children: string` - children属性,默认"children"
2603
+ - **返回类型**: `TreeNode | null` - 找到的节点或null
2604
+ - **示例**:
2605
+ ```typescript
2606
+ import { find_tree_node_by_key } from '@qy_better_lib/core';
2607
+
2608
+ const node = find_tree_node_by_key(tree, '1-1', 'key');
2609
+ console.log(node);
2610
+ ```
2611
+
2612
+ #### filter_tree
2613
+ - **功能**: 过滤树形数据
2614
+ - **参数**:
2615
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2616
+ - `predicate: (node: TreeNode) => boolean` - 过滤条件
2617
+ - `children: string` - children属性,默认"children"
2618
+ - **返回类型**: `TreeNode[]` - 过滤后的树形数据
2619
+ - **示例**:
2620
+ ```typescript
2621
+ import { filter_tree } from '@qy_better_lib/core';
2622
+
2623
+ const filtered = filter_tree(tree, (node) => node.name.includes('1'));
2624
+ console.log(filtered);
2625
+ ```
2626
+
2627
+ #### transform_tree
2628
+ - **功能**: 转换树形数据结构
2629
+ - **参数**:
2630
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2631
+ - `transform: (node: TreeNode) => TreeNode` - 转换函数
2632
+ - `children: string` - children属性,默认"children"
2633
+ - **返回类型**: `TreeNode[]` - 转换后的树形数据
2634
+ - **示例**:
2635
+ ```typescript
2636
+ import { transform_tree } from '@qy_better_lib/core';
2637
+
2638
+ const transformed = transform_tree(tree, (node) => ({
2639
+ ...node,
2640
+ label: node.name,
2641
+ value: node.key
2642
+ }));
2643
+ console.log(transformed);
2644
+ ```
2645
+
2646
+ #### add_tree_node_path
2647
+ - **功能**: 为树形节点添加路径信息
2648
+ - **参数**:
2649
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2650
+ - `key: string` - key属性,默认"key"
2651
+ - `path: string` - path属性,默认"path"
2652
+ - `children: string` - children属性,默认"children"
2653
+ - **返回类型**: `TreeNode[]` - 添加了路径信息的树形数据
2654
+ - **示例**:
2655
+ ```typescript
2656
+ import { add_tree_node_path } from '@qy_better_lib/core';
2657
+
2658
+ const treeWithPath = add_tree_node_path(tree);
2659
+ console.log(treeWithPath[0].path); // 路径信息,如 "1"
2660
+ ```
2661
+
2662
+ #### get_tree_node_descendants
2663
+ - **功能**: 获取树形节点的所有后代
2664
+ - **参数**:
2665
+ - `node: TreeNode` - 树形节点
2666
+ - `children: string` - children属性,默认"children"
2667
+ - **返回类型**: `TreeNode[]` - 所有后代节点数组
2668
+ - **示例**:
2669
+ ```typescript
2670
+ import { get_tree_node_descendants } from '@qy_better_lib/core';
2671
+
2672
+ const rootNode = tree[0];
2673
+ const descendants = get_tree_node_descendants(rootNode);
2674
+ console.log(descendants);
2675
+ ```
2676
+
2677
+ #### get_tree_node_ancestors
2678
+ - **功能**: 获取树形节点的所有祖先
2679
+ - **参数**:
2680
+ - `node: TreeNode` - 树形节点
2681
+ - `parent: string` - parent属性,默认"parent"
2682
+ - **返回类型**: `TreeNode[]` - 所有祖先节点数组
2683
+ - **示例**:
2684
+ ```typescript
2685
+ import { get_tree_node_ancestors } from '@qy_better_lib/core';
2686
+
2687
+ // 假设节点有parent属性指向父节点
2688
+ const childNode = tree[0].children[0];
2689
+ const ancestors = get_tree_node_ancestors(childNode);
2690
+ console.log(ancestors);
2691
+ ```
2692
+
2693
+ #### get_tree_depth
2694
+ - **功能**: 计算树形数据的深度
2695
+ - **参数**:
2696
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2697
+ - `children: string` - children属性,默认"children"
2698
+ - **返回类型**: `number` - 树形数据的深度
2699
+ - **示例**:
2700
+ ```typescript
2701
+ import { get_tree_depth } from '@qy_better_lib/core';
2702
+
2703
+ const depth = get_tree_depth(tree);
2704
+ console.log(depth);
2705
+ ```
2706
+
2707
+ #### flatten_tree_to_array
2708
+ - **功能**: 扁平化树形数据为数组
2709
+ - **参数**:
2710
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2711
+ - `children: string` - children属性,默认"children"
2712
+ - **返回类型**: `TreeNode[]` - 扁平化的节点数组
2713
+ - **示例**:
2714
+ ```typescript
2715
+ import { flatten_tree_to_array } from '@qy_better_lib/core';
2716
+
2717
+ const array = flatten_tree_to_array(tree);
2718
+ console.log(array);
2719
+ ```
2720
+
2721
+ #### add_tree_node
2722
+ - **功能**: 向树形结构添加节点
2723
+ - **参数**:
2724
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2725
+ - `parent_key: any` - 父节点key值
2726
+ - `new_node: TreeNode` - 新节点
2727
+ - `key: string` - key属性,默认"key"
2728
+ - `children: string` - children属性,默认"children"
2729
+ - **返回类型**: `TreeNode[]` - 更新后的树形数据
2730
+ - **示例**:
2731
+ ```typescript
2732
+ import { add_tree_node } from '@qy_better_lib/core';
2733
+
2734
+ const newNode = { key: '1-2', name: '节点1-2' };
2735
+ const newTree = add_tree_node(tree, '1', newNode);
2736
+ console.log(newTree);
2737
+ ```
2738
+
2739
+ #### remove_tree_node
2740
+ - **功能**: 从树形结构移除节点
2741
+ - **参数**:
2742
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2743
+ - `node_key: any` - 要移除的节点key值
2744
+ - `key: string` - key属性,默认"key"
2745
+ - `children: string` - children属性,默认"children"
2746
+ - **返回类型**: `TreeNode[]` - 更新后的树形数据
2747
+ - **示例**:
2748
+ ```typescript
2749
+ import { remove_tree_node } from '@qy_better_lib/core';
2750
+
2751
+ const newTree = remove_tree_node(tree, '1-1');
2752
+ console.log(newTree);
2753
+ ```
2754
+
2755
+ #### update_tree_node
2756
+ - **功能**: 更新树形结构中的节点
2757
+ - **参数**:
2758
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2759
+ - `node_key: any` - 要更新的节点key值
2760
+ - `updates: Partial<TreeNode>` - 要更新的属性
2761
+ - `key: string` - key属性,默认"key"
2762
+ - `children: string` - children属性,默认"children"
2763
+ - **返回类型**: `TreeNode[]` - 更新后的树形数据
2764
+ - **示例**:
2765
+ ```typescript
2766
+ import { update_tree_node } from '@qy_better_lib/core';
2767
+
2768
+ const newTree = update_tree_node(tree, '1', { name: '更新的节点1' });
2769
+ console.log(newTree);
2770
+ ```
2771
+
2772
+ #### sort_tree
2773
+ - **功能**: 对树形结构进行排序
2774
+ - **参数**:
2775
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2776
+ - `compare_fn: ((a: TreeNode, b: TreeNode) => number) | string` - 比较函数或属性名
2777
+ - `recursive: boolean` - 是否递归排序所有层级,默认true
2778
+ - `children: string` - children属性,默认"children"
2779
+ - **返回类型**: `TreeNode[]` - 排序后的树形数据
2780
+ - **示例**:
2781
+ ```typescript
2782
+ import { sort_tree } from '@qy_better_lib/core';
2783
+
2784
+ // 使用比较函数排序
2785
+ const sortedTree = sort_tree(tree, (a, b) => a.name.localeCompare(b.name));
2786
+
2787
+ // 使用属性名排序
2788
+ const sortedTree2 = sort_tree(tree, 'name');
2789
+ console.log(sortedTree);
2790
+ ```
2791
+
2792
+ #### clone_tree
2793
+ - **功能**: 克隆树形结构
2794
+ - **参数**:
2795
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2796
+ - `children: string` - children属性,默认"children"
2797
+ - **返回类型**: `TreeNode[]` - 克隆后的树形数据
2798
+ - **示例**:
2799
+ ```typescript
2800
+ import { clone_tree } from '@qy_better_lib/core';
2801
+
2802
+ const clonedTree = clone_tree(tree);
2803
+ console.log(clonedTree);
2804
+ ```
2805
+
2806
+ #### validate_tree
2807
+ - **功能**: 验证树形结构的有效性
2808
+ - **参数**:
2809
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2810
+ - `key: string` - key属性,默认"key"
2811
+ - `children: string` - children属性,默认"children"
2812
+ - **返回类型**: `{ valid: boolean; errors: string[] }` - 验证结果,包含是否有效和错误信息
2813
+ - **示例**:
2814
+ ```typescript
2815
+ import { validate_tree } from '@qy_better_lib/core';
2816
+
2817
+ const result = validate_tree(tree);
2818
+ console.log(result.valid); // 是否有效
2819
+ console.log(result.errors); // 错误信息
2820
+ ```
2821
+
2822
+ #### search_tree
2823
+ - **功能**: 在树形结构中搜索节点
2824
+ - **参数**:
2825
+ - `tree: TreeNode | TreeNode[]` - 树形数据
2826
+ - `predicate: ((node: TreeNode) => boolean) | Record<string, any>` - 搜索条件函数或属性值对
2827
+ - `children: string` - children属性,默认"children"
2828
+ - **返回类型**: `TreeNode[]` - 所有匹配的节点数组
2829
+ - **示例**:
2830
+ ```typescript
2831
+ import { search_tree } from '@qy_better_lib/core';
2832
+
2833
+ // 使用函数搜索
2834
+ const results = search_tree(tree, (node) => node.name.includes('1'));
2835
+
2836
+ // 使用对象搜索
2837
+ const results2 = search_tree(tree, { name: '节点1' });
2838
+ console.log(results);
2839
+ ```
2840
+
2841
+ ## 指令功能 (directives)
2842
+
2843
+ ### 1. 点击外部区域指令 (click_outside.ts)
2844
+
2845
+ #### 功能描述
2846
+ 当点击元素外部区域时触发绑定的回调函数,可用于实现下拉菜单、弹窗等组件的关闭功能。
2847
+
2848
+ #### 指令参数
2849
+ - **value**: `Function` - 点击外部区域时触发的回调函数
2850
+ - **arg**: `HTMLElement | HTMLElement[]` - 可选,需要排除的元素或元素数组
2851
+
2852
+ #### 使用示例
2853
+
2854
+ **基本用法**
2855
+ ```vue
2856
+ <template>
2857
+ <div v-click-outside="handleClickOutside">
2858
+ 点击外部区域会触发回调
2859
+ </div>
2860
+ </template>
2861
+
2862
+ <script setup lang="ts">
2863
+ import { ref } from 'vue';
2864
+
2865
+ const handleClickOutside = () => {
2866
+ console.log('点击了外部区域');
2867
+ };
2868
+ </script>
2869
+ ```
2870
+
2871
+ **带排除元素**
2872
+ ```vue
2873
+ <template>
2874
+ <div>
2875
+ <div ref="excludeElement">
2876
+ 点击此区域不会触发外部点击回调
2877
+ </div>
2878
+ <div v-click-outside:[excludeElement]="handleClickOutside">
2879
+ 点击外部区域会触发回调,但点击上方排除元素不会
2880
+ </div>
2881
+ </div>
2882
+ </template>
2883
+
2884
+ <script setup lang="ts">
2885
+ import { ref } from 'vue';
2886
+
2887
+ const excludeElement = ref<HTMLElement | null>(null);
2888
+
2889
+ const handleClickOutside = () => {
2890
+ console.log('点击了外部区域');
2891
+ };
2892
+ </script>
2893
+ ```
2894
+
2895
+ **带多个排除元素**
2896
+ ```vue
2897
+ <template>
2898
+ <div>
2899
+ <div ref="excludeElement1">
2900
+ 排除元素 1
2901
+ </div>
2902
+ <div ref="excludeElement2">
2903
+ 排除元素 2
2904
+ </div>
2905
+ <div v-click-outside:[excludeElements]="handleClickOutside">
2906
+ 点击外部区域会触发回调,但点击排除元素不会
2907
+ </div>
2908
+ </div>
2909
+ </template>
2910
+
2911
+ <script setup lang="ts">
2912
+ import { ref, computed } from 'vue';
2913
+
2914
+ const excludeElement1 = ref<HTMLElement | null>(null);
2915
+ const excludeElement2 = ref<HTMLElement | null>(null);
2916
+
2917
+ const excludeElements = computed(() => [
2918
+ excludeElement1.value,
2919
+ excludeElement2.value
2920
+ ]);
2921
+
2922
+ const handleClickOutside = () => {
2923
+ console.log('点击了外部区域');
2924
+ };
2925
+ </script>
2926
+ ```
2927
+
2928
+ #### 注册指令
2929
+
2930
+ 在 Vue 应用中注册指令:
2931
+
2932
+ ```typescript
2933
+ import { createApp } from 'vue';
2934
+ import App from './App.vue';
2935
+ import { setupDirectives } from '@qy_better_lib/core';
2936
+
2937
+ const app = createApp(App);
2938
+
2939
+ // 注册所有指令
2940
+ setupDirectives(app);
2941
+
2942
+ app.mount('#app');
2943
+ ```
2944
+
2945
+