@scx-js/scx-common 0.0.1 → 0.0.2
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/index.js +13 -13
- package/multi_map/MultiMap.js +51 -51
- package/package.json +13 -13
- package/tree/ScxTreeHelper.js +51 -51
- package/util/ArrayUtils.js +138 -138
- package/util/MathUtils.js +20 -20
- package/util/ObjectUtils.js +32 -32
- package/util/RandomUtils.js +10 -10
- package/util/ThrottleUtils.js +26 -26
- package/util/TypeUtils.js +27 -27
- package/util/URLUtils.js +43 -43
package/index.js
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
export * from "../scx-dom/Download.js";
|
2
|
-
export * from "../scx-dom/FixedElement.js";
|
3
|
-
export * from "../scx-dom/HtmlToText.js";
|
4
|
-
export * from "../scx-dom/Watermark.js";
|
5
|
-
export * from "./multi_map/MultiMap.js";
|
6
|
-
export * from "./tree/ScxTreeHelper.js";
|
7
|
-
export * from "./util/ArrayUtils.js";
|
8
|
-
export * from "./util/MathUtils.js";
|
9
|
-
export * from "./util/ObjectUtils.js";
|
10
|
-
export * from "./util/RandomUtils.js";
|
11
|
-
export * from "./util/ThrottleUtils.js";
|
12
|
-
export * from "./util/TypeUtils.js";
|
13
|
-
export * from "./util/URLUtils.js";
|
1
|
+
export * from "../scx-dom/Download.js";
|
2
|
+
export * from "../scx-dom/FixedElement.js";
|
3
|
+
export * from "../scx-dom/HtmlToText.js";
|
4
|
+
export * from "../scx-dom/Watermark.js";
|
5
|
+
export * from "./multi_map/MultiMap.js";
|
6
|
+
export * from "./tree/ScxTreeHelper.js";
|
7
|
+
export * from "./util/ArrayUtils.js";
|
8
|
+
export * from "./util/MathUtils.js";
|
9
|
+
export * from "./util/ObjectUtils.js";
|
10
|
+
export * from "./util/RandomUtils.js";
|
11
|
+
export * from "./util/ThrottleUtils.js";
|
12
|
+
export * from "./util/TypeUtils.js";
|
13
|
+
export * from "./util/URLUtils.js";
|
package/multi_map/MultiMap.js
CHANGED
@@ -1,51 +1,51 @@
|
|
1
|
-
class MultiMap {
|
2
|
-
|
3
|
-
map = {};
|
4
|
-
|
5
|
-
clear() {
|
6
|
-
this.map = {};
|
7
|
-
}
|
8
|
-
|
9
|
-
delete(key, value) {
|
10
|
-
const values = this.map[key];
|
11
|
-
if (values) {
|
12
|
-
let index = values.indexOf(value);
|
13
|
-
//可能会添加多个
|
14
|
-
while (index !== -1) {
|
15
|
-
values.splice(index, 1);
|
16
|
-
index = values.indexOf(value);
|
17
|
-
}
|
18
|
-
if (values.length === 0) {
|
19
|
-
delete this.map[key];
|
20
|
-
}
|
21
|
-
}
|
22
|
-
}
|
23
|
-
|
24
|
-
forEach(callback) {
|
25
|
-
for (let mapKey in this.map) {
|
26
|
-
const mapValues = this.map[mapKey];
|
27
|
-
for (let mapValue of mapValues) {
|
28
|
-
callback(mapKey, mapValue);
|
29
|
-
}
|
30
|
-
}
|
31
|
-
}
|
32
|
-
|
33
|
-
get(key) {
|
34
|
-
return key in this.map ? this.map[key] : [];
|
35
|
-
}
|
36
|
-
|
37
|
-
has(key) {
|
38
|
-
return key in this.map;
|
39
|
-
}
|
40
|
-
|
41
|
-
set(key, value) {
|
42
|
-
if (key in this.map) {
|
43
|
-
this.map[key].push(value);
|
44
|
-
} else {
|
45
|
-
this.map[key] = [value];
|
46
|
-
}
|
47
|
-
}
|
48
|
-
|
49
|
-
}
|
50
|
-
|
51
|
-
export {MultiMap};
|
1
|
+
class MultiMap {
|
2
|
+
|
3
|
+
map = {};
|
4
|
+
|
5
|
+
clear() {
|
6
|
+
this.map = {};
|
7
|
+
}
|
8
|
+
|
9
|
+
delete(key, value) {
|
10
|
+
const values = this.map[key];
|
11
|
+
if (values) {
|
12
|
+
let index = values.indexOf(value);
|
13
|
+
//可能会添加多个
|
14
|
+
while (index !== -1) {
|
15
|
+
values.splice(index, 1);
|
16
|
+
index = values.indexOf(value);
|
17
|
+
}
|
18
|
+
if (values.length === 0) {
|
19
|
+
delete this.map[key];
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
forEach(callback) {
|
25
|
+
for (let mapKey in this.map) {
|
26
|
+
const mapValues = this.map[mapKey];
|
27
|
+
for (let mapValue of mapValues) {
|
28
|
+
callback(mapKey, mapValue);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
get(key) {
|
34
|
+
return key in this.map ? this.map[key] : [];
|
35
|
+
}
|
36
|
+
|
37
|
+
has(key) {
|
38
|
+
return key in this.map;
|
39
|
+
}
|
40
|
+
|
41
|
+
set(key, value) {
|
42
|
+
if (key in this.map) {
|
43
|
+
this.map[key].push(value);
|
44
|
+
} else {
|
45
|
+
this.map[key] = [value];
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
}
|
50
|
+
|
51
|
+
export {MultiMap};
|
package/package.json
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
{
|
2
|
-
"name": "@scx-js/scx-common",
|
3
|
-
"version": "0.0.
|
4
|
-
"description": "SCX Common",
|
5
|
-
"license": "MIT",
|
6
|
-
"author": "scx567888",
|
7
|
-
"main": "index.js",
|
8
|
-
"type": "module",
|
9
|
-
"repository": {
|
10
|
-
"type": "git",
|
11
|
-
"url": "https://github.com/scx567888/scx-js.git"
|
12
|
-
}
|
13
|
-
}
|
1
|
+
{
|
2
|
+
"name": "@scx-js/scx-common",
|
3
|
+
"version": "0.0.2",
|
4
|
+
"description": "SCX Common",
|
5
|
+
"license": "MIT",
|
6
|
+
"author": "scx567888",
|
7
|
+
"main": "index.js",
|
8
|
+
"type": "module",
|
9
|
+
"repository": {
|
10
|
+
"type": "git",
|
11
|
+
"url": "https://github.com/scx567888/scx-js.git"
|
12
|
+
}
|
13
|
+
}
|
package/tree/ScxTreeHelper.js
CHANGED
@@ -1,51 +1,51 @@
|
|
1
|
-
import {isNull} from "../util/ObjectUtils.js";
|
2
|
-
|
3
|
-
/**
|
4
|
-
* 将含有 id parentID 的 list 列表转换为树形结构
|
5
|
-
* 这里将 parentID 为 null 或 undefined 的设置为 第一层
|
6
|
-
* list 格式要求 [{parentID:null, id:10}, {parentID:10, id:100}]
|
7
|
-
*/
|
8
|
-
function listToTree(source, rawOptions = {}) {
|
9
|
-
const {
|
10
|
-
idFieldName = "id", // id FieId 的名称 默认为 'id'
|
11
|
-
parentIDFieldName = "parentID", // parentID FieId 的名称 默认为 'parentID'
|
12
|
-
childrenFieldName = "children", // children FieId 的名称 默认为 'children'
|
13
|
-
ignoreOrphans = false, // 是否忽略孤儿节点
|
14
|
-
} = rawOptions;
|
15
|
-
//只处理数组结构
|
16
|
-
if (!source || !Array.isArray(source)) {
|
17
|
-
console.warn("listToTree : 数据为空或数据格式有误 (正确情况应为 Array) !!!");
|
18
|
-
return [];
|
19
|
-
}
|
20
|
-
let cloneData = JSON.parse(JSON.stringify(source)); // 对源数据深度克隆
|
21
|
-
const idMap = new Map();
|
22
|
-
const parentIDMap = new Map();
|
23
|
-
for (let t of cloneData) {
|
24
|
-
idMap.set(t[idFieldName], t);
|
25
|
-
const v = parentIDMap.get(t[parentIDFieldName]);
|
26
|
-
if (v) {
|
27
|
-
v.push(t);
|
28
|
-
} else {
|
29
|
-
parentIDMap.set(t[parentIDFieldName], [t]);
|
30
|
-
}
|
31
|
-
}
|
32
|
-
// 循环所有项,并添加 children 属性
|
33
|
-
return cloneData.filter(my => {
|
34
|
-
const myID = my[idFieldName]; //我自己的 id
|
35
|
-
const parentID = my[parentIDFieldName]; //我父亲的 id
|
36
|
-
//判断是否为孤儿 , 如果查询不到他的父级节点 那么他就是孤儿
|
37
|
-
let isOrphan = !ignoreOrphans && (parentID == null || idMap.get(parentID) == null);
|
38
|
-
if (myID) {
|
39
|
-
// 返回每一项的子级数组
|
40
|
-
const myChildren = parentIDMap.get(myID);
|
41
|
-
if (myChildren && myChildren.length > 0) {
|
42
|
-
my[childrenFieldName] = myChildren;
|
43
|
-
}
|
44
|
-
}
|
45
|
-
//需要返回的节点 1, 是根节点 2, 是孤儿节点
|
46
|
-
return isNull(parentID) || isOrphan;
|
47
|
-
});
|
48
|
-
|
49
|
-
}
|
50
|
-
|
51
|
-
export {listToTree};
|
1
|
+
import {isNull} from "../util/ObjectUtils.js";
|
2
|
+
|
3
|
+
/**
|
4
|
+
* 将含有 id parentID 的 list 列表转换为树形结构
|
5
|
+
* 这里将 parentID 为 null 或 undefined 的设置为 第一层
|
6
|
+
* list 格式要求 [{parentID:null, id:10}, {parentID:10, id:100}]
|
7
|
+
*/
|
8
|
+
function listToTree(source, rawOptions = {}) {
|
9
|
+
const {
|
10
|
+
idFieldName = "id", // id FieId 的名称 默认为 'id'
|
11
|
+
parentIDFieldName = "parentID", // parentID FieId 的名称 默认为 'parentID'
|
12
|
+
childrenFieldName = "children", // children FieId 的名称 默认为 'children'
|
13
|
+
ignoreOrphans = false, // 是否忽略孤儿节点
|
14
|
+
} = rawOptions;
|
15
|
+
//只处理数组结构
|
16
|
+
if (!source || !Array.isArray(source)) {
|
17
|
+
console.warn("listToTree : 数据为空或数据格式有误 (正确情况应为 Array) !!!");
|
18
|
+
return [];
|
19
|
+
}
|
20
|
+
let cloneData = JSON.parse(JSON.stringify(source)); // 对源数据深度克隆
|
21
|
+
const idMap = new Map();
|
22
|
+
const parentIDMap = new Map();
|
23
|
+
for (let t of cloneData) {
|
24
|
+
idMap.set(t[idFieldName], t);
|
25
|
+
const v = parentIDMap.get(t[parentIDFieldName]);
|
26
|
+
if (v) {
|
27
|
+
v.push(t);
|
28
|
+
} else {
|
29
|
+
parentIDMap.set(t[parentIDFieldName], [t]);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
// 循环所有项,并添加 children 属性
|
33
|
+
return cloneData.filter(my => {
|
34
|
+
const myID = my[idFieldName]; //我自己的 id
|
35
|
+
const parentID = my[parentIDFieldName]; //我父亲的 id
|
36
|
+
//判断是否为孤儿 , 如果查询不到他的父级节点 那么他就是孤儿
|
37
|
+
let isOrphan = !ignoreOrphans && (parentID == null || idMap.get(parentID) == null);
|
38
|
+
if (myID) {
|
39
|
+
// 返回每一项的子级数组
|
40
|
+
const myChildren = parentIDMap.get(myID);
|
41
|
+
if (myChildren && myChildren.length > 0) {
|
42
|
+
my[childrenFieldName] = myChildren;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
//需要返回的节点 1, 是根节点 2, 是孤儿节点
|
46
|
+
return isNull(parentID) || isOrphan;
|
47
|
+
});
|
48
|
+
|
49
|
+
}
|
50
|
+
|
51
|
+
export {listToTree};
|
package/util/ArrayUtils.js
CHANGED
@@ -1,138 +1,138 @@
|
|
1
|
-
/**
|
2
|
-
* 拷贝数组 (浅拷贝)
|
3
|
-
* @param list
|
4
|
-
* @returns {*[]}
|
5
|
-
*/
|
6
|
-
function copyArray(list) {
|
7
|
-
return [...list];
|
8
|
-
}
|
9
|
-
|
10
|
-
/**
|
11
|
-
* 根据 索引 从数组中移除 项
|
12
|
-
* @param list
|
13
|
-
* @param index
|
14
|
-
*/
|
15
|
-
function removeByIndex(list, index) {
|
16
|
-
list.splice(index, 1);
|
17
|
-
}
|
18
|
-
|
19
|
-
/**
|
20
|
-
* 内部用 所以不进行 index 是否越界的校验
|
21
|
-
* @param list a
|
22
|
-
* @param oldIndex a
|
23
|
-
* @param newIndex a
|
24
|
-
*/
|
25
|
-
function moveItemByIndex(list, oldIndex, newIndex) {
|
26
|
-
//经过计算 后有可能导致 索引没变化 这时就不需要在移动一次了
|
27
|
-
if (oldIndex !== newIndex) {
|
28
|
-
//保存临时数据
|
29
|
-
const oldItem = list[oldIndex];
|
30
|
-
//从原数组中移除数据
|
31
|
-
list.splice(oldIndex, 1);
|
32
|
-
//在指定位置插入新数据
|
33
|
-
list.splice(newIndex, 0, oldItem);
|
34
|
-
}
|
35
|
-
}
|
36
|
-
|
37
|
-
/**
|
38
|
-
* 根据 索引 从数组中上移 项
|
39
|
-
* @param list 列表
|
40
|
-
* @param index 索引
|
41
|
-
* @param loop 是否采用循环
|
42
|
-
* @param step 步长
|
43
|
-
*/
|
44
|
-
function moveUpByIndex(list, index, loop = false, step = 1) {
|
45
|
-
let minIndex = 0;
|
46
|
-
let nextIndex = index - step;
|
47
|
-
if (nextIndex < minIndex) {
|
48
|
-
nextIndex = loop ? nextIndex % list.length + list.length : minIndex;
|
49
|
-
}
|
50
|
-
return moveItemByIndex(list, index, nextIndex);
|
51
|
-
}
|
52
|
-
|
53
|
-
/**
|
54
|
-
* 根据 索引 从数组中下移 项
|
55
|
-
* @param list 列表
|
56
|
-
* @param index 索引
|
57
|
-
* @param loop 是否采用循环
|
58
|
-
* @param step 步长
|
59
|
-
*/
|
60
|
-
function moveDownByIndex(list, index, loop = false, step = 1) {
|
61
|
-
let maxIndex = list.length - 1;
|
62
|
-
let nextIndex = index + step;
|
63
|
-
if (nextIndex > maxIndex) {
|
64
|
-
nextIndex = loop ? nextIndex % list.length : maxIndex;
|
65
|
-
}
|
66
|
-
return moveItemByIndex(list, index, nextIndex);
|
67
|
-
}
|
68
|
-
|
69
|
-
/**
|
70
|
-
* 根据 项 从数组中移除 项
|
71
|
-
* @param list
|
72
|
-
* @param item
|
73
|
-
*/
|
74
|
-
function removeByItem(list, item) {
|
75
|
-
return removeByIndex(list, list.indexOf(item));
|
76
|
-
}
|
77
|
-
|
78
|
-
/**
|
79
|
-
* 根据 项 从数组中上移 项
|
80
|
-
* @param list 列表
|
81
|
-
* @param item 项
|
82
|
-
* @param loop 是否采用循环
|
83
|
-
* @param step 步长
|
84
|
-
*/
|
85
|
-
function moveUpByItem(list, item, loop = false, step = 1) {
|
86
|
-
return moveUpByIndex(list, list.indexOf(item), loop, step);
|
87
|
-
}
|
88
|
-
|
89
|
-
/**
|
90
|
-
* 根据 项 从数组中下移 项
|
91
|
-
* @param list 列表
|
92
|
-
* @param item 项
|
93
|
-
* @param loop 是否采用循环
|
94
|
-
* @param step 步长
|
95
|
-
*/
|
96
|
-
function moveDownByItem(list, item, loop = false, step = 1) {
|
97
|
-
return moveDownByIndex(list, list.indexOf(item), loop, step);
|
98
|
-
}
|
99
|
-
|
100
|
-
/**
|
101
|
-
* 在指定位置插入数据
|
102
|
-
* @param list 列表
|
103
|
-
* @param index 插入索引
|
104
|
-
* @param items 项
|
105
|
-
*/
|
106
|
-
function insertItem(list, index, ...items) {
|
107
|
-
if (index < 0) {
|
108
|
-
list.unshift(...items);
|
109
|
-
} else if (index > list.length) {
|
110
|
-
list.push(...items);
|
111
|
-
} else {
|
112
|
-
list.splice(index, 0, ...items);
|
113
|
-
}
|
114
|
-
}
|
115
|
-
|
116
|
-
function arrayEquals(array1, array2) {
|
117
|
-
if (array1.length !== array2.length) {
|
118
|
-
return false;
|
119
|
-
}
|
120
|
-
for (let i = 0; i < array1.length; i++) {
|
121
|
-
if (array1[i] !== array2[i]) {
|
122
|
-
return false;
|
123
|
-
}
|
124
|
-
}
|
125
|
-
return true;
|
126
|
-
}
|
127
|
-
|
128
|
-
export {
|
129
|
-
copyArray,
|
130
|
-
removeByIndex,
|
131
|
-
moveUpByIndex,
|
132
|
-
moveDownByIndex,
|
133
|
-
removeByItem,
|
134
|
-
moveUpByItem,
|
135
|
-
moveDownByItem,
|
136
|
-
insertItem,
|
137
|
-
arrayEquals,
|
138
|
-
};
|
1
|
+
/**
|
2
|
+
* 拷贝数组 (浅拷贝)
|
3
|
+
* @param list
|
4
|
+
* @returns {*[]}
|
5
|
+
*/
|
6
|
+
function copyArray(list) {
|
7
|
+
return [...list];
|
8
|
+
}
|
9
|
+
|
10
|
+
/**
|
11
|
+
* 根据 索引 从数组中移除 项
|
12
|
+
* @param list
|
13
|
+
* @param index
|
14
|
+
*/
|
15
|
+
function removeByIndex(list, index) {
|
16
|
+
list.splice(index, 1);
|
17
|
+
}
|
18
|
+
|
19
|
+
/**
|
20
|
+
* 内部用 所以不进行 index 是否越界的校验
|
21
|
+
* @param list a
|
22
|
+
* @param oldIndex a
|
23
|
+
* @param newIndex a
|
24
|
+
*/
|
25
|
+
function moveItemByIndex(list, oldIndex, newIndex) {
|
26
|
+
//经过计算 后有可能导致 索引没变化 这时就不需要在移动一次了
|
27
|
+
if (oldIndex !== newIndex) {
|
28
|
+
//保存临时数据
|
29
|
+
const oldItem = list[oldIndex];
|
30
|
+
//从原数组中移除数据
|
31
|
+
list.splice(oldIndex, 1);
|
32
|
+
//在指定位置插入新数据
|
33
|
+
list.splice(newIndex, 0, oldItem);
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
/**
|
38
|
+
* 根据 索引 从数组中上移 项
|
39
|
+
* @param list 列表
|
40
|
+
* @param index 索引
|
41
|
+
* @param loop 是否采用循环
|
42
|
+
* @param step 步长
|
43
|
+
*/
|
44
|
+
function moveUpByIndex(list, index, loop = false, step = 1) {
|
45
|
+
let minIndex = 0;
|
46
|
+
let nextIndex = index - step;
|
47
|
+
if (nextIndex < minIndex) {
|
48
|
+
nextIndex = loop ? nextIndex % list.length + list.length : minIndex;
|
49
|
+
}
|
50
|
+
return moveItemByIndex(list, index, nextIndex);
|
51
|
+
}
|
52
|
+
|
53
|
+
/**
|
54
|
+
* 根据 索引 从数组中下移 项
|
55
|
+
* @param list 列表
|
56
|
+
* @param index 索引
|
57
|
+
* @param loop 是否采用循环
|
58
|
+
* @param step 步长
|
59
|
+
*/
|
60
|
+
function moveDownByIndex(list, index, loop = false, step = 1) {
|
61
|
+
let maxIndex = list.length - 1;
|
62
|
+
let nextIndex = index + step;
|
63
|
+
if (nextIndex > maxIndex) {
|
64
|
+
nextIndex = loop ? nextIndex % list.length : maxIndex;
|
65
|
+
}
|
66
|
+
return moveItemByIndex(list, index, nextIndex);
|
67
|
+
}
|
68
|
+
|
69
|
+
/**
|
70
|
+
* 根据 项 从数组中移除 项
|
71
|
+
* @param list
|
72
|
+
* @param item
|
73
|
+
*/
|
74
|
+
function removeByItem(list, item) {
|
75
|
+
return removeByIndex(list, list.indexOf(item));
|
76
|
+
}
|
77
|
+
|
78
|
+
/**
|
79
|
+
* 根据 项 从数组中上移 项
|
80
|
+
* @param list 列表
|
81
|
+
* @param item 项
|
82
|
+
* @param loop 是否采用循环
|
83
|
+
* @param step 步长
|
84
|
+
*/
|
85
|
+
function moveUpByItem(list, item, loop = false, step = 1) {
|
86
|
+
return moveUpByIndex(list, list.indexOf(item), loop, step);
|
87
|
+
}
|
88
|
+
|
89
|
+
/**
|
90
|
+
* 根据 项 从数组中下移 项
|
91
|
+
* @param list 列表
|
92
|
+
* @param item 项
|
93
|
+
* @param loop 是否采用循环
|
94
|
+
* @param step 步长
|
95
|
+
*/
|
96
|
+
function moveDownByItem(list, item, loop = false, step = 1) {
|
97
|
+
return moveDownByIndex(list, list.indexOf(item), loop, step);
|
98
|
+
}
|
99
|
+
|
100
|
+
/**
|
101
|
+
* 在指定位置插入数据
|
102
|
+
* @param list 列表
|
103
|
+
* @param index 插入索引
|
104
|
+
* @param items 项
|
105
|
+
*/
|
106
|
+
function insertItem(list, index, ...items) {
|
107
|
+
if (index < 0) {
|
108
|
+
list.unshift(...items);
|
109
|
+
} else if (index > list.length) {
|
110
|
+
list.push(...items);
|
111
|
+
} else {
|
112
|
+
list.splice(index, 0, ...items);
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
function arrayEquals(array1, array2) {
|
117
|
+
if (array1.length !== array2.length) {
|
118
|
+
return false;
|
119
|
+
}
|
120
|
+
for (let i = 0; i < array1.length; i++) {
|
121
|
+
if (array1[i] !== array2[i]) {
|
122
|
+
return false;
|
123
|
+
}
|
124
|
+
}
|
125
|
+
return true;
|
126
|
+
}
|
127
|
+
|
128
|
+
export {
|
129
|
+
copyArray,
|
130
|
+
removeByIndex,
|
131
|
+
moveUpByIndex,
|
132
|
+
moveDownByIndex,
|
133
|
+
removeByItem,
|
134
|
+
moveUpByItem,
|
135
|
+
moveDownByItem,
|
136
|
+
insertItem,
|
137
|
+
arrayEquals,
|
138
|
+
};
|
package/util/MathUtils.js
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
/**
|
2
|
-
* a
|
3
|
-
* @param value1 {number|string}
|
4
|
-
* @param value2 {number|string}
|
5
|
-
* @param fractionDigits {number}
|
6
|
-
* @returns {number}
|
7
|
-
*/
|
8
|
-
function percentage(value1, value2, fractionDigits = 2) {
|
9
|
-
const v1 = parseFloat(value1);
|
10
|
-
const v2 = parseFloat(value2);
|
11
|
-
if (!isNaN(v1) && !isNaN(v2)) {
|
12
|
-
return parseFloat(((v1 / v2) * 100).toFixed(fractionDigits));
|
13
|
-
} else {
|
14
|
-
return NaN;
|
15
|
-
}
|
16
|
-
}
|
17
|
-
|
18
|
-
export {
|
19
|
-
percentage,
|
20
|
-
};
|
1
|
+
/**
|
2
|
+
* a
|
3
|
+
* @param value1 {number|string}
|
4
|
+
* @param value2 {number|string}
|
5
|
+
* @param fractionDigits {number}
|
6
|
+
* @returns {number}
|
7
|
+
*/
|
8
|
+
function percentage(value1, value2, fractionDigits = 2) {
|
9
|
+
const v1 = parseFloat(value1);
|
10
|
+
const v2 = parseFloat(value2);
|
11
|
+
if (!isNaN(v1) && !isNaN(v2)) {
|
12
|
+
return parseFloat(((v1 / v2) * 100).toFixed(fractionDigits));
|
13
|
+
} else {
|
14
|
+
return NaN;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
export {
|
19
|
+
percentage,
|
20
|
+
};
|
package/util/ObjectUtils.js
CHANGED
@@ -1,32 +1,32 @@
|
|
1
|
-
/**
|
2
|
-
*
|
3
|
-
* @param o {any}
|
4
|
-
* @returns {any}
|
5
|
-
*/
|
6
|
-
function deepCopy(o) {
|
7
|
-
//这里用一种简单粗暴的方式实现 深拷贝 不过这样会使对象上的方法丢失 不建议用于一些复杂对象
|
8
|
-
return JSON.parse(JSON.stringify(o));
|
9
|
-
}
|
10
|
-
|
11
|
-
function isNull(o) {
|
12
|
-
return !notNull(o);
|
13
|
-
}
|
14
|
-
|
15
|
-
function notNull(o) {
|
16
|
-
return o !== undefined && o !== null;
|
17
|
-
}
|
18
|
-
|
19
|
-
/**
|
20
|
-
* 判断字符串 不为空
|
21
|
-
* @param str
|
22
|
-
* @returns {boolean}
|
23
|
-
*/
|
24
|
-
function notBlank(str) {
|
25
|
-
return notNull(str) ? str.toString().trim() !== "" : false;
|
26
|
-
}
|
27
|
-
|
28
|
-
function isBlank(str) {
|
29
|
-
return !notBlank(str);
|
30
|
-
}
|
31
|
-
|
32
|
-
export {deepCopy, isNull, notNull, isBlank, notBlank};
|
1
|
+
/**
|
2
|
+
*
|
3
|
+
* @param o {any}
|
4
|
+
* @returns {any}
|
5
|
+
*/
|
6
|
+
function deepCopy(o) {
|
7
|
+
//这里用一种简单粗暴的方式实现 深拷贝 不过这样会使对象上的方法丢失 不建议用于一些复杂对象
|
8
|
+
return JSON.parse(JSON.stringify(o));
|
9
|
+
}
|
10
|
+
|
11
|
+
function isNull(o) {
|
12
|
+
return !notNull(o);
|
13
|
+
}
|
14
|
+
|
15
|
+
function notNull(o) {
|
16
|
+
return o !== undefined && o !== null;
|
17
|
+
}
|
18
|
+
|
19
|
+
/**
|
20
|
+
* 判断字符串 不为空
|
21
|
+
* @param str
|
22
|
+
* @returns {boolean}
|
23
|
+
*/
|
24
|
+
function notBlank(str) {
|
25
|
+
return notNull(str) ? str.toString().trim() !== "" : false;
|
26
|
+
}
|
27
|
+
|
28
|
+
function isBlank(str) {
|
29
|
+
return !notBlank(str);
|
30
|
+
}
|
31
|
+
|
32
|
+
export {deepCopy, isNull, notNull, isBlank, notBlank};
|
package/util/RandomUtils.js
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
function randomUUID() {
|
2
|
-
const temp_url = URL.createObjectURL(new Blob());
|
3
|
-
const uuid = temp_url.toString();
|
4
|
-
URL.revokeObjectURL(temp_url);
|
5
|
-
return uuid.substring(uuid.lastIndexOf("/") + 1);
|
6
|
-
}
|
7
|
-
|
8
|
-
export {
|
9
|
-
randomUUID,
|
10
|
-
};
|
1
|
+
function randomUUID() {
|
2
|
+
const temp_url = URL.createObjectURL(new Blob());
|
3
|
+
const uuid = temp_url.toString();
|
4
|
+
URL.revokeObjectURL(temp_url);
|
5
|
+
return uuid.substring(uuid.lastIndexOf("/") + 1);
|
6
|
+
}
|
7
|
+
|
8
|
+
export {
|
9
|
+
randomUUID,
|
10
|
+
};
|
package/util/ThrottleUtils.js
CHANGED
@@ -1,26 +1,26 @@
|
|
1
|
-
/**
|
2
|
-
* 使用 requestAnimationFrame 进行节流
|
3
|
-
* @param callback
|
4
|
-
* @return 带有节流的 callback
|
5
|
-
*/
|
6
|
-
function rafThrottle(callback) {
|
7
|
-
let requestId = null;
|
8
|
-
const throttled = function (...arg) {
|
9
|
-
if (requestId) {
|
10
|
-
return;
|
11
|
-
}
|
12
|
-
requestId = requestAnimationFrame(() => {
|
13
|
-
requestId = null;
|
14
|
-
callback.apply(this, arg);
|
15
|
-
});
|
16
|
-
};
|
17
|
-
throttled.cancel = () => {
|
18
|
-
cancelAnimationFrame(requestId);
|
19
|
-
requestId = null;
|
20
|
-
};
|
21
|
-
return throttled;
|
22
|
-
}
|
23
|
-
|
24
|
-
export {
|
25
|
-
rafThrottle,
|
26
|
-
};
|
1
|
+
/**
|
2
|
+
* 使用 requestAnimationFrame 进行节流
|
3
|
+
* @param callback
|
4
|
+
* @return 带有节流的 callback
|
5
|
+
*/
|
6
|
+
function rafThrottle(callback) {
|
7
|
+
let requestId = null;
|
8
|
+
const throttled = function (...arg) {
|
9
|
+
if (requestId) {
|
10
|
+
return;
|
11
|
+
}
|
12
|
+
requestId = requestAnimationFrame(() => {
|
13
|
+
requestId = null;
|
14
|
+
callback.apply(this, arg);
|
15
|
+
});
|
16
|
+
};
|
17
|
+
throttled.cancel = () => {
|
18
|
+
cancelAnimationFrame(requestId);
|
19
|
+
requestId = null;
|
20
|
+
};
|
21
|
+
return throttled;
|
22
|
+
}
|
23
|
+
|
24
|
+
export {
|
25
|
+
rafThrottle,
|
26
|
+
};
|
package/util/TypeUtils.js
CHANGED
@@ -1,27 +1,27 @@
|
|
1
|
-
function isString(s) {
|
2
|
-
return typeof s === "string" || s instanceof String;
|
3
|
-
}
|
4
|
-
|
5
|
-
function isNumber(n) {
|
6
|
-
return typeof n === "number" || n instanceof Number;
|
7
|
-
}
|
8
|
-
|
9
|
-
function isFunction(f) {
|
10
|
-
return typeof f === "function" || f instanceof Function;
|
11
|
-
}
|
12
|
-
|
13
|
-
function isObject(o) {
|
14
|
-
return Object.prototype.toString.call(o) === "[object Object]";
|
15
|
-
}
|
16
|
-
|
17
|
-
function isArray(value) {
|
18
|
-
return Array.isArray(value);
|
19
|
-
}
|
20
|
-
|
21
|
-
export {
|
22
|
-
isFunction,
|
23
|
-
isString,
|
24
|
-
isObject,
|
25
|
-
isNumber,
|
26
|
-
isArray,
|
27
|
-
};
|
1
|
+
function isString(s) {
|
2
|
+
return typeof s === "string" || s instanceof String;
|
3
|
+
}
|
4
|
+
|
5
|
+
function isNumber(n) {
|
6
|
+
return typeof n === "number" || n instanceof Number;
|
7
|
+
}
|
8
|
+
|
9
|
+
function isFunction(f) {
|
10
|
+
return typeof f === "function" || f instanceof Function;
|
11
|
+
}
|
12
|
+
|
13
|
+
function isObject(o) {
|
14
|
+
return Object.prototype.toString.call(o) === "[object Object]";
|
15
|
+
}
|
16
|
+
|
17
|
+
function isArray(value) {
|
18
|
+
return Array.isArray(value);
|
19
|
+
}
|
20
|
+
|
21
|
+
export {
|
22
|
+
isFunction,
|
23
|
+
isString,
|
24
|
+
isObject,
|
25
|
+
isNumber,
|
26
|
+
isArray,
|
27
|
+
};
|
package/util/URLUtils.js
CHANGED
@@ -1,43 +1,43 @@
|
|
1
|
-
import {notBlank} from "./ObjectUtils.js";
|
2
|
-
|
3
|
-
/**
|
4
|
-
* 是否是外链
|
5
|
-
* @param {string} url
|
6
|
-
* @returns {boolean}
|
7
|
-
*/
|
8
|
-
function isExternal(url) {
|
9
|
-
return /^(https?:|mailto:|tel:)/.test(url);
|
10
|
-
}
|
11
|
-
|
12
|
-
/**
|
13
|
-
* 是否是 http 路径
|
14
|
-
* @param url
|
15
|
-
* @returns {boolean}
|
16
|
-
*/
|
17
|
-
function isHttpURL(url) {
|
18
|
-
return /^(https?:)/.test(url);
|
19
|
-
}
|
20
|
-
|
21
|
-
/**
|
22
|
-
* 清理路径
|
23
|
-
* @param url
|
24
|
-
* @returns {*|string}
|
25
|
-
*/
|
26
|
-
function cleanURL(url) {
|
27
|
-
return url.join("/").split("/").filter(notBlank).join("/");
|
28
|
-
}
|
29
|
-
|
30
|
-
|
31
|
-
/**
|
32
|
-
* 拼接 http url
|
33
|
-
* @returns {*}
|
34
|
-
* @param baseURL
|
35
|
-
* @param urls
|
36
|
-
*/
|
37
|
-
function joinURL(baseURL, ...urls) {
|
38
|
-
return new URL(cleanURL(urls), baseURL);
|
39
|
-
}
|
40
|
-
|
41
|
-
export {
|
42
|
-
isExternal, isHttpURL, cleanURL, joinURL,
|
43
|
-
};
|
1
|
+
import {notBlank} from "./ObjectUtils.js";
|
2
|
+
|
3
|
+
/**
|
4
|
+
* 是否是外链
|
5
|
+
* @param {string} url
|
6
|
+
* @returns {boolean}
|
7
|
+
*/
|
8
|
+
function isExternal(url) {
|
9
|
+
return /^(https?:|mailto:|tel:)/.test(url);
|
10
|
+
}
|
11
|
+
|
12
|
+
/**
|
13
|
+
* 是否是 http 路径
|
14
|
+
* @param url
|
15
|
+
* @returns {boolean}
|
16
|
+
*/
|
17
|
+
function isHttpURL(url) {
|
18
|
+
return /^(https?:)/.test(url);
|
19
|
+
}
|
20
|
+
|
21
|
+
/**
|
22
|
+
* 清理路径
|
23
|
+
* @param url
|
24
|
+
* @returns {*|string}
|
25
|
+
*/
|
26
|
+
function cleanURL(url) {
|
27
|
+
return url.join("/").split("/").filter(notBlank).join("/");
|
28
|
+
}
|
29
|
+
|
30
|
+
|
31
|
+
/**
|
32
|
+
* 拼接 http url
|
33
|
+
* @returns {*}
|
34
|
+
* @param baseURL
|
35
|
+
* @param urls
|
36
|
+
*/
|
37
|
+
function joinURL(baseURL, ...urls) {
|
38
|
+
return new URL(cleanURL(urls), baseURL);
|
39
|
+
}
|
40
|
+
|
41
|
+
export {
|
42
|
+
isExternal, isHttpURL, cleanURL, joinURL,
|
43
|
+
};
|