@zcrkey/js-utils 0.0.4 → 0.0.6
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 +69 -56
- package/dist/cjs/eventCenter.js +120 -0
- package/dist/cjs/index.d.ts +8 -0
- package/dist/cjs/index.js +51 -0
- package/dist/cjs/objUtil.d.ts +12 -0
- package/dist/cjs/objUtil.js +37 -0
- package/dist/cjs/storage.js +118 -0
- package/dist/cjs/treeUtil.d.ts +48 -0
- package/dist/cjs/treeUtil.js +145 -0
- package/dist/{util.d.ts → cjs/util.d.ts} +41 -6
- package/dist/cjs/util.js +572 -0
- package/dist/esm/eventCenter.d.ts +59 -0
- package/dist/esm/index.d.ts +8 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/objUtil.d.ts +12 -0
- package/dist/esm/objUtil.js +28 -0
- package/dist/esm/storage.d.ts +44 -0
- package/dist/esm/treeUtil.d.ts +48 -0
- package/dist/esm/treeUtil.js +185 -0
- package/dist/esm/util.d.ts +209 -0
- package/dist/{util.js → esm/util.js} +117 -6
- package/dist/umd/index.umd.js +1 -0
- package/package.json +15 -6
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -3
- package/dist/index.umd.js +0 -1
- /package/dist/{eventCenter.d.ts → cjs/eventCenter.d.ts} +0 -0
- /package/dist/{storage.d.ts → cjs/storage.d.ts} +0 -0
- /package/dist/{eventCenter.js → esm/eventCenter.js} +0 -0
- /package/dist/{storage.js → esm/storage.js} +0 -0
|
@@ -10,7 +10,7 @@ export default class CrUtil {
|
|
|
10
10
|
* @param value
|
|
11
11
|
* @returns boolean
|
|
12
12
|
*/
|
|
13
|
-
static isObject<T = any>(value: T): value is T extends
|
|
13
|
+
static isObject<T = any>(value: T): value is T extends object ? (T extends any[] ? never : T) : never;
|
|
14
14
|
/**
|
|
15
15
|
* 判断是否为空对象
|
|
16
16
|
* @param value
|
|
@@ -28,31 +28,37 @@ export default class CrUtil {
|
|
|
28
28
|
* @param value
|
|
29
29
|
* @returns boolean
|
|
30
30
|
*/
|
|
31
|
-
static isDate(value:
|
|
31
|
+
static isDate(value: unknown): boolean;
|
|
32
32
|
/**
|
|
33
33
|
* 判断是否为字符串
|
|
34
34
|
* @param value
|
|
35
35
|
* @returns boolean
|
|
36
36
|
*/
|
|
37
|
-
static isString(value:
|
|
37
|
+
static isString(value: unknown): value is string;
|
|
38
38
|
/**
|
|
39
39
|
* 判断是否为数字
|
|
40
40
|
* @param value
|
|
41
41
|
* @returns boolean
|
|
42
42
|
*/
|
|
43
|
-
static isNumber(value:
|
|
43
|
+
static isNumber(value: unknown): value is number;
|
|
44
44
|
/**
|
|
45
45
|
* 判断是否为文件 File
|
|
46
46
|
* @param value
|
|
47
47
|
* @returns boolean
|
|
48
48
|
*/
|
|
49
|
-
static isFile(value:
|
|
49
|
+
static isFile(value: unknown): value is File;
|
|
50
50
|
/**
|
|
51
51
|
* 判断是否为 Boolean
|
|
52
52
|
* @param value
|
|
53
53
|
* @returns boolean
|
|
54
54
|
*/
|
|
55
|
-
static isBoolean(value:
|
|
55
|
+
static isBoolean(value: unknown): value is boolean;
|
|
56
|
+
/**
|
|
57
|
+
* 判断是否为 Function
|
|
58
|
+
* @param value
|
|
59
|
+
* @returns boolean
|
|
60
|
+
*/
|
|
61
|
+
static isFunction(value: unknown): value is (...args: any[]) => any;
|
|
56
62
|
/**
|
|
57
63
|
* 去掉字符串前后所有空格
|
|
58
64
|
* @param str
|
|
@@ -65,9 +71,16 @@ export default class CrUtil {
|
|
|
65
71
|
* @returns number
|
|
66
72
|
*/
|
|
67
73
|
static getArrayDimension(arr: any[]): number;
|
|
74
|
+
/**
|
|
75
|
+
* 深拷贝
|
|
76
|
+
* @param value
|
|
77
|
+
* @returns
|
|
78
|
+
*/
|
|
79
|
+
static cloneDeep<T>(value: T): T;
|
|
68
80
|
/**
|
|
69
81
|
* 深拷贝
|
|
70
82
|
* @param target
|
|
83
|
+
* @deprecated 即将移除,使用 {@link CrUtil.cloneDeep} 替代
|
|
71
84
|
* @returns
|
|
72
85
|
*/
|
|
73
86
|
static deepCopy<T = any>(target: T): T;
|
|
@@ -78,6 +91,7 @@ export default class CrUtil {
|
|
|
78
91
|
* @param settings.idField 默认值 id
|
|
79
92
|
* @param settings.pidField 默认值 parentId
|
|
80
93
|
* @param settings.childrenField 默认值 children
|
|
94
|
+
* @deprecated 即将移除,使用 {@link CrObjUtil.listToTree} 替代
|
|
81
95
|
* @returns
|
|
82
96
|
*/
|
|
83
97
|
static listToTreeData(listData: any[], settings?: {
|
|
@@ -94,6 +108,7 @@ export default class CrUtil {
|
|
|
94
108
|
* @param settings.idField 默认值 id
|
|
95
109
|
* @param settings.pidField 默认值 parentId
|
|
96
110
|
* @param settings.childrenField 默认值 children
|
|
111
|
+
* @deprecated 即将移除,使用 {@link CrObjUtil.treeToList} 替代
|
|
97
112
|
* @returns
|
|
98
113
|
*/
|
|
99
114
|
static treeDataToListData(treeData: any[], pid?: string | number, settings?: {
|
|
@@ -110,6 +125,7 @@ export default class CrUtil {
|
|
|
110
125
|
* @param settings.valueField 默认值 value
|
|
111
126
|
* @param settings.idField 默认值 id
|
|
112
127
|
* @param settings.pidField 默认值 parentId
|
|
128
|
+
* @deprecated 即将移除,使用 {@link CrObjUtil.getFlatParentDatas} 替代
|
|
113
129
|
* @returns
|
|
114
130
|
*/
|
|
115
131
|
static getParentNodes<T, R extends Record<string, any>>(listData: R[], value: number | string, settings?: {
|
|
@@ -135,6 +151,19 @@ export default class CrUtil {
|
|
|
135
151
|
static paramsParse(str: string, settings?: {
|
|
136
152
|
ignoreQueryPrefix: boolean;
|
|
137
153
|
}): {};
|
|
154
|
+
/**
|
|
155
|
+
* 获取 URL 参数
|
|
156
|
+
* @param {*} url
|
|
157
|
+
* @returns
|
|
158
|
+
* @example
|
|
159
|
+
* "https://example.com?foo=bar&baz=qux" => {"query":{"foo":"bar","baz":"qux"},"hash":{},"all":{"foo":"bar","baz":"qux"}}
|
|
160
|
+
* "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"}},
|
|
161
|
+
*/
|
|
162
|
+
static getQueryParams(url: string): {
|
|
163
|
+
query: Record<string, any>;
|
|
164
|
+
hash: Record<string, any>;
|
|
165
|
+
all: Record<string, any>;
|
|
166
|
+
};
|
|
138
167
|
/**
|
|
139
168
|
* 版本号比较
|
|
140
169
|
* @param v1
|
|
@@ -171,4 +200,10 @@ export default class CrUtil {
|
|
|
171
200
|
* @returns
|
|
172
201
|
*/
|
|
173
202
|
static compareDataDiff(data1: any, data2: any): Record<string, "added" | "removed" | "modified">;
|
|
203
|
+
/**
|
|
204
|
+
* 格式化为千分位
|
|
205
|
+
* @param value
|
|
206
|
+
* @returns 12345.6789 => 12,345.6789
|
|
207
|
+
*/
|
|
208
|
+
static fmtThousands(value: number | string | undefined): string;
|
|
174
209
|
}
|
package/dist/cjs/util.js
ADDED
|
@@ -0,0 +1,572 @@
|
|
|
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 CrObjUtil.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 CrObjUtil.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 CrObjUtil.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
|
+
};
|