util-helpers 4.15.2 → 4.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/dist/util-helpers.js +887 -479
- package/dist/util-helpers.js.map +1 -1
- package/dist/util-helpers.min.js +1 -1
- package/dist/util-helpers.min.js.map +1 -1
- package/esm/ajax.js +149 -0
- package/esm/blobToDataURL.js +8 -12
- package/esm/dataURLToBlob.js +6 -5
- package/esm/download.js +156 -0
- package/esm/fileReader.js +67 -0
- package/esm/filterTree.js +1 -1
- package/esm/findTreeNode.js +1 -1
- package/esm/findTreeNodes.js +1 -1
- package/esm/findTreeSelect.js +1 -1
- package/esm/index.js +15 -5
- package/esm/interface.doc.js +124 -0
- package/esm/{transformFieldNames.type.js → interface.type.js} +2 -4
- package/esm/listToTree.js +1 -1
- package/esm/numberToChinese.js +3 -2
- package/esm/parseIdCard.js +1 -1
- package/esm/replaceChar.js +11 -7
- package/esm/safeDate.js +26 -9
- package/esm/transformFieldNames.js +2 -3
- package/esm/treeToList.js +1 -1
- package/esm/utils/config.js +1 -1
- package/esm/utils/type/index.js +3 -1
- package/esm/utils/type/isArrayBuffer.js +25 -0
- package/esm/utils/type/isBlob.js +27 -0
- package/lib/ajax.js +156 -0
- package/lib/blobToDataURL.js +8 -12
- package/lib/dataURLToBlob.js +6 -5
- package/lib/download.js +161 -0
- package/lib/fileReader.js +74 -0
- package/lib/filterTree.js +1 -1
- package/lib/findTreeNode.js +1 -1
- package/lib/findTreeNodes.js +1 -1
- package/lib/findTreeSelect.js +1 -1
- package/lib/index.js +26 -5
- package/lib/interface.doc.js +126 -0
- package/lib/listToTree.js +1 -1
- package/lib/numberToChinese.js +3 -2
- package/lib/parseIdCard.js +1 -1
- package/lib/replaceChar.js +11 -7
- package/lib/safeDate.js +27 -10
- package/lib/transformFieldNames.js +1 -1
- package/lib/treeToList.js +1 -1
- package/lib/utils/config.js +1 -1
- package/lib/utils/type/index.js +14 -0
- package/lib/utils/type/isArrayBuffer.js +32 -0
- package/lib/utils/type/isBlob.js +34 -0
- package/package.json +2 -2
- package/types/ajax.d.ts +121 -0
- package/types/blobToDataURL.d.ts +5 -1
- package/types/download.d.ts +77 -0
- package/types/fileReader.d.ts +3 -0
- package/types/filterTree.d.ts +1 -1
- package/types/findTreeNode.d.ts +1 -1
- package/types/findTreeNodes.d.ts +1 -1
- package/types/findTreeSelect.d.ts +1 -1
- package/types/index.d.ts +8 -5
- package/types/{transformFieldNames.type.d.ts → interface.type.d.ts} +1 -1
- package/types/listToTree.d.ts +1 -1
- package/types/numberToChinese.d.ts +3 -2
- package/types/parseIdCard.d.ts +2 -2
- package/types/replaceChar.d.ts +11 -7
- package/types/safeDate.d.ts +3 -23
- package/types/transformFieldNames.d.ts +2 -2
- package/types/treeToList.d.ts +1 -1
- package/types/utils/type/index.d.ts +21 -19
- package/types/utils/type/isArrayBuffer.d.ts +21 -0
- package/types/utils/type/isBlob.d.ts +23 -0
- package/esm/transformFieldNames.doc.js +0 -35
- package/lib/transformFieldNames.doc.js +0 -42
- /package/lib/{transformFieldNames.type.js → interface.type.js} +0 -0
package/dist/util-helpers.js
CHANGED
|
@@ -537,7 +537,7 @@
|
|
|
537
537
|
}
|
|
538
538
|
|
|
539
539
|
// eslint-disable-next-line no-undef
|
|
540
|
-
var version = "4.
|
|
540
|
+
var version = "4.16.0";
|
|
541
541
|
|
|
542
542
|
/**
|
|
543
543
|
* 打印警告信息
|
|
@@ -1542,6 +1542,31 @@
|
|
|
1542
1542
|
// 最小安全数字
|
|
1543
1543
|
var MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER || -9007199254740991;
|
|
1544
1544
|
|
|
1545
|
+
/**
|
|
1546
|
+
* 检查值是否为Blob对象<br/><br/>
|
|
1547
|
+
*
|
|
1548
|
+
* <em style="font-weight: bold;">注意:该方法仅适用于浏览器端。</em>
|
|
1549
|
+
*
|
|
1550
|
+
* @static
|
|
1551
|
+
* @alias module:Type.isBlob
|
|
1552
|
+
* @since 4.16.0
|
|
1553
|
+
* @param {*} value 检查值
|
|
1554
|
+
* @returns {boolean} 是否为Blob对象
|
|
1555
|
+
* @example
|
|
1556
|
+
*
|
|
1557
|
+
* isBlob(new Blob(['a']))
|
|
1558
|
+
* // => true
|
|
1559
|
+
*
|
|
1560
|
+
* isBlob({})
|
|
1561
|
+
* // => false
|
|
1562
|
+
*
|
|
1563
|
+
* isBlob('2012')
|
|
1564
|
+
* // => false
|
|
1565
|
+
*/
|
|
1566
|
+
function isBlob(value) {
|
|
1567
|
+
return isType(value, 'Blob');
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1545
1570
|
/**
|
|
1546
1571
|
* 检查值是否为Object
|
|
1547
1572
|
*
|
|
@@ -2025,20 +2050,24 @@
|
|
|
2025
2050
|
* @returns {string} 处理后的字符
|
|
2026
2051
|
* @example
|
|
2027
2052
|
*
|
|
2028
|
-
* // 手机号
|
|
2053
|
+
* // 手机号 前3后4
|
|
2029
2054
|
* replaceChar('13000000000'); // 130****0000
|
|
2030
2055
|
*
|
|
2031
|
-
* // 身份证
|
|
2032
|
-
* replaceChar('130701199310302288'); //
|
|
2056
|
+
* // 身份证 前6后4
|
|
2057
|
+
* replaceChar('130701199310302288', { start: 6, end: -4 }); // 130701********2288
|
|
2033
2058
|
*
|
|
2034
|
-
* // 邮箱
|
|
2059
|
+
* // 邮箱 @前两位
|
|
2035
2060
|
* const email = '12345@qq.com'
|
|
2061
|
+
* const emailAtIndex = email.indexOf('@');
|
|
2062
|
+
* replaceChar(email, { start: emailAtIndex - 2, end: emailAtIndex }); // 123**@qq.com
|
|
2063
|
+
* // 邮箱 前2和@后面内容,固定替换字符4位
|
|
2036
2064
|
* replaceChar(email, {start: 2, end: email.indexOf('@'), repeat: 4}); // 12****@qq.com
|
|
2037
2065
|
*
|
|
2038
|
-
* // 银行卡号
|
|
2066
|
+
* // 银行卡号 只展示后4位,固定替换字符4位
|
|
2039
2067
|
* replaceChar('6228480402564890018', {start: 0, end: -4, repeat: 4}); // ****0018
|
|
2040
|
-
*
|
|
2041
|
-
* //
|
|
2068
|
+
* // 银行卡号 前6后4
|
|
2069
|
+
* replaceChar('6228480402564890018', { start: 6, end: -4 }); // 622848*********0018
|
|
2070
|
+
* // 银行卡号 前4后3 忽略格式的空格
|
|
2042
2071
|
* replaceChar('6228 4804 0256 4890 018', {start: 4, end: -4, exclude: ' '}); // 6228 **** **** **** 018
|
|
2043
2072
|
*
|
|
2044
2073
|
* // 用户名
|
|
@@ -2211,8 +2240,9 @@
|
|
|
2211
2240
|
}
|
|
2212
2241
|
|
|
2213
2242
|
/**
|
|
2214
|
-
*
|
|
2215
|
-
*
|
|
2243
|
+
* 数字转中文数字<br/><br/>
|
|
2244
|
+
*
|
|
2245
|
+
* 如果数字不在安全数字 -9007199254740991~9007199254740991 范围内,处理会有异常。
|
|
2216
2246
|
*
|
|
2217
2247
|
* @static
|
|
2218
2248
|
* @alias module:Processor.numberToChinese
|
|
@@ -2419,7 +2449,7 @@
|
|
|
2419
2449
|
* @since 4.0.0
|
|
2420
2450
|
* @see 参考 {@link https://baike.baidu.com/item/居民身份证号码|居民身份证号码}
|
|
2421
2451
|
* @param {string} id 身份证号码,支持15位
|
|
2422
|
-
* @returns {null
|
|
2452
|
+
* @returns {IdCardInfo | null} 省份、生日、性别,省/市/区/年/月/日/性别编码。如果解析失败将返回 null 。
|
|
2423
2453
|
* @example
|
|
2424
2454
|
*
|
|
2425
2455
|
* parseIdCard('123456789123456'); // null
|
|
@@ -2481,37 +2511,63 @@
|
|
|
2481
2511
|
};
|
|
2482
2512
|
}
|
|
2483
2513
|
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2514
|
+
var FileReaderMethodMap = {
|
|
2515
|
+
arrayBuffer: 'readAsArrayBuffer',
|
|
2516
|
+
binaryString: 'readAsBinaryString',
|
|
2517
|
+
dataURL: 'readAsDataURL',
|
|
2518
|
+
text: 'readAsText'
|
|
2519
|
+
};
|
|
2520
|
+
|
|
2521
|
+
/**
|
|
2522
|
+
* @overload
|
|
2523
|
+
* @param {Blob} blob
|
|
2524
|
+
* @param {'arrayBuffer'} type
|
|
2525
|
+
* @returns {Promise<ArrayBuffer>}
|
|
2526
|
+
*/
|
|
2527
|
+
|
|
2528
|
+
/**
|
|
2529
|
+
* @overload
|
|
2530
|
+
* @param {Blob} blob
|
|
2531
|
+
* @param {'binaryString'|'binaryString'|'dataURL'|'text'} [type='dataURL']
|
|
2532
|
+
* @returns {Promise<string>}
|
|
2533
|
+
*/
|
|
2487
2534
|
|
|
2488
2535
|
/**
|
|
2489
|
-
*
|
|
2536
|
+
* 读取 Blob 或 File 对象<br/><br/>
|
|
2537
|
+
*
|
|
2538
|
+
* <em style="font-weight: bold;">注意:该方法仅适用于浏览器端。</em>
|
|
2490
2539
|
*
|
|
2491
2540
|
* @static
|
|
2492
|
-
* @alias module:Processor.
|
|
2493
|
-
* @see 参考 {@link https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader
|
|
2494
|
-
* @since 4.
|
|
2541
|
+
* @alias module:Processor.fileReader
|
|
2542
|
+
* @see 参考 {@link https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader|FileReader}
|
|
2543
|
+
* @since 4.16.0
|
|
2495
2544
|
* @param {Blob} blob Blob 或 File 对象
|
|
2496
|
-
* @
|
|
2545
|
+
* @param {'arrayBuffer'|'binaryString'|'dataURL'|'text'} [type='dataURL'] Blob 或 File 对象
|
|
2546
|
+
* @returns {Promise<string|ArrayBuffer>} 文件的内容
|
|
2497
2547
|
* @example
|
|
2498
2548
|
* const aFileParts = ['<a id="a"><b id="b">hey!</b></a>']; // 一个包含DOMString的数组
|
|
2499
2549
|
* const htmlBlob = new Blob(aFileParts, { type: 'text/html' }); // 得到 blob
|
|
2500
2550
|
*
|
|
2501
|
-
*
|
|
2551
|
+
* fileReader(htmlBlob).then(data=>{
|
|
2502
2552
|
* console.log(data); // data:text/html;base64,PGEgaWQ9ImEiPjxiIGlkPSJiIj5oZXkhPC9iPjwvYT4=
|
|
2503
2553
|
* });
|
|
2504
2554
|
*
|
|
2505
2555
|
* const textBlob = new Blob(aFileParts, { type: 'text/plain' });
|
|
2506
2556
|
*
|
|
2507
|
-
*
|
|
2508
|
-
* console.log(data); //
|
|
2557
|
+
* fileReader(textBlob, 'text').then(data=>{
|
|
2558
|
+
* console.log(data); // <a id="a"><b id="b">hey!</b></a>
|
|
2509
2559
|
* });
|
|
2510
2560
|
*/
|
|
2511
|
-
function
|
|
2561
|
+
function fileReader(blob) {
|
|
2562
|
+
var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'dataURL';
|
|
2563
|
+
var method = FileReaderMethodMap[type];
|
|
2564
|
+
if (!method) {
|
|
2565
|
+
method = FileReaderMethodMap.dataURL;
|
|
2566
|
+
}
|
|
2512
2567
|
return new Promise(function (resolve, reject) {
|
|
2513
2568
|
var reader = new FileReader();
|
|
2514
|
-
|
|
2569
|
+
// @ts-ignore
|
|
2570
|
+
reader[method](blob);
|
|
2515
2571
|
// @ts-ignore
|
|
2516
2572
|
reader.onload = function () {
|
|
2517
2573
|
return resolve(reader.result);
|
|
@@ -2522,6 +2578,39 @@
|
|
|
2522
2578
|
});
|
|
2523
2579
|
}
|
|
2524
2580
|
|
|
2581
|
+
// file、blob文件如何预览图片?
|
|
2582
|
+
|
|
2583
|
+
/**
|
|
2584
|
+
* 将 Blob 或 File 对象转成 data:URL 格式的 Base64 字符串<br/><br/>
|
|
2585
|
+
*
|
|
2586
|
+
* <em style="font-weight: bold;">注意:该方法仅适用于浏览器端。</em>
|
|
2587
|
+
*
|
|
2588
|
+
* @static
|
|
2589
|
+
* @alias module:Processor.blobToDataURL
|
|
2590
|
+
* @see 参考 {@link https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader/readAsDataURL|FileReader.readAsDataURL()}
|
|
2591
|
+
* @since 4.1.0
|
|
2592
|
+
* @ignore
|
|
2593
|
+
* @deprecated 请使用 `fileReader` 方法
|
|
2594
|
+
* @param {Blob} blob Blob 或 File 对象
|
|
2595
|
+
* @returns {Promise<string>} data:URL 格式的 Base64 字符串。
|
|
2596
|
+
* @example
|
|
2597
|
+
* const aFileParts = ['<a id="a"><b id="b">hey!</b></a>']; // 一个包含DOMString的数组
|
|
2598
|
+
* const htmlBlob = new Blob(aFileParts, { type: 'text/html' }); // 得到 blob
|
|
2599
|
+
*
|
|
2600
|
+
* blobToDataURL(htmlBlob).then(data=>{
|
|
2601
|
+
* console.log(data); // data:text/html;base64,PGEgaWQ9ImEiPjxiIGlkPSJiIj5oZXkhPC9iPjwvYT4=
|
|
2602
|
+
* });
|
|
2603
|
+
*
|
|
2604
|
+
* const textBlob = new Blob(aFileParts, { type: 'text/plain' });
|
|
2605
|
+
*
|
|
2606
|
+
* blobToDataURL(textBlob).then(data=>{
|
|
2607
|
+
* console.log(data); // data:text/plain;base64,PGEgaWQ9ImEiPjxiIGlkPSJiIj5oZXkhPC9iPjwvYT4=
|
|
2608
|
+
* });
|
|
2609
|
+
*/
|
|
2610
|
+
function blobToDataURL(blob) {
|
|
2611
|
+
return fileReader(blob);
|
|
2612
|
+
}
|
|
2613
|
+
|
|
2525
2614
|
/**
|
|
2526
2615
|
* 将 DataURL 转为 Blob 对象
|
|
2527
2616
|
*
|
|
@@ -2536,17 +2625,18 @@
|
|
|
2536
2625
|
* dataURLToBlob(dataurl); // Blob {size: 32, type: 'text/html'}
|
|
2537
2626
|
*/
|
|
2538
2627
|
function dataURLToBlob(dataurl) {
|
|
2539
|
-
var
|
|
2540
|
-
|
|
2541
|
-
var
|
|
2542
|
-
var
|
|
2628
|
+
var parts = dataurl.split(',');
|
|
2629
|
+
var meta = parts[0].substring(5).split(';');
|
|
2630
|
+
var type = meta[0];
|
|
2631
|
+
var decoder = meta.indexOf('base64') !== -1 ? atob : decodeURIComponent;
|
|
2632
|
+
var bstr = decoder(parts[1]);
|
|
2543
2633
|
var n = bstr.length;
|
|
2544
2634
|
var u8arr = new Uint8Array(n);
|
|
2545
2635
|
while (n--) {
|
|
2546
2636
|
u8arr[n] = bstr.charCodeAt(n);
|
|
2547
2637
|
}
|
|
2548
2638
|
return new Blob([u8arr], {
|
|
2549
|
-
type:
|
|
2639
|
+
type: type
|
|
2550
2640
|
});
|
|
2551
2641
|
}
|
|
2552
2642
|
|
|
@@ -2580,11 +2670,34 @@
|
|
|
2580
2670
|
return "data:".concat(mimetype).concat(base64 ? ';base64' : '', ",").concat(data);
|
|
2581
2671
|
}
|
|
2582
2672
|
|
|
2583
|
-
|
|
2673
|
+
/**
|
|
2674
|
+
* @overload
|
|
2675
|
+
* @return {Date}
|
|
2676
|
+
*/
|
|
2677
|
+
|
|
2678
|
+
/**
|
|
2679
|
+
* @overload
|
|
2680
|
+
* @param {number | string | Date} value Unix时间戳、时间戳字符串 dateString 、Date 日期对象
|
|
2681
|
+
* @return {Date}
|
|
2682
|
+
*/
|
|
2683
|
+
|
|
2684
|
+
/**
|
|
2685
|
+
* @overload
|
|
2686
|
+
* @param {number} year 表示年份的整数值。0 到 99 会被映射至 1900 年至 1999 年,其他值代表实际年份。
|
|
2687
|
+
* @param {number} monthIndex 表示月份的整数值,从 0(1 月)到 11(12 月)。
|
|
2688
|
+
* @param {number} [date] 表示一个月中的第几天的整数值,从 1 开始。默认值为 1。
|
|
2689
|
+
* @param {number} [hours] 表示一天中的小时数的整数值 (24 小时制)。默认值为 0(午夜)。
|
|
2690
|
+
* @param {number} [minutes] 表示一个完整时间(如 01:10:00)中的分钟部分的整数值。默认值为 0。
|
|
2691
|
+
* @param {number} [seconds] 表示一个完整时间(如 01:10:00)中的秒部分的整数值。默认值为 0。
|
|
2692
|
+
* @param {number} [ms] 表示一个完整时间的毫秒部分的整数值。默认值为 0。
|
|
2693
|
+
* @return {Date}
|
|
2694
|
+
*/
|
|
2584
2695
|
|
|
2585
2696
|
/**
|
|
2586
|
-
* 创建一个 Date 实例日期对象,同 new Date()
|
|
2587
|
-
*
|
|
2697
|
+
* 创建一个 Date 实例日期对象,同 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date#%E5%8F%82%E6%95%B0">new Date()</a> <br/><br/>
|
|
2698
|
+
*
|
|
2699
|
+
* 规避了苹果设备浏览器不支持部分格式(例如,YYYY-MM-DD HH-mm 或 YYYY.MM.DD)。<br/>
|
|
2700
|
+
* 如果参数为 undefined 正常返回 Date 。
|
|
2588
2701
|
*
|
|
2589
2702
|
* @static
|
|
2590
2703
|
* @alias module:Processor.safeDate
|
|
@@ -2601,8 +2714,6 @@
|
|
|
2601
2714
|
* safeDate('2022.1.1 11:11'); // Sat Jan 01 2022 11:11:00 GMT+0800 (中国标准时间)
|
|
2602
2715
|
* safeDate(99, 1); // Mon Feb 01 1999 00:00:00 GMT+0800 (中国标准时间)
|
|
2603
2716
|
* safeDate(1646711233171); // Tue Mar 08 2022 11:47:13 GMT+0800 (中国标准时间)
|
|
2604
|
-
*
|
|
2605
|
-
*
|
|
2606
2717
|
*/
|
|
2607
2718
|
function safeDate(value) {
|
|
2608
2719
|
var safeValue = typeof value === 'string' ? value.replace(/[\\.-]/g, '/') : value;
|
|
@@ -2613,9 +2724,7 @@
|
|
|
2613
2724
|
// @ts-ignore
|
|
2614
2725
|
return _construct(Date, [safeValue].concat(args));
|
|
2615
2726
|
}
|
|
2616
|
-
|
|
2617
|
-
// @ts-ignore
|
|
2618
|
-
return isNil(safeValue) ? new Date() : new Date(safeValue);
|
|
2727
|
+
return typeof safeValue === 'undefined' ? new Date() : new Date(safeValue);
|
|
2619
2728
|
}
|
|
2620
2729
|
|
|
2621
2730
|
/**
|
|
@@ -2698,352 +2807,110 @@
|
|
|
2698
2807
|
}
|
|
2699
2808
|
|
|
2700
2809
|
/**
|
|
2701
|
-
*
|
|
2702
|
-
*
|
|
2810
|
+
* 精确乘法,支持多个数相乘,乘数默认为 1 。
|
|
2811
|
+
*
|
|
2703
2812
|
* @static
|
|
2704
|
-
* @alias module:
|
|
2705
|
-
* @since
|
|
2706
|
-
* @
|
|
2707
|
-
* @
|
|
2708
|
-
* @template {string} C
|
|
2709
|
-
* @param {D[]} data 对象数组。如果是树结构数据,需要指定第三个参数 childrenField
|
|
2710
|
-
* @param {F} fieldNames 字段名映射
|
|
2711
|
-
* @param {C} [childrenField] 子级数据字段名
|
|
2712
|
-
* @param {'spread'|'self'} [nodeAssign='spread'] 节点赋值方式。spread表示使用展开运算符创建新值,self表示使用自身对象。
|
|
2713
|
-
* @returns {import('./transformFieldNames.type.js').TransformFieldNames<D, F, C>}
|
|
2813
|
+
* @alias module:Math.times
|
|
2814
|
+
* @since 3.1.0
|
|
2815
|
+
* @param {...number|string} nums 相乘的数
|
|
2816
|
+
* @returns {number} 乘积
|
|
2714
2817
|
* @example
|
|
2818
|
+
*
|
|
2819
|
+
* times(3, 0.6); // 1.8
|
|
2820
|
+
* times(3, 0.6, 2); // 3.6
|
|
2821
|
+
* times(3, 0.6, 2, 10); // 36
|
|
2715
2822
|
*
|
|
2716
|
-
* const options = [{code: '1', name: 'one'},{code:'2', name:'two'}];
|
|
2717
|
-
* const newOptions = transformFieldNames(options, {label: 'name', value: 'code'});
|
|
2718
|
-
* // [{value: '1', label: 'one'},{value:'2', label:'two'}]
|
|
2719
|
-
*
|
|
2720
|
-
* // 嵌套数据,指定子级字段名 children
|
|
2721
|
-
* const options2 = [{code: '1', name: 'one'},{code:'2', name:'two', children: [{code:'2-1', name:'two-one', children: [{code: '2-1-1', name:'two-one-one'}]}]}];
|
|
2722
|
-
* const newOptions2 = transformFieldNames(options2, {label: 'name', value: 'code'}, 'children');
|
|
2723
|
-
* // [{value: '1', label: 'one'},{value:'2', label:'two', children: [{value: '2-1', label:'two-one', children: [{value: '2-1-1', label:'two-one-one'}]}]}]
|
|
2724
|
-
*
|
|
2725
|
-
* const options3 = [{code: '1', name: 'one'},{code:'2', name:'two', childs: [{code:'2-1', name:'two-one'}]}];
|
|
2726
|
-
* const newOptions3 = transformFieldNames(options3, {label: 'name', value: 'code'}, 'childs');
|
|
2727
|
-
* // [{value: '1', label: 'one'},{value:'2', label:'two', childs: [{value: '2-1', label:'two-one'}]}]
|
|
2728
|
-
*
|
|
2729
|
-
* // 嵌套数据,并替换子集字段名
|
|
2730
|
-
* const newOptions4 = transformFieldNames(options3, {label: 'name', value: 'code', children: 'childs'}, 'childs');
|
|
2731
|
-
* // [{value: '1', label: 'one'},{value:'2', label:'two', children: [{value: '2-1', label:'two-one'}]}]
|
|
2732
2823
|
*/
|
|
2733
|
-
function
|
|
2734
|
-
var
|
|
2735
|
-
|
|
2736
|
-
return data;
|
|
2737
|
-
}
|
|
2738
|
-
if (data.length <= 0) {
|
|
2739
|
-
// @ts-ignore
|
|
2740
|
-
return [];
|
|
2824
|
+
function times() {
|
|
2825
|
+
for (var _len = arguments.length, nums = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
2826
|
+
nums[_key] = arguments[_key];
|
|
2741
2827
|
}
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
*/
|
|
2749
|
-
function recusion(arr) {
|
|
2750
|
-
return arr.map(function (item) {
|
|
2751
|
-
if (!isObject(item)) {
|
|
2752
|
-
return item;
|
|
2753
|
-
}
|
|
2754
|
-
var newItem = nodeAssign === 'spread' ? _objectSpread2({}, item) : item;
|
|
2755
|
-
/** @type {Array.<string>} */
|
|
2756
|
-
var delKeys = [];
|
|
2757
|
-
|
|
2758
|
-
// 树形数据子节点
|
|
2759
|
-
// @ts-ignore
|
|
2760
|
-
if (childrenField && Array.isArray(newItem[childrenField]) && newItem[childrenField].length > 0) {
|
|
2761
|
-
// @ts-ignore
|
|
2762
|
-
newItem[childrenField] = recusion(newItem[childrenField].slice());
|
|
2763
|
-
}
|
|
2764
|
-
|
|
2765
|
-
// 替换字段名
|
|
2766
|
-
Object.keys(fieldNames).forEach(function (newKey) {
|
|
2767
|
-
var oldKey = fieldNames[newKey];
|
|
2768
|
-
if (oldKey in newItem) {
|
|
2769
|
-
// @ts-ignore
|
|
2770
|
-
newItem[newKey] = newItem[oldKey];
|
|
2771
|
-
// @ts-ignore
|
|
2772
|
-
delKeys.push(oldKey);
|
|
2773
|
-
}
|
|
2774
|
-
});
|
|
2775
|
-
|
|
2776
|
-
// 删除旧字段
|
|
2777
|
-
if (delKeys.length > 0) {
|
|
2778
|
-
delKeys.forEach(function (delKey) {
|
|
2779
|
-
// @ts-ignore
|
|
2780
|
-
delete newItem[delKey];
|
|
2781
|
-
});
|
|
2782
|
-
}
|
|
2783
|
-
return newItem;
|
|
2784
|
-
});
|
|
2828
|
+
var num1 = nums[0],
|
|
2829
|
+
_nums$ = nums[1],
|
|
2830
|
+
num2 = _nums$ === void 0 ? 1 : _nums$,
|
|
2831
|
+
rest = nums.slice(2);
|
|
2832
|
+
if (rest.length > 0) {
|
|
2833
|
+
return times.apply(void 0, [times(num1, num2)].concat(_toConsumableArray(rest)));
|
|
2785
2834
|
}
|
|
2835
|
+
num1 = transformEffectiveNumber(num1);
|
|
2836
|
+
num2 = transformEffectiveNumber(num2);
|
|
2786
2837
|
|
|
2838
|
+
// 兼容处理,如果参数包含无效数值时,返回 NaN
|
|
2787
2839
|
// @ts-ignore
|
|
2788
|
-
|
|
2840
|
+
if (isNaN(num1) || isNaN(num2)) {
|
|
2841
|
+
return Number.NaN;
|
|
2842
|
+
}
|
|
2843
|
+
var num1Changed = float2Fixed(num1);
|
|
2844
|
+
var num2Changed = float2Fixed(num2);
|
|
2845
|
+
var baseNum = digitLength(num1) + digitLength(num2);
|
|
2846
|
+
var leftValue = num1Changed * num2Changed;
|
|
2847
|
+
checkBoundary(leftValue);
|
|
2848
|
+
return leftValue / Math.pow(10, baseNum);
|
|
2789
2849
|
}
|
|
2790
2850
|
|
|
2791
2851
|
/**
|
|
2792
|
-
*
|
|
2852
|
+
* 精确加法,支持多个数相加,加数默认为 0 。
|
|
2853
|
+
*
|
|
2854
|
+
* @static
|
|
2855
|
+
* @alias module:Math.plus
|
|
2856
|
+
* @since 3.1.0
|
|
2857
|
+
* @param {...number|string} nums 相加的数
|
|
2858
|
+
* @returns {number} 总和
|
|
2859
|
+
* @example
|
|
2860
|
+
*
|
|
2861
|
+
* plus(0.1, 0.2); // 0.3
|
|
2862
|
+
* plus(0.1, 0.2, 0.3); // 0.6
|
|
2863
|
+
* plus(0.1, 0.2, 0.3, 0.4); // 1
|
|
2793
2864
|
*
|
|
2794
|
-
* @private
|
|
2795
|
-
* @template {Record<string,any>} [T=Record<string,any>]
|
|
2796
|
-
* @param {T[]} arr 列表数据
|
|
2797
|
-
* @param {object} [options] 配置项
|
|
2798
|
-
* @param {string} [options.childrenField='children'] 子级字段名称
|
|
2799
|
-
* @param {'none'|'null'} [options.emptyChildrenValue='none'] 子级为空时的值,none表示删除该子级,null表示为null,array表示为[]。
|
|
2800
2865
|
*/
|
|
2801
|
-
function
|
|
2802
|
-
var
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2866
|
+
function plus() {
|
|
2867
|
+
for (var _len = arguments.length, nums = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
2868
|
+
nums[_key] = arguments[_key];
|
|
2869
|
+
}
|
|
2870
|
+
var num1 = nums[0],
|
|
2871
|
+
_nums$ = nums[1],
|
|
2872
|
+
num2 = _nums$ === void 0 ? 0 : _nums$,
|
|
2873
|
+
rest = nums.slice(2);
|
|
2874
|
+
if (rest.length > 0) {
|
|
2875
|
+
return plus.apply(void 0, [plus(num1, num2)].concat(_toConsumableArray(rest)));
|
|
2876
|
+
}
|
|
2877
|
+
num1 = transformEffectiveNumber(num1);
|
|
2878
|
+
num2 = transformEffectiveNumber(num2);
|
|
2879
|
+
|
|
2880
|
+
// 兼容处理,如果参数包含无效数值时,返回 NaN
|
|
2881
|
+
// @ts-ignore
|
|
2882
|
+
if (isNaN(num1) || isNaN(num2)) {
|
|
2883
|
+
return Number.NaN;
|
|
2884
|
+
}
|
|
2885
|
+
var baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
|
|
2886
|
+
return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
|
|
2822
2887
|
}
|
|
2823
2888
|
|
|
2824
2889
|
/**
|
|
2825
|
-
*
|
|
2826
|
-
*
|
|
2890
|
+
* 精确减法,支持多个数相减,减数默认为 0 。
|
|
2891
|
+
*
|
|
2827
2892
|
* @static
|
|
2828
|
-
* @alias module:
|
|
2829
|
-
* @since 4.14.0
|
|
2830
|
-
* @template {Record<string,any>} [T=Record<string,any>]
|
|
2831
|
-
* @template {*} [R=T&Record<string,any>]
|
|
2832
|
-
* @param {T[]} list 列表数据
|
|
2833
|
-
* @param {object} [options] 配置项
|
|
2834
|
-
* @param {string} [options.keyField='id'] 当前数据的键值字段名称
|
|
2835
|
-
* @param {string} [options.parentField='pid'] 当前数据的父级字段名称
|
|
2836
|
-
* @param {string} [options.childrenField='children'] 子级字段名称
|
|
2837
|
-
* @param {'none'|'null'|'array'} [options.emptyChildrenValue='none'] 子级为空时的值,none表示删除该子级,null表示为null,array表示为[]。
|
|
2838
|
-
* @param {'spread'|'self'} [options.nodeAssign='spread'] 节点赋值方式。spread表示使用展开运算符创建新值,self表示使用自身对象。
|
|
2839
|
-
* @returns {R[]} 树结构
|
|
2840
|
-
* @example
|
|
2841
|
-
*
|
|
2842
|
-
* const menus = [
|
|
2843
|
-
* { id: '1', name: '首页', code: 'trade', pid: null },
|
|
2844
|
-
* { id: '2', name: '交易管理', code: 'trade', pid: null },
|
|
2845
|
-
* { id: '3', name: '交易查询', code: 'trade-1', pid: '2' },
|
|
2846
|
-
* { id: '4', name: '交易查询-查询操作', code: 'trade-1-1', pid: '3' },
|
|
2847
|
-
* { id: '5', name: '权限管理', code: 'authorization', pid: null },
|
|
2848
|
-
* { id: '6', name: '角色管理', code: 'authorization-1', pid: '5' },
|
|
2849
|
-
* { id: '7', name: '用户管理', code: 'authorization-2', pid: '5' }
|
|
2850
|
-
* ];
|
|
2851
|
-
* listToTree(menus);
|
|
2852
|
-
* // [{"id":"1","name":"首页","code":"trade","pid":null},{"id":"2","name":"交易管理","code":"trade","pid":null,"children":[{"id":"3","name":"交易查询","code":"trade-1","pid":"2","children":[{"id":"4","name":"交易查询-查询操作","code":"trade-1-1","pid":"3"}]}]},{"id":"5","name":"权限管理","code":"authorization","pid":null,"children":[{"id":"6","name":"角色管理","code":"authorization-1","pid":"5"},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]}]
|
|
2853
|
-
*
|
|
2854
|
-
* // 自定义子级字段名
|
|
2855
|
-
* listToTree(basicMenus, { childrenField: 'childs' });
|
|
2856
|
-
* // [{"id":"1","name":"首页","code":"trade","pid":null},{"id":"2","name":"交易管理","code":"trade","pid":null,"childs":[{"id":"3","name":"交易查询","code":"trade-1","pid":"2","childs":[{"id":"4","name":"交易查询-查询操作","code":"trade-1-1","pid":"3"}]}]},{"id":"5","name":"权限管理","code":"authorization","pid":null,"childs":[{"id":"6","name":"角色管理","code":"authorization-1","pid":"5"},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]}]
|
|
2857
|
-
*
|
|
2858
|
-
*/
|
|
2859
|
-
function listToTree(list, options) {
|
|
2860
|
-
var _ref2 = options || {},
|
|
2861
|
-
_ref2$keyField = _ref2.keyField,
|
|
2862
|
-
keyField = _ref2$keyField === void 0 ? 'id' : _ref2$keyField,
|
|
2863
|
-
_ref2$parentField = _ref2.parentField,
|
|
2864
|
-
parentField = _ref2$parentField === void 0 ? 'pid' : _ref2$parentField,
|
|
2865
|
-
_ref2$childrenField = _ref2.childrenField,
|
|
2866
|
-
childrenField = _ref2$childrenField === void 0 ? 'children' : _ref2$childrenField,
|
|
2867
|
-
_ref2$emptyChildrenVa = _ref2.emptyChildrenValue,
|
|
2868
|
-
emptyChildrenValue = _ref2$emptyChildrenVa === void 0 ? 'none' : _ref2$emptyChildrenVa,
|
|
2869
|
-
_ref2$nodeAssign = _ref2.nodeAssign,
|
|
2870
|
-
nodeAssign = _ref2$nodeAssign === void 0 ? 'spread' : _ref2$nodeAssign;
|
|
2871
|
-
|
|
2872
|
-
/** @type {R[]} */
|
|
2873
|
-
var tree = [];
|
|
2874
|
-
|
|
2875
|
-
/** @type {Object.<string, T[]>} */
|
|
2876
|
-
var record = {};
|
|
2877
|
-
if (!Array.isArray(list)) {
|
|
2878
|
-
return tree;
|
|
2879
|
-
}
|
|
2880
|
-
list.forEach(function (item) {
|
|
2881
|
-
if (isObject(item)) {
|
|
2882
|
-
var newItem = nodeAssign === 'spread' ? _objectSpread2({}, item) : item;
|
|
2883
|
-
|
|
2884
|
-
/** @type {string} */
|
|
2885
|
-
var id = newItem[keyField];
|
|
2886
|
-
|
|
2887
|
-
/** @type {string} */
|
|
2888
|
-
var pid = newItem[parentField];
|
|
2889
|
-
if (record[id]) {
|
|
2890
|
-
// @ts-ignore
|
|
2891
|
-
newItem[childrenField] = record[id];
|
|
2892
|
-
} else {
|
|
2893
|
-
// @ts-ignore
|
|
2894
|
-
newItem[childrenField] = record[id] = [];
|
|
2895
|
-
}
|
|
2896
|
-
if (pid) {
|
|
2897
|
-
if (!record[pid]) {
|
|
2898
|
-
record[pid] = [newItem];
|
|
2899
|
-
} else {
|
|
2900
|
-
record[pid].push(newItem);
|
|
2901
|
-
}
|
|
2902
|
-
} else {
|
|
2903
|
-
// @ts-ignore
|
|
2904
|
-
tree.push(newItem);
|
|
2905
|
-
}
|
|
2906
|
-
}
|
|
2907
|
-
});
|
|
2908
|
-
if (emptyChildrenValue !== 'array') {
|
|
2909
|
-
// @ts-ignore
|
|
2910
|
-
processEmptyChildren(tree, options);
|
|
2911
|
-
}
|
|
2912
|
-
return tree;
|
|
2913
|
-
}
|
|
2914
|
-
|
|
2915
|
-
/**
|
|
2916
|
-
* 树结构转列表数据
|
|
2917
|
-
*
|
|
2918
|
-
* @static
|
|
2919
|
-
* @alias module:Processor.treeToList
|
|
2920
|
-
* @since 4.14.0
|
|
2921
|
-
* @template {Record<string,any>} T
|
|
2922
|
-
* @template {keyof T} K
|
|
2923
|
-
* @template {Omit<T, K>} R
|
|
2924
|
-
* @param {T[]} tree 列表数据
|
|
2925
|
-
* @param {K} childrenField 子级字段名称
|
|
2926
|
-
* @returns {R[]} 列表数据
|
|
2927
|
-
* @example
|
|
2928
|
-
* const menus = [{ "id": "1", "name": "首页", "code": "trade", "pid": null }, { "id": "2", "name": "交易管理", "code": "trade", "pid": null, "children": [{ "id": "3", "name": "交易查询", "code": "trade-1", "pid": "2", "children": [{ "id": "4", "name": "交易查询-查询操作", "code": "trade-1-1", "pid": "3" }] }] }, { "id": "5", "name": "权限管理", "code": "authorization", "pid": null, "children": [{ "id": "6", "name": "角色管理", "code": "authorization-1", "pid": "5" }, { "id": "7", "name": "用户管理", "code": "authorization-2", "pid": "5" }] }];
|
|
2929
|
-
*
|
|
2930
|
-
* treeToList(menus, 'children'));
|
|
2931
|
-
* // [{"id":"1","name":"首页","code":"trade","pid":null},{"id":"2","name":"交易管理","code":"trade","pid":null},{"id":"3","name":"交易查询","code":"trade-1","pid":"2"},{"id":"4","name":"交易查询-查询操作","code":"trade-1-1","pid":"3"},{"id":"5","name":"权限管理","code":"authorization","pid":null},{"id":"6","name":"角色管理","code":"authorization-1","pid":"5"},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]
|
|
2932
|
-
*/
|
|
2933
|
-
function treeToList(tree, childrenField) {
|
|
2934
|
-
/** @type {R[]} */
|
|
2935
|
-
var list = [];
|
|
2936
|
-
if (!Array.isArray(tree)) {
|
|
2937
|
-
return list;
|
|
2938
|
-
}
|
|
2939
|
-
|
|
2940
|
-
/**
|
|
2941
|
-
* 递归遍历
|
|
2942
|
-
* @param {T[]} arr 列表数据
|
|
2943
|
-
*/
|
|
2944
|
-
function recusion(arr) {
|
|
2945
|
-
arr.forEach(function (item) {
|
|
2946
|
-
if (isObject(item)) {
|
|
2947
|
-
var newItem = _objectSpread2({}, item);
|
|
2948
|
-
// @ts-ignore
|
|
2949
|
-
list.push(newItem);
|
|
2950
|
-
if (newItem[childrenField]) {
|
|
2951
|
-
if (Array.isArray(newItem[childrenField]) && newItem[childrenField].length > 0) {
|
|
2952
|
-
recusion(newItem[childrenField]);
|
|
2953
|
-
}
|
|
2954
|
-
delete newItem[childrenField];
|
|
2955
|
-
}
|
|
2956
|
-
} else {
|
|
2957
|
-
// @ts-ignore
|
|
2958
|
-
list.push(item);
|
|
2959
|
-
}
|
|
2960
|
-
});
|
|
2961
|
-
}
|
|
2962
|
-
recusion(tree);
|
|
2963
|
-
return list;
|
|
2964
|
-
}
|
|
2965
|
-
|
|
2966
|
-
/**
|
|
2967
|
-
* 过滤/筛选树节点。<br/><br/>如果某节点被过滤掉,它的子节点也一并抛弃
|
|
2968
|
-
*
|
|
2969
|
-
* @static
|
|
2970
|
-
* @alias module:Processor.filterTree
|
|
2971
|
-
* @since 4.15.0
|
|
2972
|
-
* @template {any} T
|
|
2973
|
-
* @template {(item: T) => boolean} F
|
|
2974
|
-
* @param {T[]} tree 树结构数据
|
|
2975
|
-
* @param {F} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy ,结果将包含该节点
|
|
2976
|
-
* @param {string} [childrenField='children'] 子级字段名
|
|
2977
|
-
* @param {'spread'|'self'} [nodeAssign='spread'] 节点赋值方式。spread表示使用展开运算符创建新值,self表示使用自身对象。
|
|
2978
|
-
* @returns {T[]}
|
|
2979
|
-
* @example
|
|
2980
|
-
* const menus = [{ "id": "1", "name": "首页", "code": "trade", "pid": null }, { "id": "2", "name": "交易管理", "code": "trade", "pid": null, "children": [{ "id": "3", "name": "交易查询", "code": "trade-1", "pid": "2", "children": [{ "id": "4", "name": "交易查询-查询操作", "code": "trade-1-1", "pid": "3" }] }] }, { "id": "5", "name": "权限管理", "code": "authorization", "pid": null, "children": [{ "id": "6", "name": "角色管理", "code": "authorization-1", "pid": "5" }, { "id": "7", "name": "用户管理", "code": "authorization-2", "pid": "5" }] }];
|
|
2981
|
-
*
|
|
2982
|
-
* filterTree(menus, item=>item.name.indexOf('管理') > -1);
|
|
2983
|
-
* // [{"id":"2","name":"交易管理","code":"trade","pid":null,"children":[]},{"id":"5","name":"权限管理","code":"authorization","pid":null,"children":[{"id":"6","name":"角色管理","code":"authorization-1","pid":"5"},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]}]
|
|
2984
|
-
*
|
|
2985
|
-
* // 如果某节点被过滤掉,它的子节点也一并抛弃
|
|
2986
|
-
* filterTree(menus, item=>item.id === '7');
|
|
2987
|
-
* // []
|
|
2988
|
-
*
|
|
2989
|
-
* filterTree(menus, item=>item.id === 'not found');
|
|
2990
|
-
* // []
|
|
2991
|
-
*/
|
|
2992
|
-
function filterTree(tree, predicate) {
|
|
2993
|
-
var childrenField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
|
|
2994
|
-
var nodeAssign = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'spread';
|
|
2995
|
-
/** @type {T[]} */
|
|
2996
|
-
var result = [];
|
|
2997
|
-
if (!Array.isArray(tree)) {
|
|
2998
|
-
return result;
|
|
2999
|
-
}
|
|
3000
|
-
tree.forEach(function (item) {
|
|
3001
|
-
var newItem = item;
|
|
3002
|
-
if (isObject(item)) {
|
|
3003
|
-
// @ts-ignore
|
|
3004
|
-
newItem = nodeAssign === 'spread' ? _objectSpread2({}, item) : item;
|
|
3005
|
-
}
|
|
3006
|
-
if (predicate(newItem)) {
|
|
3007
|
-
if (isObject(newItem)) {
|
|
3008
|
-
/** @type {T[]|undefined} */
|
|
3009
|
-
// @ts-ignore
|
|
3010
|
-
var childs = newItem[childrenField];
|
|
3011
|
-
if (Array.isArray(childs) && childs.length > 0) {
|
|
3012
|
-
// @ts-ignore
|
|
3013
|
-
newItem[childrenField] = filterTree(childs, predicate, childrenField, nodeAssign);
|
|
3014
|
-
}
|
|
3015
|
-
}
|
|
3016
|
-
result.push(newItem);
|
|
3017
|
-
}
|
|
3018
|
-
});
|
|
3019
|
-
return result;
|
|
3020
|
-
}
|
|
3021
|
-
|
|
3022
|
-
/**
|
|
3023
|
-
* 精确乘法,支持多个数相乘,乘数默认为 1 。
|
|
3024
|
-
*
|
|
3025
|
-
* @static
|
|
3026
|
-
* @alias module:Math.times
|
|
2893
|
+
* @alias module:Math.minus
|
|
3027
2894
|
* @since 3.1.0
|
|
3028
|
-
* @param {...number|string} nums
|
|
3029
|
-
* @returns {number}
|
|
2895
|
+
* @param {...number|string} nums 相减的数
|
|
2896
|
+
* @returns {number} 差
|
|
3030
2897
|
* @example
|
|
3031
2898
|
*
|
|
3032
|
-
*
|
|
3033
|
-
*
|
|
3034
|
-
*
|
|
2899
|
+
* minus(1, 0.9); // 0.1
|
|
2900
|
+
* minus(1, 0.9, 0.02); // 0.08
|
|
2901
|
+
* minus(1, 0.9, 0.02, 0.08); // 0
|
|
3035
2902
|
*
|
|
3036
2903
|
*/
|
|
3037
|
-
function
|
|
2904
|
+
function minus() {
|
|
3038
2905
|
for (var _len = arguments.length, nums = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
3039
2906
|
nums[_key] = arguments[_key];
|
|
3040
2907
|
}
|
|
3041
2908
|
var num1 = nums[0],
|
|
3042
2909
|
_nums$ = nums[1],
|
|
3043
|
-
num2 = _nums$ === void 0 ?
|
|
2910
|
+
num2 = _nums$ === void 0 ? 0 : _nums$,
|
|
3044
2911
|
rest = nums.slice(2);
|
|
3045
2912
|
if (rest.length > 0) {
|
|
3046
|
-
return
|
|
2913
|
+
return minus.apply(void 0, [minus(num1, num2)].concat(_toConsumableArray(rest)));
|
|
3047
2914
|
}
|
|
3048
2915
|
num1 = transformEffectiveNumber(num1);
|
|
3049
2916
|
num2 = transformEffectiveNumber(num2);
|
|
@@ -3053,39 +2920,40 @@
|
|
|
3053
2920
|
if (isNaN(num1) || isNaN(num2)) {
|
|
3054
2921
|
return Number.NaN;
|
|
3055
2922
|
}
|
|
3056
|
-
var
|
|
3057
|
-
|
|
3058
|
-
var baseNum = digitLength(num1) + digitLength(num2);
|
|
3059
|
-
var leftValue = num1Changed * num2Changed;
|
|
3060
|
-
checkBoundary(leftValue);
|
|
3061
|
-
return leftValue / Math.pow(10, baseNum);
|
|
2923
|
+
var baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
|
|
2924
|
+
return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
|
|
3062
2925
|
}
|
|
3063
2926
|
|
|
3064
2927
|
/**
|
|
3065
|
-
*
|
|
2928
|
+
* 精确除法,支持多个数相除,除数默认为 1 。
|
|
3066
2929
|
*
|
|
3067
2930
|
* @static
|
|
3068
|
-
* @alias module:Math.
|
|
2931
|
+
* @alias module:Math.divide
|
|
3069
2932
|
* @since 3.1.0
|
|
3070
|
-
* @param {...number|string} nums
|
|
3071
|
-
* @returns {number}
|
|
2933
|
+
* @param {...number|string} nums 被除数和除数
|
|
2934
|
+
* @returns {number} 商数
|
|
3072
2935
|
* @example
|
|
3073
2936
|
*
|
|
3074
|
-
*
|
|
3075
|
-
*
|
|
3076
|
-
*
|
|
2937
|
+
* divide(1.21); // 1.21 除数默认为 1 ,即 1.21/1 = 1.21
|
|
2938
|
+
* divide(1.21, 1.1); // 1.1
|
|
2939
|
+
* divide(1000, 10, 10); // 10
|
|
2940
|
+
* divide(1000, 10, 10, 10); // 1
|
|
2941
|
+
*
|
|
2942
|
+
* divide(); // NaN 如果没有传入参数,被除数默认为 undefined 。 Number(undefined) 转换为 NaN ,NaN/1 = NaN
|
|
2943
|
+
* divide(null); // 0 Number(null) 转换为 0 , 0/1 = 0
|
|
2944
|
+
* divide('1.5 ', 0.5); // 3 Number('1.5 ') 转换为 1.5 ,1.5/0.5 = 3
|
|
3077
2945
|
*
|
|
3078
2946
|
*/
|
|
3079
|
-
function
|
|
2947
|
+
function divide() {
|
|
3080
2948
|
for (var _len = arguments.length, nums = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
3081
2949
|
nums[_key] = arguments[_key];
|
|
3082
2950
|
}
|
|
3083
2951
|
var num1 = nums[0],
|
|
3084
2952
|
_nums$ = nums[1],
|
|
3085
|
-
num2 = _nums$ === void 0 ?
|
|
2953
|
+
num2 = _nums$ === void 0 ? 1 : _nums$,
|
|
3086
2954
|
rest = nums.slice(2);
|
|
3087
2955
|
if (rest.length > 0) {
|
|
3088
|
-
return
|
|
2956
|
+
return divide.apply(void 0, [divide(num1, num2)].concat(_toConsumableArray(rest)));
|
|
3089
2957
|
}
|
|
3090
2958
|
num1 = transformEffectiveNumber(num1);
|
|
3091
2959
|
num2 = transformEffectiveNumber(num2);
|
|
@@ -3095,100 +2963,19 @@
|
|
|
3095
2963
|
if (isNaN(num1) || isNaN(num2)) {
|
|
3096
2964
|
return Number.NaN;
|
|
3097
2965
|
}
|
|
3098
|
-
var
|
|
3099
|
-
|
|
2966
|
+
var num1Changed = float2Fixed(num1);
|
|
2967
|
+
var num2Changed = float2Fixed(num2);
|
|
2968
|
+
checkBoundary(num1Changed);
|
|
2969
|
+
checkBoundary(num2Changed);
|
|
2970
|
+
// fix: 类似 10 ** -4 为 0.00009999999999999999,strip 修正
|
|
2971
|
+
return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1))));
|
|
3100
2972
|
}
|
|
3101
2973
|
|
|
3102
2974
|
/**
|
|
3103
|
-
*
|
|
2975
|
+
* 四舍五入,支持设置精度
|
|
3104
2976
|
*
|
|
3105
2977
|
* @static
|
|
3106
|
-
* @alias module:Math.
|
|
3107
|
-
* @since 3.1.0
|
|
3108
|
-
* @param {...number|string} nums 相减的数
|
|
3109
|
-
* @returns {number} 差
|
|
3110
|
-
* @example
|
|
3111
|
-
*
|
|
3112
|
-
* minus(1, 0.9); // 0.1
|
|
3113
|
-
* minus(1, 0.9, 0.02); // 0.08
|
|
3114
|
-
* minus(1, 0.9, 0.02, 0.08); // 0
|
|
3115
|
-
*
|
|
3116
|
-
*/
|
|
3117
|
-
function minus() {
|
|
3118
|
-
for (var _len = arguments.length, nums = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
3119
|
-
nums[_key] = arguments[_key];
|
|
3120
|
-
}
|
|
3121
|
-
var num1 = nums[0],
|
|
3122
|
-
_nums$ = nums[1],
|
|
3123
|
-
num2 = _nums$ === void 0 ? 0 : _nums$,
|
|
3124
|
-
rest = nums.slice(2);
|
|
3125
|
-
if (rest.length > 0) {
|
|
3126
|
-
return minus.apply(void 0, [minus(num1, num2)].concat(_toConsumableArray(rest)));
|
|
3127
|
-
}
|
|
3128
|
-
num1 = transformEffectiveNumber(num1);
|
|
3129
|
-
num2 = transformEffectiveNumber(num2);
|
|
3130
|
-
|
|
3131
|
-
// 兼容处理,如果参数包含无效数值时,返回 NaN
|
|
3132
|
-
// @ts-ignore
|
|
3133
|
-
if (isNaN(num1) || isNaN(num2)) {
|
|
3134
|
-
return Number.NaN;
|
|
3135
|
-
}
|
|
3136
|
-
var baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
|
|
3137
|
-
return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
|
|
3138
|
-
}
|
|
3139
|
-
|
|
3140
|
-
/**
|
|
3141
|
-
* 精确除法,支持多个数相除,除数默认为 1 。
|
|
3142
|
-
*
|
|
3143
|
-
* @static
|
|
3144
|
-
* @alias module:Math.divide
|
|
3145
|
-
* @since 3.1.0
|
|
3146
|
-
* @param {...number|string} nums 被除数和除数
|
|
3147
|
-
* @returns {number} 商数
|
|
3148
|
-
* @example
|
|
3149
|
-
*
|
|
3150
|
-
* divide(1.21); // 1.21 除数默认为 1 ,即 1.21/1 = 1.21
|
|
3151
|
-
* divide(1.21, 1.1); // 1.1
|
|
3152
|
-
* divide(1000, 10, 10); // 10
|
|
3153
|
-
* divide(1000, 10, 10, 10); // 1
|
|
3154
|
-
*
|
|
3155
|
-
* divide(); // NaN 如果没有传入参数,被除数默认为 undefined 。 Number(undefined) 转换为 NaN ,NaN/1 = NaN
|
|
3156
|
-
* divide(null); // 0 Number(null) 转换为 0 , 0/1 = 0
|
|
3157
|
-
* divide('1.5 ', 0.5); // 3 Number('1.5 ') 转换为 1.5 ,1.5/0.5 = 3
|
|
3158
|
-
*
|
|
3159
|
-
*/
|
|
3160
|
-
function divide() {
|
|
3161
|
-
for (var _len = arguments.length, nums = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
3162
|
-
nums[_key] = arguments[_key];
|
|
3163
|
-
}
|
|
3164
|
-
var num1 = nums[0],
|
|
3165
|
-
_nums$ = nums[1],
|
|
3166
|
-
num2 = _nums$ === void 0 ? 1 : _nums$,
|
|
3167
|
-
rest = nums.slice(2);
|
|
3168
|
-
if (rest.length > 0) {
|
|
3169
|
-
return divide.apply(void 0, [divide(num1, num2)].concat(_toConsumableArray(rest)));
|
|
3170
|
-
}
|
|
3171
|
-
num1 = transformEffectiveNumber(num1);
|
|
3172
|
-
num2 = transformEffectiveNumber(num2);
|
|
3173
|
-
|
|
3174
|
-
// 兼容处理,如果参数包含无效数值时,返回 NaN
|
|
3175
|
-
// @ts-ignore
|
|
3176
|
-
if (isNaN(num1) || isNaN(num2)) {
|
|
3177
|
-
return Number.NaN;
|
|
3178
|
-
}
|
|
3179
|
-
var num1Changed = float2Fixed(num1);
|
|
3180
|
-
var num2Changed = float2Fixed(num2);
|
|
3181
|
-
checkBoundary(num1Changed);
|
|
3182
|
-
checkBoundary(num2Changed);
|
|
3183
|
-
// fix: 类似 10 ** -4 为 0.00009999999999999999,strip 修正
|
|
3184
|
-
return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1))));
|
|
3185
|
-
}
|
|
3186
|
-
|
|
3187
|
-
/**
|
|
3188
|
-
* 四舍五入,支持设置精度
|
|
3189
|
-
*
|
|
3190
|
-
* @static
|
|
3191
|
-
* @alias module:Math.round
|
|
2978
|
+
* @alias module:Math.round
|
|
3192
2979
|
* @since 3.1.0
|
|
3193
2980
|
* @param {number|string} num 要四舍五入的数字
|
|
3194
2981
|
* @param {number} [precision=0] 四舍五入的精度
|
|
@@ -3214,29 +3001,150 @@
|
|
|
3214
3001
|
}
|
|
3215
3002
|
|
|
3216
3003
|
/**
|
|
3217
|
-
*
|
|
3218
|
-
|
|
3004
|
+
* @typedef {XMLHttpRequest['onloadstart']} XMLHttpRequestEvent XMLHttpRequest 事件对象
|
|
3005
|
+
*/
|
|
3006
|
+
|
|
3007
|
+
/**
|
|
3008
|
+
* @see {@link https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest|XMLHttpRequest}
|
|
3009
|
+
* @typedef {Object} AjaxOptions ajax配置项
|
|
3010
|
+
* @property {string} [method="get"] 创建请求时使用的方法
|
|
3011
|
+
* @property {Document | XMLHttpRequestBodyInit | null} [data=null] 请求体被发送的数据
|
|
3012
|
+
* @property {Object.<string, string>} [headers] 自定义请求头
|
|
3013
|
+
* @property {XMLHttpRequestResponseType} [responseType] 响应类型
|
|
3014
|
+
* @property {number} [timeout] 请求超时的毫秒数
|
|
3015
|
+
* @property {boolean} [withCredentials=false] 跨域请求时是否需要使用凭证
|
|
3016
|
+
* @property {boolean} [async=true] 是否异步执行操作
|
|
3017
|
+
* @property {string|null} [user=null] 用户名,用于认证用途
|
|
3018
|
+
* @property {string|null} [password=null] 密码,用于认证用途
|
|
3019
|
+
* @property {XMLHttpRequestEvent} [onLoadStart] 接收到响应数据时触发
|
|
3020
|
+
* @property {XMLHttpRequestEvent} [onProgress] 请求接收到更多数据时,周期性地触发
|
|
3021
|
+
* @property {XMLHttpRequestEvent} [onAbort] 当 request 被停止时触发,例如当程序调用 XMLHttpRequest.abort() 时
|
|
3022
|
+
* @property {XMLHttpRequestEvent} [onTimeout] 在预设时间内没有接收到响应时触发
|
|
3023
|
+
* @property {XMLHttpRequestEvent} [onError] 当 request 遭遇错误时触发
|
|
3024
|
+
* @property {XMLHttpRequestEvent} [onLoad] 请求成功完成时触发
|
|
3025
|
+
* @property {XMLHttpRequestEvent} [onLoadEnd] 请求结束时触发,无论请求成功 (load) 还是失败 (abort 或 error)
|
|
3026
|
+
*/
|
|
3027
|
+
|
|
3028
|
+
/**
|
|
3029
|
+
* 请求<br/><br/>
|
|
3030
|
+
*
|
|
3031
|
+
* <em style="font-weight: bold;">注意:该方法仅适用于浏览器端。</em>
|
|
3032
|
+
*
|
|
3219
3033
|
* @static
|
|
3220
|
-
* @alias module:Other.
|
|
3221
|
-
* @since 4.
|
|
3222
|
-
* @
|
|
3223
|
-
* @
|
|
3034
|
+
* @alias module:Other.ajax
|
|
3035
|
+
* @since 4.16.0
|
|
3036
|
+
* @see {@link https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest|XMLHttpRequest}
|
|
3037
|
+
* @param {string} url 地址
|
|
3038
|
+
* @param {AjaxOptions} [options] 配置项
|
|
3039
|
+
* @returns {Promise<ProgressEvent<EventTarget>>}
|
|
3224
3040
|
* @example
|
|
3225
|
-
*
|
|
3226
|
-
* const test = async ()=>{
|
|
3227
|
-
* await waitTime();
|
|
3228
|
-
* // do something
|
|
3229
|
-
* }
|
|
3230
|
-
*
|
|
3231
|
-
* waitTime(500).then(()=>{
|
|
3041
|
+
* ajax('/somefile').then(res=>{
|
|
3232
3042
|
* // do something
|
|
3233
3043
|
* });
|
|
3234
3044
|
*
|
|
3045
|
+
* ajax('/api', { method: 'post' }).then(res=>{
|
|
3046
|
+
* // do something
|
|
3047
|
+
* });
|
|
3235
3048
|
*/
|
|
3236
|
-
function
|
|
3237
|
-
var
|
|
3238
|
-
|
|
3239
|
-
|
|
3049
|
+
function ajax(url, options) {
|
|
3050
|
+
var _ref = options || {},
|
|
3051
|
+
_ref$method = _ref.method,
|
|
3052
|
+
method = _ref$method === void 0 ? 'get' : _ref$method,
|
|
3053
|
+
_ref$data = _ref.data,
|
|
3054
|
+
data = _ref$data === void 0 ? null : _ref$data,
|
|
3055
|
+
timeout = _ref.timeout,
|
|
3056
|
+
headers = _ref.headers,
|
|
3057
|
+
_ref$withCredentials = _ref.withCredentials,
|
|
3058
|
+
withCredentials = _ref$withCredentials === void 0 ? false : _ref$withCredentials,
|
|
3059
|
+
_ref$async = _ref.async,
|
|
3060
|
+
async = _ref$async === void 0 ? true : _ref$async,
|
|
3061
|
+
_ref$user = _ref.user,
|
|
3062
|
+
user = _ref$user === void 0 ? null : _ref$user,
|
|
3063
|
+
_ref$password = _ref.password,
|
|
3064
|
+
password = _ref$password === void 0 ? null : _ref$password,
|
|
3065
|
+
responseType = _ref.responseType,
|
|
3066
|
+
onAbort = _ref.onAbort,
|
|
3067
|
+
onError = _ref.onError,
|
|
3068
|
+
onLoad = _ref.onLoad,
|
|
3069
|
+
onLoadEnd = _ref.onLoadEnd,
|
|
3070
|
+
onLoadStart = _ref.onLoadStart,
|
|
3071
|
+
onProgress = _ref.onProgress,
|
|
3072
|
+
onTimeout = _ref.onTimeout;
|
|
3073
|
+
return new Promise(function (resolve, reject) {
|
|
3074
|
+
var xhr = new XMLHttpRequest();
|
|
3075
|
+
xhr.open(method.toLowerCase(), url, async, user, password);
|
|
3076
|
+
|
|
3077
|
+
// 设置请求超时
|
|
3078
|
+
if (typeof timeout === 'number' && timeout > 0) {
|
|
3079
|
+
xhr.timeout = timeout;
|
|
3080
|
+
}
|
|
3081
|
+
|
|
3082
|
+
// 跨域请求时是否需要使用凭证
|
|
3083
|
+
xhr.withCredentials = withCredentials;
|
|
3084
|
+
|
|
3085
|
+
// 设置响应类型
|
|
3086
|
+
if (responseType) {
|
|
3087
|
+
xhr.responseType = responseType;
|
|
3088
|
+
}
|
|
3089
|
+
|
|
3090
|
+
// 设置请求头
|
|
3091
|
+
if (_typeof(headers) === 'object') {
|
|
3092
|
+
Object.keys(headers).map(function (item) {
|
|
3093
|
+
xhr.setRequestHeader(item, headers[item]);
|
|
3094
|
+
});
|
|
3095
|
+
}
|
|
3096
|
+
|
|
3097
|
+
/**
|
|
3098
|
+
* 请求成功异步调用
|
|
3099
|
+
* @param {XMLHttpRequestEvent} [cb] 回调方法
|
|
3100
|
+
*/
|
|
3101
|
+
var wrapSuccess = function wrapSuccess(cb) {
|
|
3102
|
+
/**
|
|
3103
|
+
* 内部方法
|
|
3104
|
+
* @param {ProgressEvent<EventTarget>} e 事件对象
|
|
3105
|
+
*/
|
|
3106
|
+
return function (e) {
|
|
3107
|
+
resolve(e);
|
|
3108
|
+
cb === null || cb === void 0 ? void 0 : cb.call(xhr, e);
|
|
3109
|
+
};
|
|
3110
|
+
};
|
|
3111
|
+
|
|
3112
|
+
/**
|
|
3113
|
+
* 请求失败(中断/超时/失败)处理
|
|
3114
|
+
* @param {XMLHttpRequestEvent} [cb] 回调方法
|
|
3115
|
+
*/
|
|
3116
|
+
var wrapError = function wrapError(cb) {
|
|
3117
|
+
/**
|
|
3118
|
+
* 内部方法
|
|
3119
|
+
* @param {ProgressEvent<EventTarget>} e 事件对象
|
|
3120
|
+
*/
|
|
3121
|
+
return function (e) {
|
|
3122
|
+
reject(e);
|
|
3123
|
+
cb === null || cb === void 0 ? void 0 : cb.call(xhr, e);
|
|
3124
|
+
};
|
|
3125
|
+
};
|
|
3126
|
+
|
|
3127
|
+
// 事件处理
|
|
3128
|
+
/**@type {Object.<keyof XMLHttpRequestEventTargetEventMap, XMLHttpRequestEvent | undefined>} */
|
|
3129
|
+
var events = {
|
|
3130
|
+
loadstart: onLoadStart,
|
|
3131
|
+
progress: onProgress,
|
|
3132
|
+
abort: wrapError(onAbort),
|
|
3133
|
+
timeout: wrapError(onTimeout),
|
|
3134
|
+
error: wrapError(onError),
|
|
3135
|
+
load: wrapSuccess(onLoad),
|
|
3136
|
+
loadend: onLoadEnd
|
|
3137
|
+
};
|
|
3138
|
+
/**@type {(keyof XMLHttpRequestEventTargetEventMap)[]} */
|
|
3139
|
+
// @ts-ignore
|
|
3140
|
+
var eventNames = Object.keys(events);
|
|
3141
|
+
eventNames.map(function (item) {
|
|
3142
|
+
var func = events[item];
|
|
3143
|
+
if (func) {
|
|
3144
|
+
xhr.addEventListener(item, func);
|
|
3145
|
+
}
|
|
3146
|
+
});
|
|
3147
|
+
xhr.send(data);
|
|
3240
3148
|
});
|
|
3241
3149
|
}
|
|
3242
3150
|
|
|
@@ -3293,6 +3201,154 @@
|
|
|
3293
3201
|
return pos;
|
|
3294
3202
|
}
|
|
3295
3203
|
|
|
3204
|
+
/**
|
|
3205
|
+
* 下载文件
|
|
3206
|
+
*
|
|
3207
|
+
* @param {string} blobUrl blob 地址
|
|
3208
|
+
* @param {string} [fileName] 文件名称
|
|
3209
|
+
*/
|
|
3210
|
+
function saver(blobUrl, fileName) {
|
|
3211
|
+
var anchor = document.createElement('a');
|
|
3212
|
+
// anchor.href = decodeURIComponent(blobUrl);
|
|
3213
|
+
anchor.href = blobUrl;
|
|
3214
|
+
anchor.style.display = 'none';
|
|
3215
|
+
anchor.setAttribute('download', fileName || '');
|
|
3216
|
+
|
|
3217
|
+
/**
|
|
3218
|
+
* 处理点击事件,防止事件冒泡到 body/html 的点击事件。
|
|
3219
|
+
*
|
|
3220
|
+
* @param {MouseEvent} e 鼠标事件对象
|
|
3221
|
+
*/
|
|
3222
|
+
function handleClick(e) {
|
|
3223
|
+
e.stopPropagation();
|
|
3224
|
+
anchor.removeEventListener('click', handleClick);
|
|
3225
|
+
}
|
|
3226
|
+
anchor.addEventListener('click', handleClick);
|
|
3227
|
+
document.body.appendChild(anchor);
|
|
3228
|
+
anchor.click();
|
|
3229
|
+
document.body.removeChild(anchor);
|
|
3230
|
+
}
|
|
3231
|
+
|
|
3232
|
+
/**
|
|
3233
|
+
* @typedef {import('./ajax.js').AjaxOptions} AjaxOptions ajax 配置项
|
|
3234
|
+
*/
|
|
3235
|
+
|
|
3236
|
+
/**
|
|
3237
|
+
* @callback TransformRequest
|
|
3238
|
+
* @param {AjaxOptions} options ajax 配置项
|
|
3239
|
+
* @returns {AjaxOptions}
|
|
3240
|
+
*/
|
|
3241
|
+
|
|
3242
|
+
/**
|
|
3243
|
+
* @callback TransformResponse
|
|
3244
|
+
* @param {Blob} res 响应的Blob对象。如果你通过 transformRequest 修改了 responseType ,该参数将是该类型响应值。
|
|
3245
|
+
* @returns {Blob}
|
|
3246
|
+
*/
|
|
3247
|
+
|
|
3248
|
+
/**
|
|
3249
|
+
* @typedef {Object} DownloadOptions 下载配置项
|
|
3250
|
+
* @property {string} [options.fileName] 文件名称
|
|
3251
|
+
* @property {string} [options.type] MIME 类型
|
|
3252
|
+
* @property {'url'|'text'} [options.dataType] 手动设置数据类型,默认会根据传入的数据判断类型,主要是为了区分 url 和 text 。<br/>如果你要下载的文本是 url ,请设置 'text' ;如果你要下载的 url 是绝对/相对路径,请设置 'url' 。
|
|
3253
|
+
* @property {TransformRequest} [options.transformRequest] 请求前触发,XHR 对象或配置调整
|
|
3254
|
+
* @property {TransformResponse} [options.transformResponse] 请求成功后触发,在传递给 then/catch 前,允许修改响应数据
|
|
3255
|
+
*/
|
|
3256
|
+
|
|
3257
|
+
/**
|
|
3258
|
+
* 下载<br/><br/>
|
|
3259
|
+
*
|
|
3260
|
+
* <em style="font-weight: bold;">注意:该方法仅适用于浏览器端,兼容 IE10+ 和现代浏览器。</em>
|
|
3261
|
+
*
|
|
3262
|
+
* @static
|
|
3263
|
+
* @alias module:Other.download
|
|
3264
|
+
* @since 4.16.0
|
|
3265
|
+
* @see {@link https://zh.wikipedia.org/wiki/多用途互聯網郵件擴展|多用途互联网邮件扩展}
|
|
3266
|
+
* @param {string|Blob|ArrayBuffer|Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array|BigInt64Array|BigUint64Array} data 字符串、blob数据或url地址
|
|
3267
|
+
* @param {string|DownloadOptions} [options] 文件名称 或 配置项
|
|
3268
|
+
* @returns {Promise<void>}
|
|
3269
|
+
* @example
|
|
3270
|
+
* // 文本
|
|
3271
|
+
* download('hello world', 'text.txt');
|
|
3272
|
+
*
|
|
3273
|
+
* // 远程文件
|
|
3274
|
+
* download('/xxx.jpg', { dataType: 'url' });
|
|
3275
|
+
*
|
|
3276
|
+
* // blob文件
|
|
3277
|
+
* download(new Blob(['hello world']), 'text.txt');
|
|
3278
|
+
*
|
|
3279
|
+
*/
|
|
3280
|
+
function download(data, options) {
|
|
3281
|
+
var config = _typeof(options) === 'object' ? options : {};
|
|
3282
|
+
if (typeof options === 'string') {
|
|
3283
|
+
config.fileName = options;
|
|
3284
|
+
}
|
|
3285
|
+
var fileName = config.fileName,
|
|
3286
|
+
type = config.type,
|
|
3287
|
+
dataType = config.dataType,
|
|
3288
|
+
transformRequest = config.transformRequest,
|
|
3289
|
+
transformResponse = config.transformResponse;
|
|
3290
|
+
|
|
3291
|
+
/** @type {Blob|undefined} */
|
|
3292
|
+
var payload;
|
|
3293
|
+
|
|
3294
|
+
// dataURLs、blob url、url、string
|
|
3295
|
+
if (typeof data === 'string') {
|
|
3296
|
+
if (!dataType && /^blob:.*?\/.*/.test(data)) {
|
|
3297
|
+
// blob url
|
|
3298
|
+
saver(data, fileName);
|
|
3299
|
+
return Promise.resolve();
|
|
3300
|
+
} else if (!dataType && /^data:([\w+-]+\/[\w+.-]+)?[,;]/.test(data)) {
|
|
3301
|
+
// dataURLs
|
|
3302
|
+
payload = dataURLToBlob(data);
|
|
3303
|
+
} else if (dataType === 'url' || !dataType && isUrl(data)) {
|
|
3304
|
+
// url
|
|
3305
|
+
/** @type {AjaxOptions} */
|
|
3306
|
+
var defaultAjaxOptions = {
|
|
3307
|
+
responseType: 'blob'
|
|
3308
|
+
};
|
|
3309
|
+
// 请求前配置调整
|
|
3310
|
+
var ajaxOptions = typeof transformRequest === 'function' ? transformRequest(defaultAjaxOptions) : defaultAjaxOptions;
|
|
3311
|
+
return ajax(data, ajaxOptions).then(function (e) {
|
|
3312
|
+
/** @type {Blob} */
|
|
3313
|
+
// @ts-ignore
|
|
3314
|
+
// 响应结果调整
|
|
3315
|
+
var res = typeof transformResponse === 'function' ? transformResponse(e.target.response) : e.target.response;
|
|
3316
|
+
var currentFileName = fileName || data.split("?")[0].split("#")[0].split("/").pop();
|
|
3317
|
+
return download(res, {
|
|
3318
|
+
fileName: currentFileName,
|
|
3319
|
+
type: type || (isBlob(res) ? res.type : undefined)
|
|
3320
|
+
});
|
|
3321
|
+
});
|
|
3322
|
+
} else {
|
|
3323
|
+
// string
|
|
3324
|
+
payload = new Blob([data], {
|
|
3325
|
+
type: type || 'text/plain'
|
|
3326
|
+
});
|
|
3327
|
+
}
|
|
3328
|
+
} else if (isBlob(data)) {
|
|
3329
|
+
// @ts-ignore
|
|
3330
|
+
payload = data;
|
|
3331
|
+
}
|
|
3332
|
+
|
|
3333
|
+
// html、TypedArray
|
|
3334
|
+
if (!(payload instanceof Blob)) {
|
|
3335
|
+
payload = new Blob([data], {
|
|
3336
|
+
type: type
|
|
3337
|
+
});
|
|
3338
|
+
}
|
|
3339
|
+
|
|
3340
|
+
// @ts-ignore
|
|
3341
|
+
if (navigator.msSaveBlob) {
|
|
3342
|
+
// @ts-ignore
|
|
3343
|
+
navigator.msSaveBlob(payload, fileName || 'download');
|
|
3344
|
+
} else {
|
|
3345
|
+
var url = URL.createObjectURL(payload);
|
|
3346
|
+
saver(url, fileName);
|
|
3347
|
+
URL.revokeObjectURL(url);
|
|
3348
|
+
}
|
|
3349
|
+
return Promise.resolve();
|
|
3350
|
+
}
|
|
3351
|
+
|
|
3296
3352
|
var numberChars = '0123456789';
|
|
3297
3353
|
var letterChars = 'abcdefghijklmnopqrstuvwxyz';
|
|
3298
3354
|
var defaultChars = numberChars + letterChars + letterChars.toUpperCase();
|
|
@@ -3371,11 +3427,360 @@
|
|
|
3371
3427
|
return len;
|
|
3372
3428
|
}
|
|
3373
3429
|
|
|
3430
|
+
/**
|
|
3431
|
+
* 等待时间返回 Promise 。常用于异步方法中延时。
|
|
3432
|
+
*
|
|
3433
|
+
* @static
|
|
3434
|
+
* @alias module:Other.waitTime
|
|
3435
|
+
* @since 4.2.0
|
|
3436
|
+
* @param {number} [time=1000] 延时时间,单位毫秒
|
|
3437
|
+
* @returns {Promise<void>}
|
|
3438
|
+
* @example
|
|
3439
|
+
*
|
|
3440
|
+
* const test = async ()=>{
|
|
3441
|
+
* await waitTime();
|
|
3442
|
+
* // do something
|
|
3443
|
+
* }
|
|
3444
|
+
*
|
|
3445
|
+
* waitTime(500).then(()=>{
|
|
3446
|
+
* // do something
|
|
3447
|
+
* });
|
|
3448
|
+
*
|
|
3449
|
+
*/
|
|
3450
|
+
function waitTime() {
|
|
3451
|
+
var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1000;
|
|
3452
|
+
return new Promise(function (resolve) {
|
|
3453
|
+
setTimeout(resolve, time);
|
|
3454
|
+
});
|
|
3455
|
+
}
|
|
3456
|
+
|
|
3457
|
+
/**
|
|
3458
|
+
* 转换字段名,返回一个转换字段后的值,不改变原值。
|
|
3459
|
+
*
|
|
3460
|
+
* @static
|
|
3461
|
+
* @alias module:Processor.transformFieldNames
|
|
3462
|
+
* @since 4.14.0
|
|
3463
|
+
* @template {*} D
|
|
3464
|
+
* @template {Record<string, keyof D>} F
|
|
3465
|
+
* @template {string} C
|
|
3466
|
+
* @param {D[]} data 对象数组。如果是树结构数据,需要指定第三个参数 childrenField
|
|
3467
|
+
* @param {F} fieldNames 字段名映射
|
|
3468
|
+
* @param {C} [childrenField] 子级数据字段名
|
|
3469
|
+
* @param {'spread'|'self'} [nodeAssign='spread'] 节点赋值方式。spread表示使用展开运算符创建新值,self表示使用自身对象。
|
|
3470
|
+
* @returns {import('./interface.type.js').TransformFieldNames<D, F, C>}
|
|
3471
|
+
* @example
|
|
3472
|
+
*
|
|
3473
|
+
* const options = [{code: '1', name: 'one'},{code:'2', name:'two'}];
|
|
3474
|
+
* const newOptions = transformFieldNames(options, {label: 'name', value: 'code'});
|
|
3475
|
+
* // [{value: '1', label: 'one'},{value:'2', label:'two'}]
|
|
3476
|
+
*
|
|
3477
|
+
* // 嵌套数据,指定子级字段名 children
|
|
3478
|
+
* const options2 = [{code: '1', name: 'one'},{code:'2', name:'two', children: [{code:'2-1', name:'two-one', children: [{code: '2-1-1', name:'two-one-one'}]}]}];
|
|
3479
|
+
* const newOptions2 = transformFieldNames(options2, {label: 'name', value: 'code'}, 'children');
|
|
3480
|
+
* // [{value: '1', label: 'one'},{value:'2', label:'two', children: [{value: '2-1', label:'two-one', children: [{value: '2-1-1', label:'two-one-one'}]}]}]
|
|
3481
|
+
*
|
|
3482
|
+
* const options3 = [{code: '1', name: 'one'},{code:'2', name:'two', childs: [{code:'2-1', name:'two-one'}]}];
|
|
3483
|
+
* const newOptions3 = transformFieldNames(options3, {label: 'name', value: 'code'}, 'childs');
|
|
3484
|
+
* // [{value: '1', label: 'one'},{value:'2', label:'two', childs: [{value: '2-1', label:'two-one'}]}]
|
|
3485
|
+
*
|
|
3486
|
+
* // 嵌套数据,并替换子集字段名
|
|
3487
|
+
* const newOptions4 = transformFieldNames(options3, {label: 'name', value: 'code', children: 'childs'}, 'childs');
|
|
3488
|
+
* // [{value: '1', label: 'one'},{value:'2', label:'two', children: [{value: '2-1', label:'two-one'}]}]
|
|
3489
|
+
*/
|
|
3490
|
+
function transformFieldNames(data, fieldNames, childrenField) {
|
|
3491
|
+
var nodeAssign = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'spread';
|
|
3492
|
+
if (!Array.isArray(data)) {
|
|
3493
|
+
return data;
|
|
3494
|
+
}
|
|
3495
|
+
if (data.length <= 0) {
|
|
3496
|
+
// @ts-ignore
|
|
3497
|
+
return [];
|
|
3498
|
+
}
|
|
3499
|
+
|
|
3500
|
+
/**
|
|
3501
|
+
* 递归处理字段名
|
|
3502
|
+
*
|
|
3503
|
+
* @param {Array.<object>} arr 列表数据
|
|
3504
|
+
* @returns {*}
|
|
3505
|
+
*/
|
|
3506
|
+
function recusion(arr) {
|
|
3507
|
+
return arr.map(function (item) {
|
|
3508
|
+
if (!isObject(item)) {
|
|
3509
|
+
return item;
|
|
3510
|
+
}
|
|
3511
|
+
var newItem = nodeAssign === 'spread' ? _objectSpread2({}, item) : item;
|
|
3512
|
+
/** @type {Array.<string>} */
|
|
3513
|
+
var delKeys = [];
|
|
3514
|
+
|
|
3515
|
+
// 树形数据子节点
|
|
3516
|
+
// @ts-ignore
|
|
3517
|
+
if (childrenField && Array.isArray(newItem[childrenField]) && newItem[childrenField].length > 0) {
|
|
3518
|
+
// @ts-ignore
|
|
3519
|
+
newItem[childrenField] = recusion(newItem[childrenField].slice());
|
|
3520
|
+
}
|
|
3521
|
+
|
|
3522
|
+
// 替换字段名
|
|
3523
|
+
Object.keys(fieldNames).forEach(function (newKey) {
|
|
3524
|
+
var oldKey = fieldNames[newKey];
|
|
3525
|
+
if (oldKey in newItem) {
|
|
3526
|
+
// @ts-ignore
|
|
3527
|
+
newItem[newKey] = newItem[oldKey];
|
|
3528
|
+
// @ts-ignore
|
|
3529
|
+
delKeys.push(oldKey);
|
|
3530
|
+
}
|
|
3531
|
+
});
|
|
3532
|
+
|
|
3533
|
+
// 删除旧字段
|
|
3534
|
+
if (delKeys.length > 0) {
|
|
3535
|
+
delKeys.forEach(function (delKey) {
|
|
3536
|
+
// @ts-ignore
|
|
3537
|
+
delete newItem[delKey];
|
|
3538
|
+
});
|
|
3539
|
+
}
|
|
3540
|
+
return newItem;
|
|
3541
|
+
});
|
|
3542
|
+
}
|
|
3543
|
+
|
|
3544
|
+
// @ts-ignore
|
|
3545
|
+
return recusion(data.slice());
|
|
3546
|
+
}
|
|
3547
|
+
|
|
3548
|
+
/**
|
|
3549
|
+
* 递归处理空子级
|
|
3550
|
+
*
|
|
3551
|
+
* @private
|
|
3552
|
+
* @template {Record<string,any>} [T=Record<string,any>]
|
|
3553
|
+
* @param {T[]} arr 列表数据
|
|
3554
|
+
* @param {object} [options] 配置项
|
|
3555
|
+
* @param {string} [options.childrenField='children'] 子级字段名称
|
|
3556
|
+
* @param {'none'|'null'} [options.emptyChildrenValue='none'] 子级为空时的值,none表示删除该子级,null表示为null,array表示为[]。
|
|
3557
|
+
*/
|
|
3558
|
+
function processEmptyChildren(arr, options) {
|
|
3559
|
+
var _ref = options || {},
|
|
3560
|
+
_ref$childrenField = _ref.childrenField,
|
|
3561
|
+
childrenField = _ref$childrenField === void 0 ? 'children' : _ref$childrenField,
|
|
3562
|
+
_ref$emptyChildrenVal = _ref.emptyChildrenValue,
|
|
3563
|
+
emptyChildrenValue = _ref$emptyChildrenVal === void 0 ? 'none' : _ref$emptyChildrenVal;
|
|
3564
|
+
arr.forEach(function (item) {
|
|
3565
|
+
// if (isObject(item) && Array.isArray(item[childrenField])) {
|
|
3566
|
+
if (item[childrenField].length <= 0) {
|
|
3567
|
+
if (emptyChildrenValue === 'null') {
|
|
3568
|
+
// @ts-ignore
|
|
3569
|
+
item[childrenField] = null;
|
|
3570
|
+
// } else if (emptyChildrenValue === 'none') { // emptyChildrenValue='array' 不会执行该内部方法
|
|
3571
|
+
} else {
|
|
3572
|
+
delete item[childrenField];
|
|
3573
|
+
}
|
|
3574
|
+
} else {
|
|
3575
|
+
processEmptyChildren(item[childrenField], options);
|
|
3576
|
+
}
|
|
3577
|
+
// }
|
|
3578
|
+
});
|
|
3579
|
+
}
|
|
3580
|
+
|
|
3581
|
+
/**
|
|
3582
|
+
* 列表数据转树结构
|
|
3583
|
+
*
|
|
3584
|
+
* @static
|
|
3585
|
+
* @alias module:Tree.listToTree
|
|
3586
|
+
* @since 4.14.0
|
|
3587
|
+
* @template {Record<string,any>} [T=Record<string,any>]
|
|
3588
|
+
* @template {*} [R=T&Record<string,any>]
|
|
3589
|
+
* @param {T[]} list 列表数据
|
|
3590
|
+
* @param {object} [options] 配置项
|
|
3591
|
+
* @param {string} [options.keyField='id'] 当前数据的键值字段名称
|
|
3592
|
+
* @param {string} [options.parentField='pid'] 当前数据的父级字段名称
|
|
3593
|
+
* @param {string} [options.childrenField='children'] 子级字段名称
|
|
3594
|
+
* @param {'none'|'null'|'array'} [options.emptyChildrenValue='none'] 子级为空时的值,none表示删除该子级,null表示为null,array表示为[]。
|
|
3595
|
+
* @param {'spread'|'self'} [options.nodeAssign='spread'] 节点赋值方式。spread表示使用展开运算符创建新值,self表示使用自身对象。
|
|
3596
|
+
* @returns {R[]} 树结构
|
|
3597
|
+
* @example
|
|
3598
|
+
*
|
|
3599
|
+
* const menus = [
|
|
3600
|
+
* { id: '1', name: '首页', code: 'trade', pid: null },
|
|
3601
|
+
* { id: '2', name: '交易管理', code: 'trade', pid: null },
|
|
3602
|
+
* { id: '3', name: '交易查询', code: 'trade-1', pid: '2' },
|
|
3603
|
+
* { id: '4', name: '交易查询-查询操作', code: 'trade-1-1', pid: '3' },
|
|
3604
|
+
* { id: '5', name: '权限管理', code: 'authorization', pid: null },
|
|
3605
|
+
* { id: '6', name: '角色管理', code: 'authorization-1', pid: '5' },
|
|
3606
|
+
* { id: '7', name: '用户管理', code: 'authorization-2', pid: '5' }
|
|
3607
|
+
* ];
|
|
3608
|
+
* listToTree(menus);
|
|
3609
|
+
* // [{"id":"1","name":"首页","code":"trade","pid":null},{"id":"2","name":"交易管理","code":"trade","pid":null,"children":[{"id":"3","name":"交易查询","code":"trade-1","pid":"2","children":[{"id":"4","name":"交易查询-查询操作","code":"trade-1-1","pid":"3"}]}]},{"id":"5","name":"权限管理","code":"authorization","pid":null,"children":[{"id":"6","name":"角色管理","code":"authorization-1","pid":"5"},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]}]
|
|
3610
|
+
*
|
|
3611
|
+
* // 自定义子级字段名
|
|
3612
|
+
* listToTree(basicMenus, { childrenField: 'childs' });
|
|
3613
|
+
* // [{"id":"1","name":"首页","code":"trade","pid":null},{"id":"2","name":"交易管理","code":"trade","pid":null,"childs":[{"id":"3","name":"交易查询","code":"trade-1","pid":"2","childs":[{"id":"4","name":"交易查询-查询操作","code":"trade-1-1","pid":"3"}]}]},{"id":"5","name":"权限管理","code":"authorization","pid":null,"childs":[{"id":"6","name":"角色管理","code":"authorization-1","pid":"5"},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]}]
|
|
3614
|
+
*
|
|
3615
|
+
*/
|
|
3616
|
+
function listToTree(list, options) {
|
|
3617
|
+
var _ref2 = options || {},
|
|
3618
|
+
_ref2$keyField = _ref2.keyField,
|
|
3619
|
+
keyField = _ref2$keyField === void 0 ? 'id' : _ref2$keyField,
|
|
3620
|
+
_ref2$parentField = _ref2.parentField,
|
|
3621
|
+
parentField = _ref2$parentField === void 0 ? 'pid' : _ref2$parentField,
|
|
3622
|
+
_ref2$childrenField = _ref2.childrenField,
|
|
3623
|
+
childrenField = _ref2$childrenField === void 0 ? 'children' : _ref2$childrenField,
|
|
3624
|
+
_ref2$emptyChildrenVa = _ref2.emptyChildrenValue,
|
|
3625
|
+
emptyChildrenValue = _ref2$emptyChildrenVa === void 0 ? 'none' : _ref2$emptyChildrenVa,
|
|
3626
|
+
_ref2$nodeAssign = _ref2.nodeAssign,
|
|
3627
|
+
nodeAssign = _ref2$nodeAssign === void 0 ? 'spread' : _ref2$nodeAssign;
|
|
3628
|
+
|
|
3629
|
+
/** @type {R[]} */
|
|
3630
|
+
var tree = [];
|
|
3631
|
+
|
|
3632
|
+
/** @type {Object.<string, T[]>} */
|
|
3633
|
+
var record = {};
|
|
3634
|
+
if (!Array.isArray(list)) {
|
|
3635
|
+
return tree;
|
|
3636
|
+
}
|
|
3637
|
+
list.forEach(function (item) {
|
|
3638
|
+
if (isObject(item)) {
|
|
3639
|
+
var newItem = nodeAssign === 'spread' ? _objectSpread2({}, item) : item;
|
|
3640
|
+
|
|
3641
|
+
/** @type {string} */
|
|
3642
|
+
var id = newItem[keyField];
|
|
3643
|
+
|
|
3644
|
+
/** @type {string} */
|
|
3645
|
+
var pid = newItem[parentField];
|
|
3646
|
+
if (record[id]) {
|
|
3647
|
+
// @ts-ignore
|
|
3648
|
+
newItem[childrenField] = record[id];
|
|
3649
|
+
} else {
|
|
3650
|
+
// @ts-ignore
|
|
3651
|
+
newItem[childrenField] = record[id] = [];
|
|
3652
|
+
}
|
|
3653
|
+
if (pid) {
|
|
3654
|
+
if (!record[pid]) {
|
|
3655
|
+
record[pid] = [newItem];
|
|
3656
|
+
} else {
|
|
3657
|
+
record[pid].push(newItem);
|
|
3658
|
+
}
|
|
3659
|
+
} else {
|
|
3660
|
+
// @ts-ignore
|
|
3661
|
+
tree.push(newItem);
|
|
3662
|
+
}
|
|
3663
|
+
}
|
|
3664
|
+
});
|
|
3665
|
+
if (emptyChildrenValue !== 'array') {
|
|
3666
|
+
// @ts-ignore
|
|
3667
|
+
processEmptyChildren(tree, options);
|
|
3668
|
+
}
|
|
3669
|
+
return tree;
|
|
3670
|
+
}
|
|
3671
|
+
|
|
3672
|
+
/**
|
|
3673
|
+
* 树结构转列表数据
|
|
3674
|
+
*
|
|
3675
|
+
* @static
|
|
3676
|
+
* @alias module:Tree.treeToList
|
|
3677
|
+
* @since 4.14.0
|
|
3678
|
+
* @template {Record<string,any>} T
|
|
3679
|
+
* @template {keyof T} K
|
|
3680
|
+
* @template {Omit<T, K>} R
|
|
3681
|
+
* @param {T[]} tree 列表数据
|
|
3682
|
+
* @param {K} childrenField 子级字段名称
|
|
3683
|
+
* @returns {R[]} 列表数据
|
|
3684
|
+
* @example
|
|
3685
|
+
* const menus = [{ "id": "1", "name": "首页", "code": "trade", "pid": null }, { "id": "2", "name": "交易管理", "code": "trade", "pid": null, "children": [{ "id": "3", "name": "交易查询", "code": "trade-1", "pid": "2", "children": [{ "id": "4", "name": "交易查询-查询操作", "code": "trade-1-1", "pid": "3" }] }] }, { "id": "5", "name": "权限管理", "code": "authorization", "pid": null, "children": [{ "id": "6", "name": "角色管理", "code": "authorization-1", "pid": "5" }, { "id": "7", "name": "用户管理", "code": "authorization-2", "pid": "5" }] }];
|
|
3686
|
+
*
|
|
3687
|
+
* treeToList(menus, 'children'));
|
|
3688
|
+
* // [{"id":"1","name":"首页","code":"trade","pid":null},{"id":"2","name":"交易管理","code":"trade","pid":null},{"id":"3","name":"交易查询","code":"trade-1","pid":"2"},{"id":"4","name":"交易查询-查询操作","code":"trade-1-1","pid":"3"},{"id":"5","name":"权限管理","code":"authorization","pid":null},{"id":"6","name":"角色管理","code":"authorization-1","pid":"5"},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]
|
|
3689
|
+
*/
|
|
3690
|
+
function treeToList(tree, childrenField) {
|
|
3691
|
+
/** @type {R[]} */
|
|
3692
|
+
var list = [];
|
|
3693
|
+
if (!Array.isArray(tree)) {
|
|
3694
|
+
return list;
|
|
3695
|
+
}
|
|
3696
|
+
|
|
3697
|
+
/**
|
|
3698
|
+
* 递归遍历
|
|
3699
|
+
* @param {T[]} arr 列表数据
|
|
3700
|
+
*/
|
|
3701
|
+
function recusion(arr) {
|
|
3702
|
+
arr.forEach(function (item) {
|
|
3703
|
+
if (isObject(item)) {
|
|
3704
|
+
var newItem = _objectSpread2({}, item);
|
|
3705
|
+
// @ts-ignore
|
|
3706
|
+
list.push(newItem);
|
|
3707
|
+
if (newItem[childrenField]) {
|
|
3708
|
+
if (Array.isArray(newItem[childrenField]) && newItem[childrenField].length > 0) {
|
|
3709
|
+
recusion(newItem[childrenField]);
|
|
3710
|
+
}
|
|
3711
|
+
delete newItem[childrenField];
|
|
3712
|
+
}
|
|
3713
|
+
} else {
|
|
3714
|
+
// @ts-ignore
|
|
3715
|
+
list.push(item);
|
|
3716
|
+
}
|
|
3717
|
+
});
|
|
3718
|
+
}
|
|
3719
|
+
recusion(tree);
|
|
3720
|
+
return list;
|
|
3721
|
+
}
|
|
3722
|
+
|
|
3723
|
+
/**
|
|
3724
|
+
* 过滤/筛选树节点。<br/><br/>如果某节点被过滤掉,它的子节点也一并抛弃
|
|
3725
|
+
*
|
|
3726
|
+
* @static
|
|
3727
|
+
* @alias module:Tree.filterTree
|
|
3728
|
+
* @since 4.15.0
|
|
3729
|
+
* @template {any} T
|
|
3730
|
+
* @template {(item: T) => boolean} F
|
|
3731
|
+
* @param {T[]} tree 树结构数据
|
|
3732
|
+
* @param {F} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy ,结果将包含该节点
|
|
3733
|
+
* @param {string} [childrenField='children'] 子级字段名
|
|
3734
|
+
* @param {'spread'|'self'} [nodeAssign='spread'] 节点赋值方式。spread表示使用展开运算符创建新值,self表示使用自身对象。
|
|
3735
|
+
* @returns {T[]}
|
|
3736
|
+
* @example
|
|
3737
|
+
* const menus = [{ "id": "1", "name": "首页", "code": "trade", "pid": null }, { "id": "2", "name": "交易管理", "code": "trade", "pid": null, "children": [{ "id": "3", "name": "交易查询", "code": "trade-1", "pid": "2", "children": [{ "id": "4", "name": "交易查询-查询操作", "code": "trade-1-1", "pid": "3" }] }] }, { "id": "5", "name": "权限管理", "code": "authorization", "pid": null, "children": [{ "id": "6", "name": "角色管理", "code": "authorization-1", "pid": "5" }, { "id": "7", "name": "用户管理", "code": "authorization-2", "pid": "5" }] }];
|
|
3738
|
+
*
|
|
3739
|
+
* filterTree(menus, item=>item.name.indexOf('管理') > -1);
|
|
3740
|
+
* // [{"id":"2","name":"交易管理","code":"trade","pid":null,"children":[]},{"id":"5","name":"权限管理","code":"authorization","pid":null,"children":[{"id":"6","name":"角色管理","code":"authorization-1","pid":"5"},{"id":"7","name":"用户管理","code":"authorization-2","pid":"5"}]}]
|
|
3741
|
+
*
|
|
3742
|
+
* // 如果某节点被过滤掉,它的子节点也一并抛弃
|
|
3743
|
+
* filterTree(menus, item=>item.id === '7');
|
|
3744
|
+
* // []
|
|
3745
|
+
*
|
|
3746
|
+
* filterTree(menus, item=>item.id === 'not found');
|
|
3747
|
+
* // []
|
|
3748
|
+
*/
|
|
3749
|
+
function filterTree(tree, predicate) {
|
|
3750
|
+
var childrenField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
|
|
3751
|
+
var nodeAssign = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'spread';
|
|
3752
|
+
/** @type {T[]} */
|
|
3753
|
+
var result = [];
|
|
3754
|
+
if (!Array.isArray(tree)) {
|
|
3755
|
+
return result;
|
|
3756
|
+
}
|
|
3757
|
+
tree.forEach(function (item) {
|
|
3758
|
+
var newItem = item;
|
|
3759
|
+
if (isObject(item)) {
|
|
3760
|
+
// @ts-ignore
|
|
3761
|
+
newItem = nodeAssign === 'spread' ? _objectSpread2({}, item) : item;
|
|
3762
|
+
}
|
|
3763
|
+
if (predicate(newItem)) {
|
|
3764
|
+
if (isObject(newItem)) {
|
|
3765
|
+
/** @type {T[]|undefined} */
|
|
3766
|
+
// @ts-ignore
|
|
3767
|
+
var childs = newItem[childrenField];
|
|
3768
|
+
if (Array.isArray(childs) && childs.length > 0) {
|
|
3769
|
+
// @ts-ignore
|
|
3770
|
+
newItem[childrenField] = filterTree(childs, predicate, childrenField, nodeAssign);
|
|
3771
|
+
}
|
|
3772
|
+
}
|
|
3773
|
+
result.push(newItem);
|
|
3774
|
+
}
|
|
3775
|
+
});
|
|
3776
|
+
return result;
|
|
3777
|
+
}
|
|
3778
|
+
|
|
3374
3779
|
/**
|
|
3375
3780
|
* 查找树结构数据节点
|
|
3376
3781
|
*
|
|
3377
3782
|
* @static
|
|
3378
|
-
* @alias module:
|
|
3783
|
+
* @alias module:Tree.findTreeNode
|
|
3379
3784
|
* @since 4.14.0
|
|
3380
3785
|
* @template {any} T
|
|
3381
3786
|
* @template {(item: T) => boolean} F
|
|
@@ -3443,7 +3848,7 @@
|
|
|
3443
3848
|
* 查找树结构数据多个节点
|
|
3444
3849
|
*
|
|
3445
3850
|
* @static
|
|
3446
|
-
* @alias module:
|
|
3851
|
+
* @alias module:Tree.findTreeNodes
|
|
3447
3852
|
* @since 4.15.0
|
|
3448
3853
|
* @template {any} T
|
|
3449
3854
|
* @template {(item: T) => boolean} F
|
|
@@ -3557,7 +3962,7 @@
|
|
|
3557
3962
|
* 查找包含当前节点的所有父级节点
|
|
3558
3963
|
*
|
|
3559
3964
|
* @static
|
|
3560
|
-
* @alias module:
|
|
3965
|
+
* @alias module:Tree.findTreeSelect
|
|
3561
3966
|
* @since 4.14.0
|
|
3562
3967
|
* @template {any} T
|
|
3563
3968
|
* @template {(item: T) => boolean} F
|
|
@@ -3582,11 +3987,14 @@
|
|
|
3582
3987
|
return internalFindTreeSelect(tree, predicate, childrenField);
|
|
3583
3988
|
}
|
|
3584
3989
|
|
|
3990
|
+
exports.ajax = ajax;
|
|
3585
3991
|
exports.blobToDataURL = blobToDataURL;
|
|
3586
3992
|
exports.bytesToSize = bytesToSize;
|
|
3587
3993
|
exports.calculateCursorPosition = calculateCursorPosition;
|
|
3588
3994
|
exports.dataURLToBlob = dataURLToBlob;
|
|
3589
3995
|
exports.divide = divide;
|
|
3996
|
+
exports.download = download;
|
|
3997
|
+
exports.fileReader = fileReader;
|
|
3590
3998
|
exports.filterTree = filterTree;
|
|
3591
3999
|
exports.findTreeNode = findTreeNode;
|
|
3592
4000
|
exports.findTreeNodes = findTreeNodes;
|