midway-fatcms 0.0.16 → 0.0.18

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.
Files changed (146) hide show
  1. package/dist/config/config.default.js +5 -3
  2. package/dist/configuration.d.ts +0 -3
  3. package/dist/configuration.js +0 -19
  4. package/dist/controller/gateway/ProxyApiGatewayController.d.ts +0 -2
  5. package/dist/controller/gateway/ProxyApiGatewayController.js +0 -18
  6. package/dist/controller/helpers.controller.d.ts +4 -5
  7. package/dist/controller/helpers.controller.js +56 -14
  8. package/dist/controller/manage/AccountRoleManageApi.js +3 -5
  9. package/dist/controller/manage/AnyApiMangeApi.js +4 -3
  10. package/dist/controller/manage/AppMangeApi.js +3 -4
  11. package/dist/controller/manage/AppPageMangeApi.js +4 -3
  12. package/dist/controller/manage/CrudMethodsMangeApi.js +3 -4
  13. package/dist/controller/manage/DataDictManageApi.js +6 -7
  14. package/dist/controller/manage/DeployManageApi.js +4 -5
  15. package/dist/controller/manage/FlowConfigManageApi.js +3 -5
  16. package/dist/controller/manage/MenuManageApi.js +3 -4
  17. package/dist/controller/manage/ProxyApiMangeApi.js +3 -4
  18. package/dist/controller/manage/SysConfigMangeApi.js +3 -3
  19. package/dist/controller/manage/SystemInfoManageApi.js +3 -1
  20. package/dist/controller/manage/WorkbenchMangeApi.js +3 -4
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.js +3 -0
  23. package/dist/libs/crud-pro/models/TransactionSqlServer.js +27 -4
  24. package/dist/libs/crud-pro/services/CrudProCachedCfgService.d.ts +5 -8
  25. package/dist/libs/crud-pro/services/CrudProCachedCfgService.js +25 -42
  26. package/dist/libs/crud-pro/services/CrudProDataTypeConvertService.d.ts +2 -37
  27. package/dist/libs/crud-pro/services/CrudProDataTypeConvertService.js +137 -213
  28. package/dist/libs/crud-pro/utils/CrudMonitor.d.ts +0 -9
  29. package/dist/libs/crud-pro/utils/CrudMonitor.js +0 -21
  30. package/dist/libs/crud-pro/utils/MixinUtils.d.ts +2 -17
  31. package/dist/libs/crud-pro/utils/MixinUtils.js +4 -84
  32. package/dist/libs/crud-pro/utils/idgene/generateSnowflakeId.d.ts +12 -0
  33. package/dist/libs/crud-pro/utils/idgene/generateSnowflakeId.js +61 -0
  34. package/dist/libs/crud-pro/utils/idgene/generateSnowflakeIdExt.d.ts +19 -0
  35. package/dist/libs/crud-pro/utils/idgene/generateSnowflakeIdExt.js +89 -0
  36. package/dist/libs/crud-pro/utils/idgene/index.d.ts +3 -0
  37. package/dist/libs/crud-pro/utils/idgene/index.js +10 -0
  38. package/dist/libs/crud-pro/utils/idgene/uuid.d.ts +7 -0
  39. package/dist/libs/crud-pro/utils/idgene/uuid.js +28 -0
  40. package/dist/libs/crud-pro/utils/pool/SqlServerUtils.js +26 -0
  41. package/dist/libs/crud-pro-quick/fixSoftDelete.d.ts +0 -17
  42. package/dist/libs/crud-pro-quick/fixSoftDelete.js +55 -5
  43. package/dist/libs/crud-pro-quick/models.d.ts +11 -1
  44. package/dist/middleware/cacherefresh.middleware.d.ts +3 -46
  45. package/dist/middleware/cacherefresh.middleware.js +9 -67
  46. package/dist/models/CacheRefreshCategory.d.ts +1 -18
  47. package/dist/models/CacheRefreshCategory.js +0 -17
  48. package/dist/models/SystemEntities.d.ts +2 -0
  49. package/dist/models/bizmodels.d.ts +0 -8
  50. package/dist/models/bizmodels.js +0 -8
  51. package/dist/schedule/scheduleNames.d.ts +2 -0
  52. package/dist/schedule/scheduleNames.js +3 -1
  53. package/dist/service/SysAppService.d.ts +0 -6
  54. package/dist/service/SysAppService.js +10 -79
  55. package/dist/service/SysConfigService.d.ts +0 -6
  56. package/dist/service/SysConfigService.js +6 -51
  57. package/dist/service/SysDictDataService.d.ts +0 -5
  58. package/dist/service/SysDictDataService.js +7 -65
  59. package/dist/service/SysMenuService.d.ts +0 -4
  60. package/dist/service/SysMenuService.js +5 -44
  61. package/dist/service/WorkbenchService.d.ts +1 -6
  62. package/dist/service/WorkbenchService.js +9 -63
  63. package/dist/service/anyapi/AnyApiService.d.ts +1 -1
  64. package/dist/service/anyapi/AnyApiService.js +6 -16
  65. package/dist/service/base/bizmemcache/BizMemCacheService.d.ts +16 -0
  66. package/dist/service/base/bizmemcache/BizMemCacheService.js +241 -0
  67. package/dist/service/base/bizmemcache/BizMemCacheStore.d.ts +34 -0
  68. package/dist/service/base/bizmemcache/BizMemCacheStore.js +119 -0
  69. package/dist/service/base/bizmemcache/BizMemCacheTypes.d.ts +60 -0
  70. package/dist/service/base/bizmemcache/BizMemCacheTypes.js +18 -0
  71. package/dist/service/base/cache-refresh/CacheRefreshHub.d.ts +0 -22
  72. package/dist/service/base/cache-refresh/CacheRefreshHub.js +0 -22
  73. package/dist/service/base/cache-refresh/CacheRefreshHubScheduleService.d.ts +0 -6
  74. package/dist/service/base/cache-refresh/CacheRefreshHubScheduleService.js +0 -6
  75. package/dist/service/crudstd/CrudStdService.js +1 -1
  76. package/dist/service/curd/CurdMixByDictService.d.ts +0 -4
  77. package/dist/service/curd/CurdMixByDictService.js +9 -55
  78. package/dist/service/curd/CurdMixBySysConfigService.d.ts +0 -5
  79. package/dist/service/curd/CurdMixBySysConfigService.js +9 -54
  80. package/dist/service/curd/CurdMixByWorkbenchService.d.ts +0 -1
  81. package/dist/service/curd/CurdMixByWorkbenchService.js +9 -36
  82. package/dist/service/curd/CurdProService.d.ts +0 -1
  83. package/dist/service/curd/CurdProService.js +0 -4
  84. package/dist/service/curd/fixCfgModel.js +21 -1
  85. package/dist/service/proxyapi/ProxyApiLoadService.d.ts +3 -8
  86. package/dist/service/proxyapi/ProxyApiLoadService.js +40 -68
  87. package/dist/service/proxyapi/ProxyApiService.d.ts +2 -0
  88. package/dist/service/proxyapi/ProxyApiService.js +32 -9
  89. package/dist/service/proxyapi/RouteTrie.d.ts +1 -7
  90. package/dist/service/proxyapi/RouteTrie.js +1 -17
  91. package/package.json +1 -1
  92. package/src/config/config.default.ts +4 -2
  93. package/src/configuration.ts +0 -23
  94. package/src/controller/gateway/ProxyApiGatewayController.ts +1 -9
  95. package/src/controller/helpers.controller.ts +66 -15
  96. package/src/controller/manage/AccountRoleManageApi.ts +3 -5
  97. package/src/controller/manage/AnyApiMangeApi.ts +4 -3
  98. package/src/controller/manage/AppMangeApi.ts +4 -5
  99. package/src/controller/manage/AppPageMangeApi.ts +4 -3
  100. package/src/controller/manage/CrudMethodsMangeApi.ts +4 -5
  101. package/src/controller/manage/DataDictManageApi.ts +7 -8
  102. package/src/controller/manage/DeployManageApi.ts +2 -3
  103. package/src/controller/manage/FlowConfigManageApi.ts +3 -5
  104. package/src/controller/manage/MenuManageApi.ts +4 -5
  105. package/src/controller/manage/ProxyApiMangeApi.ts +4 -5
  106. package/src/controller/manage/SysConfigMangeApi.ts +5 -5
  107. package/src/controller/manage/SystemInfoManageApi.ts +3 -1
  108. package/src/controller/manage/WorkbenchMangeApi.ts +4 -5
  109. package/src/index.ts +3 -0
  110. package/src/libs/crud-pro/models/TransactionSqlServer.ts +26 -4
  111. package/src/libs/crud-pro/services/CrudProCachedCfgService.ts +25 -43
  112. package/src/libs/crud-pro/services/CrudProDataTypeConvertService.ts +149 -219
  113. package/src/libs/crud-pro/utils/CrudMonitor.ts +0 -23
  114. package/src/libs/crud-pro/utils/MixinUtils.ts +309 -400
  115. package/src/libs/crud-pro/utils/idgene/generateSnowflakeId.ts +65 -0
  116. package/src/libs/crud-pro/utils/idgene/generateSnowflakeIdExt.ts +99 -0
  117. package/src/libs/crud-pro/utils/idgene/index.ts +3 -0
  118. package/src/libs/crud-pro/utils/idgene/uuid.ts +26 -0
  119. package/src/libs/crud-pro/utils/pool/SqlServerUtils.ts +31 -0
  120. package/src/libs/crud-pro-quick/fixSoftDelete.ts +84 -18
  121. package/src/libs/crud-pro-quick/models.ts +15 -3
  122. package/src/middleware/cacherefresh.middleware.ts +10 -71
  123. package/src/models/CacheRefreshCategory.ts +0 -17
  124. package/src/models/SystemEntities.ts +2 -0
  125. package/src/models/bizmodels.ts +0 -8
  126. package/src/schedule/scheduleNames.ts +5 -3
  127. package/src/service/SysAppService.ts +7 -78
  128. package/src/service/SysConfigService.ts +4 -45
  129. package/src/service/SysDictDataService.ts +5 -64
  130. package/src/service/SysMenuService.ts +3 -40
  131. package/src/service/WorkbenchService.ts +9 -72
  132. package/src/service/anyapi/AnyApiService.ts +5 -17
  133. package/src/service/base/bizmemcache/BizMemCacheService.ts +290 -0
  134. package/src/service/base/bizmemcache/BizMemCacheStore.ts +159 -0
  135. package/src/service/base/bizmemcache/BizMemCacheTypes.ts +76 -0
  136. package/src/service/base/cache-refresh/CacheRefreshHub.ts +0 -22
  137. package/src/service/base/cache-refresh/CacheRefreshHubScheduleService.ts +0 -6
  138. package/src/service/crudstd/CrudStdService.ts +3 -2
  139. package/src/service/curd/CurdMixByDictService.ts +10 -61
  140. package/src/service/curd/CurdMixBySysConfigService.ts +9 -62
  141. package/src/service/curd/CurdMixByWorkbenchService.ts +7 -32
  142. package/src/service/curd/CurdProService.ts +0 -6
  143. package/src/service/curd/fixCfgModel.ts +145 -125
  144. package/src/service/proxyapi/ProxyApiLoadService.ts +39 -77
  145. package/src/service/proxyapi/ProxyApiService.ts +45 -9
  146. package/src/service/proxyapi/RouteTrie.ts +1 -18
@@ -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,19 @@
1
+ /**
2
+ * 128 位雪花 ID 生成器(独立于 MixinUtils.generateSnowflakeId,原 63 位算法不变)
3
+ *
4
+ * 位布局(128 bit,无符号,BigInt 拼接后 Base58 编码返回):
5
+ * - 64 bit 时间戳:相对 2024-01-01 00:00:00 UTC 的毫秒偏移
6
+ * - 16 bit 机器ID:0-65535,优先参数 > 环境变量 SNOWFLAKE_MACHINE_ID > process.pid 低 16 位
7
+ * - 48 bit 序列号:同一毫秒内自增,约 2.8e14 个/ms,实际不会耗尽
8
+ *
9
+ * 输出:Bitcoin 字母表 Base58(无 0/O/I/l),当前约 21 字符,理论最大 22 字符,建议 VARCHAR(24)
10
+ */
11
+ declare const EPOCH: bigint;
12
+ /**
13
+ * 生成 128 位雪花 ID(Base58 字符串)
14
+ *
15
+ * @param machineId 机器ID(0-65535),不传则依次从环境变量 SNOWFLAKE_MACHINE_ID、process.pid 获取
16
+ * @returns Base58 编码的 128 位雪花 ID
17
+ */
18
+ declare function generateSnowflakeIdExt(machineId?: number): string;
19
+ export { generateSnowflakeIdExt, EPOCH as SNOWFLAKE_EXT_EPOCH };
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ /**
3
+ * 128 位雪花 ID 生成器(独立于 MixinUtils.generateSnowflakeId,原 63 位算法不变)
4
+ *
5
+ * 位布局(128 bit,无符号,BigInt 拼接后 Base58 编码返回):
6
+ * - 64 bit 时间戳:相对 2024-01-01 00:00:00 UTC 的毫秒偏移
7
+ * - 16 bit 机器ID:0-65535,优先参数 > 环境变量 SNOWFLAKE_MACHINE_ID > process.pid 低 16 位
8
+ * - 48 bit 序列号:同一毫秒内自增,约 2.8e14 个/ms,实际不会耗尽
9
+ *
10
+ * 输出:Bitcoin 字母表 Base58(无 0/O/I/l),当前约 21 字符,理论最大 22 字符,建议 VARCHAR(24)
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.SNOWFLAKE_EXT_EPOCH = exports.generateSnowflakeIdExt = void 0;
14
+ const EPOCH = BigInt(1704067200000); // 2024-01-01 00:00:00 UTC
15
+ exports.SNOWFLAKE_EXT_EPOCH = EPOCH;
16
+ const TS_SHIFT = BigInt(64);
17
+ const MID_SHIFT = BigInt(48);
18
+ const MID_MASK = BigInt(0xffff);
19
+ const SEQ_MASK = BigInt('0xffffffffffff'); // 48 bit
20
+ const SEQ_START = BigInt(1);
21
+ const DRIFT_TOLERANCE = BigInt(5);
22
+ /** Bitcoin Base58 字母表 */
23
+ const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
24
+ const BASE58_RADIX = BigInt(58);
25
+ let snowflakeExtSeq = SEQ_START;
26
+ let snowflakeExtLastTs = BigInt(-1);
27
+ /** 无符号 BigInt → Base58 字符串 */
28
+ function encodeBase58(value) {
29
+ if (value === BigInt(0)) {
30
+ return BASE58_ALPHABET[0];
31
+ }
32
+ let n = value;
33
+ let result = '';
34
+ while (n > BigInt(0)) {
35
+ const rem = Number(n % BASE58_RADIX);
36
+ result = BASE58_ALPHABET[rem] + result;
37
+ n = n / BASE58_RADIX;
38
+ }
39
+ return result;
40
+ }
41
+ /** 解析机器 ID(16 bit) */
42
+ function resolveMachineId(machineId) {
43
+ var _a;
44
+ let mid = Number(machineId);
45
+ if (machineId === undefined || machineId === null || isNaN(mid)) {
46
+ const envMid = typeof process !== 'undefined' && ((_a = process.env) === null || _a === void 0 ? void 0 : _a.SNOWFLAKE_MACHINE_ID)
47
+ ? parseInt(process.env.SNOWFLAKE_MACHINE_ID, 10)
48
+ : NaN;
49
+ mid = !isNaN(envMid)
50
+ ? envMid
51
+ : typeof process !== 'undefined' && process.pid
52
+ ? process.pid
53
+ : 0;
54
+ }
55
+ return BigInt(Math.abs(mid)) & MID_MASK;
56
+ }
57
+ /**
58
+ * 生成 128 位雪花 ID(Base58 字符串)
59
+ *
60
+ * @param machineId 机器ID(0-65535),不传则依次从环境变量 SNOWFLAKE_MACHINE_ID、process.pid 获取
61
+ * @returns Base58 编码的 128 位雪花 ID
62
+ */
63
+ function generateSnowflakeIdExt(machineId) {
64
+ const mid = resolveMachineId(machineId);
65
+ let ts = BigInt(Date.now()) - EPOCH;
66
+ if (ts < snowflakeExtLastTs) {
67
+ const drift = snowflakeExtLastTs - ts;
68
+ if (drift <= DRIFT_TOLERANCE) {
69
+ ts = snowflakeExtLastTs;
70
+ }
71
+ else {
72
+ throw new Error(`SnowflakeExt clock drift detected: ${drift}ms backwards. Refusing to generate ID.`);
73
+ }
74
+ }
75
+ if (ts === snowflakeExtLastTs) {
76
+ snowflakeExtSeq = (snowflakeExtSeq + BigInt(1)) & SEQ_MASK;
77
+ if (snowflakeExtSeq === BigInt(0)) {
78
+ ts = snowflakeExtLastTs + BigInt(1);
79
+ snowflakeExtSeq = SEQ_START;
80
+ }
81
+ }
82
+ else {
83
+ snowflakeExtSeq = SEQ_START;
84
+ }
85
+ snowflakeExtLastTs = ts;
86
+ const id = (ts << TS_SHIFT) | (mid << MID_SHIFT) | snowflakeExtSeq;
87
+ return encodeBase58(id);
88
+ }
89
+ exports.generateSnowflakeIdExt = generateSnowflakeIdExt;
@@ -0,0 +1,3 @@
1
+ export { generateSnowflakeId } from './generateSnowflakeId';
2
+ export { generateSnowflakeIdExt, SNOWFLAKE_EXT_EPOCH } from './generateSnowflakeIdExt';
3
+ export { uuid } from './uuid';
@@ -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,7 @@
1
+ /**
2
+ * 生成 UUID v4 字符串(纯随机,无外部依赖)
3
+ * 格式:xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,其中 y 为 8/9/a/b 之一
4
+ * @returns 符合 RFC 4122 v4 规范的 UUID 字符串
5
+ */
6
+ declare function uuid(): string;
7
+ export { 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;
@@ -4,10 +4,36 @@ exports.getConnectionPool = void 0;
4
4
  const mssql_1 = require("mssql");
5
5
  const keys_1 = require("../../models/keys");
6
6
  const POOL_CACHE_MAP = {};
7
+ const POOL_CONNECTING_MAP = {};
8
+ async function doConnectPool(poolName, poolObj) {
9
+ // 避免重复连接同一个池
10
+ if (POOL_CONNECTING_MAP[poolName]) {
11
+ return POOL_CONNECTING_MAP[poolName];
12
+ }
13
+ const connectPromise = poolObj.connect().then((connectedPool) => {
14
+ console.log(`[crud-pro] SQL Server connection pool "${poolName}" connected successfully.`);
15
+ return connectedPool;
16
+ }).catch((err) => {
17
+ console.error(`[crud-pro] SQL Server connection pool "${poolName}" connect failed:`, err);
18
+ throw err;
19
+ }).finally(() => {
20
+ delete POOL_CONNECTING_MAP[poolName];
21
+ });
22
+ POOL_CONNECTING_MAP[poolName] = connectPromise;
23
+ return connectPromise;
24
+ }
7
25
  function getConnectionPool(poolName, poolOptions) {
8
26
  let pool = POOL_CACHE_MAP[poolName];
9
27
  if (!pool) {
10
28
  const poolObj = new mssql_1.ConnectionPool(poolOptions);
29
+ // 监听连接池错误,避免未捕获的异常导致进程崩溃
30
+ poolObj.on('error', (err) => {
31
+ console.error(`[crud-pro] SQL Server connection pool "${poolName}" error:`, err);
32
+ });
33
+ // 预连接池,避免首次请求时才建立连接导致延迟
34
+ doConnectPool(poolName, poolObj).catch(() => {
35
+ // 错误已在 doConnectPool 中打印,此处无需重复处理
36
+ });
11
37
  pool = {
12
38
  dbType: keys_1.SqlDbType.sqlserver,
13
39
  poolName: poolName,
@@ -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 fixSoftDelete(oldSqlSimpleName, cfgModel, params, visitor) {
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?: boolean;
42
+ enableSoftDelete?: TEnableSoftDelete;
33
43
  }
@@ -1,47 +1,4 @@
1
1
  import { NextFunction, Context } from '@midwayjs/koa';
2
- import { CacheNameEnum } from '../models/bizmodels';
3
- import { CacheRefreshCategory } from '../models/CacheRefreshCategory';
4
- /**
5
- * 缓存刷新中间件
6
- *
7
- * 在路由处理成功完成后,自动触发指定缓存项的刷新。
8
- * 采用后置刷新模式:先 await next() 让业务逻辑执行完毕,再刷新缓存。
9
- *
10
- * 应用场景:
11
- * 1. manage 增删改操作后自动刷新关联的业务缓存
12
- * 2. 精准刷新:只刷新与本次操作相关的缓存项,避免全量刷新
13
- *
14
- * 使用示例:
15
- * ```typescript
16
- * // 刷新全部业务缓存(向后兼容,等同原来的 refreshCache())
17
- * @Post('/createRole', { middleware: [checkPermission('write'), refreshCache()] })
18
- * async createRole() { ... }
19
- *
20
- * // 精准刷新:只刷新指定缓存项
21
- * @Post('/createMenu', { middleware: [checkPermission('write'), refreshCache(CacheNameEnum.GetSysMenusList)] })
22
- * async createMenu() { ... }
23
- *
24
- * // 同时刷新多个缓存项
25
- * @Post('/createApp', { middleware: [checkPermission('write'), refreshCache([CacheNameEnum.GetSysAppOne, CacheNameEnum.GetSysAppPageOne])] })
26
- * async createApp() { ... }
27
- * ```
28
- *
29
- * @param cacheName 缓存名称,不传则刷新全部,支持单个或数组
30
- */
31
- declare function refreshCache(cacheName?: CacheNameEnum | CacheNameEnum[]): (ctx: Context, next: NextFunction) => Promise<void>;
32
- /**
33
- * 缓存类别刷新中间件
34
- *
35
- * 通过 CacheRefreshHub 刷新指定类别的缓存(TableMeta / LinkToCustom / ProxyApiRoute 等)。
36
- * 适用于非 CacheNameEnum 管理的缓存类别。
37
- *
38
- * 使用示例:
39
- * ```typescript
40
- * @Post('/createProxyApi', { middleware: [checkPermission('write'), refreshCategory(CacheRefreshCategory.ProxyApiRoute)] })
41
- * async createProxyApi() { ... }
42
- * ```
43
- *
44
- * @param category 缓存类别,支持单个或数组
45
- */
46
- declare function refreshCategory(category: CacheRefreshCategory | CacheRefreshCategory[]): (ctx: Context, next: NextFunction) => Promise<void>;
47
- export { refreshCache, refreshCategory };
2
+ import { BizMemCacheKey } from '../service/base/bizmemcache/BizMemCacheTypes';
3
+ declare function refreshBizMemCache(cacheKey: BizMemCacheKey | BizMemCacheKey[]): (ctx: Context, next: NextFunction) => Promise<void>;
4
+ export { refreshBizMemCache };
@@ -1,74 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.refreshCategory = exports.refreshCache = void 0;
4
- const CacheServiceFactory_1 = require("../service/base/cache/CacheServiceFactory");
5
- const CacheRefreshHub_1 = require("../service/base/cache-refresh/CacheRefreshHub");
6
- /**
7
- * 缓存刷新中间件
8
- *
9
- * 在路由处理成功完成后,自动触发指定缓存项的刷新。
10
- * 采用后置刷新模式:先 await next() 让业务逻辑执行完毕,再刷新缓存。
11
- *
12
- * 应用场景:
13
- * 1. manage 增删改操作后自动刷新关联的业务缓存
14
- * 2. 精准刷新:只刷新与本次操作相关的缓存项,避免全量刷新
15
- *
16
- * 使用示例:
17
- * ```typescript
18
- * // 刷新全部业务缓存(向后兼容,等同原来的 refreshCache())
19
- * @Post('/createRole', { middleware: [checkPermission('write'), refreshCache()] })
20
- * async createRole() { ... }
21
- *
22
- * // 精准刷新:只刷新指定缓存项
23
- * @Post('/createMenu', { middleware: [checkPermission('write'), refreshCache(CacheNameEnum.GetSysMenusList)] })
24
- * async createMenu() { ... }
25
- *
26
- * // 同时刷新多个缓存项
27
- * @Post('/createApp', { middleware: [checkPermission('write'), refreshCache([CacheNameEnum.GetSysAppOne, CacheNameEnum.GetSysAppPageOne])] })
28
- * async createApp() { ... }
29
- * ```
30
- *
31
- * @param cacheName 缓存名称,不传则刷新全部,支持单个或数组
32
- */
33
- function refreshCache(cacheName) {
34
- const cacheNames = cacheName ? (Array.isArray(cacheName) ? cacheName : [cacheName]) : null;
3
+ exports.refreshBizMemCache = void 0;
4
+ const redis_1 = require("@midwayjs/redis");
5
+ const BizMemCacheStore_1 = require("../service/base/bizmemcache/BizMemCacheStore");
6
+ function refreshBizMemCache(cacheKey) {
7
+ const cacheKeys = Array.isArray(cacheKey) ? cacheKey : [cacheKey];
35
8
  return async (ctx, next) => {
36
9
  await next();
37
- const cacheServiceFactory = await ctx.requestContext.getAsync(CacheServiceFactory_1.CacheServiceFactory);
38
- if (cacheNames) {
39
- // 精准刷新:只刷新指定的缓存项
40
- for (const name of cacheNames) {
41
- await cacheServiceFactory.refreshByCacheName(name, ctx);
42
- }
43
- }
44
- else {
45
- // 全量刷新:刷新所有已注册的业务缓存
46
- await cacheServiceFactory.refreshAllCache(ctx);
47
- }
48
- };
49
- }
50
- exports.refreshCache = refreshCache;
51
- /**
52
- * 缓存类别刷新中间件
53
- *
54
- * 通过 CacheRefreshHub 刷新指定类别的缓存(TableMeta / LinkToCustom / ProxyApiRoute 等)。
55
- * 适用于非 CacheNameEnum 管理的缓存类别。
56
- *
57
- * 使用示例:
58
- * ```typescript
59
- * @Post('/createProxyApi', { middleware: [checkPermission('write'), refreshCategory(CacheRefreshCategory.ProxyApiRoute)] })
60
- * async createProxyApi() { ... }
61
- * ```
62
- *
63
- * @param category 缓存类别,支持单个或数组
64
- */
65
- function refreshCategory(category) {
66
- const categories = Array.isArray(category) ? category : [category];
67
- return async (ctx, next) => {
68
- await next();
69
- for (const cat of categories) {
70
- await CacheRefreshHub_1.CacheRefreshHub.refresh(cat, ctx);
10
+ const redisService = await ctx.requestContext.getAsync(redis_1.RedisService);
11
+ for (const key of cacheKeys) {
12
+ await BizMemCacheStore_1.bizMemCacheStore.markDirty(key, redisService);
71
13
  }
72
14
  };
73
15
  }
74
- exports.refreshCategory = refreshCategory;
16
+ exports.refreshBizMemCache = refreshBizMemCache;