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
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const SNOWFLAKE_SEQ_START = 1;
|
|
2
|
+
let snowflakeSeq = SNOWFLAKE_SEQ_START;
|
|
3
|
+
let snowflakeLastTs = -1;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 生成雪花ID(64位整数,JS 中以 string 返回)
|
|
7
|
+
* 结构:1位符号 + 41位时间戳(ms) + 10位机器ID + 12位序列号
|
|
8
|
+
* - 时间戳:相对于 2024-01-01 00:00:00 的毫秒偏移,可用约 69 年
|
|
9
|
+
* - 机器ID:0-1023,优先取参数 > 环境变量 SNOWFLAKE_MACHINE_ID > process.pid 低10位
|
|
10
|
+
* - 序列号:0-4095,同一毫秒内自增
|
|
11
|
+
*
|
|
12
|
+
* @param machineId 机器ID(0-1023),不传则依次从环境变量 SNOWFLAKE_MACHINE_ID、process.pid 获取
|
|
13
|
+
* @returns 雪花ID字符串
|
|
14
|
+
*/
|
|
15
|
+
function generateSnowflakeId(machineId?: number): string {
|
|
16
|
+
const EPOCH = 1704067200000; // 2024-01-01 00:00:00 UTC
|
|
17
|
+
|
|
18
|
+
let mid = Number(machineId);
|
|
19
|
+
if (mid === undefined || mid === null || isNaN(mid)) {
|
|
20
|
+
// 优先从环境变量获取,适配多实例部署场景
|
|
21
|
+
const envMid = typeof process !== 'undefined' && process.env && process.env.SNOWFLAKE_MACHINE_ID
|
|
22
|
+
? parseInt(process.env.SNOWFLAKE_MACHINE_ID, 10)
|
|
23
|
+
: NaN;
|
|
24
|
+
mid = !isNaN(envMid) ? envMid : (typeof process !== 'undefined' && process.pid ? process.pid & 0x3ff : 0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
mid = Math.abs(mid) & 0x3ff; // 确保在 0-1023 范围
|
|
28
|
+
|
|
29
|
+
let now = Date.now();
|
|
30
|
+
let ts = now - EPOCH;
|
|
31
|
+
|
|
32
|
+
// 时钟回拨保护:若当前时间戳小于上次,直接沿用上次时间戳继续递增,
|
|
33
|
+
// 避免 NTP 校正/VM 快照恢复等场景下生成重复 ID,同时不阻塞 CPU
|
|
34
|
+
if (ts < snowflakeLastTs) {
|
|
35
|
+
const drift = snowflakeLastTs - ts;
|
|
36
|
+
if (drift <= 5) {
|
|
37
|
+
// 小幅回拨,沿用上次时间戳(ID 仅比实际时间快 ≤5ms,不影响唯一性和排序性)
|
|
38
|
+
ts = snowflakeLastTs;
|
|
39
|
+
} else {
|
|
40
|
+
// 大幅回拨,无法安全恢复,抛出异常
|
|
41
|
+
throw new Error(`Snowflake clock drift detected: ${drift}ms backwards. Refusing to generate ID.`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (ts === snowflakeLastTs) {
|
|
46
|
+
snowflakeSeq = (snowflakeSeq + 1) & 0xfff; // 0-4095 循环
|
|
47
|
+
if (snowflakeSeq === 0) {
|
|
48
|
+
// 本毫秒序列号耗尽,直接推进到下一毫秒(不阻塞CPU忙等待)
|
|
49
|
+
// ID 的时间戳比实际时间快 ≤1ms,不影响唯一性和排序性
|
|
50
|
+
ts = snowflakeLastTs + 1;
|
|
51
|
+
snowflakeSeq = SNOWFLAKE_SEQ_START;
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
snowflakeSeq = SNOWFLAKE_SEQ_START;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
snowflakeLastTs = ts;
|
|
58
|
+
|
|
59
|
+
// 雪花ID超过JS安全整数范围(2^53),Number运算会丢失精度
|
|
60
|
+
// 使用 BigInt 做位移拼接,确保 64 位精度完整
|
|
61
|
+
const id = (BigInt(ts) << BigInt(22)) | (BigInt(mid) << BigInt(12)) | BigInt(snowflakeSeq);
|
|
62
|
+
return id.toString();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { generateSnowflakeId };
|
|
@@ -0,0 +1,106 @@
|
|
|
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
|
+
|
|
14
|
+
const EPOCH = BigInt(1704067200000); // 2024-01-01 00:00:00 UTC
|
|
15
|
+
|
|
16
|
+
const TS_BITS = BigInt(41);
|
|
17
|
+
const MID_BITS = BigInt(10);
|
|
18
|
+
const SEQ_BITS = BigInt(77);
|
|
19
|
+
const TS_MASK = (BigInt(1) << TS_BITS) - BigInt(1); // 41 bit
|
|
20
|
+
const MID_MASK = (BigInt(1) << MID_BITS) - BigInt(1); // 10 bit
|
|
21
|
+
const SEQ_MASK = (BigInt(1) << SEQ_BITS) - BigInt(1); // 77 bit
|
|
22
|
+
const PAD_LENGTH = 22;
|
|
23
|
+
|
|
24
|
+
const SEQ_START = BigInt(1);
|
|
25
|
+
const DRIFT_TOLERANCE = BigInt(5);
|
|
26
|
+
|
|
27
|
+
/** Bitcoin Base58 字母表 */
|
|
28
|
+
const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
|
29
|
+
const BASE58_RADIX = BigInt(58);
|
|
30
|
+
|
|
31
|
+
let snowflakeExtSeq = SEQ_START;
|
|
32
|
+
let snowflakeExtLastTs = BigInt(-1);
|
|
33
|
+
|
|
34
|
+
/** 无符号 BigInt → Base58 字符串 */
|
|
35
|
+
function encodeBase58(value: bigint): string {
|
|
36
|
+
if (value === BigInt(0)) {
|
|
37
|
+
return BASE58_ALPHABET[0];
|
|
38
|
+
}
|
|
39
|
+
let n = value;
|
|
40
|
+
let result = '';
|
|
41
|
+
while (n > BigInt(0)) {
|
|
42
|
+
const rem = Number(n % BASE58_RADIX);
|
|
43
|
+
result = BASE58_ALPHABET[rem] + result;
|
|
44
|
+
n = n / BASE58_RADIX;
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** 解析机器 ID(10 bit,0-1023) */
|
|
50
|
+
function resolveMachineId(machineId?: number): bigint {
|
|
51
|
+
let mid = Number(machineId);
|
|
52
|
+
if (machineId === undefined || machineId === null || isNaN(mid)) {
|
|
53
|
+
const envMid =
|
|
54
|
+
typeof process !== 'undefined' && process.env?.SNOWFLAKE_MACHINE_ID
|
|
55
|
+
? parseInt(process.env.SNOWFLAKE_MACHINE_ID, 10)
|
|
56
|
+
: NaN;
|
|
57
|
+
mid = !isNaN(envMid)
|
|
58
|
+
? envMid
|
|
59
|
+
: typeof process !== 'undefined' && process.pid
|
|
60
|
+
? process.pid
|
|
61
|
+
: 0;
|
|
62
|
+
}
|
|
63
|
+
return BigInt(Math.abs(mid)) & MID_MASK;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 生成 128 位雪花 ID(Base58 字符串,恒定 22 字符)
|
|
68
|
+
*
|
|
69
|
+
* 位布局:41 bit 时间戳 | 10 bit 机器ID | 77 bit 序列号
|
|
70
|
+
* 时间戳采用 41 bit(与标准 64 位雪花 ID 一致),毫秒精度,可用约 69 年。
|
|
71
|
+
* 机器ID 采用 10 bit(0-1023),与标准 64 位雪花 ID 一致,防止多机 ID 冲突。
|
|
72
|
+
* 时间戳在高位,ID 随时间单调递增,适合做数据库主键。
|
|
73
|
+
* Base58 输出左填充 '1'(零字符)至 22 字符,保证长度恒定且不破坏字典序排序。
|
|
74
|
+
*
|
|
75
|
+
* @param machineId 机器ID(0-1023),不传则依次从环境变量 SNOWFLAKE_MACHINE_ID、process.pid 获取
|
|
76
|
+
* @returns Base58 编码的 128 位雪花 ID(恒定 22 字符)
|
|
77
|
+
*/
|
|
78
|
+
function generateSnowflakeIdExt(machineId?: number): string {
|
|
79
|
+
const mid = resolveMachineId(machineId);
|
|
80
|
+
|
|
81
|
+
let ts = BigInt(Date.now()) - EPOCH;
|
|
82
|
+
|
|
83
|
+
if (ts < snowflakeExtLastTs) {
|
|
84
|
+
const drift = snowflakeExtLastTs - ts;
|
|
85
|
+
if (drift <= DRIFT_TOLERANCE) {
|
|
86
|
+
ts = snowflakeExtLastTs;
|
|
87
|
+
} else {
|
|
88
|
+
throw new Error(
|
|
89
|
+
`SnowflakeExt clock drift detected: ${drift}ms backwards. Refusing to generate ID.`
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (ts === snowflakeExtLastTs) {
|
|
95
|
+
snowflakeExtSeq = (snowflakeExtSeq + BigInt(1)) & SEQ_MASK;
|
|
96
|
+
} else {
|
|
97
|
+
snowflakeExtSeq = SEQ_START;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
snowflakeExtLastTs = ts;
|
|
101
|
+
|
|
102
|
+
const id = ((ts & TS_MASK) << (MID_BITS + SEQ_BITS)) | (mid << SEQ_BITS) | snowflakeExtSeq;
|
|
103
|
+
return encodeBase58(id).padStart(PAD_LENGTH, BASE58_ALPHABET[0]);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export { generateSnowflakeIdExt, EPOCH as SNOWFLAKE_EXT_EPOCH };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 生成 UUID v4 字符串(纯随机,无外部依赖)
|
|
3
|
+
* 格式:xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,其中 y 为 8/9/a/b 之一
|
|
4
|
+
* @returns 符合 RFC 4122 v4 规范的 UUID 字符串
|
|
5
|
+
*/
|
|
6
|
+
function uuid(): string {
|
|
7
|
+
// crypto.getRandomValues 在 Node.js >= 11 和现代浏览器中可用
|
|
8
|
+
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
9
|
+
const bytes = new Uint8Array(16);
|
|
10
|
+
crypto.getRandomValues(bytes);
|
|
11
|
+
// 版本位:第6字节高4位设为 0100 (v4)
|
|
12
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
|
13
|
+
// 变体位:第8字节高2位设为 10
|
|
14
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
15
|
+
const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
|
|
16
|
+
return hex.slice(0, 8) + '-' + hex.slice(8, 12) + '-' + hex.slice(12, 16) + '-' + hex.slice(16, 20) + '-' + hex.slice(20);
|
|
17
|
+
}
|
|
18
|
+
// 降级方案:Math.random
|
|
19
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
|
20
|
+
const r = Math.random() * 16 | 0;
|
|
21
|
+
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
22
|
+
return v.toString(16);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { uuid };
|
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
import { KeysOfSimpleSQL } from "@/libs/crud-pro/models/keys";
|
|
2
2
|
import { IRequestModel, IVisitor } from "@/libs/crud-pro/interfaces";
|
|
3
|
-
import { IRequestCfgModel2, ICommonStandardColumns } from "./models";
|
|
3
|
+
import { IRequestCfgModel2, ICommonStandardColumns, ICommonStandardColumns2 } from "./models";
|
|
4
|
+
import { DateTimeUtils } from "@/libs/crud-pro/utils/DateTimeUtils";
|
|
4
5
|
|
|
5
|
-
/**
|
|
6
|
-
* 软删除需要的用户信息(最小子集)
|
|
7
|
-
*/
|
|
8
|
-
interface ISoftDeleteUserInfo {
|
|
9
|
-
accountId: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* 获取当前用户信息的函数类型
|
|
14
|
-
*/
|
|
15
|
-
type GetCurrentUserFunc = () => ISoftDeleteUserInfo | null | undefined;
|
|
16
6
|
|
|
17
7
|
/**
|
|
18
8
|
* 软删除处理函数
|
|
@@ -28,17 +18,13 @@ type GetCurrentUserFunc = () => ISoftDeleteUserInfo | null | undefined;
|
|
|
28
18
|
* @param params 请求参数(会被修改)
|
|
29
19
|
* @param visitor 获取当前用户信息的函数(用于软删除时记录删除人)
|
|
30
20
|
*/
|
|
31
|
-
function
|
|
21
|
+
function fixSoftDelete1(
|
|
32
22
|
oldSqlSimpleName: KeysOfSimpleSQL,
|
|
33
23
|
cfgModel: IRequestCfgModel2,
|
|
34
24
|
params: IRequestModel,
|
|
35
25
|
visitor?: IVisitor
|
|
36
26
|
): void {
|
|
37
27
|
|
|
38
|
-
// 没有开启软删除,不做处理,直接物理删除
|
|
39
|
-
if (cfgModel.enableSoftDelete !== true) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
28
|
|
|
43
29
|
// INSERT 操作:刚插入的数据,肯定是未删除的
|
|
44
30
|
if (KeysOfSimpleSQL.SIMPLE_INSERT === oldSqlSimpleName) {
|
|
@@ -83,8 +69,88 @@ function fixSoftDelete(
|
|
|
83
69
|
}
|
|
84
70
|
|
|
85
71
|
|
|
72
|
+
function fixSoftDelete2(
|
|
73
|
+
oldSqlSimpleName: KeysOfSimpleSQL,
|
|
74
|
+
cfgModel: IRequestCfgModel2,
|
|
75
|
+
params: IRequestModel,
|
|
76
|
+
visitor?: IVisitor
|
|
77
|
+
): void {
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
// INSERT 操作:刚插入的数据,肯定是未删除的
|
|
81
|
+
if (KeysOfSimpleSQL.SIMPLE_INSERT === oldSqlSimpleName) {
|
|
82
|
+
if (!params.data) {
|
|
83
|
+
params.data = {};
|
|
84
|
+
}
|
|
85
|
+
const dataObj = params.data as ICommonStandardColumns2;
|
|
86
|
+
dataObj.is_deleted = false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// DELETE 操作:如果是软删除,修改为 UPDATE 语句
|
|
90
|
+
if (KeysOfSimpleSQL.SIMPLE_DELETE === oldSqlSimpleName) {
|
|
91
|
+
|
|
92
|
+
if (!params.condition || Object.keys(params.condition).length === 0) {
|
|
93
|
+
throw new Error('执行删除操作,必须指定删除条件');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
// 在原有 data 对象上添加软删除字段
|
|
98
|
+
if (!params.data) {
|
|
99
|
+
params.data = {};
|
|
100
|
+
}
|
|
101
|
+
const dataObj = params.data as ICommonStandardColumns2;
|
|
102
|
+
dataObj.is_deleted = true;
|
|
103
|
+
dataObj.deleted_at = DateTimeUtils.getCurrentTimeString();
|
|
104
|
+
dataObj.deleted_by = visitor?.accountId || '';
|
|
105
|
+
|
|
106
|
+
// 改为执行 UPDATE 操作
|
|
107
|
+
cfgModel.sqlSimpleName = KeysOfSimpleSQL.SIMPLE_UPDATE;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// QUERY 操作:强制查询未删除的记录
|
|
111
|
+
if (KeysOfSimpleSQL.SIMPLE_QUERY_ONE === oldSqlSimpleName
|
|
112
|
+
|| KeysOfSimpleSQL.SIMPLE_QUERY === oldSqlSimpleName
|
|
113
|
+
|| KeysOfSimpleSQL.SIMPLE_QUERY_PAGE === oldSqlSimpleName) {
|
|
114
|
+
|
|
115
|
+
if (!params.condition) {
|
|
116
|
+
params.condition = {};
|
|
117
|
+
}
|
|
118
|
+
params.condition.is_deleted = false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* 软删除处理函数
|
|
126
|
+
*
|
|
127
|
+
* @param oldSqlSimpleName 原始 SQL 类型
|
|
128
|
+
* @param cfgModel 配置模型
|
|
129
|
+
* @param params 请求参数(会被修改)
|
|
130
|
+
* @param visitor 获取当前用户信息的函数(用于软删除时记录删除人)
|
|
131
|
+
*/
|
|
132
|
+
function fixSoftDelete(
|
|
133
|
+
oldSqlSimpleName: KeysOfSimpleSQL,
|
|
134
|
+
cfgModel: IRequestCfgModel2,
|
|
135
|
+
params: IRequestModel,
|
|
136
|
+
visitor?: IVisitor
|
|
137
|
+
): void {
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
if (cfgModel.enableSoftDelete === true || cfgModel.enableSoftDelete === 'soft') {
|
|
141
|
+
fixSoftDelete1(oldSqlSimpleName, cfgModel, params, visitor);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (cfgModel.enableSoftDelete === 'soft2') {
|
|
146
|
+
fixSoftDelete2(oldSqlSimpleName, cfgModel, params, visitor);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
86
153
|
export {
|
|
87
154
|
fixSoftDelete,
|
|
88
155
|
};
|
|
89
156
|
|
|
90
|
-
export type { ISoftDeleteUserInfo, GetCurrentUserFunc };
|
|
@@ -2,7 +2,7 @@ import { IRequestCfgModel } from '@/libs/crud-pro/interfaces';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* 常用标准表结构字段(6个字段)
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
6
|
* 用于软删除和审计跟踪:
|
|
7
7
|
* - deleted_at: 删除时间戳,0=未删除
|
|
8
8
|
* - deleted_by: 删除人ID
|
|
@@ -20,9 +20,21 @@ export interface ICommonStandardColumns {
|
|
|
20
20
|
modified_at?: number;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
export interface ICommonStandardColumns2 {
|
|
24
|
+
is_deleted?: boolean | number;
|
|
25
|
+
deleted_at?: string;
|
|
26
|
+
deleted_by?: string;
|
|
27
|
+
created_by?: string;
|
|
28
|
+
created_at?: number;
|
|
29
|
+
modified_by?: string;
|
|
30
|
+
modified_at?: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type TEnableSoftDelete = null | false | true | 'soft' | 'soft2';
|
|
34
|
+
|
|
23
35
|
/**
|
|
24
36
|
* 扩展的请求配置模型
|
|
25
|
-
*
|
|
37
|
+
*
|
|
26
38
|
* 在 IRequestCfgModel 基础上添加了业务层常用的配置项:
|
|
27
39
|
* - enableStandardUpdateCfg: 启用标准字段自动填充
|
|
28
40
|
* - enableStandardUpdateCfgCondition: 启用标准字段条件注入
|
|
@@ -31,5 +43,5 @@ export interface ICommonStandardColumns {
|
|
|
31
43
|
export interface IRequestCfgModel2 extends IRequestCfgModel {
|
|
32
44
|
enableStandardUpdateCfg?: boolean | string[]; // 默认为true
|
|
33
45
|
enableStandardUpdateCfgCondition?: boolean | string[]; // 默认为false
|
|
34
|
-
enableSoftDelete?:
|
|
46
|
+
enableSoftDelete?: TEnableSoftDelete
|
|
35
47
|
}
|
|
@@ -42,22 +42,4 @@ export class SysAppService extends BaseService {
|
|
|
42
42
|
return parsedAppInfo2;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
async removeSysAppOneCache(app_code: string) {
|
|
46
|
-
if (!app_code || typeof app_code !== 'string') {
|
|
47
|
-
throw new Error('[removeSysAppOneCache] app_code required');
|
|
48
|
-
}
|
|
49
|
-
await bizMemCacheStore.markDirty('sysAppCacheObj', this.redisService);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async removeSysAppPageCache() {
|
|
53
|
-
await bizMemCacheStore.markDirty('sysAppPageCacheObj', this.redisService);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async removeSysAppCacheByCondition({ condition }: any) {
|
|
57
|
-
if (!condition) {
|
|
58
|
-
throw new Error('[removeSysAppCacheByCondition] condition required');
|
|
59
|
-
}
|
|
60
|
-
await bizMemCacheStore.markDirty('sysAppCacheObj', this.redisService);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
45
|
}
|
|
@@ -13,12 +13,4 @@ export class SysConfigService extends BaseService {
|
|
|
13
13
|
return sysConfigCodeMap[config_code];
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
async removeSysConfigOneCache(config_code: string) {
|
|
18
|
-
if (!config_code || typeof config_code !== 'string') {
|
|
19
|
-
throw new Error('[removeSysConfigOneCache] config_code required');
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
await bizMemCacheStore.markDirty('sysConfgCacheObj', this.redisService);
|
|
23
|
-
}
|
|
24
16
|
}
|
|
@@ -12,18 +12,4 @@ export class SysDictDataService extends BaseService {
|
|
|
12
12
|
const dictCodeMap = bizMemCacheStore.getDataDictItem()?.dictCodeMap || {};
|
|
13
13
|
return dictCodeMap[dict_code] || [];
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
public async removeCacheByDictItemId(dict_item_id: string) {
|
|
17
|
-
if (!dict_item_id) {
|
|
18
|
-
throw new Error('[removeCacheByDictItemId] dict_item_id required');
|
|
19
|
-
}
|
|
20
|
-
await bizMemCacheStore.markDirty('dataDictItemCacheObj', this.redisService);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
public async removeCacheByDictCode(dict_code: string) {
|
|
24
|
-
if (!dict_code || typeof dict_code !== 'string') {
|
|
25
|
-
throw new Error('[removeCacheByDictCode] dict_code required');
|
|
26
|
-
}
|
|
27
|
-
await bizMemCacheStore.markDirty('dataDictItemCacheObj', this.redisService);
|
|
28
|
-
}
|
|
29
15
|
}
|
|
@@ -19,11 +19,6 @@ export class WorkbenchService extends BaseService {
|
|
|
19
19
|
@Config('fatcmsTargetWorkbenchCode')
|
|
20
20
|
private fatcmsTargetWorkbenchCode: string;
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
public async clearCache() {
|
|
24
|
-
await bizMemCacheStore.markDirty('workbenchCachedObj', this.redisService);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
22
|
private getWorkbenchCachedObj(): IWorkbenchCachedObj {
|
|
28
23
|
return bizMemCacheStore.getWorkbench();
|
|
29
24
|
}
|
|
@@ -35,8 +35,10 @@ export class BizMemCacheService extends BaseService implements IScheduleService
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
private async reloadIfRedisChanged(key: BizMemCacheKey, loader: () => Promise<void>) {
|
|
38
|
-
const
|
|
39
|
-
|
|
38
|
+
const redisTimeStr = await this.redisService.get(bizMemCacheStore.getRedisKey(key));
|
|
39
|
+
const redisTime = Number(redisTimeStr) || 0;
|
|
40
|
+
const memTime = bizMemCacheStore.getLastTime(key);
|
|
41
|
+
if (redisTime !== memTime) {
|
|
40
42
|
await loader();
|
|
41
43
|
bizMemCacheStore.setLastTime(key, redisTime);
|
|
42
44
|
}
|
|
@@ -30,16 +30,17 @@ function createEmptyData(): IBizMemCacheData {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function createEmptyLastTime(): Record<BizMemCacheKey, number> {
|
|
33
|
+
const defaultLastTime = -9999;
|
|
33
34
|
return {
|
|
34
|
-
workbenchCachedObj:
|
|
35
|
-
sysConfgCacheObj:
|
|
36
|
-
sysMenuCacheObj:
|
|
37
|
-
dataDictItemCacheObj:
|
|
38
|
-
sysAppCacheObj:
|
|
39
|
-
sysAppPageCacheObj:
|
|
40
|
-
sysAnyApiCacheObj:
|
|
41
|
-
sysProxyApiCacheObj:
|
|
42
|
-
crudMethodCacheObj:
|
|
35
|
+
workbenchCachedObj: defaultLastTime,
|
|
36
|
+
sysConfgCacheObj: defaultLastTime,
|
|
37
|
+
sysMenuCacheObj: defaultLastTime,
|
|
38
|
+
dataDictItemCacheObj: defaultLastTime,
|
|
39
|
+
sysAppCacheObj: defaultLastTime,
|
|
40
|
+
sysAppPageCacheObj: defaultLastTime,
|
|
41
|
+
sysAnyApiCacheObj: defaultLastTime,
|
|
42
|
+
sysProxyApiCacheObj: defaultLastTime,
|
|
43
|
+
crudMethodCacheObj: defaultLastTime,
|
|
43
44
|
};
|
|
44
45
|
}
|
|
45
46
|
|
|
@@ -16,6 +16,7 @@ import { ApiBaseService } from '../base/ApiBaseService';
|
|
|
16
16
|
import { parseDatabaseName } from '@/libs/crud-pro/utils/DatabaseName';
|
|
17
17
|
import { GLOBAL_STATIC_CONFIG } from '@/libs/global-config/global-config';
|
|
18
18
|
import { SysAppService } from "@/service/SysAppService";
|
|
19
|
+
import { TEnableSoftDelete } from "@/libs/crud-pro-quick/models";
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
export const SPECIAL_SETTING_KEY = {
|
|
@@ -102,7 +103,7 @@ export class CrudStdService extends ApiBaseService {
|
|
|
102
103
|
const stdCrudCfgObj = appInfo.stdCrudCfgObj;
|
|
103
104
|
|
|
104
105
|
//删除策略
|
|
105
|
-
const deleteStrategy = _.get(stdCrudCfgObj, 'othersSetting.values.deleteStrategy');
|
|
106
|
+
const deleteStrategy: TEnableSoftDelete = _.get(stdCrudCfgObj, 'othersSetting.values.deleteStrategy');
|
|
106
107
|
// 自动
|
|
107
108
|
const enableStandardUpdateCfg: string[] = _.get(stdCrudCfgObj, 'othersSetting.values.enableStandardUpdateCfg');
|
|
108
109
|
const enableStandardUpdateCfgCondition: string[] = _.get(stdCrudCfgObj, 'othersSetting.values.enableStandardUpdateCfgCondition');
|
|
@@ -117,7 +118,7 @@ export class CrudStdService extends ApiBaseService {
|
|
|
117
118
|
sqlTable: getExecuteTableNameBySettingKey(appInfo, stdAction, sqlSimpleName),
|
|
118
119
|
sqlSimpleName,
|
|
119
120
|
updateCfg: {},
|
|
120
|
-
enableSoftDelete: deleteStrategy
|
|
121
|
+
enableSoftDelete: deleteStrategy, // 软删除配置
|
|
121
122
|
enableStandardUpdateCfg: Array.isArray(enableStandardUpdateCfg) && enableStandardUpdateCfg.length > 0 ? enableStandardUpdateCfg : ['by', 'at'], // 默认为 ['by', 'at']
|
|
122
123
|
enableStandardUpdateCfgCondition: Array.isArray(enableStandardUpdateCfgCondition) && enableStandardUpdateCfgCondition.length > 0 ? enableStandardUpdateCfgCondition : false, // 默认为false
|
|
123
124
|
};
|