@hhfenpm/utils 1.0.2 → 1.0.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.
package/dist/index.esm.js CHANGED
@@ -2194,66 +2194,103 @@ function cleanEscapedString(input) {
2194
2194
  return matched[1].replace(doubleQuoteRegExp, "'");
2195
2195
  }
2196
2196
 
2197
- // 数据格式化
2198
-
2199
- // 完整时间:yyyy-MM-dd HH:mm:ss
2200
- function format_date(timestamp, str = "yyyy-MM-dd") {
2197
+ /**
2198
+ * 日期格式化
2199
+ * @param {number|string} timestamp - 时间戳
2200
+ * @param {string} formatStr - 格式化字符串,默认 "yyyy-MM-dd"
2201
+ * @returns {string} 格式化后的日期字符串
2202
+ */
2203
+ function formatDate(timestamp, formatStr = 'yyyy-MM-dd') {
2201
2204
  if (!timestamp) return ''
2202
2205
  try {
2203
2206
  const num = +timestamp;
2204
2207
  if (num) {
2205
- return format(num, str)
2208
+ return format(num, formatStr)
2206
2209
  }
2207
- return format(new Date(timestamp), str)
2210
+ return format(new Date(timestamp), formatStr)
2208
2211
  } catch (error) {
2209
2212
  return ''
2210
2213
  }
2211
2214
  }
2212
2215
 
2216
+ /**
2217
+ * 日期时间格式化(精确到分钟)
2218
+ * @param {number|string} timestamp - 时间戳
2219
+ * @returns {string} 格式化后的日期时间字符串 "yyyy-MM-dd HH:mm"
2220
+ */
2213
2221
  function formatDateMinute(timestamp) {
2214
2222
  if (!timestamp) return ''
2215
2223
  try {
2216
- return format(+timestamp, "yyyy-MM-dd HH:mm")
2224
+ return format(+timestamp, 'yyyy-MM-dd HH:mm')
2217
2225
  } catch (error) {
2218
2226
  return ''
2219
2227
  }
2220
2228
  }
2221
2229
 
2222
- // 小数转百分比 数字(会删除小数点后面的0)
2223
- function format_decimal(number = 0, num = 2, scale = 100) {
2224
- return +(+number * scale).toFixed(num)
2230
+ /**
2231
+ * 小数转百分比(数字,会删除小数点后面的0
2232
+ * @param {number} number - 小数
2233
+ * @param {number} decimalPlaces - 保留小数位数,默认2
2234
+ * @param {number} scale - 缩放比例,默认100
2235
+ * @returns {number} 百分比数字
2236
+ */
2237
+ function formatDecimal(number = 0, decimalPlaces = 2, scale = 100) {
2238
+ return +(+number * scale).toFixed(decimalPlaces)
2225
2239
  }
2226
2240
 
2227
- // 小数转百分比 字符串(不会删除小数点后面的0)
2228
- function format_decimal_string(number = 0, num = 2, scale = 100) {
2229
- return (+number * scale).toFixed(num)
2241
+ /**
2242
+ * 小数转百分比(字符串,不会删除小数点后面的0
2243
+ * @param {number} number - 小数
2244
+ * @param {number} decimalPlaces - 保留小数位数,默认2
2245
+ * @param {number} scale - 缩放比例,默认100
2246
+ * @returns {string} 百分比字符串
2247
+ */
2248
+ function formatDecimalString(
2249
+ number = 0,
2250
+ decimalPlaces = 2,
2251
+ scale = 100
2252
+ ) {
2253
+ return (+number * scale).toFixed(decimalPlaces)
2230
2254
  }
2231
2255
 
2232
- // 处理金额
2233
- function format_money(number = 0, num = 2, scale = 100) {
2234
- return (+number / scale).toFixed(num)
2256
+ /**
2257
+ * 金额格式化
2258
+ * @param {number} number - 金额数字
2259
+ * @param {number} decimalPlaces - 保留小数位数,默认2
2260
+ * @param {number} scale - 缩放比例,默认100
2261
+ * @returns {string} 格式化后的金额字符串
2262
+ */
2263
+ function formatMoney(number = 0, decimalPlaces = 2, scale = 100) {
2264
+ return (+number / scale).toFixed(decimalPlaces)
2235
2265
  }
2236
2266
 
2237
- // 创建唯一id
2238
- function create_guid() {
2267
+ /**
2268
+ * 创建唯一ID
2269
+ * @returns {string} 唯一ID
2270
+ */
2271
+ function createGuid() {
2239
2272
  return (
2240
2273
  (Math.random() * 10000000).toString(16).substring(0, 4) +
2241
- "-" +
2274
+ '-' +
2242
2275
  new Date().getTime() +
2243
- "-" +
2276
+ '-' +
2244
2277
  Math.random().toString().substring(2, 7)
2245
2278
  )
2246
2279
  }
2247
2280
 
2248
- // 数字格式
2249
- function format_number(num) {
2250
- if (!num) return 0
2281
+ /**
2282
+ * 数字格式化(千分位)
2283
+ * @param {number} num - 数字
2284
+ * @returns {string} 格式化后的数字字符串
2285
+ */
2286
+ function formatNumber(num) {
2287
+ if (!num) return '0'
2251
2288
  let str = `${num}`;
2252
2289
  let len = str.length;
2253
2290
  if (len === 3) {
2254
2291
  return str
2255
2292
  }
2256
- let str2 = "";
2293
+ let str2 = '';
2257
2294
  let max = Math.floor(len / 3);
2258
2295
  if (len % 3 === 0) {
2259
2296
  max = max - 1;
@@ -2261,19 +2298,24 @@ function format_number(num) {
2261
2298
  for (let i = 0; i < max; i++) {
2262
2299
  let s = str.slice(len - 3, len);
2263
2300
  str = str.substring(0, len - 3);
2264
- str2 = "," + s + str2;
2301
+ str2 = ',' + s + str2;
2265
2302
  len = str.length;
2266
2303
  }
2267
2304
  str += str2;
2268
2305
  return str
2269
2306
  }
2270
2307
 
2271
- // 数组转标签
2272
- function arr_label(arr, props) {
2308
+ /**
2309
+ * 数组转标签对象
2310
+ * @param {Array} arr - 数组
2311
+ * @param {Object} props - 属性映射 {label: 'label', value: 'value', children: 'children', re: true}
2312
+ * @returns {Object} 标签对象
2313
+ */
2314
+ function arrToLabel(arr, props) {
2273
2315
  props = {
2274
- label: "label",
2275
- value: "value",
2276
- children: "children",
2316
+ label: 'label',
2317
+ value: 'value',
2318
+ children: 'children',
2277
2319
  re: true,
2278
2320
  ...props,
2279
2321
  };
@@ -2290,11 +2332,16 @@ function arr_label(arr, props) {
2290
2332
  return obj
2291
2333
  }
2292
2334
 
2293
- // 数组转对象
2294
- function arr_obj(arr, props) {
2335
+ /**
2336
+ * 数组转对象
2337
+ * @param {Array} arr - 数组
2338
+ * @param {Object} props - 属性映射 {value: 'value', children: 'children', re: true}
2339
+ * @returns {Object} 对象
2340
+ */
2341
+ function arrToObj(arr, props) {
2295
2342
  props = {
2296
- value: "value",
2297
- children: "children",
2343
+ value: 'value',
2344
+ children: 'children',
2298
2345
  re: true,
2299
2346
  ...props,
2300
2347
  };
@@ -2311,53 +2358,69 @@ function arr_obj(arr, props) {
2311
2358
  return obj
2312
2359
  }
2313
2360
 
2314
- // 复制
2315
- function copy_content(content) {
2361
+ /**
2362
+ * 复制文本到剪贴板
2363
+ * @param {string} content - 要复制的内容
2364
+ * @returns {boolean} 是否成功
2365
+ */
2366
+ function copyContent(content) {
2316
2367
  if (typeof document === 'undefined') {
2317
- console.warn('copy_content需要在浏览器环境使用');
2368
+ console.warn('copyContent需要在浏览器环境使用');
2318
2369
  return false
2319
2370
  }
2320
- const input = document.createElement("input");
2321
- input.setAttribute("value", content);
2371
+ const input = document.createElement('input');
2372
+ input.setAttribute('value', content);
2322
2373
  document.body.appendChild(input);
2323
2374
  input.select();
2324
- const result = document.execCommand("copy");
2375
+ const result = document.execCommand('copy');
2325
2376
  document.body.removeChild(input);
2326
2377
  return result
2327
2378
  }
2328
2379
 
2329
- //计算高度
2330
- function calculate_height(item, container) {
2380
+ /**
2381
+ * 计算高度(判断元素高度是否超过容器)
2382
+ * @param {string} itemId - 元素ID
2383
+ * @param {string} containerId - 容器ID
2384
+ * @returns {boolean} 元素高度是否超过容器
2385
+ */
2386
+ function calculateHeight(itemId, containerId) {
2331
2387
  if (typeof document === 'undefined') {
2332
2388
  return false
2333
2389
  }
2334
- const dom = document.getElementById(item);
2335
- const containerDom = document.getElementById(container);
2390
+ const dom = document.getElementById(itemId);
2391
+ const containerDom = document.getElementById(containerId);
2336
2392
  if (dom && containerDom) {
2337
2393
  const height = dom.offsetHeight;
2338
- const max_height = containerDom.offsetHeight;
2339
- return height > max_height
2394
+ const maxHeight = containerDom.offsetHeight;
2395
+ return height > maxHeight
2340
2396
  }
2341
2397
  return false
2342
2398
  }
2343
2399
 
2344
- // 文字超过8个...
2345
- function formatTxt(text) {
2346
- if (!text) return ""
2347
-
2348
- let trimTetx = text.trim();
2349
-
2350
- if (trimTetx.length <= 8) {
2351
- return trimTetx
2400
+ /**
2401
+ * 文字截断(超过指定长度显示...)
2402
+ * @param {string} text - 文本
2403
+ * @param {number} maxLength - 最大长度,默认8
2404
+ * @returns {string} 截断后的文本
2405
+ */
2406
+ function formatText(text, maxLength = 8) {
2407
+ if (!text) return ''
2408
+ let trimText = text.trim();
2409
+ if (trimText.length <= maxLength) {
2410
+ return trimText
2352
2411
  }
2353
-
2354
- return trimTetx.substring(0, 8) + "..."
2412
+ return trimText.substring(0, maxLength) + '...'
2355
2413
  }
2356
2414
 
2357
- //设置光标
2358
- function set_cursor(dom, start = 0, end = 0) {
2415
+ /**
2416
+ * 设置光标位置(用于contenteditable元素)
2417
+ * @param {HTMLElement} dom - DOM元素
2418
+ * @param {number} start - 起始位置,默认0
2419
+ * @param {number} end - 结束位置,默认0
2420
+ */
2421
+ function setCursor(dom, start = 0, end = 0) {
2359
2422
  if (typeof window === 'undefined' || !dom) {
2360
- console.warn('set_cursor需要在浏览器环境使用');
2423
+ console.warn('setCursor需要在浏览器环境使用');
2361
2424
  return
2362
2425
  }
2363
2426
  const selection = window.getSelection();
@@ -2369,11 +2432,19 @@ function set_cursor(dom, start = 0, end = 0) {
2369
2432
  dom.focus();
2370
2433
  }
2371
2434
 
2372
- // 同步setTimeout
2435
+ /**
2436
+ * 同步setTimeout(Promise版本)
2437
+ * @param {number} time - 延迟时间(毫秒)
2438
+ * @returns {Promise} Promise对象
2439
+ */
2373
2440
  function sleep(time) {
2374
- return new Promise((resolve) => setTimeout(resolve, time))
2441
+ return new Promise(resolve => setTimeout(resolve, time))
2375
2442
  }
2376
2443
 
2444
+ /**
2445
+ * 检测浏览器缩放比例
2446
+ * @returns {number} 缩放比例
2447
+ */
2377
2448
  function detectZoom() {
2378
2449
  if (typeof window === 'undefined') {
2379
2450
  return 1
@@ -2388,7 +2459,10 @@ function detectZoom() {
2388
2459
  if (screen.deviceXDPI && screen.logicalXDPI) {
2389
2460
  ratio = screen.deviceXDPI / screen.logicalXDPI;
2390
2461
  }
2391
- } else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
2462
+ } else if (
2463
+ window.outerWidth !== undefined &&
2464
+ window.innerWidth !== undefined
2465
+ ) {
2392
2466
  ratio = window.outerWidth / window.innerWidth;
2393
2467
  }
2394
2468
 
@@ -2397,25 +2471,28 @@ function detectZoom() {
2397
2471
 
2398
2472
  /**
2399
2473
  * 递归查找树节点
2400
- * @param {Array} tree 树数据
2401
- * @param {String} id 节点id值
2402
- * @param {Object} keyMap 节点字段映射
2403
- * @returns {Object|Null} 节点对象
2474
+ * @param {Array} tree - 树数据
2475
+ * @param {string} id - 节点id值
2476
+ * @param {Object} keyMap - 节点字段映射 {id: 'id', children: 'children'}
2477
+ * @returns {Object|null} 节点对象
2404
2478
  */
2405
2479
  function findNodeOfTree(tree, id, keyMap = {}) {
2406
- const _keyMap = {
2407
- id: "id",
2408
- children: "children",
2480
+ const keyMapConfig = {
2481
+ id: 'id',
2482
+ children: 'children',
2409
2483
  ...keyMap,
2410
2484
  };
2411
2485
 
2412
2486
  function searchTree(nodes) {
2413
2487
  for (let node of nodes) {
2414
- if (node[_keyMap.id] === id) {
2488
+ if (node[keyMapConfig.id] === id) {
2415
2489
  return node
2416
2490
  }
2417
- if (node[_keyMap.children] && node[_keyMap.children].length > 0) {
2418
- const foundNode = searchTree(node[_keyMap.children]);
2491
+ if (
2492
+ node[keyMapConfig.children] &&
2493
+ node[keyMapConfig.children].length > 0
2494
+ ) {
2495
+ const foundNode = searchTree(node[keyMapConfig.children]);
2419
2496
  if (foundNode) {
2420
2497
  return foundNode
2421
2498
  }
@@ -2427,24 +2504,35 @@ function findNodeOfTree(tree, id, keyMap = {}) {
2427
2504
  return searchTree(tree)
2428
2505
  }
2429
2506
 
2430
- function copyToClip(content, type = "input") {
2507
+ /**
2508
+ * 复制文本到剪贴板(兼容版)
2509
+ * @param {string} content - 要复制的内容
2510
+ * @param {string} type - 元素类型,'input' 或 'textarea',默认'input'
2511
+ * @returns {boolean} 是否成功
2512
+ */
2513
+ function copyToClip(content, type = 'input') {
2431
2514
  if (typeof document === 'undefined') {
2432
2515
  console.warn('copyToClip需要在浏览器环境使用');
2433
2516
  return false
2434
2517
  }
2435
- var aux = document.createElement(type);
2518
+ const aux = document.createElement(type);
2436
2519
  document.body.appendChild(aux);
2437
- if (type === "input") {
2438
- aux.setAttribute("value", content);
2520
+ if (type === 'input') {
2521
+ aux.setAttribute('value', content);
2439
2522
  } else {
2440
2523
  aux.value = content;
2441
2524
  }
2442
2525
  aux.select();
2443
- const result = document.execCommand("copy");
2526
+ const result = document.execCommand('copy');
2444
2527
  document.body.removeChild(aux);
2445
2528
  return result
2446
2529
  }
2447
2530
 
2531
+ /**
2532
+ * 手机号脱敏
2533
+ * @param {string|number} phone - 手机号
2534
+ * @returns {string} 脱敏后的手机号
2535
+ */
2448
2536
  function hidePhone(phone) {
2449
2537
  if (!phone) return ''
2450
2538
  phone = phone.toString();
@@ -2452,7 +2540,9 @@ function hidePhone(phone) {
2452
2540
  }
2453
2541
 
2454
2542
  /**
2455
- * 将字符串中的属于正则表达式的特殊字符,转换成正则表达式中的普通字符
2543
+ * 转义正则表达式特殊字符
2544
+ * @param {string} string - 要转义的字符串
2545
+ * @returns {string} 转义后的字符串
2456
2546
  */
2457
2547
  function escapeRegExp(string) {
2458
2548
  if (!string) {
@@ -2461,10 +2551,15 @@ function escapeRegExp(string) {
2461
2551
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
2462
2552
  }
2463
2553
 
2464
- // 基于 Promise 的 validateField 方法,为了校验多个字段时避免回调地狱
2554
+ /**
2555
+ * 基于Promise的表单字段验证(避免回调地狱)
2556
+ * @param {string} prop - 字段名
2557
+ * @param {Object} form - 表单实例
2558
+ * @returns {Promise} Promise对象,验证通过resolve,失败reject
2559
+ */
2465
2560
  function validateFieldAsync(prop, form) {
2466
2561
  return new Promise((resolve, reject) => {
2467
- form.validateField(prop, (valid) => {
2562
+ form.validateField(prop, valid => {
2468
2563
  if (valid) {
2469
2564
  reject(new Error(valid));
2470
2565
  } else {
@@ -2474,19 +2569,28 @@ function validateFieldAsync(prop, form) {
2474
2569
  })
2475
2570
  }
2476
2571
 
2477
- // 校验手机号
2572
+ /**
2573
+ * 手机号验证规则
2574
+ * @param {Object} rule - 验证规则
2575
+ * @param {string} value - 待验证的值
2576
+ * @param {Function} callback - 回调函数
2577
+ */
2478
2578
  function validatePhone(rule, value, callback) {
2479
2579
  const reg = /^1[3456789]\d{9}$/;
2480
2580
  if (!value) {
2481
- return callback(new Error("请输入手机号"))
2581
+ return callback(new Error('请输入手机号'))
2482
2582
  } else if (!reg.test(value)) {
2483
- return callback(new Error("请输入正确的手机号"))
2583
+ return callback(new Error('请输入正确的手机号'))
2484
2584
  } else {
2485
2585
  callback();
2486
2586
  }
2487
2587
  }
2488
2588
 
2489
- // 对象是否为空
2589
+ /**
2590
+ * 判断对象是否为空
2591
+ * @param {Object} obj - 待判断的对象
2592
+ * @returns {boolean} 是否为空对象
2593
+ */
2490
2594
  function isEmptyObj(obj) {
2491
2595
  for (const name in obj) {
2492
2596
  return false
@@ -2494,102 +2598,113 @@ function isEmptyObj(obj) {
2494
2598
  return true
2495
2599
  }
2496
2600
 
2497
- // 只判断两个值对应相等,不包含引用
2601
+ /**
2602
+ * 深度比较两个值是否相等(不包含引用比较)
2603
+ * @param {*} a - 第一个值
2604
+ * @param {*} b - 第二个值
2605
+ * @returns {boolean} 是否相等
2606
+ */
2498
2607
  function isEqual(a, b) {
2499
2608
  const classNameA = Object.prototype.toString.call(a);
2500
2609
  const classNameB = Object.prototype.toString.call(b);
2501
- // 如果数据类型不相等,则返回false
2502
2610
  if (classNameA !== classNameB) {
2503
2611
  return false
2504
- } else {
2505
- // 如果数据类型相等,再根据不同数据类型分别判断
2506
- if (classNameA === "[object Object]") {
2507
- for (let key in a) {
2508
- if (!isEqual(a[key], b[key])) return false
2509
- }
2510
- for (let key in b) {
2511
- if (!isEqual(a[key], b[key])) return false
2612
+ }
2613
+ if (classNameA === '[object Object]') {
2614
+ for (let key in a) {
2615
+ if (!isEqual(a[key], b[key])) return false
2616
+ }
2617
+ for (let key in b) {
2618
+ if (!isEqual(a[key], b[key])) return false
2619
+ }
2620
+ return true
2621
+ } else if (classNameA === '[object Array]') {
2622
+ if (a.length !== b.length) {
2623
+ return false
2624
+ } else {
2625
+ for (let i = 0, len = a.length; i < len; i++) {
2626
+ if (!isEqual(a[i], b[i])) return false
2512
2627
  }
2513
2628
  return true
2514
- } else if (classNameA === "[object Array]") {
2515
- if (a.length !== b.length) {
2516
- return false
2517
- } else {
2518
- for (let i = 0, len = a.length; i < len; i++) {
2519
- if (!isEqual(a[i], b[i])) return false
2520
- }
2521
- return true
2522
- }
2523
- } else if (classNameA === "[object Function]") {
2524
- return a.toString() === b.toString()
2525
- } else {
2526
- return Object.is(a, b)
2527
2629
  }
2630
+ } else if (classNameA === '[object Function]') {
2631
+ return a.toString() === b.toString()
2632
+ } else {
2633
+ return Object.is(a, b)
2528
2634
  }
2529
2635
  }
2530
2636
 
2531
- // 是否为空
2637
+ /**
2638
+ * 判断值是否为空
2639
+ * @param {*} value - 待判断的值
2640
+ * @returns {boolean} 是否为空
2641
+ */
2532
2642
  function isEmpty(value) {
2533
- if (value === undefined || value === null || value === "") {
2643
+ if (value === undefined || value === null || value === '') {
2534
2644
  return true
2535
2645
  }
2536
2646
  return false
2537
2647
  }
2538
2648
 
2649
+ /**
2650
+ * 获取浏览器信息
2651
+ * @returns {Object} {type: string, version: string}
2652
+ */
2539
2653
  function getBrowserInfo() {
2540
2654
  if (typeof navigator === 'undefined') {
2541
2655
  return {
2542
- type: "Unknown",
2543
- version: "Unknown",
2656
+ type: 'Unknown',
2657
+ version: 'Unknown',
2544
2658
  }
2545
2659
  }
2660
+
2546
2661
  const userAgent = navigator.userAgent;
2547
- let browserType = "Unknown";
2548
- let browserVersion = "Unknown";
2662
+ let browserType = 'Unknown';
2663
+ let browserVersion = 'Unknown';
2549
2664
 
2550
2665
  // Check for Firefox
2551
- if (userAgent.indexOf("Firefox") > -1) {
2552
- browserType = "Mozilla Firefox";
2666
+ if (userAgent.indexOf('Firefox') > -1) {
2667
+ browserType = 'Mozilla Firefox';
2553
2668
  const match = userAgent.match(/Firefox\/(\d+\.\d+)/);
2554
- browserVersion = match ? match[1] : "Unknown";
2669
+ browserVersion = match ? match[1] : 'Unknown';
2555
2670
  }
2556
2671
  // Check for Samsung Browser
2557
- else if (userAgent.indexOf("SamsungBrowser") > -1) {
2558
- browserType = "Samsung Internet";
2672
+ else if (userAgent.indexOf('SamsungBrowser') > -1) {
2673
+ browserType = 'Samsung Internet';
2559
2674
  const match = userAgent.match(/SamsungBrowser\/(\d+\.\d+)/);
2560
- browserVersion = match ? match[1] : "Unknown";
2675
+ browserVersion = match ? match[1] : 'Unknown';
2561
2676
  }
2562
2677
  // Check for Opera or OPR (Opera based on Chromium)
2563
- else if (userAgent.indexOf("Opera") > -1 || userAgent.indexOf("OPR") > -1) {
2564
- browserType = "Opera";
2678
+ else if (userAgent.indexOf('Opera') > -1 || userAgent.indexOf('OPR') > -1) {
2679
+ browserType = 'Opera';
2565
2680
  const match = userAgent.match(/(Opera|OPR)\/(\d+\.\d+)/);
2566
- browserVersion = match ? match[2] : "Unknown";
2681
+ browserVersion = match ? match[2] : 'Unknown';
2567
2682
  }
2568
2683
  // Check for Internet Explorer
2569
- else if (userAgent.indexOf("Trident") > -1) {
2570
- browserType = "Microsoft Internet Explorer";
2684
+ else if (userAgent.indexOf('Trident') > -1) {
2685
+ browserType = 'Microsoft Internet Explorer';
2571
2686
  const versionMatch = userAgent.match(/rv:(\d+\.\d+)/);
2572
2687
  if (versionMatch) {
2573
2688
  browserVersion = versionMatch[1];
2574
2689
  }
2575
2690
  }
2576
2691
  // Check for Microsoft Edge
2577
- else if (userAgent.indexOf("Edge") > -1) {
2578
- browserType = "Microsoft Edge";
2692
+ else if (userAgent.indexOf('Edge') > -1) {
2693
+ browserType = 'Microsoft Edge';
2579
2694
  const match = userAgent.match(/Edge\/(\d+\.\d+)/);
2580
- browserVersion = match ? match[1] : "Unknown";
2695
+ browserVersion = match ? match[1] : 'Unknown';
2581
2696
  }
2582
2697
  // Check for Google Chrome
2583
- else if (userAgent.indexOf("Chrome") > -1) {
2584
- browserType = "Google Chrome";
2698
+ else if (userAgent.indexOf('Chrome') > -1) {
2699
+ browserType = 'Google Chrome';
2585
2700
  const match = userAgent.match(/Chrome\/(\d+\.\d+)/);
2586
- browserVersion = match ? match[1] : "Unknown";
2701
+ browserVersion = match ? match[1] : 'Unknown';
2587
2702
  }
2588
2703
  // Check for Apple Safari
2589
- else if (userAgent.indexOf("Safari") > -1) {
2590
- browserType = "Apple Safari";
2704
+ else if (userAgent.indexOf('Safari') > -1) {
2705
+ browserType = 'Apple Safari';
2591
2706
  const match = userAgent.match(/Version\/(\d+\.\d+)/);
2592
- browserVersion = match ? match[1] : "Unknown";
2707
+ browserVersion = match ? match[1] : 'Unknown';
2593
2708
  }
2594
2709
 
2595
2710
  return {
@@ -2598,30 +2713,39 @@ function getBrowserInfo() {
2598
2713
  }
2599
2714
  }
2600
2715
 
2716
+ /**
2717
+ * 检测浏览器是否支持媒体设备(getUserMedia)
2718
+ * @returns {boolean} 是否支持
2719
+ */
2601
2720
  function isSupported() {
2602
2721
  if (typeof navigator === 'undefined') {
2603
2722
  return false
2604
2723
  }
2724
+
2605
2725
  const browserInfo = getBrowserInfo();
2606
- if (browserInfo.type === "Mozilla Firefox") {
2726
+ if (browserInfo.type === 'Mozilla Firefox') {
2607
2727
  return parseFloat(browserInfo.version) > 38
2608
2728
  }
2609
2729
  return !!(
2610
2730
  navigator.mediaDevices &&
2611
- (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia)
2731
+ (navigator.mediaDevices.getUserMedia ||
2732
+ navigator.getUserMedia ||
2733
+ navigator.webkitGetUserMedia)
2612
2734
  )
2613
2735
  }
2614
2736
 
2615
- // 校验无意义连续符号
2737
+ /**
2738
+ * 校验无意义连续符号
2739
+ * @param {string} input - 待校验的输入
2740
+ * @returns {Object} {isValid: boolean, message: string}
2741
+ */
2616
2742
  function validateMeaninglessConsecutiveSymbols(input) {
2617
- // 检查是否为空
2618
2743
  if (input.trim() === '') {
2619
2744
  return {
2620
2745
  isValid: false,
2621
2746
  message: '请输入内容',
2622
2747
  }
2623
2748
  }
2624
- // 检查连续符号(中英文符号)
2625
2749
  const symbolRegex =
2626
2750
  /([\-\+\=\*\.\,\;\:\!\@\#\$\%\^\&\_\(\)\[\]\{\}\|\\\/\?\<\>\~\"\'\`\s]|[\u3000-\u303F]|[\uFF00-\uFFEF])\1{6,}/;
2627
2751
  if (symbolRegex.test(input)) {
@@ -2630,7 +2754,6 @@ function validateMeaninglessConsecutiveSymbols(input) {
2630
2754
  message: '输入无意义内容,请修改',
2631
2755
  }
2632
2756
  }
2633
- // 检查连续数字
2634
2757
  const digitRegex = /(\d)\1{6,}/;
2635
2758
  if (digitRegex.test(input)) {
2636
2759
  return {
@@ -2638,7 +2761,6 @@ function validateMeaninglessConsecutiveSymbols(input) {
2638
2761
  message: '输入无意义内容,请修改',
2639
2762
  }
2640
2763
  }
2641
- // 检查连续相同文字(中英文)
2642
2764
  const charRegex = /([\u4e00-\u9fa5a-zA-Z])\1{2,}/;
2643
2765
  if (charRegex.test(input)) {
2644
2766
  return {
@@ -2652,188 +2774,274 @@ function validateMeaninglessConsecutiveSymbols(input) {
2652
2774
  }
2653
2775
  }
2654
2776
 
2655
- // 数据存储
2777
+ /**
2778
+ * 内存缓存对象
2779
+ */
2656
2780
  const cache = {
2657
2781
  data: {},
2782
+
2783
+ /**
2784
+ * 设置缓存
2785
+ * @param {string} key - 键名
2786
+ * @param {*} data - 数据
2787
+ */
2658
2788
  set(key, data) {
2659
2789
  this.data[key] = data;
2660
2790
  },
2791
+
2792
+ /**
2793
+ * 获取缓存
2794
+ * @param {string} key - 键名
2795
+ * @returns {*} 缓存的数据
2796
+ */
2661
2797
  get(key) {
2662
2798
  return this.data[key]
2663
2799
  },
2800
+
2801
+ /**
2802
+ * 清除缓存
2803
+ * @param {string} key - 键名,如果不传则清除所有缓存
2804
+ */
2664
2805
  clear(key) {
2665
2806
  if (key) {
2666
2807
  delete this.data[key];
2667
2808
  } else {
2668
2809
  this.data = {};
2669
2810
  }
2670
- }
2811
+ },
2671
2812
  };
2672
2813
 
2673
- // 建立唯一的key值
2674
- const buildUniqueUrl = (url, method, params = {}, data = {}) => {
2675
- const paramStr = (obj) => {
2814
+ /**
2815
+ * 构建唯一的URL key(用于请求缓存)
2816
+ * @param {string} url - 请求URL
2817
+ * @param {string} method - 请求方法
2818
+ * @param {Object} params - URL参数
2819
+ * @param {Object} data - 请求体数据
2820
+ * @returns {string} 唯一的URL key
2821
+ */
2822
+ function buildUniqueUrl(url, method, params = {}, data = {}) {
2823
+ const paramStr = obj => {
2676
2824
  if (Object.prototype.toString.call(obj) === '[object Object]') {
2677
- return JSON.stringify(Object.keys(obj).sort().reduce((result, key) => {
2678
- result[key] = obj[key];
2679
- return result
2680
- }, {}))
2825
+ return JSON.stringify(
2826
+ Object.keys(obj)
2827
+ .sort()
2828
+ .reduce((result, key) => {
2829
+ result[key] = obj[key];
2830
+ return result
2831
+ }, {})
2832
+ )
2681
2833
  } else {
2682
2834
  return JSON.stringify(obj)
2683
2835
  }
2684
2836
  };
2685
2837
  url += `?${paramStr(params)}&${paramStr(data)}&${method}`;
2686
2838
  return url
2687
- };
2839
+ }
2688
2840
 
2689
- // 系统标识
2690
- let system_flag = null;
2841
+ let systemFlag = null;
2691
2842
 
2692
- function set_system_key(key) {
2693
- system_flag = key;
2694
- return system_flag;
2843
+ /**
2844
+ * 设置系统标识
2845
+ * @param {string} flag - 系统标识
2846
+ * @returns {string} 系统标识
2847
+ */
2848
+ function setSystemKey(flag) {
2849
+ systemFlag = flag;
2850
+ return systemFlag
2695
2851
  }
2696
2852
 
2697
- function get_system_key(key) {
2698
- if (!system_flag) {
2699
- console.warn("系统标识未设置,请先调用 set_system_key()");
2700
- return key;
2853
+ /**
2854
+ * 获取带系统标识的key
2855
+ * @param {string} key - 原始key
2856
+ * @returns {string} 带系统标识的key
2857
+ */
2858
+ function getSystemKey(key) {
2859
+ if (!systemFlag) {
2860
+ console.warn('系统标识未设置,请先调用 setSystemKey()');
2861
+ return key
2701
2862
  }
2702
- return `${system_flag}_${key}`;
2863
+ return `${systemFlag}_${key}`
2703
2864
  }
2704
2865
 
2705
- // 用户信息
2706
- function removeSession(key = "session") {
2707
- if (typeof window === "undefined" || !window.localStorage) {
2708
- console.warn("localStorage不可用");
2709
- return;
2866
+ /**
2867
+ * 移除localStorage中的session
2868
+ * @param {string} key - 键名,默认'session'
2869
+ */
2870
+ function removeSession(key = 'session') {
2871
+ if (typeof window === 'undefined' || !window.localStorage) {
2872
+ console.warn('localStorage不可用');
2873
+ return
2710
2874
  }
2711
- localStorage.removeItem(get_system_key(key));
2875
+ localStorage.removeItem(getSystemKey(key));
2712
2876
  }
2713
2877
 
2714
- function setSession(session, key = "session") {
2715
- if (typeof window === "undefined" || !window.localStorage) {
2716
- console.warn("localStorage不可用");
2717
- return;
2878
+ /**
2879
+ * 设置localStorage中的session
2880
+ * @param {*} session - 要存储的数据
2881
+ * @param {string} key - 键名,默认'session'
2882
+ */
2883
+ function setSession(session, key = 'session') {
2884
+ if (typeof window === 'undefined' || !window.localStorage) {
2885
+ console.warn('localStorage不可用');
2886
+ return
2718
2887
  }
2719
- localStorage.setItem(get_system_key(key), JSON.stringify(session));
2888
+ localStorage.setItem(getSystemKey(key), JSON.stringify(session));
2720
2889
  }
2721
2890
 
2722
- function getSession(key = "session") {
2723
- if (typeof window === "undefined" || !window.localStorage) {
2724
- console.warn("localStorage不可用");
2725
- return null;
2891
+ /**
2892
+ * 获取localStorage中的session
2893
+ * @param {string} key - 键名,默认'session'
2894
+ * @returns {*} 存储的数据
2895
+ */
2896
+ function getSession(key = 'session') {
2897
+ if (typeof window === 'undefined' || !window.localStorage) {
2898
+ console.warn('localStorage不可用');
2899
+ return null
2726
2900
  }
2727
- const value = localStorage.getItem(get_system_key(key));
2728
- if (value === null || value === undefined || value === "") {
2729
- return value;
2730
- } else if (value === "undefined") {
2731
- return undefined;
2901
+ const value = localStorage.getItem(getSystemKey(key));
2902
+ if (value === null || value === undefined || value === '') {
2903
+ return value
2904
+ } else if (value === 'undefined') {
2905
+ return undefined
2732
2906
  } else {
2733
2907
  try {
2734
- return JSON.parse(value);
2908
+ return JSON.parse(value)
2735
2909
  } catch (e) {
2736
- console.error("解析session失败:", e);
2737
- return value;
2910
+ console.error('解析session失败:', e);
2911
+ return value
2738
2912
  }
2739
2913
  }
2740
2914
  }
2741
2915
 
2742
- // 扩展session中的部分属性,而不是全量替换
2743
- function extentSession(patch, key = "session") {
2744
- if (typeof window === "undefined" || !window.localStorage) {
2745
- console.warn("localStorage不可用");
2746
- return null;
2916
+ /**
2917
+ * 扩展session中的部分属性,而不是全量替换
2918
+ * @param {Object} patch - 要扩展的属性
2919
+ * @param {string} key - 键名,默认'session'
2920
+ * @returns {*} 更新后的session
2921
+ */
2922
+ function extendSession(patch, key = 'session') {
2923
+ if (typeof window === 'undefined' || !window.localStorage) {
2924
+ console.warn('localStorage不可用');
2925
+ return null
2747
2926
  }
2748
2927
  const prev = getSession(key);
2749
- if (typeof prev === "object" && prev !== null) {
2928
+ if (typeof prev === 'object' && prev !== null) {
2750
2929
  localStorage.setItem(
2751
- get_system_key(key),
2930
+ getSystemKey(key),
2752
2931
  JSON.stringify({ ...prev, ...patch })
2753
2932
  );
2754
2933
  }
2755
- return getSession(key);
2934
+ return getSession(key)
2756
2935
  }
2757
2936
 
2758
- function setSessionStorage(session, key = "collapse") {
2759
- if (typeof window === "undefined" || !window.sessionStorage) {
2760
- console.warn("sessionStorage不可用");
2761
- return;
2937
+ /**
2938
+ * 设置sessionStorage
2939
+ * @param {*} session - 要存储的数据
2940
+ * @param {string} key - 键名,默认'collapse'
2941
+ */
2942
+ function setSessionStorage(session, key = 'collapse') {
2943
+ if (typeof window === 'undefined' || !window.sessionStorage) {
2944
+ console.warn('sessionStorage不可用');
2945
+ return
2762
2946
  }
2763
- sessionStorage.setItem(get_system_key(key), JSON.stringify(session));
2947
+ sessionStorage.setItem(getSystemKey(key), JSON.stringify(session));
2764
2948
  }
2765
2949
 
2766
- function getSessionStorage(key = "collapse") {
2767
- if (typeof window === "undefined" || !window.sessionStorage) {
2768
- console.warn("sessionStorage不可用");
2769
- return null;
2950
+ /**
2951
+ * 获取sessionStorage
2952
+ * @param {string} key - 键名,默认'collapse'
2953
+ * @returns {*} 存储的数据
2954
+ */
2955
+ function getSessionStorage(key = 'collapse') {
2956
+ if (typeof window === 'undefined' || !window.sessionStorage) {
2957
+ console.warn('sessionStorage不可用');
2958
+ return null
2770
2959
  }
2771
- const value = sessionStorage.getItem(get_system_key(key));
2772
- if (value === null || value === undefined || value === "") {
2773
- return value;
2774
- } else if (value === "undefined") {
2775
- return undefined;
2960
+ const value = sessionStorage.getItem(getSystemKey(key));
2961
+ if (value === null || value === undefined || value === '') {
2962
+ return value
2963
+ } else if (value === 'undefined') {
2964
+ return undefined
2776
2965
  } else {
2777
2966
  try {
2778
- return JSON.parse(value);
2967
+ return JSON.parse(value)
2779
2968
  } catch (e) {
2780
- console.error("解析sessionStorage失败:", e);
2781
- return value;
2969
+ console.error('解析sessionStorage失败:', e);
2970
+ return value
2782
2971
  }
2783
2972
  }
2784
2973
  }
2785
2974
 
2786
- function removeSessionStorage(key = "collapse") {
2787
- if (typeof window === "undefined" || !window.sessionStorage) {
2788
- console.warn("sessionStorage不可用");
2789
- return;
2975
+ /**
2976
+ * 移除sessionStorage
2977
+ * @param {string} key - 键名,默认'collapse'
2978
+ */
2979
+ function removeSessionStorage(key = 'collapse') {
2980
+ if (typeof window === 'undefined' || !window.sessionStorage) {
2981
+ console.warn('sessionStorage不可用');
2982
+ return
2790
2983
  }
2791
- sessionStorage.removeItem(get_system_key(key));
2984
+ sessionStorage.removeItem(getSystemKey(key));
2792
2985
  }
2793
2986
 
2794
- // 图片地址
2987
+ /**
2988
+ * 获取图片URL
2989
+ * @param {string} url - 图片路径
2990
+ * @returns {string} 完整的图片URL
2991
+ */
2795
2992
  function getImgURL(url) {
2796
2993
  if (!url) return ''
2797
- if (!/^http/g.test(url) && !/^data:image/g.test(url)) {
2798
- const backendServer = typeof window !== 'undefined' && window.GLOBAL_CONFIG
2799
- ? window.GLOBAL_CONFIG.backend_server
2994
+ if (/^http/g.test(url) || /^data:image/g.test(url)) {
2995
+ return url
2996
+ }
2997
+ const backendServer =
2998
+ typeof window !== 'undefined' && window.GLOBAL_CONFIG
2999
+ ? window.GLOBAL_CONFIG.backend_server
2800
3000
  : '';
2801
- if (backendServer) {
2802
- url = `${backendServer}/_uploads/files/${url}`;
2803
- }
3001
+ if (!backendServer) {
3002
+ console.warn('未配置 backend_server,返回原始URL');
3003
+ return url
2804
3004
  }
2805
- return url
3005
+ return `${backendServer}/_uploads/files/${url}`
2806
3006
  }
2807
3007
 
2808
- // 量表图片地址
3008
+ /**
3009
+ * 获取量表图片URL
3010
+ * @param {string} url - 图片路径
3011
+ * @returns {string} 完整的图片URL
3012
+ */
2809
3013
  function getGaugeImgUrl(url) {
2810
3014
  if (!url) return ''
2811
- if (!/^http/g.test(url) && !/^data:image/g.test(url)) {
2812
- const backendServer = typeof window !== 'undefined' && window.GLOBAL_CONFIG
2813
- ? window.GLOBAL_CONFIG.backend_server
3015
+ if (/^http/g.test(url) || /^data:image/g.test(url)) {
3016
+ return url
3017
+ }
3018
+ const backendServer =
3019
+ typeof window !== 'undefined' && window.GLOBAL_CONFIG
3020
+ ? window.GLOBAL_CONFIG.backend_server
2814
3021
  : '';
2815
- if (backendServer) {
2816
- url = `${backendServer}/api/v1/ma/mobile/resource/local/files?file=${url}`;
2817
- }
3022
+ if (!backendServer) {
3023
+ console.warn('未配置 backend_server,返回原始URL');
3024
+ return url
2818
3025
  }
2819
- return url
3026
+ return `${backendServer}/api/v1/ma/mobile/resource/local/files?file=${url}`
2820
3027
  }
2821
3028
 
2822
- // 医生头像
2823
- function doctor_head_img(url) {
3029
+ /**
3030
+ * 获取医生头像URL
3031
+ * @param {string} url - 图片路径
3032
+ * @param {string} defaultUrl - 默认头像URL
3033
+ * @returns {string} 完整的图片URL
3034
+ */
3035
+ function doctorHeadImg(url, defaultUrl = './img/doc_defalut_male.jpg') {
2824
3036
  if (!url) {
2825
- return './img/doc_defalut_male.jpg'
3037
+ return defaultUrl
2826
3038
  }
2827
- if (!/^http/g.test(url) && !/^data:image/g.test(url)) {
2828
- return `https://annetinfo1.oss-cn-shenzhen.aliyuncs.com/${url}`
3039
+ if (/^http/g.test(url) || /^data:image/g.test(url)) {
3040
+ return url
2829
3041
  }
2830
- return url
3042
+ return `https://annetinfo1.oss-cn-shenzhen.aliyuncs.com/${url}`
2831
3043
  }
2832
3044
 
2833
- /**
2834
- * 设备检测工具函数
2835
- */
2836
-
2837
3045
  /**
2838
3046
  * 检测当前设备是否为平板
2839
3047
  * @returns {boolean} 是否为平板设备
@@ -2843,46 +3051,37 @@ function isTablet() {
2843
3051
  return false
2844
3052
  }
2845
3053
 
2846
- // 获取用户代理字符串
2847
3054
  const userAgent = navigator.userAgent.toLowerCase();
2848
-
2849
- // 检测常见的平板设备标识
2850
3055
  const tabletPatterns = [
2851
- /ipad/, // iPad
2852
- /android.*tablet/, // Android 平板
2853
- /kindle/, // Kindle
2854
- /silk/, // Amazon Silk
2855
- /playbook/, // BlackBerry PlayBook
2856
- /bb10/, // BlackBerry 10
2857
- /rim tablet/, // BlackBerry Tablet OS
2858
- /windows.*touch/, // Windows 平板
2859
- /tablet/, // 通用平板标识
3056
+ /ipad/,
3057
+ /android.*tablet/,
3058
+ /kindle/,
3059
+ /silk/,
3060
+ /playbook/,
3061
+ /bb10/,
3062
+ /rim tablet/,
3063
+ /windows.*touch/,
3064
+ /tablet/,
2860
3065
  ];
2861
-
2862
- // 检查用户代理是否匹配平板模式
2863
- const isTabletByUserAgent = tabletPatterns.some(pattern => pattern.test(userAgent));
2864
-
2865
- // 检测屏幕尺寸和触摸支持
3066
+ const isTabletByUserAgent = tabletPatterns.some(pattern =>
3067
+ pattern.test(userAgent)
3068
+ );
2866
3069
  const hasTouch = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
2867
3070
  const screenWidth = window.screen.width;
2868
3071
  const screenHeight = window.screen.height;
2869
3072
  const minDimension = Math.min(screenWidth, screenHeight);
2870
3073
  const maxDimension = Math.max(screenWidth, screenHeight);
2871
-
2872
- // 平板设备的典型屏幕尺寸范围
2873
- const isTabletByScreenSize = (
2874
- (minDimension >= 600 && minDimension <= 1200) &&
2875
- (maxDimension >= 800 && maxDimension <= 1600)
2876
- );
2877
-
2878
- // 检测是否为移动设备但屏幕较大(可能是平板)
2879
- const isMobile = /android|webos|iphone|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
3074
+ const isTabletByScreenSize =
3075
+ minDimension >= 600 &&
3076
+ minDimension <= 1200 &&
3077
+ maxDimension >= 800 &&
3078
+ maxDimension <= 1600;
3079
+ const isMobile =
3080
+ /android|webos|iphone|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
2880
3081
  const isLargeMobile = isMobile && minDimension >= 600;
2881
-
2882
- // 综合判断:用户代理匹配 (屏幕尺寸符合平板特征 支持触摸) (大屏移动设备)
2883
- return isTabletByUserAgent ||
2884
- (isTabletByScreenSize && hasTouch) ||
2885
- isLargeMobile
3082
+ return (
3083
+ isTabletByUserAgent || (isTabletByScreenSize && hasTouch) || isLargeMobile
3084
+ )
2886
3085
  }
2887
3086
 
2888
3087
  /**
@@ -2899,7 +3098,8 @@ function getDeviceType() {
2899
3098
  }
2900
3099
 
2901
3100
  const userAgent = navigator.userAgent.toLowerCase();
2902
- const isMobile = /android|webos|iphone|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
3101
+ const isMobile =
3102
+ /android|webos|iphone|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
2903
3103
 
2904
3104
  return isMobile ? 'mobile' : 'desktop'
2905
3105
  }
@@ -2929,7 +3129,7 @@ function getDeviceInfo() {
2929
3129
  screenWidth: 0,
2930
3130
  screenHeight: 0,
2931
3131
  devicePixelRatio: 1,
2932
- orientation: 'unknown'
3132
+ orientation: 'unknown',
2933
3133
  }
2934
3134
  }
2935
3135
 
@@ -2941,29 +3141,19 @@ function getDeviceInfo() {
2941
3141
  screenWidth: window.screen.width,
2942
3142
  screenHeight: window.screen.height,
2943
3143
  devicePixelRatio: window.devicePixelRatio || 1,
2944
- orientation: screen.orientation ? screen.orientation.type : 'unknown'
3144
+ orientation: screen.orientation ? screen.orientation.type : 'unknown',
2945
3145
  }
2946
3146
  }
2947
3147
 
2948
- /* eslint-disable */
2949
-
2950
- /*
2951
- 将url的传参参数形式的字符串转化为json对象格式
2952
-
2953
- let param = 'school=gongda&hobby=skating&number=3'
2954
- let jsonObj = queryToObj(param)
2955
-
2956
- console.log(jsonObj)
2957
- 输出:{
2958
- school: 'gongda',
2959
- hobby: 'skaing',
2960
- number: '3'
2961
- }
2962
- */
3148
+ /**
3149
+ * 将查询字符串转换为对象
3150
+ * @param {string} str - 查询字符串,如 'a=1&b=2'
3151
+ * @returns {Object} 对象,如 {a: '1', b: '2'}
3152
+ */
2963
3153
  function queryToObj(str) {
2964
- var theRequest = {};
3154
+ const theRequest = {};
2965
3155
  if (str) {
2966
- var strs = str.includes('&') ? str.split('&') : ('&' + str).split('&');
3156
+ const strs = str.includes('&') ? str.split('&') : ('&' + str).split('&');
2967
3157
  for (let i = 0; i < strs.length; i++) {
2968
3158
  if (strs[i].includes('=')) {
2969
3159
  const parts = strs[i].split('=');
@@ -2974,11 +3164,11 @@ function queryToObj(str) {
2974
3164
  return theRequest
2975
3165
  }
2976
3166
 
2977
- /*
2978
- * 将obj转换成url参数形式
2979
- * toQueryString({a:1,b:2}) => a=1&b=2
2980
- *
2981
- * */
3167
+ /**
3168
+ * 将对象转换为查询字符串
3169
+ * @param {Object} obj - 对象,如 {a: 1, b: 2}
3170
+ * @returns {string} 查询字符串,如 'a=1&b=2'
3171
+ */
2982
3172
  function toQueryPair(key, value) {
2983
3173
  if (typeof value == 'undefined') {
2984
3174
  return key
@@ -2987,111 +3177,95 @@ function toQueryPair(key, value) {
2987
3177
  }
2988
3178
 
2989
3179
  function toQueryString(obj) {
2990
- var ret = [];
2991
- for (var key in obj) {
2992
- key = encodeURIComponent(key);
2993
- var values = obj[key];
3180
+ const ret = [];
3181
+ for (const key in obj) {
3182
+ const encodedKey = encodeURIComponent(key);
3183
+ const values = obj[key];
2994
3184
  if (values && values.constructor == Array) {
2995
- //数组
2996
- var queryValues = [];
2997
- for (var i = 0, len = values.length, value; i < len; i++) {
3185
+ const queryValues = [];
3186
+ for (let i = 0, len = values.length, value; i < len; i++) {
2998
3187
  value = values[i];
2999
- queryValues.push(toQueryPair(key, value));
3188
+ queryValues.push(toQueryPair(encodedKey, value));
3000
3189
  }
3001
3190
  ret = ret.concat(queryValues);
3002
3191
  } else {
3003
- //字符串
3004
- ret.push(toQueryPair(key, values));
3192
+ ret.push(toQueryPair(encodedKey, values));
3005
3193
  }
3006
3194
  }
3007
3195
  return ret.join('&')
3008
3196
  }
3009
3197
 
3010
- /*
3011
- 直接取url中的参数转为json(或者不转)
3012
- 用法1:
3013
- let para = urlToJson()
3014
- console.log(para)
3015
-
3016
- 用法2:
3017
- let para = urlToJson('https://www.baidu.com?a=1&b=2')
3018
- console.log(para)
3019
-
3020
- * */
3198
+ /**
3199
+ * URL转JSON对象
3200
+ * @param {string} selfUrl - URL字符串,如果不传则使用当前页面URL
3201
+ * @returns {Object} {paramStr: string, paramJson: Object}
3202
+ */
3021
3203
  function urlToJson(selfUrl) {
3022
3204
  if (typeof window === 'undefined') {
3023
3205
  return { paramStr: '', paramJson: {} }
3024
3206
  }
3025
3207
  const url = selfUrl ? selfUrl : window.location.href;
3026
3208
 
3027
- const reg = /\?.*$/; // 正则取'?后的参数'
3209
+ const reg = /\?.*$/;
3028
3210
  const urlMatch = url.match(reg);
3029
-
3030
- // 匹配去掉?的纯参数(正则精髓,贪婪永远匹配最后一个?后的参数)
3031
- const param = urlMatch && urlMatch.length ? urlMatch[0].replace(/^\?*.*\?/, '') : '';
3211
+ const param =
3212
+ urlMatch && urlMatch.length ? urlMatch[0].replace(/^\?*.*\?/, '') : '';
3032
3213
 
3033
3214
  const output = {
3034
3215
  paramStr: param,
3035
- paramJson: queryToObj(param)
3216
+ paramJson: queryToObj(param),
3036
3217
  };
3037
3218
 
3038
3219
  return output
3039
3220
  }
3040
3221
 
3041
- /*
3042
- 直接取url中的某个参数
3043
- 用法:
3044
- let deviceType = getQueryString('deviceType')
3045
- console.log(deviceType)
3046
-
3047
- * */
3222
+ /**
3223
+ * 获取URL中的指定参数
3224
+ * @param {string} name - 参数名
3225
+ * @param {string} url - URL字符串,如果不传则使用当前页面URL
3226
+ * @returns {string} 参数值
3227
+ */
3048
3228
  function getQueryString(name, url) {
3049
3229
  if (typeof window === 'undefined') {
3050
3230
  return ''
3051
3231
  }
3052
3232
  url = url || window.location.href;
3053
- var str = url.match(new RegExp('([?&#])' + name.replace('#', '') + '=([^#&?]*)', 'gi'));
3233
+ const str = url.match(
3234
+ new RegExp('([?&#])' + name.replace('#', '') + '=([^#&?]*)', 'gi')
3235
+ );
3054
3236
  return str ? decodeURIComponent(str[0].split('=')[1]) : ''
3055
3237
  }
3056
3238
 
3057
- /*
3058
- 更改url中的某个参数,返回更改后的最终带参数url
3059
- 参数解析:
3060
- json: 更改参数的json对象
3061
- originUrl:预置的网站地址
3062
-
3063
- 用法一:
3064
- let resultUrl = setUrl({id: 1, name: '测试页面'})
3065
- console.log(resultUrl) // 输出:https://********.html?id=1&name=测试页面
3066
-
3067
- 用法二:
3068
- let resultUrl = setUrl({id: 3, name: '哈哈哈'}, 'https://www.baidu.com')
3069
- console.log(resultUrl) // 输出:https://www.baidu.com?id=3&name=哈哈哈
3070
-
3071
- * */
3239
+ /**
3240
+ * 设置URL参数,返回新的URL
3241
+ * @param {Object} json - 要设置的参数对象
3242
+ * @param {string} originUrl - 原始URL,如果不传则使用当前页面URL
3243
+ * @returns {string} 新的URL
3244
+ */
3072
3245
  function setUrl(json, originUrl = '') {
3073
3246
  if (typeof window === 'undefined') {
3074
3247
  return ''
3075
3248
  }
3076
3249
  let paramJson = urlToJson().paramJson;
3077
- // 新的参数
3078
3250
  let newJson = {
3079
3251
  ...paramJson,
3080
- ...json
3252
+ ...json,
3081
3253
  };
3082
-
3083
- // 参数对象 =》get参数
3084
3254
  let paramStr = toQueryString(newJson);
3085
-
3086
- // url的origin + pathname
3087
- let oPath = originUrl ? originUrl : window.location.origin + window.location.pathname;
3255
+ let oPath = originUrl
3256
+ ? originUrl
3257
+ : window.location.origin + window.location.pathname;
3088
3258
 
3089
3259
  let resultUrl = oPath + '?' + paramStr;
3090
3260
  return resultUrl
3091
3261
  }
3092
3262
 
3093
- // url参数(兼容旧API)
3094
- function get_url_params(url) {
3263
+ /**
3264
+ * 获取URL参数
3265
+ * @param {string} url - URL字符串,默认使用当前页面URL
3266
+ * @returns {Object} 参数对象
3267
+ */
3268
+ function getUrlParams(url) {
3095
3269
  if (typeof window === 'undefined') {
3096
3270
  return {}
3097
3271
  }
@@ -3099,62 +3273,134 @@ function get_url_params(url) {
3099
3273
  return urlToJson(targetUrl).paramJson
3100
3274
  }
3101
3275
 
3276
+ /**
3277
+ * 将毫秒转换为时分秒
3278
+ * @param {number} ms - 毫秒数
3279
+ * @param {boolean} secondsTo2decimal - 秒数是否保留两位小数,默认false
3280
+ * @returns {Object} {hours: number, minutes: number, seconds: number}
3281
+ */
3102
3282
  function convertMilliseconds(ms, secondsTo2decimal = false) {
3103
- if (!ms) return "";
3283
+ if (!ms)
3284
+ return {
3285
+ hours: 0,
3286
+ minutes: 0,
3287
+ seconds: 0,
3288
+ }
3104
3289
 
3105
- const hours = Math.floor(ms / 3600000); // 计算小时
3106
- const minutes = Math.floor((ms % 3600000) / 60000); // 计算分钟
3290
+ const hours = Math.floor(ms / 3600000);
3291
+ const minutes = Math.floor((ms % 3600000) / 60000);
3107
3292
  let seconds = 0;
3293
+
3108
3294
  if (secondsTo2decimal) {
3109
3295
  seconds = parseFloat(((ms % 60000) / 1000).toFixed(2));
3110
3296
  } else {
3111
- seconds = Math.floor((ms % 60000) / 1000); // 计算秒数
3297
+ seconds = Math.floor((ms % 60000) / 1000);
3112
3298
  }
3113
3299
 
3114
3300
  return {
3115
3301
  hours,
3116
3302
  minutes,
3117
3303
  seconds,
3118
- };
3304
+ }
3119
3305
  }
3120
3306
 
3121
- const myDebounce = function (fn, time = 600) {
3122
- let timerId = "";
3123
- return function (...arg) {
3124
- timerId && clearTimeout(timerId);
3307
+ /**
3308
+ * 防抖函数
3309
+ * @param {Function} fn - 要防抖的函数
3310
+ * @param {number} delay - 延迟时间(毫秒),默认600
3311
+ * @returns {Function} 防抖后的函数
3312
+ */
3313
+ function debounce(fn, delay = 600) {
3314
+ let timerId = null;
3315
+ return function (...args) {
3316
+ if (timerId) clearTimeout(timerId);
3125
3317
  timerId = setTimeout(() => {
3126
- fn && fn.call(this, ...arg);
3127
- }, time);
3128
- };
3129
- };
3318
+ fn && fn.call(this, ...args);
3319
+ }, delay);
3320
+ }
3321
+ }
3322
+
3323
+ /**
3324
+ * 防抖函数(别名,向后兼容)
3325
+ * @param {Function} fn - 要防抖的函数
3326
+ * @param {number} delay - 延迟时间(毫秒),默认600
3327
+ * @returns {Function} 防抖后的函数
3328
+ */
3329
+ const myDebounce = debounce;
3330
+
3331
+ /**
3332
+ * 节流函数
3333
+ * @param {Function} fn - 要节流的函数
3334
+ * @param {number} delay - 延迟时间(毫秒),默认100
3335
+ * @returns {Function} 节流后的函数
3336
+ */
3337
+ function throttle(fn, delay = 100) {
3338
+ let timer = null;
3339
+ let startTime = Date.now();
3130
3340
 
3131
- const mapStringifyReplacer = function (key, value) {
3341
+ return function (...args) {
3342
+ const currentTime = Date.now();
3343
+ const diff = delay - (currentTime - startTime);
3344
+
3345
+ if (timer) clearTimeout(timer);
3346
+
3347
+ if (diff <= 0) {
3348
+ fn.apply(this, args);
3349
+ startTime = Date.now();
3350
+ } else {
3351
+ timer = setTimeout(() => {
3352
+ fn.apply(this, args);
3353
+ }, diff);
3354
+ }
3355
+ }
3356
+ }
3357
+
3358
+ /**
3359
+ * Map序列化的replacer函数(用于JSON.stringify)
3360
+ * @param {string} key - 键名
3361
+ * @param {*} value - 值
3362
+ * @returns {*} 处理后的值
3363
+ */
3364
+ function mapStringifyReplacer(key, value) {
3132
3365
  if (value instanceof Map) {
3133
3366
  return {
3134
- dataType: "Map",
3367
+ dataType: 'Map',
3135
3368
  value: Array.from(value.entries()),
3136
- };
3369
+ }
3137
3370
  } else {
3138
- return value;
3371
+ return value
3139
3372
  }
3140
- };
3373
+ }
3141
3374
 
3142
- const mapParseReviver = function (key, value) {
3143
- if (typeof value === "object" && value !== null) {
3144
- if (value.dataType === "Map") {
3145
- return new Map(value.value);
3375
+ /**
3376
+ * Map反序列化的reviver函数(用于JSON.parse)
3377
+ * @param {string} key - 键名
3378
+ * @param {*} value - 值
3379
+ * @returns {*} 处理后的值
3380
+ */
3381
+ function mapParseReviver(key, value) {
3382
+ if (typeof value === 'object' && value !== null) {
3383
+ if (value.dataType === 'Map') {
3384
+ return new Map(value.value)
3146
3385
  }
3147
3386
  }
3148
- return value;
3149
- };
3387
+ return value
3388
+ }
3150
3389
 
3390
+ /**
3391
+ * 获取指定月数前的今天
3392
+ * @param {number} reduce - 减少的月数,默认12
3393
+ * @returns {number} 时间戳
3394
+ */
3151
3395
  function getHalfYearAgoToday(reduce = 12) {
3152
3396
  const today = new Date().setHours(0, 0, 0, 0);
3153
3397
  const currentMonth = new Date().getMonth();
3154
- return new Date(today).setMonth(currentMonth - reduce);
3398
+ return new Date(today).setMonth(currentMonth - reduce)
3155
3399
  }
3156
3400
 
3157
- // 文件下载助手
3401
+ /**
3402
+ * 文件下载助手
3403
+ */
3158
3404
  const fileDownloadHelper = {
3159
3405
  /**
3160
3406
  * 下载文件
@@ -3162,14 +3408,15 @@ const fileDownloadHelper = {
3162
3408
  * @param {string} filename - 下载文件名
3163
3409
  */
3164
3410
  download(blob, filename) {
3165
- if (typeof window === "undefined") {
3166
- console.warn("fileDownloadHelper.download只能在浏览器环境使用");
3167
- return;
3411
+ if (typeof window === 'undefined') {
3412
+ console.warn('fileDownloadHelper.download只能在浏览器环境使用');
3413
+ return
3168
3414
  }
3415
+
3169
3416
  const url = window.URL.createObjectURL(blob);
3170
- const link = document.createElement("a");
3417
+ const link = document.createElement('a');
3171
3418
  link.href = url;
3172
- link.setAttribute("download", filename);
3419
+ link.setAttribute('download', filename);
3173
3420
  document.body.appendChild(link);
3174
3421
  link.click();
3175
3422
  window.URL.revokeObjectURL(url);
@@ -3183,93 +3430,60 @@ const fileDownloadHelper = {
3183
3430
  * @returns {string} 文件名
3184
3431
  */
3185
3432
  getFilenameFromHeaders(headers, defaultName) {
3186
- const contentDisposition = headers["content-disposition"];
3187
- if (!contentDisposition) return defaultName;
3433
+ const contentDisposition = headers['content-disposition'];
3434
+ if (!contentDisposition) return defaultName
3188
3435
 
3189
3436
  const filenameMatch = contentDisposition.match(/filename=(.+)/);
3190
3437
  return filenameMatch && filenameMatch.length > 1
3191
- ? decodeURIComponent(filenameMatch[1]).replace(/['"]/g, "")
3192
- : defaultName;
3438
+ ? decodeURIComponent(filenameMatch[1]).replace(/['"]/g, '')
3439
+ : defaultName
3193
3440
  },
3194
3441
  };
3195
3442
 
3196
3443
  /**
3197
- * 复制文本到剪贴板
3444
+ * 复制文本到剪贴板(Promise版本)
3198
3445
  * @param {string} text - 要复制的文本
3199
- * @returns {Promise<boolean>} - 返回一个Promise,复制成功返回true,失败返回false
3446
+ * @returns {Promise<boolean>} 复制成功返回true,失败返回false
3200
3447
  */
3201
3448
  async function copyText(text) {
3202
- if (typeof window === "undefined") {
3203
- console.warn("copyText只能在浏览器环境使用");
3204
- return false;
3449
+ if (typeof window === 'undefined') {
3450
+ console.warn('copyText只能在浏览器环境使用');
3451
+ return false
3205
3452
  }
3206
3453
 
3207
3454
  try {
3208
- // 优先使用现代的Clipboard API
3209
3455
  if (navigator.clipboard && window.isSecureContext) {
3210
3456
  await navigator.clipboard.writeText(text);
3211
- return true;
3457
+ return true
3212
3458
  }
3213
-
3214
- // 降级方案:使用传统的document.execCommand方法
3215
- const textArea = document.createElement("textarea");
3459
+ const textArea = document.createElement('textarea');
3216
3460
  textArea.value = text;
3217
-
3218
- // 防止页面滚动
3219
- textArea.style.position = "fixed";
3220
- textArea.style.left = "-999999px";
3221
- textArea.style.top = "-999999px";
3461
+ textArea.style.position = 'fixed';
3462
+ textArea.style.left = '-999999px';
3463
+ textArea.style.top = '-999999px';
3222
3464
 
3223
3465
  document.body.appendChild(textArea);
3224
3466
  textArea.focus();
3225
3467
  textArea.select();
3226
3468
 
3227
3469
  try {
3228
- const successful = document.execCommand("copy");
3470
+ const successful = document.execCommand('copy');
3229
3471
  document.body.removeChild(textArea);
3230
- return successful;
3472
+ return successful
3231
3473
  } catch (err) {
3232
3474
  document.body.removeChild(textArea);
3233
- return false;
3475
+ return false
3234
3476
  }
3235
3477
  } catch (err) {
3236
- return false;
3478
+ return false
3237
3479
  }
3238
3480
  }
3239
3481
 
3240
- // 防抖(兼容旧API)
3241
- function debounce(fn, delay = 200) {
3242
- let timeout = null;
3243
- return function () {
3244
- let context = this;
3245
- let args = arguments;
3246
- clearTimeout(timeout);
3247
- timeout = setTimeout(() => {
3248
- fn.apply(context, args);
3249
- }, delay);
3250
- };
3251
- }
3252
-
3253
- // 节流
3254
- const throttle = (fn, delay = 100) => {
3255
- let timer = null;
3256
- let start_time = Date.now();
3257
- return function (...args) {
3258
- const current_time = Date.now();
3259
- const diff = delay - (current_time - start_time);
3260
- if (timer) clearTimeout(timer);
3261
- if (diff <= 0) {
3262
- fn.apply(this, args);
3263
- start_time = Date.now();
3264
- } else {
3265
- timer = setTimeout(() => {
3266
- fn.apply(this, args);
3267
- }, diff);
3268
- }
3269
- };
3270
- };
3271
-
3272
- const uuid = function () {
3482
+ /**
3483
+ * 生成短UUID
3484
+ * @returns {string} UUID字符串
3485
+ */
3486
+ function uuid() {
3273
3487
  let random;
3274
3488
 
3275
3489
  try {
@@ -3286,24 +3500,41 @@ const uuid = function () {
3286
3500
  }
3287
3501
 
3288
3502
  return random.toString(36)
3289
- };
3503
+ }
3290
3504
 
3291
- const uuidLong = function () {
3505
+ /**
3506
+ * 生成长UUID(由三个短UUID拼接)
3507
+ * @returns {string} 长UUID字符串
3508
+ */
3509
+ function uuidLong() {
3292
3510
  return `${uuid()}${uuid()}${uuid()}`
3293
- };
3294
-
3295
- function baseGet(object, path) {
3296
- path = castPath(path);
3297
-
3298
- var index = 0,
3299
- length = path.length;
3511
+ }
3300
3512
 
3301
- while (object != null && index < length) {
3302
- object = object[path[index++]];
3513
+ /**
3514
+ * 将字符串路径转换为数组
3515
+ * @param {string} string - 路径字符串,如 'a.b[0].c'
3516
+ * @returns {Array} 路径数组
3517
+ */
3518
+ function stringToPath(string) {
3519
+ const result = [];
3520
+ if (string.charCodeAt(0) === 46) {
3521
+ result.push('');
3303
3522
  }
3304
- return (index && index == length) ? object : undefined
3523
+ string.replace(
3524
+ /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,
3525
+ function (match, number, quote, subString) {
3526
+ result.push(quote ? subString.replace(/\\(\\)?/g, '$1') : number || match);
3527
+ }
3528
+ );
3529
+ return result
3305
3530
  }
3306
3531
 
3532
+ /**
3533
+ * 转换路径为数组格式
3534
+ * @param {string|Array} value - 路径字符串或数组
3535
+ * @param {Object} object - 对象
3536
+ * @returns {Array} 路径数组
3537
+ */
3307
3538
  function castPath(value, object) {
3308
3539
  if (Array.isArray(value)) {
3309
3540
  return value
@@ -3311,29 +3542,53 @@ function castPath(value, object) {
3311
3542
  return stringToPath(String(value))
3312
3543
  }
3313
3544
 
3314
- function stringToPath(string) {
3315
- var result = [];
3316
- if (string.charCodeAt(0) === 46 /* . */) {
3317
- result.push('');
3545
+ /**
3546
+ * 基础get方法
3547
+ * @param {Object} object - 对象
3548
+ * @param {string|Array} path - 路径
3549
+ * @returns {*} 获取到的值
3550
+ */
3551
+ function baseGet(object, path) {
3552
+ path = castPath(path);
3553
+
3554
+ let index = 0;
3555
+ const length = path.length;
3556
+
3557
+ while (object != null && index < length) {
3558
+ object = object[path[index++]];
3318
3559
  }
3319
- string.replace(/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g, function(match, number, quote, subString) {
3320
- result.push(quote ? subString.replace(/\\(\\)?/g, '$1') : (number || match));
3321
- });
3322
- return result
3560
+ return index && index == length ? object : undefined
3323
3561
  }
3324
3562
 
3563
+ /**
3564
+ * 获取对象属性值(支持路径)
3565
+ * @param {Object} object - 对象
3566
+ * @param {string|Array} path - 路径,如 'a.b[0].c' 或 ['a', 'b', 0, 'c']
3567
+ * @param {*} defaultValue - 默认值
3568
+ * @returns {*} 获取到的值,如果不存在则返回默认值
3569
+ */
3325
3570
  function get(object, path, defaultValue) {
3326
- var result = object == null ? undefined : baseGet(object, path);
3571
+ const result = object == null ? undefined : baseGet(object, path);
3327
3572
  return result === undefined ? defaultValue : result
3328
3573
  }
3329
3574
 
3330
- // 防止重复请求
3575
+ /**
3576
+ * Axios 适配器 - 防止重复请求
3577
+ * @param {Object} options - 配置选项
3578
+ * @param {number} options.cacheTime - 缓存时间(毫秒),设置为0不清除缓存,默认0
3579
+ * @param {boolean} options.cache - 是否支持缓存,默认false
3580
+ * @param {boolean} options.noWarn - 是否禁用警告,默认false
3581
+ * @returns {Function} Axios 适配器函数
3582
+ */
3331
3583
  var index = (options = {}) =>
3332
- async (config) => {
3584
+ async config => {
3333
3585
  const defaultOptions = {
3334
- time: 0, // 设置为0,不清除缓存
3586
+ cacheTime: 0,
3587
+ cache: false,
3588
+ noWarn: false,
3335
3589
  ...options,
3336
3590
  };
3591
+
3337
3592
  const index = buildUniqueUrl(
3338
3593
  config.url,
3339
3594
  config.method,
@@ -3341,16 +3596,16 @@ var index = (options = {}) =>
3341
3596
  config.data
3342
3597
  );
3343
3598
  let responsePromise = cache.get(index);
3344
- if (!responsePromise) {
3599
+
3600
+ if (!responsePromise || !defaultOptions.cache) {
3345
3601
  responsePromise = (async () => {
3346
3602
  try {
3347
- // 需要确保axios可用,这里假设axios已经通过其他方式引入
3348
3603
  let axios = null;
3349
- if (typeof window !== "undefined" && window.axios) {
3604
+ if (typeof window !== 'undefined' && window.axios) {
3350
3605
  axios = window.axios;
3351
- } else if (typeof require !== "undefined") {
3606
+ } else if (typeof require !== 'undefined') {
3352
3607
  try {
3353
- axios = require("axios");
3608
+ axios = require('axios');
3354
3609
  } catch (e) {
3355
3610
  // ignore
3356
3611
  }
@@ -3358,23 +3613,27 @@ var index = (options = {}) =>
3358
3613
 
3359
3614
  if (axios && axios.defaults && axios.defaults.adapter) {
3360
3615
  const response = await axios.defaults.adapter(config);
3361
- return Promise.resolve(response);
3616
+ return Promise.resolve(response)
3362
3617
  } else {
3363
- throw new Error("axios未找到,请确保已安装axios");
3618
+ throw new Error('axios未找到,请确保已安装axios')
3364
3619
  }
3365
3620
  } catch (reason) {
3366
3621
  cache.clear(index);
3367
- return Promise.reject(reason);
3622
+ if (defaultOptions.noWarn) reason.noWarn = true;
3623
+ return Promise.reject(reason)
3368
3624
  }
3369
3625
  })();
3626
+
3370
3627
  cache.set(index, responsePromise);
3371
- if (defaultOptions.time !== 0) {
3628
+
3629
+ if (defaultOptions.cacheTime !== 0) {
3372
3630
  setTimeout(() => {
3373
3631
  cache.clear(index);
3374
- }, defaultOptions.time);
3632
+ }, defaultOptions.cacheTime);
3375
3633
  }
3376
3634
  }
3377
- return responsePromise.then((data) => JSON.parse(JSON.stringify(data))); // 为防止数据源污染
3635
+
3636
+ return responsePromise.then(data => JSON.parse(JSON.stringify(data)))
3378
3637
  };
3379
3638
 
3380
- export { arr_label, arr_obj, buildUniqueUrl, cache, calculate_height, convertMilliseconds, copyText, copyToClip, copy_content, create_guid, debounce, index as defaultAdapter, detectZoom, doctor_head_img, escapeRegExp, extentSession, fileDownloadHelper, findNodeOfTree, formatDateMinute, formatTxt, format_date, format_decimal, format_decimal_string, format_money, format_number, get, getBrowserInfo, getDeviceInfo, getDeviceType, getGaugeImgUrl, getHalfYearAgoToday, getImgURL, getQueryString, getSession, getSessionStorage, get_system_key, get_url_params, hidePhone, isEmpty, isEmptyObj, isEqual, isSupported, isTablet, isTouchDevice, mapParseReviver, mapStringifyReplacer, myDebounce, queryToObj, removeSession, removeSessionStorage, setSession, setSessionStorage, setUrl, set_cursor, set_system_key, sleep, throttle, toQueryString, urlToJson, uuid, uuidLong, validateFieldAsync, validateMeaninglessConsecutiveSymbols, validatePhone };
3639
+ export { arrToLabel, arrToObj, buildUniqueUrl, cache, calculateHeight, convertMilliseconds, copyContent, copyText, copyToClip, createGuid, debounce, index as defaultAdapter, detectZoom, doctorHeadImg, escapeRegExp, extendSession, fileDownloadHelper, findNodeOfTree, formatDate, formatDateMinute, formatDecimal, formatDecimalString, formatMoney, formatNumber, formatText, get, getBrowserInfo, getDeviceInfo, getDeviceType, getGaugeImgUrl, getHalfYearAgoToday, getImgURL, getQueryString, getSession, getSessionStorage, getSystemKey, getUrlParams, hidePhone, isEmpty, isEmptyObj, isEqual, isSupported, isTablet, isTouchDevice, mapParseReviver, mapStringifyReplacer, myDebounce, queryToObj, removeSession, removeSessionStorage, setCursor, setSession, setSessionStorage, setSystemKey, setUrl, sleep, throttle, toQueryString, urlToJson, uuid, uuidLong, validateFieldAsync, validateMeaninglessConsecutiveSymbols, validatePhone };