midway-fatcms 0.0.17 → 0.0.19
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/libs/crud-pro/services/CrudProDataTypeConvertService.d.ts +2 -37
- package/dist/libs/crud-pro/services/CrudProDataTypeConvertService.js +137 -213
- package/dist/libs/crud-pro/utils/MixinUtils.d.ts +2 -17
- package/dist/libs/crud-pro/utils/MixinUtils.js +4 -84
- package/dist/libs/crud-pro/utils/idgene/generateSnowflakeId.d.ts +12 -0
- package/dist/libs/crud-pro/utils/idgene/generateSnowflakeId.js +61 -0
- package/dist/libs/crud-pro/utils/idgene/generateSnowflakeIdExt.d.ts +27 -0
- package/dist/libs/crud-pro/utils/idgene/generateSnowflakeIdExt.js +96 -0
- package/dist/libs/crud-pro/utils/idgene/index.d.ts +3 -0
- package/dist/libs/crud-pro/utils/idgene/index.js +10 -0
- package/dist/libs/crud-pro/utils/idgene/uuid.d.ts +7 -0
- package/dist/libs/crud-pro/utils/idgene/uuid.js +28 -0
- package/dist/libs/crud-pro-quick/fixSoftDelete.d.ts +0 -17
- package/dist/libs/crud-pro-quick/fixSoftDelete.js +55 -5
- package/dist/libs/crud-pro-quick/models.d.ts +11 -1
- package/dist/service/SysAppService.d.ts +0 -3
- package/dist/service/SysAppService.js +0 -15
- package/dist/service/SysConfigService.d.ts +0 -1
- package/dist/service/SysConfigService.js +0 -6
- package/dist/service/SysDictDataService.d.ts +0 -2
- package/dist/service/SysDictDataService.js +0 -12
- package/dist/service/SysMenuService.d.ts +0 -1
- package/dist/service/SysMenuService.js +0 -3
- package/dist/service/WorkbenchService.d.ts +0 -1
- package/dist/service/WorkbenchService.js +0 -3
- package/dist/service/base/bizmemcache/BizMemCacheService.js +4 -2
- package/dist/service/base/bizmemcache/BizMemCacheStore.js +10 -9
- package/dist/service/crudstd/CrudStdService.js +1 -1
- package/dist/service/curd/fixCfgModel.js +21 -1
- package/package.json +1 -1
- package/src/libs/crud-pro/services/CrudProDataTypeConvertService.ts +149 -219
- package/src/libs/crud-pro/utils/MixinUtils.ts +309 -400
- package/src/libs/crud-pro/utils/idgene/generateSnowflakeId.ts +65 -0
- package/src/libs/crud-pro/utils/idgene/generateSnowflakeIdExt.ts +106 -0
- package/src/libs/crud-pro/utils/idgene/index.ts +3 -0
- package/src/libs/crud-pro/utils/idgene/uuid.ts +26 -0
- package/src/libs/crud-pro-quick/fixSoftDelete.ts +84 -18
- package/src/libs/crud-pro-quick/models.ts +15 -3
- package/src/service/SysAppService.ts +0 -18
- package/src/service/SysConfigService.ts +0 -8
- package/src/service/SysDictDataService.ts +0 -14
- package/src/service/SysMenuService.ts +0 -4
- package/src/service/WorkbenchService.ts +0 -5
- package/src/service/base/bizmemcache/BizMemCacheService.ts +4 -2
- package/src/service/base/bizmemcache/BizMemCacheStore.ts +10 -9
- package/src/service/crudstd/CrudStdService.ts +3 -2
- package/src/service/curd/fixCfgModel.ts +145 -125
|
@@ -2,90 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MixinUtils = void 0;
|
|
4
4
|
const exceptions_1 = require("../exceptions");
|
|
5
|
+
const idgene_1 = require("./idgene");
|
|
5
6
|
// 至少需要2个字符
|
|
6
7
|
const FIELD_NAME_REG_EXP = /^[a-zA-Z][0-9a-zA-Z_]+$/;
|
|
7
|
-
// ===================== 雪花ID =====================
|
|
8
|
-
const SNOWFLAKE_SEQ_START = 1;
|
|
9
|
-
let snowflakeSeq = SNOWFLAKE_SEQ_START;
|
|
10
|
-
let snowflakeLastTs = -1;
|
|
11
|
-
/**
|
|
12
|
-
* 生成雪花ID(64位整数,JS 中以 string 返回)
|
|
13
|
-
* 结构:1位符号 + 41位时间戳(ms) + 10位机器ID + 12位序列号
|
|
14
|
-
* - 时间戳:相对于 2024-01-01 00:00:00 的毫秒偏移,可用约 69 年
|
|
15
|
-
* - 机器ID:0-1023,优先取参数 > 环境变量 SNOWFLAKE_MACHINE_ID > process.pid 低10位
|
|
16
|
-
* - 序列号:0-4095,同一毫秒内自增
|
|
17
|
-
*
|
|
18
|
-
* @param machineId 机器ID(0-1023),不传则依次从环境变量 SNOWFLAKE_MACHINE_ID、process.pid 获取
|
|
19
|
-
* @returns 雪花ID字符串
|
|
20
|
-
*/
|
|
21
|
-
function generateSnowflakeId(machineId) {
|
|
22
|
-
const EPOCH = 1704067200000; // 2024-01-01 00:00:00 UTC
|
|
23
|
-
let mid = Number(machineId);
|
|
24
|
-
if (mid === undefined || mid === null || isNaN(mid)) {
|
|
25
|
-
// 优先从环境变量获取,适配多实例部署场景
|
|
26
|
-
const envMid = typeof process !== 'undefined' && process.env && process.env.SNOWFLAKE_MACHINE_ID
|
|
27
|
-
? parseInt(process.env.SNOWFLAKE_MACHINE_ID, 10)
|
|
28
|
-
: NaN;
|
|
29
|
-
mid = !isNaN(envMid) ? envMid : (typeof process !== 'undefined' && process.pid ? process.pid & 0x3ff : 0);
|
|
30
|
-
}
|
|
31
|
-
mid = Math.abs(mid) & 0x3ff; // 确保在 0-1023 范围
|
|
32
|
-
let now = Date.now();
|
|
33
|
-
let ts = now - EPOCH;
|
|
34
|
-
// 时钟回拨保护:若当前时间戳小于上次,直接沿用上次时间戳继续递增,
|
|
35
|
-
// 避免 NTP 校正/VM 快照恢复等场景下生成重复 ID,同时不阻塞 CPU
|
|
36
|
-
if (ts < snowflakeLastTs) {
|
|
37
|
-
const drift = snowflakeLastTs - ts;
|
|
38
|
-
if (drift <= 5) {
|
|
39
|
-
// 小幅回拨,沿用上次时间戳(ID 仅比实际时间快 ≤5ms,不影响唯一性和排序性)
|
|
40
|
-
ts = snowflakeLastTs;
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
// 大幅回拨,无法安全恢复,抛出异常
|
|
44
|
-
throw new Error(`Snowflake clock drift detected: ${drift}ms backwards. Refusing to generate ID.`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
if (ts === snowflakeLastTs) {
|
|
48
|
-
snowflakeSeq = (snowflakeSeq + 1) & 0xfff; // 0-4095 循环
|
|
49
|
-
if (snowflakeSeq === 0) {
|
|
50
|
-
// 本毫秒序列号耗尽,直接推进到下一毫秒(不阻塞CPU忙等待)
|
|
51
|
-
// ID 的时间戳比实际时间快 ≤1ms,不影响唯一性和排序性
|
|
52
|
-
ts = snowflakeLastTs + 1;
|
|
53
|
-
snowflakeSeq = SNOWFLAKE_SEQ_START;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
snowflakeSeq = SNOWFLAKE_SEQ_START;
|
|
58
|
-
}
|
|
59
|
-
snowflakeLastTs = ts;
|
|
60
|
-
// 雪花ID超过JS安全整数范围(2^53),Number运算会丢失精度
|
|
61
|
-
// 使用 BigInt 做位移拼接,确保 64 位精度完整
|
|
62
|
-
const id = (BigInt(ts) << BigInt(22)) | (BigInt(mid) << BigInt(12)) | BigInt(snowflakeSeq);
|
|
63
|
-
return id.toString();
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* 生成 UUID v4 字符串(纯随机,无外部依赖)
|
|
67
|
-
* 格式:xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,其中 y 为 8/9/a/b 之一
|
|
68
|
-
* @returns 符合 RFC 4122 v4 规范的 UUID 字符串
|
|
69
|
-
*/
|
|
70
|
-
function uuid() {
|
|
71
|
-
// crypto.getRandomValues 在 Node.js >= 11 和现代浏览器中可用
|
|
72
|
-
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
73
|
-
const bytes = new Uint8Array(16);
|
|
74
|
-
crypto.getRandomValues(bytes);
|
|
75
|
-
// 版本位:第6字节高4位设为 0100 (v4)
|
|
76
|
-
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
|
77
|
-
// 变体位:第8字节高2位设为 10
|
|
78
|
-
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
79
|
-
const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
|
|
80
|
-
return hex.slice(0, 8) + '-' + hex.slice(8, 12) + '-' + hex.slice(12, 16) + '-' + hex.slice(16, 20) + '-' + hex.slice(20);
|
|
81
|
-
}
|
|
82
|
-
// 降级方案:Math.random
|
|
83
|
-
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
|
84
|
-
const r = Math.random() * 16 | 0;
|
|
85
|
-
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
86
|
-
return v.toString(16);
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
8
|
const MixinUtils = {
|
|
90
9
|
isNil(obj) {
|
|
91
10
|
return typeof obj === 'undefined' || obj === null;
|
|
@@ -342,7 +261,7 @@ const MixinUtils = {
|
|
|
342
261
|
* 格式:xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,其中 y 为 8/9/a/b 之一
|
|
343
262
|
* @returns 符合 RFC 4122 v4 规范的 UUID 字符串
|
|
344
263
|
*/
|
|
345
|
-
uuid: uuid,
|
|
264
|
+
uuid: idgene_1.uuid,
|
|
346
265
|
/**
|
|
347
266
|
* 生成雪花ID(64位整数,以字符串返回)
|
|
348
267
|
* 结构:1位符号 + 41位时间戳(ms) + 10位机器ID + 12位序列号
|
|
@@ -351,6 +270,7 @@ const MixinUtils = {
|
|
|
351
270
|
* @param machineId 机器ID(0-1023),不传则依次从环境变量 SNOWFLAKE_MACHINE_ID、process.pid 获取
|
|
352
271
|
* @returns 雪花ID字符串
|
|
353
272
|
*/
|
|
354
|
-
generateSnowflakeId: generateSnowflakeId,
|
|
273
|
+
generateSnowflakeId: idgene_1.generateSnowflakeId,
|
|
274
|
+
generateSnowflakeIdExt: idgene_1.generateSnowflakeIdExt,
|
|
355
275
|
};
|
|
356
276
|
exports.MixinUtils = MixinUtils;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 生成雪花ID(64位整数,JS 中以 string 返回)
|
|
3
|
+
* 结构:1位符号 + 41位时间戳(ms) + 10位机器ID + 12位序列号
|
|
4
|
+
* - 时间戳:相对于 2024-01-01 00:00:00 的毫秒偏移,可用约 69 年
|
|
5
|
+
* - 机器ID:0-1023,优先取参数 > 环境变量 SNOWFLAKE_MACHINE_ID > process.pid 低10位
|
|
6
|
+
* - 序列号:0-4095,同一毫秒内自增
|
|
7
|
+
*
|
|
8
|
+
* @param machineId 机器ID(0-1023),不传则依次从环境变量 SNOWFLAKE_MACHINE_ID、process.pid 获取
|
|
9
|
+
* @returns 雪花ID字符串
|
|
10
|
+
*/
|
|
11
|
+
declare function generateSnowflakeId(machineId?: number): string;
|
|
12
|
+
export { generateSnowflakeId };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateSnowflakeId = void 0;
|
|
4
|
+
const SNOWFLAKE_SEQ_START = 1;
|
|
5
|
+
let snowflakeSeq = SNOWFLAKE_SEQ_START;
|
|
6
|
+
let snowflakeLastTs = -1;
|
|
7
|
+
/**
|
|
8
|
+
* 生成雪花ID(64位整数,JS 中以 string 返回)
|
|
9
|
+
* 结构:1位符号 + 41位时间戳(ms) + 10位机器ID + 12位序列号
|
|
10
|
+
* - 时间戳:相对于 2024-01-01 00:00:00 的毫秒偏移,可用约 69 年
|
|
11
|
+
* - 机器ID:0-1023,优先取参数 > 环境变量 SNOWFLAKE_MACHINE_ID > process.pid 低10位
|
|
12
|
+
* - 序列号:0-4095,同一毫秒内自增
|
|
13
|
+
*
|
|
14
|
+
* @param machineId 机器ID(0-1023),不传则依次从环境变量 SNOWFLAKE_MACHINE_ID、process.pid 获取
|
|
15
|
+
* @returns 雪花ID字符串
|
|
16
|
+
*/
|
|
17
|
+
function generateSnowflakeId(machineId) {
|
|
18
|
+
const EPOCH = 1704067200000; // 2024-01-01 00:00:00 UTC
|
|
19
|
+
let mid = Number(machineId);
|
|
20
|
+
if (mid === undefined || mid === null || isNaN(mid)) {
|
|
21
|
+
// 优先从环境变量获取,适配多实例部署场景
|
|
22
|
+
const envMid = typeof process !== 'undefined' && process.env && process.env.SNOWFLAKE_MACHINE_ID
|
|
23
|
+
? parseInt(process.env.SNOWFLAKE_MACHINE_ID, 10)
|
|
24
|
+
: NaN;
|
|
25
|
+
mid = !isNaN(envMid) ? envMid : (typeof process !== 'undefined' && process.pid ? process.pid & 0x3ff : 0);
|
|
26
|
+
}
|
|
27
|
+
mid = Math.abs(mid) & 0x3ff; // 确保在 0-1023 范围
|
|
28
|
+
let now = Date.now();
|
|
29
|
+
let ts = now - EPOCH;
|
|
30
|
+
// 时钟回拨保护:若当前时间戳小于上次,直接沿用上次时间戳继续递增,
|
|
31
|
+
// 避免 NTP 校正/VM 快照恢复等场景下生成重复 ID,同时不阻塞 CPU
|
|
32
|
+
if (ts < snowflakeLastTs) {
|
|
33
|
+
const drift = snowflakeLastTs - ts;
|
|
34
|
+
if (drift <= 5) {
|
|
35
|
+
// 小幅回拨,沿用上次时间戳(ID 仅比实际时间快 ≤5ms,不影响唯一性和排序性)
|
|
36
|
+
ts = snowflakeLastTs;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// 大幅回拨,无法安全恢复,抛出异常
|
|
40
|
+
throw new Error(`Snowflake clock drift detected: ${drift}ms backwards. Refusing to generate ID.`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (ts === snowflakeLastTs) {
|
|
44
|
+
snowflakeSeq = (snowflakeSeq + 1) & 0xfff; // 0-4095 循环
|
|
45
|
+
if (snowflakeSeq === 0) {
|
|
46
|
+
// 本毫秒序列号耗尽,直接推进到下一毫秒(不阻塞CPU忙等待)
|
|
47
|
+
// ID 的时间戳比实际时间快 ≤1ms,不影响唯一性和排序性
|
|
48
|
+
ts = snowflakeLastTs + 1;
|
|
49
|
+
snowflakeSeq = SNOWFLAKE_SEQ_START;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
snowflakeSeq = SNOWFLAKE_SEQ_START;
|
|
54
|
+
}
|
|
55
|
+
snowflakeLastTs = ts;
|
|
56
|
+
// 雪花ID超过JS安全整数范围(2^53),Number运算会丢失精度
|
|
57
|
+
// 使用 BigInt 做位移拼接,确保 64 位精度完整
|
|
58
|
+
const id = (BigInt(ts) << BigInt(22)) | (BigInt(mid) << BigInt(12)) | BigInt(snowflakeSeq);
|
|
59
|
+
return id.toString();
|
|
60
|
+
}
|
|
61
|
+
exports.generateSnowflakeId = generateSnowflakeId;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 128 位雪花 ID 生成器(优化版)
|
|
3
|
+
*
|
|
4
|
+
* 位布局(128 bit,无符号,BigInt 拼接后 Base58 编码返回):
|
|
5
|
+
* - 41 bit 时间戳:相对 2024-01-01 00:00:00 UTC 的毫秒偏移,可用约 69 年(至 ~2093 年)
|
|
6
|
+
* - 10 bit 机器ID:0-1023,与标准 64 位雪花 ID 一致,优先参数 > 环境变量 > process.pid
|
|
7
|
+
* - 77 bit 序列号:同一毫秒内自增,2^77 ≈ 1.5×10²³,无需考虑耗尽
|
|
8
|
+
*
|
|
9
|
+
* 输出:Bitcoin 字母表 Base58(无 0/O/I/l),左填充 '1' 至恒定 22 字符,建议 VARCHAR(24)
|
|
10
|
+
* 时间戳在高位,ID 随时间单调递增,适合做数据库主键。
|
|
11
|
+
* 2^128-1 < 58^22,故 22 字符足以覆盖全部 128 位取值范围。
|
|
12
|
+
*/
|
|
13
|
+
declare const EPOCH: bigint;
|
|
14
|
+
/**
|
|
15
|
+
* 生成 128 位雪花 ID(Base58 字符串,恒定 22 字符)
|
|
16
|
+
*
|
|
17
|
+
* 位布局:41 bit 时间戳 | 10 bit 机器ID | 77 bit 序列号
|
|
18
|
+
* 时间戳采用 41 bit(与标准 64 位雪花 ID 一致),毫秒精度,可用约 69 年。
|
|
19
|
+
* 机器ID 采用 10 bit(0-1023),与标准 64 位雪花 ID 一致,防止多机 ID 冲突。
|
|
20
|
+
* 时间戳在高位,ID 随时间单调递增,适合做数据库主键。
|
|
21
|
+
* Base58 输出左填充 '1'(零字符)至 22 字符,保证长度恒定且不破坏字典序排序。
|
|
22
|
+
*
|
|
23
|
+
* @param machineId 机器ID(0-1023),不传则依次从环境变量 SNOWFLAKE_MACHINE_ID、process.pid 获取
|
|
24
|
+
* @returns Base58 编码的 128 位雪花 ID(恒定 22 字符)
|
|
25
|
+
*/
|
|
26
|
+
declare function generateSnowflakeIdExt(machineId?: number): string;
|
|
27
|
+
export { generateSnowflakeIdExt, EPOCH as SNOWFLAKE_EXT_EPOCH };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 128 位雪花 ID 生成器(优化版)
|
|
4
|
+
*
|
|
5
|
+
* 位布局(128 bit,无符号,BigInt 拼接后 Base58 编码返回):
|
|
6
|
+
* - 41 bit 时间戳:相对 2024-01-01 00:00:00 UTC 的毫秒偏移,可用约 69 年(至 ~2093 年)
|
|
7
|
+
* - 10 bit 机器ID:0-1023,与标准 64 位雪花 ID 一致,优先参数 > 环境变量 > process.pid
|
|
8
|
+
* - 77 bit 序列号:同一毫秒内自增,2^77 ≈ 1.5×10²³,无需考虑耗尽
|
|
9
|
+
*
|
|
10
|
+
* 输出:Bitcoin 字母表 Base58(无 0/O/I/l),左填充 '1' 至恒定 22 字符,建议 VARCHAR(24)
|
|
11
|
+
* 时间戳在高位,ID 随时间单调递增,适合做数据库主键。
|
|
12
|
+
* 2^128-1 < 58^22,故 22 字符足以覆盖全部 128 位取值范围。
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.SNOWFLAKE_EXT_EPOCH = exports.generateSnowflakeIdExt = void 0;
|
|
16
|
+
const EPOCH = BigInt(1704067200000); // 2024-01-01 00:00:00 UTC
|
|
17
|
+
exports.SNOWFLAKE_EXT_EPOCH = EPOCH;
|
|
18
|
+
const TS_BITS = BigInt(41);
|
|
19
|
+
const MID_BITS = BigInt(10);
|
|
20
|
+
const SEQ_BITS = BigInt(77);
|
|
21
|
+
const TS_MASK = (BigInt(1) << TS_BITS) - BigInt(1); // 41 bit
|
|
22
|
+
const MID_MASK = (BigInt(1) << MID_BITS) - BigInt(1); // 10 bit
|
|
23
|
+
const SEQ_MASK = (BigInt(1) << SEQ_BITS) - BigInt(1); // 77 bit
|
|
24
|
+
const PAD_LENGTH = 22;
|
|
25
|
+
const SEQ_START = BigInt(1);
|
|
26
|
+
const DRIFT_TOLERANCE = BigInt(5);
|
|
27
|
+
/** Bitcoin Base58 字母表 */
|
|
28
|
+
const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
|
29
|
+
const BASE58_RADIX = BigInt(58);
|
|
30
|
+
let snowflakeExtSeq = SEQ_START;
|
|
31
|
+
let snowflakeExtLastTs = BigInt(-1);
|
|
32
|
+
/** 无符号 BigInt → Base58 字符串 */
|
|
33
|
+
function encodeBase58(value) {
|
|
34
|
+
if (value === BigInt(0)) {
|
|
35
|
+
return BASE58_ALPHABET[0];
|
|
36
|
+
}
|
|
37
|
+
let n = value;
|
|
38
|
+
let result = '';
|
|
39
|
+
while (n > BigInt(0)) {
|
|
40
|
+
const rem = Number(n % BASE58_RADIX);
|
|
41
|
+
result = BASE58_ALPHABET[rem] + result;
|
|
42
|
+
n = n / BASE58_RADIX;
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
/** 解析机器 ID(10 bit,0-1023) */
|
|
47
|
+
function resolveMachineId(machineId) {
|
|
48
|
+
var _a;
|
|
49
|
+
let mid = Number(machineId);
|
|
50
|
+
if (machineId === undefined || machineId === null || isNaN(mid)) {
|
|
51
|
+
const envMid = typeof process !== 'undefined' && ((_a = process.env) === null || _a === void 0 ? void 0 : _a.SNOWFLAKE_MACHINE_ID)
|
|
52
|
+
? parseInt(process.env.SNOWFLAKE_MACHINE_ID, 10)
|
|
53
|
+
: NaN;
|
|
54
|
+
mid = !isNaN(envMid)
|
|
55
|
+
? envMid
|
|
56
|
+
: typeof process !== 'undefined' && process.pid
|
|
57
|
+
? process.pid
|
|
58
|
+
: 0;
|
|
59
|
+
}
|
|
60
|
+
return BigInt(Math.abs(mid)) & MID_MASK;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 生成 128 位雪花 ID(Base58 字符串,恒定 22 字符)
|
|
64
|
+
*
|
|
65
|
+
* 位布局:41 bit 时间戳 | 10 bit 机器ID | 77 bit 序列号
|
|
66
|
+
* 时间戳采用 41 bit(与标准 64 位雪花 ID 一致),毫秒精度,可用约 69 年。
|
|
67
|
+
* 机器ID 采用 10 bit(0-1023),与标准 64 位雪花 ID 一致,防止多机 ID 冲突。
|
|
68
|
+
* 时间戳在高位,ID 随时间单调递增,适合做数据库主键。
|
|
69
|
+
* Base58 输出左填充 '1'(零字符)至 22 字符,保证长度恒定且不破坏字典序排序。
|
|
70
|
+
*
|
|
71
|
+
* @param machineId 机器ID(0-1023),不传则依次从环境变量 SNOWFLAKE_MACHINE_ID、process.pid 获取
|
|
72
|
+
* @returns Base58 编码的 128 位雪花 ID(恒定 22 字符)
|
|
73
|
+
*/
|
|
74
|
+
function generateSnowflakeIdExt(machineId) {
|
|
75
|
+
const mid = resolveMachineId(machineId);
|
|
76
|
+
let ts = BigInt(Date.now()) - EPOCH;
|
|
77
|
+
if (ts < snowflakeExtLastTs) {
|
|
78
|
+
const drift = snowflakeExtLastTs - ts;
|
|
79
|
+
if (drift <= DRIFT_TOLERANCE) {
|
|
80
|
+
ts = snowflakeExtLastTs;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
throw new Error(`SnowflakeExt clock drift detected: ${drift}ms backwards. Refusing to generate ID.`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (ts === snowflakeExtLastTs) {
|
|
87
|
+
snowflakeExtSeq = (snowflakeExtSeq + BigInt(1)) & SEQ_MASK;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
snowflakeExtSeq = SEQ_START;
|
|
91
|
+
}
|
|
92
|
+
snowflakeExtLastTs = ts;
|
|
93
|
+
const id = ((ts & TS_MASK) << (MID_BITS + SEQ_BITS)) | (mid << SEQ_BITS) | snowflakeExtSeq;
|
|
94
|
+
return encodeBase58(id).padStart(PAD_LENGTH, BASE58_ALPHABET[0]);
|
|
95
|
+
}
|
|
96
|
+
exports.generateSnowflakeIdExt = generateSnowflakeIdExt;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.uuid = exports.SNOWFLAKE_EXT_EPOCH = exports.generateSnowflakeIdExt = exports.generateSnowflakeId = void 0;
|
|
4
|
+
var generateSnowflakeId_1 = require("./generateSnowflakeId");
|
|
5
|
+
Object.defineProperty(exports, "generateSnowflakeId", { enumerable: true, get: function () { return generateSnowflakeId_1.generateSnowflakeId; } });
|
|
6
|
+
var generateSnowflakeIdExt_1 = require("./generateSnowflakeIdExt");
|
|
7
|
+
Object.defineProperty(exports, "generateSnowflakeIdExt", { enumerable: true, get: function () { return generateSnowflakeIdExt_1.generateSnowflakeIdExt; } });
|
|
8
|
+
Object.defineProperty(exports, "SNOWFLAKE_EXT_EPOCH", { enumerable: true, get: function () { return generateSnowflakeIdExt_1.SNOWFLAKE_EXT_EPOCH; } });
|
|
9
|
+
var uuid_1 = require("./uuid");
|
|
10
|
+
Object.defineProperty(exports, "uuid", { enumerable: true, get: function () { return uuid_1.uuid; } });
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.uuid = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* 生成 UUID v4 字符串(纯随机,无外部依赖)
|
|
6
|
+
* 格式:xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,其中 y 为 8/9/a/b 之一
|
|
7
|
+
* @returns 符合 RFC 4122 v4 规范的 UUID 字符串
|
|
8
|
+
*/
|
|
9
|
+
function uuid() {
|
|
10
|
+
// crypto.getRandomValues 在 Node.js >= 11 和现代浏览器中可用
|
|
11
|
+
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
12
|
+
const bytes = new Uint8Array(16);
|
|
13
|
+
crypto.getRandomValues(bytes);
|
|
14
|
+
// 版本位:第6字节高4位设为 0100 (v4)
|
|
15
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
|
16
|
+
// 变体位:第8字节高2位设为 10
|
|
17
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
18
|
+
const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
|
|
19
|
+
return hex.slice(0, 8) + '-' + hex.slice(8, 12) + '-' + hex.slice(12, 16) + '-' + hex.slice(16, 20) + '-' + hex.slice(20);
|
|
20
|
+
}
|
|
21
|
+
// 降级方案:Math.random
|
|
22
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
|
23
|
+
const r = Math.random() * 16 | 0;
|
|
24
|
+
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
25
|
+
return v.toString(16);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
exports.uuid = uuid;
|
|
@@ -1,25 +1,9 @@
|
|
|
1
1
|
import { KeysOfSimpleSQL } from "../../libs/crud-pro/models/keys";
|
|
2
2
|
import { IRequestModel, IVisitor } from "../../libs/crud-pro/interfaces";
|
|
3
3
|
import { IRequestCfgModel2 } from "./models";
|
|
4
|
-
/**
|
|
5
|
-
* 软删除需要的用户信息(最小子集)
|
|
6
|
-
*/
|
|
7
|
-
interface ISoftDeleteUserInfo {
|
|
8
|
-
accountId: string;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* 获取当前用户信息的函数类型
|
|
12
|
-
*/
|
|
13
|
-
declare type GetCurrentUserFunc = () => ISoftDeleteUserInfo | null | undefined;
|
|
14
4
|
/**
|
|
15
5
|
* 软删除处理函数
|
|
16
6
|
*
|
|
17
|
-
* 当 cfgModel.enableSoftDelete === true 时,自动处理软删除逻辑:
|
|
18
|
-
*
|
|
19
|
-
* 1. INSERT 操作:自动设置 deleted_at = 0
|
|
20
|
-
* 2. DELETE 操作:转为 UPDATE,设置 deleted_at = 时间戳, deleted_by = 当前用户
|
|
21
|
-
* 3. QUERY 操作:自动添加 deleted_at = 0 条件
|
|
22
|
-
*
|
|
23
7
|
* @param oldSqlSimpleName 原始 SQL 类型
|
|
24
8
|
* @param cfgModel 配置模型
|
|
25
9
|
* @param params 请求参数(会被修改)
|
|
@@ -27,4 +11,3 @@ declare type GetCurrentUserFunc = () => ISoftDeleteUserInfo | null | undefined;
|
|
|
27
11
|
*/
|
|
28
12
|
declare function fixSoftDelete(oldSqlSimpleName: KeysOfSimpleSQL, cfgModel: IRequestCfgModel2, params: IRequestModel, visitor?: IVisitor): void;
|
|
29
13
|
export { fixSoftDelete, };
|
|
30
|
-
export type { ISoftDeleteUserInfo, GetCurrentUserFunc };
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.fixSoftDelete = void 0;
|
|
4
4
|
const keys_1 = require("../../libs/crud-pro/models/keys");
|
|
5
|
+
const DateTimeUtils_1 = require("../../libs/crud-pro/utils/DateTimeUtils");
|
|
5
6
|
/**
|
|
6
7
|
* 软删除处理函数
|
|
7
8
|
*
|
|
@@ -16,11 +17,7 @@ const keys_1 = require("../../libs/crud-pro/models/keys");
|
|
|
16
17
|
* @param params 请求参数(会被修改)
|
|
17
18
|
* @param visitor 获取当前用户信息的函数(用于软删除时记录删除人)
|
|
18
19
|
*/
|
|
19
|
-
function
|
|
20
|
-
// 没有开启软删除,不做处理,直接物理删除
|
|
21
|
-
if (cfgModel.enableSoftDelete !== true) {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
20
|
+
function fixSoftDelete1(oldSqlSimpleName, cfgModel, params, visitor) {
|
|
24
21
|
// INSERT 操作:刚插入的数据,肯定是未删除的
|
|
25
22
|
if (keys_1.KeysOfSimpleSQL.SIMPLE_INSERT === oldSqlSimpleName) {
|
|
26
23
|
if (!params.data) {
|
|
@@ -55,4 +52,57 @@ function fixSoftDelete(oldSqlSimpleName, cfgModel, params, visitor) {
|
|
|
55
52
|
params.condition.deleted_at = 0;
|
|
56
53
|
}
|
|
57
54
|
}
|
|
55
|
+
function fixSoftDelete2(oldSqlSimpleName, cfgModel, params, visitor) {
|
|
56
|
+
// INSERT 操作:刚插入的数据,肯定是未删除的
|
|
57
|
+
if (keys_1.KeysOfSimpleSQL.SIMPLE_INSERT === oldSqlSimpleName) {
|
|
58
|
+
if (!params.data) {
|
|
59
|
+
params.data = {};
|
|
60
|
+
}
|
|
61
|
+
const dataObj = params.data;
|
|
62
|
+
dataObj.is_deleted = false;
|
|
63
|
+
}
|
|
64
|
+
// DELETE 操作:如果是软删除,修改为 UPDATE 语句
|
|
65
|
+
if (keys_1.KeysOfSimpleSQL.SIMPLE_DELETE === oldSqlSimpleName) {
|
|
66
|
+
if (!params.condition || Object.keys(params.condition).length === 0) {
|
|
67
|
+
throw new Error('执行删除操作,必须指定删除条件');
|
|
68
|
+
}
|
|
69
|
+
// 在原有 data 对象上添加软删除字段
|
|
70
|
+
if (!params.data) {
|
|
71
|
+
params.data = {};
|
|
72
|
+
}
|
|
73
|
+
const dataObj = params.data;
|
|
74
|
+
dataObj.is_deleted = true;
|
|
75
|
+
dataObj.deleted_at = DateTimeUtils_1.DateTimeUtils.getCurrentTimeString();
|
|
76
|
+
dataObj.deleted_by = (visitor === null || visitor === void 0 ? void 0 : visitor.accountId) || '';
|
|
77
|
+
// 改为执行 UPDATE 操作
|
|
78
|
+
cfgModel.sqlSimpleName = keys_1.KeysOfSimpleSQL.SIMPLE_UPDATE;
|
|
79
|
+
}
|
|
80
|
+
// QUERY 操作:强制查询未删除的记录
|
|
81
|
+
if (keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_ONE === oldSqlSimpleName
|
|
82
|
+
|| keys_1.KeysOfSimpleSQL.SIMPLE_QUERY === oldSqlSimpleName
|
|
83
|
+
|| keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_PAGE === oldSqlSimpleName) {
|
|
84
|
+
if (!params.condition) {
|
|
85
|
+
params.condition = {};
|
|
86
|
+
}
|
|
87
|
+
params.condition.is_deleted = false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 软删除处理函数
|
|
92
|
+
*
|
|
93
|
+
* @param oldSqlSimpleName 原始 SQL 类型
|
|
94
|
+
* @param cfgModel 配置模型
|
|
95
|
+
* @param params 请求参数(会被修改)
|
|
96
|
+
* @param visitor 获取当前用户信息的函数(用于软删除时记录删除人)
|
|
97
|
+
*/
|
|
98
|
+
function fixSoftDelete(oldSqlSimpleName, cfgModel, params, visitor) {
|
|
99
|
+
if (cfgModel.enableSoftDelete === true || cfgModel.enableSoftDelete === 'soft') {
|
|
100
|
+
fixSoftDelete1(oldSqlSimpleName, cfgModel, params, visitor);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (cfgModel.enableSoftDelete === 'soft2') {
|
|
104
|
+
fixSoftDelete2(oldSqlSimpleName, cfgModel, params, visitor);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
58
108
|
exports.fixSoftDelete = fixSoftDelete;
|
|
@@ -18,6 +18,16 @@ export interface ICommonStandardColumns {
|
|
|
18
18
|
modified_by?: string;
|
|
19
19
|
modified_at?: number;
|
|
20
20
|
}
|
|
21
|
+
export interface ICommonStandardColumns2 {
|
|
22
|
+
is_deleted?: boolean | number;
|
|
23
|
+
deleted_at?: string;
|
|
24
|
+
deleted_by?: string;
|
|
25
|
+
created_by?: string;
|
|
26
|
+
created_at?: number;
|
|
27
|
+
modified_by?: string;
|
|
28
|
+
modified_at?: number;
|
|
29
|
+
}
|
|
30
|
+
export declare type TEnableSoftDelete = null | false | true | 'soft' | 'soft2';
|
|
21
31
|
/**
|
|
22
32
|
* 扩展的请求配置模型
|
|
23
33
|
*
|
|
@@ -29,5 +39,5 @@ export interface ICommonStandardColumns {
|
|
|
29
39
|
export interface IRequestCfgModel2 extends IRequestCfgModel {
|
|
30
40
|
enableStandardUpdateCfg?: boolean | string[];
|
|
31
41
|
enableStandardUpdateCfgCondition?: boolean | string[];
|
|
32
|
-
enableSoftDelete?:
|
|
42
|
+
enableSoftDelete?: TEnableSoftDelete;
|
|
33
43
|
}
|
|
@@ -6,7 +6,4 @@ export declare class SysAppService extends BaseService {
|
|
|
6
6
|
}): Promise<Record<string, any>>;
|
|
7
7
|
getSysAppOne(app_code: string): Promise<Record<string, any>>;
|
|
8
8
|
deletePrivateField(parsedAppInfo: any): any;
|
|
9
|
-
removeSysAppOneCache(app_code: string): Promise<void>;
|
|
10
|
-
removeSysAppPageCache(): Promise<void>;
|
|
11
|
-
removeSysAppCacheByCondition({ condition }: any): Promise<void>;
|
|
12
9
|
}
|
|
@@ -46,21 +46,6 @@ let SysAppService = class SysAppService extends BaseService_1.BaseService {
|
|
|
46
46
|
delete parsedAppInfo2.std_crud_tbl;
|
|
47
47
|
return parsedAppInfo2;
|
|
48
48
|
}
|
|
49
|
-
async removeSysAppOneCache(app_code) {
|
|
50
|
-
if (!app_code || typeof app_code !== 'string') {
|
|
51
|
-
throw new Error('[removeSysAppOneCache] app_code required');
|
|
52
|
-
}
|
|
53
|
-
await BizMemCacheStore_1.bizMemCacheStore.markDirty('sysAppCacheObj', this.redisService);
|
|
54
|
-
}
|
|
55
|
-
async removeSysAppPageCache() {
|
|
56
|
-
await BizMemCacheStore_1.bizMemCacheStore.markDirty('sysAppPageCacheObj', this.redisService);
|
|
57
|
-
}
|
|
58
|
-
async removeSysAppCacheByCondition({ condition }) {
|
|
59
|
-
if (!condition) {
|
|
60
|
-
throw new Error('[removeSysAppCacheByCondition] condition required');
|
|
61
|
-
}
|
|
62
|
-
await BizMemCacheStore_1.bizMemCacheStore.markDirty('sysAppCacheObj', this.redisService);
|
|
63
|
-
}
|
|
64
49
|
};
|
|
65
50
|
SysAppService = __decorate([
|
|
66
51
|
(0, core_1.Provide)()
|
|
@@ -19,12 +19,6 @@ let SysConfigService = class SysConfigService extends BaseService_1.BaseService
|
|
|
19
19
|
const sysConfigCodeMap = ((_a = BizMemCacheStore_1.bizMemCacheStore.getSysConfig()) === null || _a === void 0 ? void 0 : _a.sysConfigCodeMap) || {};
|
|
20
20
|
return sysConfigCodeMap[config_code];
|
|
21
21
|
}
|
|
22
|
-
async removeSysConfigOneCache(config_code) {
|
|
23
|
-
if (!config_code || typeof config_code !== 'string') {
|
|
24
|
-
throw new Error('[removeSysConfigOneCache] config_code required');
|
|
25
|
-
}
|
|
26
|
-
await BizMemCacheStore_1.bizMemCacheStore.markDirty('sysConfgCacheObj', this.redisService);
|
|
27
|
-
}
|
|
28
22
|
};
|
|
29
23
|
SysConfigService = __decorate([
|
|
30
24
|
(0, core_1.Provide)()
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { BaseService } from './base/BaseService';
|
|
2
2
|
export declare class SysDictDataService extends BaseService {
|
|
3
3
|
getDataDictItemsByDictCode(dict_code: string): Promise<any[]>;
|
|
4
|
-
removeCacheByDictItemId(dict_item_id: string): Promise<void>;
|
|
5
|
-
removeCacheByDictCode(dict_code: string): Promise<void>;
|
|
6
4
|
}
|
|
@@ -19,18 +19,6 @@ let SysDictDataService = class SysDictDataService extends BaseService_1.BaseServ
|
|
|
19
19
|
const dictCodeMap = ((_a = BizMemCacheStore_1.bizMemCacheStore.getDataDictItem()) === null || _a === void 0 ? void 0 : _a.dictCodeMap) || {};
|
|
20
20
|
return dictCodeMap[dict_code] || [];
|
|
21
21
|
}
|
|
22
|
-
async removeCacheByDictItemId(dict_item_id) {
|
|
23
|
-
if (!dict_item_id) {
|
|
24
|
-
throw new Error('[removeCacheByDictItemId] dict_item_id required');
|
|
25
|
-
}
|
|
26
|
-
await BizMemCacheStore_1.bizMemCacheStore.markDirty('dataDictItemCacheObj', this.redisService);
|
|
27
|
-
}
|
|
28
|
-
async removeCacheByDictCode(dict_code) {
|
|
29
|
-
if (!dict_code || typeof dict_code !== 'string') {
|
|
30
|
-
throw new Error('[removeCacheByDictCode] dict_code required');
|
|
31
|
-
}
|
|
32
|
-
await BizMemCacheStore_1.bizMemCacheStore.markDirty('dataDictItemCacheObj', this.redisService);
|
|
33
|
-
}
|
|
34
22
|
};
|
|
35
23
|
SysDictDataService = __decorate([
|
|
36
24
|
(0, core_1.Provide)()
|
|
@@ -19,9 +19,6 @@ let SysMenuService = class SysMenuService extends BaseService_1.BaseService {
|
|
|
19
19
|
var _a;
|
|
20
20
|
return ((_a = BizMemCacheStore_1.bizMemCacheStore.getSysMenu()) === null || _a === void 0 ? void 0 : _a.sysMenuList) || [];
|
|
21
21
|
}
|
|
22
|
-
async removeSysMenuCache() {
|
|
23
|
-
await BizMemCacheStore_1.bizMemCacheStore.markDirty('sysMenuCacheObj', this.redisService);
|
|
24
|
-
}
|
|
25
22
|
};
|
|
26
23
|
SysMenuService = __decorate([
|
|
27
24
|
(0, core_1.Provide)()
|
|
@@ -19,9 +19,6 @@ const AsyncTaskModel_1 = require("../models/AsyncTaskModel");
|
|
|
19
19
|
const format_url_1 = require("../libs/utils/format-url");
|
|
20
20
|
const BizMemCacheStore_1 = require("../service/base/bizmemcache/BizMemCacheStore");
|
|
21
21
|
let WorkbenchService = class WorkbenchService extends BaseService_1.BaseService {
|
|
22
|
-
async clearCache() {
|
|
23
|
-
await BizMemCacheStore_1.bizMemCacheStore.markDirty('workbenchCachedObj', this.redisService);
|
|
24
|
-
}
|
|
25
22
|
getWorkbenchCachedObj() {
|
|
26
23
|
return BizMemCacheStore_1.bizMemCacheStore.getWorkbench();
|
|
27
24
|
}
|
|
@@ -35,8 +35,10 @@ let BizMemCacheService = class BizMemCacheService extends BaseService_1.BaseServ
|
|
|
35
35
|
await this.reloadIfRedisChanged('crudMethodCacheObj', () => this.loadCrudMethodCacheObj());
|
|
36
36
|
}
|
|
37
37
|
async reloadIfRedisChanged(key, loader) {
|
|
38
|
-
const
|
|
39
|
-
|
|
38
|
+
const redisTimeStr = await this.redisService.get(BizMemCacheStore_1.bizMemCacheStore.getRedisKey(key));
|
|
39
|
+
const redisTime = Number(redisTimeStr) || 0;
|
|
40
|
+
const memTime = BizMemCacheStore_1.bizMemCacheStore.getLastTime(key);
|
|
41
|
+
if (redisTime !== memTime) {
|
|
40
42
|
await loader();
|
|
41
43
|
BizMemCacheStore_1.bizMemCacheStore.setLastTime(key, redisTime);
|
|
42
44
|
}
|