web-component-gallery 2.3.12 → 2.3.14

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/utils/Filter.js CHANGED
@@ -1,16 +1,98 @@
1
1
  /**
2
- * 获取 n 天前的时间
2
+ * 格式化日期
3
+ * @param {string|number|Date} time - 时间
4
+ * @param {string} cFormat - 格式化模板
5
+ * {y}年 {m}月 {d}日 {h}时 {i}分 {s}秒 {a}星期 {q}季度
6
+ * @returns {string|null} 格式化后的日期字符串
7
+ */
8
+ export function formatDate(time, cFormat) {
9
+ if (arguments.length === 0 || !time) return null
10
+
11
+ const format = cFormat || "{y}-{m}-{d} {h}:{i}:{s}"
12
+ let date
13
+
14
+ if (typeof time === "object") {
15
+ date = time
16
+ } else {
17
+ let timestamp = time
18
+
19
+ if (typeof timestamp === "string") {
20
+ timestamp = /^[0-9]+$/.test(timestamp)
21
+ ? parseInt(timestamp)
22
+ : timestamp.replace(/-/g, "/")
23
+ }
24
+
25
+ if (typeof timestamp === "number" && timestamp.toString().length === 10) {
26
+ timestamp *= 1000
27
+ }
28
+
29
+ date = new Date(timestamp)
30
+ }
31
+
32
+ if (isNaN(date.getTime())) {
33
+ console.warn('无效的日期格式')
34
+ return null
35
+ }
36
+
37
+ const formatObj = {
38
+ y: date.getFullYear(),
39
+ m: date.getMonth() + 1,
40
+ d: date.getDate(),
41
+ h: date.getHours(),
42
+ i: date.getMinutes(),
43
+ s: date.getSeconds(),
44
+ a: date.getDay(),
45
+ q: Math.floor((date.getMonth() + 3) / 3),
46
+ }
47
+
48
+ const timeStr = format.replace(/{([ymdhisaq])+}/g, (result, key) => {
49
+ const value = formatObj[key]
50
+
51
+ if (key === "a") {
52
+ return ["日", "一", "二", "三", "四", "五", "六"][value]
53
+ }
54
+
55
+ return String(value).padStart(2, "0")
56
+ })
57
+
58
+ return timeStr
59
+ }
60
+
61
+ /**
62
+ * 获取相对时间(通用函数)
3
63
  * @param {number} n - 数量
64
+ * @param {string} unit - 单位:'days'|'hours'|'minutes'|'seconds'
65
+ * @param {boolean} isBefore - 是否之前
4
66
  * @param {string|Date} baseTime - 基准时间(可选)
5
67
  * @param {string} cFormat - 格式化模板
6
68
  * @returns {string} 格式化日期
7
69
  */
8
- export function getNDaysBefore(n, baseTime = null, cFormat) {
70
+ export function getRelativeTime(n, unit = 'days', isBefore = true, baseTime = null, cFormat) {
9
71
  const base = baseTime ? new Date(baseTime) : new Date()
10
- const targetTime = new Date(base.getTime() - n * 24 * 60 * 60 * 1000)
72
+ const multipliers = {
73
+ days: 24 * 60 * 60 * 1000,
74
+ hours: 60 * 60 * 1000,
75
+ minutes: 60 * 1000,
76
+ seconds: 1000
77
+ }
78
+
79
+ const diff = n * (multipliers[unit] || multipliers.days)
80
+ const targetTime = new Date(base.getTime() + (isBefore ? -diff : diff))
81
+
11
82
  return formatDate(targetTime, cFormat)
12
83
  }
13
84
 
85
+ /**
86
+ * 获取 n 天前的时间
87
+ * @param {number} n - 数量
88
+ * @param {string|Date} baseTime - 基准时间(可选)
89
+ * @param {string} cFormat - 格式化模板
90
+ * @returns {string} 格式化日期
91
+ */
92
+ export function getNDaysBefore(n, baseTime = null, cFormat) {
93
+ return getRelativeTime(n, 'days', true, baseTime, cFormat)
94
+ }
95
+
14
96
  /**
15
97
  * 获取 n 小时前的时间
16
98
  * @param {number} n - 小时数
@@ -19,9 +101,7 @@ export function getNDaysBefore(n, baseTime = null, cFormat) {
19
101
  * @returns {string} 格式化日期
20
102
  */
21
103
  export function getNHoursBefore(n, baseTime = null, cFormat) {
22
- const base = baseTime ? new Date(baseTime) : new Date()
23
- const targetTime = new Date(base.getTime() - n * 60 * 60 * 1000)
24
- return formatDate(targetTime, cFormat)
104
+ return getRelativeTime(n, 'hours', true, baseTime, cFormat)
25
105
  }
26
106
 
27
107
  /**
@@ -32,9 +112,7 @@ export function getNHoursBefore(n, baseTime = null, cFormat) {
32
112
  * @returns {string} 格式化日期
33
113
  */
34
114
  export function getNMinutesBefore(n, baseTime = null, cFormat) {
35
- const base = baseTime ? new Date(baseTime) : new Date()
36
- const targetTime = new Date(base.getTime() - n * 60 * 1000)
37
- return formatDate(targetTime, cFormat)
115
+ return getRelativeTime(n, 'minutes', true, baseTime, cFormat)
38
116
  }
39
117
 
40
118
  /**
@@ -45,9 +123,7 @@ export function getNMinutesBefore(n, baseTime = null, cFormat) {
45
123
  * @returns {string} 格式化日期
46
124
  */
47
125
  export function getNSecondsBefore(n, baseTime = null, cFormat) {
48
- const base = baseTime ? new Date(baseTime) : new Date()
49
- const targetTime = new Date(base.getTime() - n * 1000)
50
- return formatDate(targetTime, cFormat)
126
+ return getRelativeTime(n, 'seconds', true, baseTime, cFormat)
51
127
  }
52
128
 
53
129
  /**
@@ -58,9 +134,7 @@ export function getNSecondsBefore(n, baseTime = null, cFormat) {
58
134
  * @returns {string} 格式化日期
59
135
  */
60
136
  export function getNDaysAfter(n, baseTime = null, cFormat) {
61
- const base = baseTime ? new Date(baseTime) : new Date()
62
- const targetTime = new Date(base.getTime() + n * 24 * 60 * 60 * 1000)
63
- return formatDate(targetTime, cFormat)
137
+ return getRelativeTime(n, 'days', false, baseTime, cFormat)
64
138
  }
65
139
 
66
140
  /**
@@ -71,75 +145,7 @@ export function getNDaysAfter(n, baseTime = null, cFormat) {
71
145
  * @returns {string} 格式化日期
72
146
  */
73
147
  export function getNHoursAfter(n, baseTime = null, cFormat) {
74
- const base = baseTime ? new Date(baseTime) : new Date()
75
- const targetTime = new Date(base.getTime() + n * 60 * 60 * 1000)
76
- return formatDate(targetTime, cFormat)
77
- }
78
-
79
- /**
80
- * 格式化日期
81
- * @param {string|number|Date} time - 时间
82
- * @param {string} cFormat - 格式化模板
83
- * {y}年 {m}月 {d}日 {h}时 {i}分 {s}秒 {a}星期 {q}季度
84
- * @returns {string|null} 格式化后的日期字符串
85
- */
86
- export function formatDate(time, cFormat) {
87
- if (arguments.length === 0 || !time) return null
88
-
89
- const format = cFormat || "{y}-{m}-{d} {h}:{i}:{s}"
90
- let date
91
-
92
- // 处理不同类型的输入
93
- if (typeof time === "object") {
94
- date = time
95
- } else {
96
- let timestamp = time
97
-
98
- // 字符串处理
99
- if (typeof timestamp === "string") {
100
- timestamp = /^[0-9]+$/.test(timestamp)
101
- ? parseInt(timestamp)
102
- : timestamp.replace(/-/g, "/")
103
- }
104
-
105
- // 10 位时间戳转毫秒
106
- if (typeof timestamp === "number" && timestamp.toString().length === 10) {
107
- timestamp *= 1000
108
- }
109
-
110
- date = new Date(timestamp)
111
- }
112
-
113
- // 验证日期有效性
114
- if (isNaN(date.getTime())) {
115
- console.warn('无效的日期格式')
116
- return null
117
- }
118
-
119
- const formatObj = {
120
- y: date.getFullYear(),
121
- m: date.getMonth() + 1,
122
- d: date.getDate(),
123
- h: date.getHours(),
124
- i: date.getMinutes(),
125
- s: date.getSeconds(),
126
- a: date.getDay(),
127
- q: Math.floor((date.getMonth() + 3) / 3), // 季度
128
- }
129
-
130
- const timeStr = format.replace(/{([ymdhisaq])+}/g, (result, key) => {
131
- const value = formatObj[key]
132
-
133
- // 星期处理
134
- if (key === "a") {
135
- return ["日", "一", "二", "三", "四", "五", "六"][value]
136
- }
137
-
138
- // 补零处理
139
- return String(value).padStart(2, "0")
140
- })
141
-
142
- return timeStr
148
+ return getRelativeTime(n, 'hours', false, baseTime, cFormat)
143
149
  }
144
150
 
145
151
  /**
@@ -151,7 +157,6 @@ export function formatDate(time, cFormat) {
151
157
  export function formatTimestamp(timestamp, format) {
152
158
  if (!timestamp) return null
153
159
 
154
- // 10 位时间戳转毫秒
155
160
  if (String(timestamp).length === 10) {
156
161
  timestamp *= 1000
157
162
  }
@@ -163,7 +168,7 @@ export function formatTimestamp(timestamp, format) {
163
168
  * 计算两个日期之间的差异
164
169
  * @param {string|Date} date1 - 日期 1
165
170
  * @param {string|Date} date2 - 日期 2
166
- * @returns {Object} 差异对象 {days, hours, minutes, seconds, milliseconds}
171
+ * @returns {Object} 差异对象
167
172
  */
168
173
  export function dateDiff(date1, date2) {
169
174
  const d1 = new Date(date1)
@@ -204,28 +209,27 @@ export function getDaysInMonth(year, month) {
204
209
  /**
205
210
  * 颜色十六进制转 RGB/RGBA
206
211
  * @param {string} sHex - 十六进制色值
207
- * @param {number} alpha - 透明度
208
- * @returns {string} rgba(r,g,b,a) 格式字符串
212
+ * @param {number} [alpha] - 透明度(0-1)
213
+ * @returns {string} rgba(r,g,b,a) 或 rgb(r,g,b) 格式字符串
209
214
  */
210
215
  export function colorRgba(sHex, alpha) {
211
216
  const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
212
217
  let sColor = sHex.toLowerCase()
213
218
 
214
219
  if (sColor && reg.test(sColor)) {
215
- // 简写形式转为完整形式 #fff -> #ffffff
216
220
  if (sColor.length === 4) {
217
221
  sColor = "#" + [1, 2, 3].map(i =>
218
222
  sColor.slice(i, i + 1).repeat(2)
219
223
  ).join("")
220
224
  }
221
225
 
222
- // 提取 RGB 值
223
226
  const rgbValues = []
224
227
  for (let i = 1; i < 7; i += 2) {
225
228
  rgbValues.push(parseInt(`0x${sColor.slice(i, i + 2)}`))
226
229
  }
227
230
 
228
- return alpha !== undefined
231
+ // 修复:使用 alpha == null 检查(同时排除 undefined 和 null)
232
+ return (alpha != null)
229
233
  ? `rgba(${rgbValues.join(",")},${alpha})`
230
234
  : `rgb(${rgbValues.join(",")})`
231
235
  }
@@ -258,7 +262,6 @@ export function randomColor(full = false) {
258
262
  return '#' + Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0')
259
263
  }
260
264
 
261
- // 生成柔和的彩色
262
265
  const hue = Math.floor(Math.random() * 360)
263
266
  const saturation = 70 + Math.floor(Math.random() * 20)
264
267
  const lightness = 60 + Math.floor(Math.random() * 20)
@@ -305,14 +308,12 @@ export function hslToHex(h, s, l) {
305
308
  * @returns {Array} [百分比数组,数值数组]
306
309
  */
307
310
  export function produceDataSeriesEx(segment, total, baseValue) {
308
- // 生成分段百分比
309
311
  const percentArray = new Array(segment).fill(0)
310
312
  for (let i = 0; i < total; i++) {
311
313
  const randomIndex = Math.floor(Math.random() * segment)
312
314
  percentArray[randomIndex]++
313
315
  }
314
316
 
315
- // 计算对应数值
316
317
  const valueArray = percentArray.map(percent =>
317
318
  Math.floor(percent / 100 * baseValue)
318
319
  )
@@ -321,7 +322,7 @@ export function produceDataSeriesEx(segment, total, baseValue) {
321
322
  }
322
323
 
323
324
  /**
324
- * 深拷贝
325
+ * 深拷贝(增强版)
325
326
  * @param {*} obj - 要拷贝的对象
326
327
  * @returns {*} 深拷贝后的结果
327
328
  */
@@ -334,6 +335,10 @@ export function deepClone(obj) {
334
335
  return new Date(obj.getTime())
335
336
  }
336
337
 
338
+ if (obj instanceof RegExp) {
339
+ return new RegExp(obj.source, obj.flags)
340
+ }
341
+
337
342
  if (obj instanceof Array) {
338
343
  return obj.reduce((arr, item) => {
339
344
  arr.push(deepClone(item))
@@ -347,55 +352,43 @@ export function deepClone(obj) {
347
352
  return newObj
348
353
  }, {})
349
354
  }
355
+
356
+ return obj
350
357
  }
351
358
 
352
359
  /**
353
360
  * 数据类型转换工具函数
354
361
  * @param {*} data - 原始数据
355
- * @param {string|Object|null} format - 目标类型或转换配置对象
362
+ * @param {string|Object|null} format - 目标类型或转换配置
356
363
  * - 字符串:'String'|'Number'|'Boolean'|'Array'|'Object'
357
- * - 对象:转换映射配置 {key: type}
358
- * - null/undefined:智能自动转换
364
+ * - 对象:映射配置 {key: type}
365
+ * - 数组:字段配置 [{ fields: ['a'], type: 'Number' }]
366
+ * - null:智能转换
359
367
  * @param {Object} options - 配置选项
360
- * @param {boolean} options.useDefault - 转换不成功是否返回默认值(默认 true)
361
- * @param {*} options.defaultValue - 自定义默认值(可选)
368
+ * @param {*} options.defaultValue - 自定义默认值
362
369
  * @returns {*} 转换后的数据
363
370
  *
364
371
  * @example
365
- * // 智能转换(不传 format)
366
- * transferData('123') // 123 (自动推断为 Number)
367
- * transferData('true') // true (自动推断为 Boolean)
368
- * transferData('[1,2]') // [1,2] (自动推断为 Array)
369
- * transferData('hello') // 'hello' (保持 String)
370
- *
371
- * // 字符串模式:基本类型转换
372
- * transferData('123', 'Number') // 123
373
- * transferData(null, 'Array') // []
374
- *
375
- * // 对象模式:根据 key 批量转换
376
- * transferData({a:'1', b:'2'}, {a: 'Number', b: 'Number'})
377
- * // {a: 1, b: 2}
378
- *
379
- * // 配置选项
380
- * transferData('abc', 'Number') // NaN
381
- * transferData('abc', 'Number', { defaultValue: -1 }) // -1
372
+ * transferData('123') // 智能转换:123
373
+ * transferData('123', 'Number') // Number:123
374
+ * transferData('true', 'Boolean') // Boolean:true
375
+ * transferData(123, 'String') // String:'123'
376
+ * transferData('[1,2]', 'Array') // Array:[1,2]
377
+ * transferData('{"a":1}', 'Object') // Object:{a:1}
378
+ * transferData({a:'1'}, ['a']) // 批量转 Number:{a:1}
379
+ * transferData({a:'1'}, [['a'],'Number']) // 指定类型:{a:1}
380
+ * transferData({a:'1'}, [{fields:['a'],type:'Number'}]) // 对象配置:{a:1}
381
+ * transferData({a:null}, ['a'], {defaultValue:0}) // 带默认值:{a:0}
382
+ * transferData([{a:'1'},{a:'2'}], ['a']) // 数组递归:[{a:1},{a:2}]
383
+ * transferData({a:'1',b:'2'}, {a:'Number'}) // 对象映射:{a:1,b:'2'}
382
384
  */
383
385
  export function transferData(data, format, options = {}) {
384
- // 智能转换模式
385
386
  if (!format) return autoTransferDataInternal(data, options)
386
387
 
387
- const { defaultValue } = options
388
-
389
- // 数组模式:支持两种形式
390
- // 1. ['a', 'b', 'c'] - 转换为 Number
391
- // 2. [['a', 'b'], 'Number'] - 指定类型
392
- // 3. [{ fields: ['a', 'b'], type: 'Number' }] - 对象配置
393
388
  if (Array.isArray(format)) return transferDataByFields(data, format, options)
394
389
 
395
- // 对象映射模式
396
390
  if (typeof format === 'object') return transferDataByMap(data, format, options)
397
391
 
398
- // 默认值配置
399
392
  const defaults = {
400
393
  Number: 0,
401
394
  Boolean: false,
@@ -404,12 +397,10 @@ export function transferData(data, format, options = {}) {
404
397
  Object: {}
405
398
  }
406
399
 
407
- const defaultVal = defaultValue ?? defaults[format]
400
+ const defaultVal = options.defaultValue ?? defaults[format]
408
401
 
409
- // 空值处理
410
402
  if (data == null) return defaultVal
411
403
 
412
- // 复杂类型处理 (Array/Object)
413
404
  if (format === 'Array' || format === 'Object') {
414
405
  const isTargetType = (format === 'Array' && Array.isArray(data)) ||
415
406
  (format === 'Object' && typeof data === 'object' && !Array.isArray(data))
@@ -424,7 +415,6 @@ export function transferData(data, format, options = {}) {
424
415
  }
425
416
  }
426
417
 
427
- // 基础类型转换
428
418
  try {
429
419
  switch (format) {
430
420
  case 'Number': {
@@ -439,7 +429,6 @@ export function transferData(data, format, options = {}) {
439
429
  return Boolean(data)
440
430
  }
441
431
  case 'String': {
442
- // 对象/数组转为 JSON 字符串
443
432
  if (typeof data === 'object') {
444
433
  try {
445
434
  return JSON.stringify(data)
@@ -461,56 +450,76 @@ export function transferData(data, format, options = {}) {
461
450
  * 根据字段数组批量转换数据
462
451
  * @param {*} data - 原始数据
463
452
  * @param {Array} format - 格式配置
464
- * - ['a', 'b', 'c'] - 默认转为 Number
465
- * - [['a', 'b'], 'Number'] - 指定类型
466
- * - [{ fields: ['a', 'b'], type: 'Number' }] - 对象配置
467
453
  * @param {Object} options - 配置选项
468
454
  * @returns {*} 转换后的数据
469
455
  */
470
456
  function transferDataByFields(data, format, options) {
457
+ // 边界情况处理
471
458
  if (data == null || typeof data !== 'object') {
472
459
  return data ?? options.defaultValue
473
460
  }
474
461
 
475
- let fields = []
476
- let type = 'Number' // 默认转为 Number
477
-
478
- // 解析数组配置
479
- if (format.length === 0) return data
480
-
481
- // 形式 1: ['a', 'b', 'c'] - 默认转 Number
482
- if (typeof format[0] === 'string') {
483
- fields = format
484
- }
485
- // 形式 2: [['a', 'b'], 'Number'] - [fields, type]
486
- else if (Array.isArray(format[0])) {
487
- fields = format[0]
488
- if (format[1]) type = format[1]
489
- }
490
- // 形式 3: [{ fields: ['a', 'b'], type: 'Number' }] - 对象配置
491
- else if (typeof format[0] === 'object') {
492
- const config = format[0]
493
- fields = config.fields || []
494
- type = config.type || 'Number'
495
- }
462
+ // 空配置直接返回
463
+ if (!format || format.length === 0) return data
496
464
 
497
- // 如果是数组,递归处理每个元素
465
+ // 数组处理:递归处理每个元素(提前到最前面)
498
466
  if (Array.isArray(data)) {
499
467
  return data.map(item => transferDataByFields(item, format, options))
500
468
  }
501
469
 
502
- // 对象处理:转换指定字段
503
470
  const result = { ...data }
471
+ const configType = typeof format[0]
504
472
 
505
- for (const field of fields) {
506
- if (field in result) {
507
- result[field] = transferData(result[field], type, options)
473
+ if (configType === 'string' || Array.isArray(format[0])) {
474
+ // 形式 1 和形式 2:统一解析
475
+ const { fields, type } = parseFormatConfig(format)
476
+
477
+ for (const field of fields) {
478
+ if (field in result) {
479
+ result[field] = transferData(result[field], type, options)
480
+ }
508
481
  }
482
+ } else if (configType === 'object') {
483
+ // 形式 3:对象配置数组
484
+ format.forEach(config => {
485
+ const fields = config.fields || []
486
+ const type = config.type || 'Number'
487
+
488
+ for (const field of fields) {
489
+ if (field in result) {
490
+ const fieldOptions = config.defaultValue !== undefined
491
+ ? { ...options, defaultValue: config.defaultValue }
492
+ : options
493
+
494
+ result[field] = transferData(result[field], type, fieldOptions)
495
+ }
496
+ }
497
+ })
509
498
  }
510
499
 
511
500
  return result
512
501
  }
513
502
 
503
+ /**
504
+ * 解析传统格式配置
505
+ * @param {Array} format - 格式配置
506
+ * @returns {{fields: Array, type: string}} 解析后的配置
507
+ */
508
+ function parseFormatConfig(format) {
509
+ if (typeof format[0] === 'string') {
510
+ return { fields: format, type: 'Number' }
511
+ }
512
+
513
+ if (Array.isArray(format[0])) {
514
+ return {
515
+ fields: format[0] || [],
516
+ type: format[1] || 'Number'
517
+ }
518
+ }
519
+
520
+ return { fields: [], type: 'Number' }
521
+ }
522
+
514
523
  /**
515
524
  * 智能数据类型转换(内部函数)
516
525
  * @param {*} data - 原始数据
@@ -542,18 +551,16 @@ function autoTransferDataInternal(data, options) {
542
551
 
543
552
  /**
544
553
  * 根据映射对象批量转换数据
545
- * @param {*} data - 原始数据(对象或数组)
546
- * @param {Object} formatMap - 转换映射对象 {key: type}
554
+ * @param {*} data - 原始数据
555
+ * @param {Object} formatMap - 转换映射对象
547
556
  * @param {Object} options - 配置选项
548
557
  * @returns {*} 转换后的数据
549
558
  */
550
559
  function transferDataByMap(data, formatMap, options) {
551
- // 数据为空,返回空对象或原数据
552
560
  if (data === null || data === undefined) {
553
561
  return options.defaultValue ?? {}
554
562
  }
555
563
 
556
- // 数组处理:对每个元素应用转换映射
557
564
  if (Array.isArray(data)) {
558
565
  return data.map(item => {
559
566
  if (typeof item !== 'object') return item
@@ -561,17 +568,14 @@ function transferDataByMap(data, formatMap, options) {
561
568
  })
562
569
  }
563
570
 
564
- // 对象处理:根据 formatMap 的 key 进行转换
565
571
  const result = {}
566
572
 
567
- // 遍历映射表进行类型转换
568
573
  for (const key in formatMap) {
569
574
  if (Object.hasOwn(formatMap, key)) {
570
575
  result[key] = transferData(data[key], formatMap[key], options)
571
576
  }
572
577
  }
573
578
 
574
- // 保留未在映射表中定义的其他属性
575
579
  for (const key in data) {
576
580
  if (Object.hasOwn(data, key) && !Object.hasOwn(result, key)) {
577
581
  result[key] = data[key]
@@ -585,18 +589,21 @@ function transferDataByMap(data, formatMap, options) {
585
589
  * 查找字符串中第 n 次出现的位置
586
590
  * @param {string} str - 源字符串
587
591
  * @param {string} charToFind - 查找字符
588
- * @param {number} n - 第几次出现
592
+ * @param {number} n - 第几次出现(从 1 开始)
589
593
  * @returns {number} 位置索引,未找到返回 -1
590
594
  */
591
595
  export function findNthOccurrence(str, charToFind, n) {
596
+ if (n < 1) return -1
597
+
598
+ let index = -1
592
599
  let count = 0
593
- let index = str.indexOf(charToFind)
594
-
595
- while (count < n && index !== -1) {
596
- index = str.indexOf(charToFind, index + 1)
597
- count++
600
+
601
+ while (count < n) {
602
+ index = str.indexOf(charToFind, index + 1)
603
+ if (index === -1) return -1
604
+ count++
598
605
  }
599
-
606
+
600
607
  return index
601
608
  }
602
609
 
@@ -612,7 +619,6 @@ export function setFormData(object) {
612
619
  if (Object.prototype.hasOwnProperty.call(object, key)) {
613
620
  const value = object[key]
614
621
 
615
- // 处理嵌套对象和数组
616
622
  value instanceof Object || Array.isArray(value)
617
623
  ? formData.append(key, JSON.stringify(value))
618
624
  : formData.append(key, value)
@@ -656,7 +662,7 @@ export function throttle(func, delay = 300) {
656
662
  /**
657
663
  * 数组去重
658
664
  * @param {Array} arr - 要去重的数组
659
- * @param {string} key - 对象去重的键(可选)
665
+ * @param {string} [key] - 对象去重的键(可选)
660
666
  * @returns {Array} 去重后的数组
661
667
  */
662
668
  export function uniqueArray(arr, key) {