@zcrkey/js-utils 0.0.12 → 0.0.15

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/cjs/util.js DELETED
@@ -1,607 +0,0 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- // If the importer is in node compatibility mode or this is not an ESM
21
- // file that has been converted to a CommonJS file using a Babel-
22
- // compatible transform (i.e. "__esModule" has not been set), then set
23
- // "default" to the CommonJS "module.exports" for node compatibility.
24
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
- mod
26
- ));
27
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
-
29
- // src/util.ts
30
- var util_exports = {};
31
- __export(util_exports, {
32
- default: () => CrUtil
33
- });
34
- module.exports = __toCommonJS(util_exports);
35
- var import_lodash = require("lodash");
36
- var import_qs = __toESM(require("qs"));
37
- var CrUtil = class {
38
- /**
39
- * 判断是否为数组
40
- * @param value
41
- * @returns boolean
42
- */
43
- static isArray(value) {
44
- return Array.isArray(value);
45
- }
46
- /**
47
- * 判断是否为对象
48
- * @param value
49
- * @returns boolean
50
- */
51
- static isObject(value) {
52
- return typeof value === "object" && value !== null && !CrUtil.isArray(value);
53
- }
54
- /**
55
- * 判断是否为空对象
56
- * @param value
57
- * @returns boolean
58
- */
59
- static isEmptyObject(value) {
60
- return Object.keys(value).length === 0 && value.constructor === Object;
61
- }
62
- /**
63
- * 判断是否对象的属性是否全部为空
64
- * @param value
65
- * @returns boolean
66
- */
67
- static isObjectPropertiesAllEmpty(value) {
68
- return Object.keys(value).every((key) => {
69
- const _value = value[key];
70
- return _value === void 0 || _value === null || _value === "" || _value === 0 && typeof _value === "number" || isNaN(_value);
71
- });
72
- }
73
- /**
74
- * 判断是否为日期
75
- * @param value
76
- * @returns boolean
77
- */
78
- static isDate(value) {
79
- return Object.prototype.toString.call(value) === "[object Date]";
80
- }
81
- /**
82
- * 判断是否为字符串
83
- * @param value
84
- * @returns boolean
85
- */
86
- static isString(value) {
87
- return Object.prototype.toString.call(value) === "[object String]";
88
- }
89
- /**
90
- * 判断是否为数字
91
- * @param value
92
- * @returns boolean
93
- */
94
- static isNumber(value) {
95
- return typeof value === "number" && !isNaN(value);
96
- }
97
- /**
98
- * 判断是否为文件 File
99
- * @param value
100
- * @returns boolean
101
- */
102
- static isFile(value) {
103
- return Object.prototype.toString.call(value) === "[object File]";
104
- }
105
- /**
106
- * 判断是否为 Boolean
107
- * @param value
108
- * @returns boolean
109
- */
110
- static isBoolean(value) {
111
- return Object.prototype.toString.call(value) === "[object Boolean]";
112
- }
113
- /**
114
- * 判断是否为 Function
115
- * @param value
116
- * @returns boolean
117
- */
118
- static isFunction(value) {
119
- return typeof value === "function";
120
- }
121
- /**
122
- * 去掉字符串前后所有空格
123
- * @param str
124
- * @returns string
125
- */
126
- static trim(str) {
127
- return (str + "").replace(/(^[\s\n\t]+|[\s\n\t]+$)/g, "");
128
- }
129
- /**
130
- * 获取数组为几维数组
131
- * @param arr
132
- * @returns number
133
- */
134
- static getArrayDimension(arr) {
135
- if (!CrUtil.isArray(arr))
136
- return 0;
137
- let maxDimension = 0;
138
- for (let i = 0; i < arr.length; i++) {
139
- const dimension = CrUtil.getArrayDimension(arr[i]);
140
- maxDimension = Math.max(maxDimension, dimension);
141
- }
142
- return maxDimension + 1;
143
- }
144
- /**
145
- * 深拷贝
146
- * @param value
147
- * @returns
148
- */
149
- static cloneDeep(value) {
150
- return (0, import_lodash.cloneDeep)(value);
151
- }
152
- /**
153
- * 深拷贝
154
- * @param target
155
- * @deprecated 即将移除,使用 {@link CrUtil.cloneDeep} 替代
156
- * @returns
157
- */
158
- static deepCopy(target) {
159
- let _target;
160
- if (CrUtil.isArray(target)) {
161
- _target = [];
162
- for (let i = 0, len = target.length; i < len; i++) {
163
- if (CrUtil.isArray(target[i]) || CrUtil.isObject(target[i])) {
164
- _target.push(CrUtil.deepCopy(target[i]));
165
- } else {
166
- _target.push(target[i]);
167
- }
168
- }
169
- } else if (CrUtil.isObject(target)) {
170
- _target = {};
171
- for (let i in target) {
172
- if (CrUtil.isArray(target[i]) || CrUtil.isObject(target[i])) {
173
- _target[i] = CrUtil.deepCopy(target[i]);
174
- } else {
175
- _target[i] = target[i];
176
- }
177
- }
178
- } else {
179
- _target = target;
180
- }
181
- return _target;
182
- }
183
- /**
184
- * 列表数据转树型数据
185
- * @param listData
186
- * @param settings
187
- * @param settings.idField 默认值 id
188
- * @param settings.pidField 默认值 parentId
189
- * @param settings.childrenField 默认值 children
190
- * @deprecated 即将移除,使用 {@link CrTreeUtil.listToTree} 替代
191
- * @returns
192
- */
193
- static listToTreeData(listData, settings) {
194
- const options = Object.assign(
195
- {
196
- idField: "id",
197
- pidField: "parentId",
198
- childrenField: "children",
199
- isDeepCopy: false,
200
- getData: (item) => {
201
- return item;
202
- }
203
- },
204
- settings
205
- );
206
- const { idField, pidField, childrenField, isDeepCopy, getData } = options;
207
- if (isDeepCopy) {
208
- listData = CrUtil.deepCopy(listData);
209
- }
210
- const pidMap = /* @__PURE__ */ new Map();
211
- const idMap = /* @__PURE__ */ new Map();
212
- for (const item of listData) {
213
- const pid = item[pidField];
214
- const id = item[idField];
215
- if (!pidMap.has(pid)) {
216
- pidMap.set(pid, []);
217
- }
218
- pidMap.get(pid).push(item);
219
- idMap.set(id, item);
220
- }
221
- const buildTree = (pid) => {
222
- const children = pidMap.get(pid) || [];
223
- return children.map((item) => {
224
- const rawChildren = buildTree(item[idField]);
225
- const node = {
226
- ...getData(item)
227
- };
228
- if (rawChildren.length > 0) {
229
- node[childrenField] = rawChildren;
230
- }
231
- return node;
232
- });
233
- };
234
- const rootPids = /* @__PURE__ */ new Set();
235
- for (const pid of pidMap.keys()) {
236
- if (pid === void 0 || pid === null || pid === 0 || !idMap.has(pid)) {
237
- rootPids.add(pid);
238
- }
239
- }
240
- const tree = [];
241
- for (const pid of rootPids) {
242
- tree.push(...buildTree(pid));
243
- }
244
- return tree;
245
- }
246
- /**
247
- * 树型数据转列表数据
248
- * @param treeData
249
- * @param settings
250
- * @param settings.idField 默认值 id
251
- * @param settings.pidField 默认值 parentId
252
- * @param settings.childrenField 默认值 children
253
- * @deprecated 即将移除,使用 {@link CrTreeUtil.treeToList} 替代
254
- * @returns
255
- */
256
- static treeDataToListData(treeData, pid = 0, settings) {
257
- let options = Object.assign(
258
- {
259
- idField: "id",
260
- pidField: "parentId",
261
- childrenField: "children",
262
- isDeepCopy: false
263
- },
264
- settings
265
- );
266
- let listData = [];
267
- for (let i = 0; i < treeData.length; i++) {
268
- const node = treeData[i];
269
- const item = { ...node };
270
- item[options.pidField] = pid;
271
- delete item[options.childrenField];
272
- listData.push(item);
273
- if (node[options.childrenField]) {
274
- const childrenList = this.treeDataToListData(
275
- node[options.childrenField],
276
- item[options.idField],
277
- settings
278
- );
279
- listData.push(...childrenList);
280
- }
281
- }
282
- if (options.isDeepCopy) {
283
- listData = CrUtil.deepCopy(listData);
284
- }
285
- return listData;
286
- }
287
- /**
288
- * 获取所有父级数据(包含自身)
289
- * @param listData
290
- * @param value
291
- * @param settings
292
- * @param settings.valueField 默认值 value
293
- * @param settings.idField 默认值 id
294
- * @param settings.pidField 默认值 parentId
295
- * @deprecated 即将移除,使用 {@link CrTreeUtil.getFlatParentDatas} 替代
296
- * @returns
297
- */
298
- static getParentNodes(listData, value, settings) {
299
- const options = Object.assign(
300
- {
301
- valueField: "value",
302
- idField: "id",
303
- pidField: "parentId",
304
- getData: (item) => {
305
- return item;
306
- }
307
- },
308
- settings
309
- );
310
- if (!(listData && listData.length > 0) || !value) {
311
- return [];
312
- }
313
- const idField = options.idField;
314
- const pidField = options.pidField;
315
- const valueField = options.valueField;
316
- const nodes = [];
317
- let node = listData.find(
318
- (item) => item[valueField] == value
319
- );
320
- if (node) {
321
- nodes.push(options.getData(node));
322
- while (node && node[pidField]) {
323
- const parentOption = listData.find(
324
- // eslint-disable-next-line @typescript-eslint/no-loop-func
325
- (item) => item[idField] == node[pidField]
326
- );
327
- if (parentOption) {
328
- nodes.push(options.getData(parentOption));
329
- }
330
- node = parentOption;
331
- }
332
- }
333
- nodes.reverse();
334
- return nodes;
335
- }
336
- /**
337
- * 参数序列化
338
- * @param params {a:'1',b:{},c:[]}
339
- * @returns
340
- */
341
- static paramsSerializer(params, settings) {
342
- const options = Object.assign(
343
- {
344
- isFilterNonNull: false
345
- },
346
- settings
347
- );
348
- if (options.isFilterNonNull) {
349
- Object.keys(params).forEach((key) => {
350
- if (params[key] === null || params[key] === void 0 || params[key] === "") {
351
- delete params[key];
352
- }
353
- });
354
- }
355
- return import_qs.default.stringify(params);
356
- }
357
- /**
358
- * 参数解析
359
- * @param {*} str
360
- * @param {*} settings
361
- * @returns
362
- */
363
- static paramsParse(str, settings) {
364
- let obj = {};
365
- let option = Object.assign(
366
- {
367
- ignoreQueryPrefix: true
368
- },
369
- settings
370
- );
371
- if (str) {
372
- obj = import_qs.default.parse(str, option);
373
- }
374
- return obj;
375
- }
376
- /**
377
- * 获取 URL 参数
378
- * @param {*} url
379
- * @returns
380
- * @example
381
- * "https://example.com?foo=bar&baz=qux" => {"query":{"foo":"bar","baz":"qux"},"hash":{},"all":{"foo":"bar","baz":"qux"}}
382
- * "https://example.com/page?foo=1#/?a=1&b=2" => {"query":{"foo":"1"},"hash":{"/":"","a":"1","b":"2"},"all":{"foo":"1","/":"","a":"1","b":"2"}},
383
- */
384
- static getQueryParams(url) {
385
- const query = {};
386
- const hash = {};
387
- const all = {};
388
- const parse = (queryString) => {
389
- if (!queryString) {
390
- return {};
391
- }
392
- try {
393
- return import_qs.default.parse(queryString);
394
- } catch {
395
- const result = {};
396
- if (!queryString)
397
- return result;
398
- queryString.split("&").forEach((pair) => {
399
- if (!pair)
400
- return;
401
- const [key, val] = pair.split("=");
402
- if (key)
403
- result[decodeURIComponent(key)] = decodeURIComponent(val || "");
404
- });
405
- return result;
406
- }
407
- };
408
- try {
409
- const [base, hashPart] = url.split("#");
410
- const queryPart = base.split("?")[1];
411
- Object.assign(query, parse(queryPart));
412
- if (hashPart) {
413
- for (const part of hashPart.split("?")) {
414
- Object.assign(hash, parse(part));
415
- }
416
- }
417
- Object.assign(all, query, hash);
418
- } catch (error) {
419
- console.error("getQueryParams:", error);
420
- }
421
- return { query, hash, all };
422
- }
423
- /**
424
- * 版本号比较
425
- * @param v1
426
- * @param v2
427
- * @returns number
428
- * @description v1大于v2(1)、v1小于v2(-1)、v1等于v2(0)
429
- */
430
- static compareVersion(v1, v2) {
431
- let v1Arr = CrUtil.trim(v1).split(".");
432
- let v2Arr = CrUtil.trim(v2).split(".");
433
- const len = Math.max(v1.length, v2.length);
434
- while (v1Arr.length < len) {
435
- v1Arr.push("0");
436
- }
437
- while (v2Arr.length < len) {
438
- v2Arr.push("0");
439
- }
440
- for (let i = 0; i < len; i++) {
441
- const num1 = parseInt(v1Arr[i]);
442
- const num2 = parseInt(v2Arr[i]);
443
- if (num1 > num2) {
444
- return 1;
445
- } else if (num1 < num2) {
446
- return -1;
447
- }
448
- }
449
- return 0;
450
- }
451
- /**
452
- * 根据 ids 获取相对应的数据名称
453
- * @param data
454
- * @param ids
455
- * @param settings
456
- * @returns string
457
- */
458
- static getDataNameByIds(data, ids, settings) {
459
- const options = Object.assign(
460
- {
461
- sep: "、",
462
- idField: "id",
463
- nameField: "name"
464
- },
465
- settings
466
- );
467
- let str = "";
468
- if (ids && ids.length > 0) {
469
- str = ids.map((id) => {
470
- let item = data.find((item2) => item2[options.idField] == id);
471
- if (item) {
472
- return item[options.nameField];
473
- } else {
474
- return "";
475
- }
476
- }).join(options.sep);
477
- }
478
- return str;
479
- }
480
- /**
481
- * 追加html标签属性值
482
- * @param htmlStr
483
- * @param tagName
484
- * @param attrName
485
- * @param newAttrValue
486
- * @returns string
487
- */
488
- static appendHtmlTagAttr(htmlStr, tagName, attrName, newAttrValue) {
489
- let regex = new RegExp(`(<${tagName}\\s+)([^>]*?)([^>]*>)`, "g");
490
- let replacedHtml = htmlStr.replace(regex, function(match, p1, p2, p3) {
491
- let _regex = new RegExp(`${attrName}="(.*?)"`, "g");
492
- if (_regex.exec(match)) {
493
- let __regex = new RegExp(
494
- `(<${tagName}\\s+)([^>]*?)${attrName}="(.*)"([^>]*>)`,
495
- "g"
496
- );
497
- return match.replace(__regex, function(_match, _p1, _p2, _p3, _p4) {
498
- return _p1 + _p2 + `${attrName}="${_p3} ${newAttrValue}"` + _p4;
499
- });
500
- } else {
501
- return p1 + `${attrName}="${newAttrValue}" ` + p3;
502
- }
503
- });
504
- replacedHtml = replacedHtml.replace(
505
- new RegExp(`<${tagName}>`, "g"),
506
- `<${tagName} ${attrName}="${newAttrValue}">`
507
- );
508
- return replacedHtml;
509
- }
510
- /**
511
- * 比较数据差异
512
- * @param data1
513
- * @param data2
514
- * @returns
515
- */
516
- static compareDataDiff(data1, data2) {
517
- const diffFieldSet = {};
518
- const compare = (path, o1, o2) => {
519
- if (CrUtil.isArray(o1) && CrUtil.isArray(o2)) {
520
- const lengthDiff = o1.length - o2.length;
521
- if (lengthDiff !== 0) {
522
- diffFieldSet[path] = "modified";
523
- if (lengthDiff > 0) {
524
- for (let i = o2.length; i < o1.length; i++) {
525
- diffFieldSet[`${path}[${i}]`] = "removed";
526
- }
527
- } else {
528
- for (let i = o1.length; i < o2.length; i++) {
529
- diffFieldSet[`${path}[${i}]`] = "added";
530
- }
531
- }
532
- } else {
533
- for (let i = 0; i < o1.length; i++) {
534
- compare(`${path}[${i}]`, o1[i], o2[i]);
535
- }
536
- }
537
- } else if (CrUtil.isObject(o1) && CrUtil.isObject(o2)) {
538
- for (let key in o1) {
539
- const _path = path ? `${path}.${key}` : key;
540
- if (Object.prototype.hasOwnProperty.call(o1, key) && !(key in o2)) {
541
- diffFieldSet[_path] = "removed";
542
- } else if (Object.prototype.hasOwnProperty.call(o2, key)) {
543
- compare(_path, o1[key], o2[key]);
544
- }
545
- }
546
- for (let key in o2) {
547
- const _path = path ? `${path}.${key}` : key;
548
- if (Object.prototype.hasOwnProperty.call(o2, key) && !(key in o1)) {
549
- diffFieldSet[_path] = "added";
550
- }
551
- }
552
- } else if (o1 !== o2) {
553
- diffFieldSet[path] = "modified";
554
- }
555
- };
556
- compare("", data1, data2);
557
- return diffFieldSet;
558
- }
559
- /**
560
- * 格式化为千分位,主要用于展示格式化
561
- * @param value
562
- * @returns 12345.6789 => 12,345.6789
563
- */
564
- static fmtThousands(value) {
565
- if (value == void 0 || value == null || isNaN(Number(value))) {
566
- return String(value);
567
- }
568
- const [intPart, decimalPart] = String(value).split(".");
569
- const formattedInt = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
570
- return decimalPart ? `${formattedInt}.${decimalPart}` : formattedInt;
571
- }
572
- /**
573
- * 格式化为千分位格式
574
- * @param value
575
- * @returns
576
- */
577
- static formatThousands(value) {
578
- if (value == null)
579
- return "";
580
- const raw = String(value).trim();
581
- if (!raw)
582
- return "";
583
- const hasTrailingDot = raw.endsWith(".");
584
- let str = raw.replace(/[^\d.-]/g, "");
585
- const sign = str.startsWith("-") ? "-" : "";
586
- str = str.replace(/-/g, "");
587
- const [intRaw, decRaw = ""] = str.split(".", 2);
588
- const intPart = intRaw.replace(/,/g, "").replace(/^0+(?=\d)/, "");
589
- const formattedInt = intPart ? intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : "";
590
- let result = sign + formattedInt;
591
- if (decRaw || hasTrailingDot)
592
- result += ".";
593
- if (decRaw)
594
- result += decRaw;
595
- return result;
596
- }
597
- /**
598
- * 解析千分位格式
599
- * @param value
600
- * @returns
601
- */
602
- static parseThousands(value) {
603
- if (value == null)
604
- return "";
605
- return String(value).trim().replace(/,/g, "").replace(/[^\d.-]/g, "").replace(/(?!^)-/g, "").replace(/(\..*)\./g, "$1");
606
- }
607
- };