baja-lite 1.7.7 → 1.7.8
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/fn.d.ts +2 -1
- package/fn.js +15 -7
- package/package.json +2 -2
- package/snowflake.d.ts +8 -0
- package/snowflake.js +17 -4
- package/sql.d.ts +4 -4
- package/sql.js +44 -33
- package/string.d.ts +27 -0
- package/string.js +27 -0
package/fn.d.ts
CHANGED
|
@@ -79,7 +79,8 @@ export declare enum ExcuteSplitMode {
|
|
|
79
79
|
## 分割数组方式:2种,选择一种即可
|
|
80
80
|
1. everyLength=每组个数(最后一组可能不足次数)
|
|
81
81
|
2. groupCount=拆分几组
|
|
82
|
-
## settled 异步执行是否并行执行? 默认false
|
|
82
|
+
## `settled` 异步执行是否并行执行? 默认false。
|
|
83
|
+
** 注意:开启并行执行时,请确保 `fn` 内部没有共享状态(如共用同一个数据库连接),否则可能导致冲突。
|
|
83
84
|
## `extendParams`:扩展参数
|
|
84
85
|
** 数组
|
|
85
86
|
** 结合分组方式:groupCount使用。例如:
|
package/fn.js
CHANGED
|
@@ -88,7 +88,11 @@ export function excuteSplit(sync, datas, fn, { everyLength = 0, groupCount = 0,
|
|
|
88
88
|
try {
|
|
89
89
|
const reasons = [];
|
|
90
90
|
if (settled) {
|
|
91
|
-
const result = await Promise.allSettled(list.map((list, i) =>
|
|
91
|
+
const result = await Promise.allSettled(list.map((list, i) => {
|
|
92
|
+
const startIndex = i * ps.everyLength;
|
|
93
|
+
const endIndex = startIndex + list.length - 1;
|
|
94
|
+
return fn(list, i, list.length, extendParams[i], startIndex, endIndex);
|
|
95
|
+
}));
|
|
92
96
|
for (const item of result) {
|
|
93
97
|
if (item.status === 'rejected') {
|
|
94
98
|
reject(item.reason);
|
|
@@ -100,7 +104,7 @@ export function excuteSplit(sync, datas, fn, { everyLength = 0, groupCount = 0,
|
|
|
100
104
|
}
|
|
101
105
|
else {
|
|
102
106
|
for (let i = 0; i < list.length; i++) {
|
|
103
|
-
const startIndex =
|
|
107
|
+
const startIndex = i * ps.everyLength;
|
|
104
108
|
const endIndex = startIndex + list[i].length - 1;
|
|
105
109
|
reasons.push(await fn(list[i], i, list.length, extendParams[i], startIndex, endIndex));
|
|
106
110
|
}
|
|
@@ -117,7 +121,11 @@ export function excuteSplit(sync, datas, fn, { everyLength = 0, groupCount = 0,
|
|
|
117
121
|
try {
|
|
118
122
|
const reasons = { result: [], error: [] };
|
|
119
123
|
if (settled) {
|
|
120
|
-
const result = await Promise.allSettled(list.map((list, i) =>
|
|
124
|
+
const result = await Promise.allSettled(list.map((list, i) => {
|
|
125
|
+
const startIndex = i * ps.everyLength;
|
|
126
|
+
const endIndex = startIndex + list.length - 1;
|
|
127
|
+
return fn(list, i, list.length, extendParams[i], startIndex, endIndex);
|
|
128
|
+
}));
|
|
121
129
|
for (const item of result) {
|
|
122
130
|
if (item.status === 'rejected') {
|
|
123
131
|
reasons.error.push(item.reason);
|
|
@@ -129,7 +137,7 @@ export function excuteSplit(sync, datas, fn, { everyLength = 0, groupCount = 0,
|
|
|
129
137
|
}
|
|
130
138
|
else {
|
|
131
139
|
for (let i = 0; i < list.length; i++) {
|
|
132
|
-
const startIndex =
|
|
140
|
+
const startIndex = i * ps.everyLength;
|
|
133
141
|
const endIndex = startIndex + list[i].length - 1;
|
|
134
142
|
try {
|
|
135
143
|
reasons.result.push(await fn(list[i], i, list.length, extendParams[i], startIndex, endIndex));
|
|
@@ -149,7 +157,7 @@ export function excuteSplit(sync, datas, fn, { everyLength = 0, groupCount = 0,
|
|
|
149
157
|
else if (sync === ExcuteSplitMode.SyncTrust) {
|
|
150
158
|
const reasons = [];
|
|
151
159
|
for (let i = 0; i < list.length; i++) {
|
|
152
|
-
const startIndex =
|
|
160
|
+
const startIndex = i * ps.everyLength;
|
|
153
161
|
const endIndex = startIndex + list[i].length - 1;
|
|
154
162
|
reasons.push(fn(list[i], i, list.length, extendParams[i], startIndex, endIndex));
|
|
155
163
|
}
|
|
@@ -159,8 +167,8 @@ export function excuteSplit(sync, datas, fn, { everyLength = 0, groupCount = 0,
|
|
|
159
167
|
const reasons = { result: [], error: [] };
|
|
160
168
|
for (let i = 0; i < list.length; i++) {
|
|
161
169
|
try {
|
|
162
|
-
const startIndex =
|
|
163
|
-
const endIndex = startIndex + list[i].length -
|
|
170
|
+
const startIndex = i * ps.everyLength;
|
|
171
|
+
const endIndex = startIndex + list[i].length - 0;
|
|
164
172
|
reasons.result.push(fn(list[i], i, list.length, extendParams[i], startIndex, endIndex));
|
|
165
173
|
}
|
|
166
174
|
catch (error) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "baja-lite",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.8",
|
|
4
4
|
"description": "some util for self",
|
|
5
5
|
"homepage": "https://github.com/void-soul/baja-lite",
|
|
6
6
|
"repository": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"reflect-metadata": "0.2.2",
|
|
48
48
|
"request": "2.88.2",
|
|
49
49
|
"request-promise": "4.2.6",
|
|
50
|
-
"sql-formatter": "15.7.
|
|
50
|
+
"sql-formatter": "15.7.3",
|
|
51
51
|
"sqlstring": "2.3.3",
|
|
52
52
|
"tslib": "2.8.1"
|
|
53
53
|
},
|
package/snowflake.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 雪花算法 ID 生成器
|
|
3
|
+
* 用于生成分布式唯一 ID
|
|
4
|
+
*/
|
|
1
5
|
export declare class Snowflake {
|
|
2
6
|
private seq;
|
|
3
7
|
private mid;
|
|
@@ -7,6 +11,10 @@ export declare class Snowflake {
|
|
|
7
11
|
mid?: number;
|
|
8
12
|
offset?: number;
|
|
9
13
|
});
|
|
14
|
+
/**
|
|
15
|
+
* 生成下一个唯一 ID
|
|
16
|
+
* @returns 10 进制字符串形式的 ID,失败返回 null
|
|
17
|
+
*/
|
|
10
18
|
generate(): string | null;
|
|
11
19
|
}
|
|
12
20
|
export declare const snowflake: Snowflake;
|
package/snowflake.js
CHANGED
|
@@ -66,6 +66,10 @@ function convertBase(str, fromBase, toBase) {
|
|
|
66
66
|
}
|
|
67
67
|
return out;
|
|
68
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* 雪花算法 ID 生成器
|
|
71
|
+
* 用于生成分布式唯一 ID
|
|
72
|
+
*/
|
|
69
73
|
export class Snowflake {
|
|
70
74
|
constructor(options) {
|
|
71
75
|
options = options || {};
|
|
@@ -74,20 +78,29 @@ export class Snowflake {
|
|
|
74
78
|
this.offset = options.offset || 0;
|
|
75
79
|
this.lastTime = 0;
|
|
76
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* 生成下一个唯一 ID
|
|
83
|
+
* @returns 10 进制字符串形式的 ID,失败返回 null
|
|
84
|
+
*/
|
|
77
85
|
generate() {
|
|
78
|
-
let time = Date.now()
|
|
79
|
-
|
|
86
|
+
let time = Date.now();
|
|
87
|
+
// 基础保护:如果系统时间回拨,强制同步到最后一次生成时间以防止 ID 重复
|
|
88
|
+
if (time < this.lastTime) {
|
|
89
|
+
time = this.lastTime;
|
|
90
|
+
}
|
|
91
|
+
if (this.lastTime === time) {
|
|
80
92
|
this.seq++;
|
|
81
93
|
if (this.seq > 4095) {
|
|
82
94
|
this.seq = 0;
|
|
83
|
-
|
|
95
|
+
// 方案2:不再忙等待,直接预支进入下一毫秒
|
|
96
|
+
time++;
|
|
84
97
|
}
|
|
85
98
|
}
|
|
86
99
|
else {
|
|
87
100
|
this.seq = 0;
|
|
88
101
|
}
|
|
89
102
|
this.lastTime = time;
|
|
90
|
-
let bSeq = this.seq.toString(2), bMid = this.mid.toString(2);
|
|
103
|
+
let bTime = (time - this.offset).toString(2), bSeq = this.seq.toString(2), bMid = this.mid.toString(2);
|
|
91
104
|
while (bSeq.length < 12) {
|
|
92
105
|
bSeq = "0" + bSeq;
|
|
93
106
|
}
|
package/sql.d.ts
CHANGED
|
@@ -518,8 +518,8 @@ export interface Connection {
|
|
|
518
518
|
/** 多行多列 */
|
|
519
519
|
query<Many_Row_Many_Column = any>(sync: SyncMode.Sync, sql?: string, params?: any): Many_Row_Many_Column[];
|
|
520
520
|
query<Many_Row_Many_Column = any>(sync: SyncMode.Async, sql?: string, params?: any): Promise<Many_Row_Many_Column[]>;
|
|
521
|
-
|
|
522
|
-
|
|
521
|
+
release(sync: SyncMode.Sync): void;
|
|
522
|
+
release(sync: SyncMode.Async): Promise<void>;
|
|
523
523
|
}
|
|
524
524
|
interface Dao {
|
|
525
525
|
[_daoDB]: any;
|
|
@@ -606,8 +606,8 @@ export declare class SqliteRemoteConnection implements Connection {
|
|
|
606
606
|
raw<T = any>(sync: SyncMode.Async, sql?: string, params?: any): Promise<T[]>;
|
|
607
607
|
query<T = any>(sync: SyncMode.Sync, sql?: string, params?: any): T[];
|
|
608
608
|
query<T = any>(sync: SyncMode.Async, sql?: string, params?: any): Promise<T[]>;
|
|
609
|
-
|
|
610
|
-
|
|
609
|
+
release(sync: SyncMode.Sync): void;
|
|
610
|
+
release(sync: SyncMode.Async): Promise<void>;
|
|
611
611
|
}
|
|
612
612
|
export declare class SqliteRemote implements Dao {
|
|
613
613
|
[_sqliteRemoteName]: string;
|
package/sql.js
CHANGED
|
@@ -390,15 +390,15 @@ class MysqlConnection {
|
|
|
390
390
|
}
|
|
391
391
|
});
|
|
392
392
|
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
393
|
+
release(sync) {
|
|
394
|
+
try {
|
|
395
|
+
this[_daoConnection]?.release();
|
|
396
|
+
}
|
|
397
|
+
catch (error) {
|
|
398
|
+
}
|
|
399
|
+
if (sync === SyncMode.Async) {
|
|
400
|
+
return Promise.resolve();
|
|
400
401
|
}
|
|
401
|
-
;
|
|
402
402
|
}
|
|
403
403
|
}
|
|
404
404
|
_b = _inTransaction;
|
|
@@ -408,10 +408,21 @@ export class Mysql {
|
|
|
408
408
|
this.keepAlive();
|
|
409
409
|
}
|
|
410
410
|
async keepAlive() {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
411
|
+
let connection = null;
|
|
412
|
+
try {
|
|
413
|
+
connection = await this.createConnection(SyncMode.Async);
|
|
414
|
+
const data = await connection?.query(SyncMode.Async, 'SELECT 1 FROM DUAL');
|
|
415
|
+
globalThis[_LoggerService].debug?.('keepAlive->', data?.[0]?.[1]);
|
|
416
|
+
}
|
|
417
|
+
catch (error) {
|
|
418
|
+
globalThis[_LoggerService].error('keepAlive error', error);
|
|
419
|
+
}
|
|
420
|
+
finally {
|
|
421
|
+
if (connection) {
|
|
422
|
+
await connection.release(SyncMode.Async);
|
|
423
|
+
}
|
|
424
|
+
setTimeout(() => this.keepAlive(), globalThis[_MysqlKeepAliveTime] ?? 30000);
|
|
425
|
+
}
|
|
415
426
|
}
|
|
416
427
|
createConnection(sync) {
|
|
417
428
|
if (sync === SyncMode.Sync) {
|
|
@@ -691,15 +702,15 @@ class PostgresqlConnection {
|
|
|
691
702
|
}
|
|
692
703
|
});
|
|
693
704
|
}
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
705
|
+
release(sync) {
|
|
706
|
+
try {
|
|
707
|
+
this[_daoConnection]?.release();
|
|
708
|
+
}
|
|
709
|
+
catch (error) {
|
|
710
|
+
}
|
|
711
|
+
if (sync === SyncMode.Async) {
|
|
712
|
+
return Promise.resolve();
|
|
701
713
|
}
|
|
702
|
-
;
|
|
703
714
|
}
|
|
704
715
|
}
|
|
705
716
|
_c = _inTransaction;
|
|
@@ -930,7 +941,7 @@ class SqliteConnection {
|
|
|
930
941
|
throw error;
|
|
931
942
|
}
|
|
932
943
|
}
|
|
933
|
-
|
|
944
|
+
release(sync) {
|
|
934
945
|
}
|
|
935
946
|
}
|
|
936
947
|
_d = _inTransaction;
|
|
@@ -1174,7 +1185,7 @@ export class SqliteRemoteConnection {
|
|
|
1174
1185
|
}
|
|
1175
1186
|
});
|
|
1176
1187
|
}
|
|
1177
|
-
|
|
1188
|
+
release(sync) {
|
|
1178
1189
|
}
|
|
1179
1190
|
}
|
|
1180
1191
|
_e = _inTransaction;
|
|
@@ -1706,27 +1717,27 @@ export class SqlCache {
|
|
|
1706
1717
|
this.sqlFNMap = options.sqlFNMap;
|
|
1707
1718
|
}
|
|
1708
1719
|
if (options.sqlFNDir) {
|
|
1709
|
-
const sqlFis = globalThis[_fs].readdirSync(options.
|
|
1720
|
+
const sqlFis = globalThis[_fs].readdirSync(options.sqlFNDir);
|
|
1710
1721
|
for (const modeName of sqlFis) {
|
|
1711
1722
|
const extname = globalThis[_path].extname(modeName);
|
|
1712
1723
|
const name = globalThis[_path].basename(modeName, extname);
|
|
1713
|
-
const file = globalThis[_path].join(options.
|
|
1714
|
-
if (extname === 'mu') {
|
|
1724
|
+
const file = globalThis[_path].join(options.sqlFNDir, modeName);
|
|
1725
|
+
if (extname === '.mu') {
|
|
1715
1726
|
this.sqlFNMap[name] = globalThis[_fs].readFileSync(file, { encoding: 'utf-8' }).toString();
|
|
1716
1727
|
}
|
|
1717
1728
|
}
|
|
1718
1729
|
}
|
|
1719
1730
|
if (options.sqlMapperMap) {
|
|
1720
|
-
globalThis[_resultMap] = options.
|
|
1731
|
+
globalThis[_resultMap] = options.sqlMapperMap;
|
|
1721
1732
|
}
|
|
1722
1733
|
if (options.sqlMapperDir) {
|
|
1723
|
-
const sqlFis = globalThis[_fs].readdirSync(options.
|
|
1734
|
+
const sqlFis = globalThis[_fs].readdirSync(options.sqlMapperDir);
|
|
1724
1735
|
globalThis[_resultMap] ?? (globalThis[_resultMap] = {});
|
|
1725
1736
|
for (const modeName of sqlFis) {
|
|
1726
1737
|
const extname = globalThis[_path].extname(modeName);
|
|
1727
1738
|
const name = globalThis[_path].basename(modeName, extname);
|
|
1728
|
-
const file = globalThis[_path].join(options.
|
|
1729
|
-
if (extname === 'json') {
|
|
1739
|
+
const file = globalThis[_path].join(options.sqlMapperDir, modeName);
|
|
1740
|
+
if (extname === '.json') {
|
|
1730
1741
|
globalThis[_resultMap][name] = JSON.parse(globalThis[_fs].readFileSync(file, { encoding: 'utf-8' }).toString());
|
|
1731
1742
|
}
|
|
1732
1743
|
}
|
|
@@ -1827,7 +1838,7 @@ function P(skipConn = false) {
|
|
|
1827
1838
|
finally {
|
|
1828
1839
|
if (needRealseConn && option && option.conn) {
|
|
1829
1840
|
try {
|
|
1830
|
-
option.conn.
|
|
1841
|
+
option.conn.release(SyncMode.Sync);
|
|
1831
1842
|
}
|
|
1832
1843
|
catch (error) {
|
|
1833
1844
|
}
|
|
@@ -1865,7 +1876,7 @@ function P(skipConn = false) {
|
|
|
1865
1876
|
finally {
|
|
1866
1877
|
if (needRealseConn && option && option.conn) {
|
|
1867
1878
|
try {
|
|
1868
|
-
option.conn.
|
|
1879
|
+
await option.conn.release(SyncMode.Async);
|
|
1869
1880
|
}
|
|
1870
1881
|
catch (error) {
|
|
1871
1882
|
}
|
|
@@ -1895,7 +1906,7 @@ function P(skipConn = false) {
|
|
|
1895
1906
|
finally {
|
|
1896
1907
|
if (needRealseConn && option && option.conn) {
|
|
1897
1908
|
try {
|
|
1898
|
-
option.conn.
|
|
1909
|
+
await option.conn.release(SyncMode.Async);
|
|
1899
1910
|
}
|
|
1900
1911
|
catch (error) {
|
|
1901
1912
|
}
|
|
@@ -1925,7 +1936,7 @@ function P(skipConn = false) {
|
|
|
1925
1936
|
finally {
|
|
1926
1937
|
if (needRealseConn && option && option.conn) {
|
|
1927
1938
|
try {
|
|
1928
|
-
option.conn.
|
|
1939
|
+
await option.conn.release(SyncMode.Async);
|
|
1929
1940
|
}
|
|
1930
1941
|
catch (error) {
|
|
1931
1942
|
}
|
package/string.d.ts
CHANGED
|
@@ -2,16 +2,43 @@
|
|
|
2
2
|
* 通过uri获取key
|
|
3
3
|
* @param uri
|
|
4
4
|
*/
|
|
5
|
+
/**
|
|
6
|
+
* 通过 URI 获取图片 Key
|
|
7
|
+
* @param uri 图片完整路径或包含 Key 的字符串
|
|
8
|
+
*/
|
|
5
9
|
export declare const getPicKey: (uri: string) => string;
|
|
10
|
+
/**
|
|
11
|
+
* 判断对象/字符串是否为空
|
|
12
|
+
* @param source 待判断的对象
|
|
13
|
+
* @param skipEmptyString 是否跳过仅包含空白字符的字符串,默认为 true
|
|
14
|
+
*/
|
|
6
15
|
export declare const emptyString: (source: any, skipEmptyString?: boolean) => boolean;
|
|
16
|
+
/**
|
|
17
|
+
* 判断对象/字符串是否不为空
|
|
18
|
+
*/
|
|
7
19
|
export declare const notEmptyString: (source: any, skipEmptyString?: boolean) => boolean;
|
|
20
|
+
/**
|
|
21
|
+
* 安全字符串处理(移除单引号,防止简单 SQL 注入)
|
|
22
|
+
*/
|
|
8
23
|
export declare const safeString: (source?: string) => string;
|
|
24
|
+
/**
|
|
25
|
+
* 修剪对象中所有字符串属性的首尾空格
|
|
26
|
+
*/
|
|
9
27
|
export declare const trimObject: <T>(data: any) => T;
|
|
28
|
+
/**
|
|
29
|
+
* 生成指定长度的随机数字字符串
|
|
30
|
+
*/
|
|
10
31
|
export declare const randomNumber: (len: number) => string;
|
|
32
|
+
/**
|
|
33
|
+
* 生成指定长度的随机字符串(包含大小写字母和数字)
|
|
34
|
+
*/
|
|
11
35
|
export declare const randomString: (len: number) => string;
|
|
12
36
|
export declare const randomString2: (len: number) => string;
|
|
13
37
|
export declare const randomString3: (len: number) => string;
|
|
14
38
|
export declare const buildWxStr: (data: {
|
|
15
39
|
[key: string]: string;
|
|
16
40
|
}, maxLabelLength: number, ...titles: string[]) => string;
|
|
41
|
+
/**
|
|
42
|
+
* 将字符串中的中文标点符号统一替换为对应的英文标点
|
|
43
|
+
*/
|
|
17
44
|
export declare const replaceChineseCode: (str: string) => string;
|
package/string.js
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* 通过uri获取key
|
|
3
3
|
* @param uri
|
|
4
4
|
*/
|
|
5
|
+
/**
|
|
6
|
+
* 通过 URI 获取图片 Key
|
|
7
|
+
* @param uri 图片完整路径或包含 Key 的字符串
|
|
8
|
+
*/
|
|
5
9
|
export const getPicKey = (uri) => {
|
|
6
10
|
const arr = /key=([0-9a-zA-Z.]+)/.exec(uri);
|
|
7
11
|
if (arr && arr.length === 2) {
|
|
@@ -9,20 +13,34 @@ export const getPicKey = (uri) => {
|
|
|
9
13
|
}
|
|
10
14
|
return uri;
|
|
11
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* 判断对象/字符串是否为空
|
|
18
|
+
* @param source 待判断的对象
|
|
19
|
+
* @param skipEmptyString 是否跳过仅包含空白字符的字符串,默认为 true
|
|
20
|
+
*/
|
|
12
21
|
export const emptyString = (source, skipEmptyString = true) => {
|
|
13
22
|
return (source === null ||
|
|
14
23
|
source === undefined ||
|
|
15
24
|
(skipEmptyString === true && (source === '' || `${source}`.replace(/\s/g, '') === '')));
|
|
16
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* 判断对象/字符串是否不为空
|
|
28
|
+
*/
|
|
17
29
|
export const notEmptyString = (source, skipEmptyString = true) => {
|
|
18
30
|
return emptyString(source, skipEmptyString) === false;
|
|
19
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* 安全字符串处理(移除单引号,防止简单 SQL 注入)
|
|
34
|
+
*/
|
|
20
35
|
export const safeString = (source) => {
|
|
21
36
|
if (source) {
|
|
22
37
|
return `${source}`.replace(/'/g, '');
|
|
23
38
|
}
|
|
24
39
|
return '';
|
|
25
40
|
};
|
|
41
|
+
/**
|
|
42
|
+
* 修剪对象中所有字符串属性的首尾空格
|
|
43
|
+
*/
|
|
26
44
|
export const trimObject = (data) => {
|
|
27
45
|
if (data) {
|
|
28
46
|
for (const k in data) {
|
|
@@ -33,11 +51,17 @@ export const trimObject = (data) => {
|
|
|
33
51
|
}
|
|
34
52
|
return data;
|
|
35
53
|
};
|
|
54
|
+
/**
|
|
55
|
+
* 生成指定长度的随机数字字符串
|
|
56
|
+
*/
|
|
36
57
|
export const randomNumber = (len) => {
|
|
37
58
|
return `${parseInt(`${(Math.random() * 9 + 1) * Math.pow(10, (len - 1))}`, 10)}`;
|
|
38
59
|
};
|
|
39
60
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
40
61
|
const charLen = chars.length;
|
|
62
|
+
/**
|
|
63
|
+
* 生成指定长度的随机字符串(包含大小写字母和数字)
|
|
64
|
+
*/
|
|
41
65
|
export const randomString = (len) => {
|
|
42
66
|
return Array.from(new Array(len)).map(() => chars.charAt(Math.floor(Math.random() * charLen))).join('');
|
|
43
67
|
};
|
|
@@ -100,6 +124,9 @@ const table = {
|
|
|
100
124
|
'~': '~',
|
|
101
125
|
'﹏': '~'
|
|
102
126
|
};
|
|
127
|
+
/**
|
|
128
|
+
* 将字符串中的中文标点符号统一替换为对应的英文标点
|
|
129
|
+
*/
|
|
103
130
|
export const replaceChineseCode = (str) => {
|
|
104
131
|
return str.replace(chinese, (a) => table[a] || '');
|
|
105
132
|
};
|