midway-fatcms 0.0.4 → 0.0.6
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/README.md +635 -352
- package/dist/controller/manage/CrudStandardDesignApi.d.ts +0 -2
- package/dist/controller/manage/CrudStandardDesignApi.js +11 -85
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/libs/crud-pro/CrudPro.d.ts +9 -1
- package/dist/libs/crud-pro/CrudPro.js +15 -0
- package/dist/libs/crud-pro/README.md +809 -0
- package/dist/libs/crud-pro/README_FUNC.md +193 -0
- package/dist/libs/crud-pro/exceptions.d.ts +2 -0
- package/dist/libs/crud-pro/exceptions.js +2 -0
- package/dist/libs/crud-pro/interfaces.d.ts +34 -1
- package/dist/libs/crud-pro/models/ExecuteContext.d.ts +3 -3
- package/dist/libs/crud-pro/models/ExecuteContext.js +2 -0
- package/dist/libs/crud-pro/models/RequestModel.d.ts +41 -1
- package/dist/libs/crud-pro/models/RequestModel.js +103 -39
- package/dist/libs/crud-pro/models/ResModel.d.ts +6 -4
- package/dist/libs/crud-pro/models/ServiceHub.d.ts +1 -0
- package/dist/libs/crud-pro/models/keys.d.ts +6 -1
- package/dist/libs/crud-pro/models/keys.js +5 -0
- package/dist/libs/crud-pro/services/CrudProDataTypeConvertService.d.ts +52 -0
- package/dist/libs/crud-pro/services/CrudProDataTypeConvertService.js +158 -0
- package/dist/libs/crud-pro/services/CrudProExecuteSqlService.js +20 -1
- package/dist/libs/crud-pro/services/CrudProFieldValidateService.d.ts +7 -0
- package/dist/libs/crud-pro/services/CrudProFieldValidateService.js +32 -0
- package/dist/libs/crud-pro/services/CrudProGenSqlService.d.ts +13 -0
- package/dist/libs/crud-pro/services/CrudProGenSqlService.js +44 -7
- package/dist/libs/crud-pro/services/CrudProOriginToExecuteSql.d.ts +43 -0
- package/dist/libs/crud-pro/services/CrudProOriginToExecuteSql.js +132 -1
- package/dist/libs/crud-pro/services/CrudProTableMetaService.d.ts +15 -1
- package/dist/libs/crud-pro/services/CrudProTableMetaService.js +107 -0
- package/dist/libs/crud-pro/services/CurdProServiceHub.d.ts +5 -1
- package/dist/libs/crud-pro/services/CurdProServiceHub.js +11 -0
- package/dist/libs/crud-pro/utils/DateTimeUtils.d.ts +1 -0
- package/dist/libs/crud-pro/utils/DateTimeUtils.js +3 -0
- package/dist/libs/crud-pro/utils/MixinUtils.d.ts +32 -0
- package/dist/libs/crud-pro/utils/MixinUtils.js +85 -1
- package/dist/libs/crud-pro/utils/ValidateUtils.js +1 -1
- package/dist/libs/crud-sharding/ROUTING_LOGIC.md +944 -0
- package/dist/libs/crud-sharding/ShardingConfig.d.ts +218 -0
- package/dist/libs/crud-sharding/ShardingConfig.js +32 -0
- package/dist/libs/crud-sharding/ShardingCountCache.d.ts +69 -0
- package/dist/libs/crud-sharding/ShardingCountCache.js +160 -0
- package/dist/libs/crud-sharding/ShardingCrudPro.d.ts +363 -0
- package/dist/libs/crud-sharding/ShardingCrudPro.js +699 -0
- package/dist/libs/crud-sharding/ShardingMerger.d.ts +130 -0
- package/dist/libs/crud-sharding/ShardingMerger.js +280 -0
- package/dist/libs/crud-sharding/ShardingRouter.d.ts +69 -0
- package/dist/libs/crud-sharding/ShardingRouter.js +377 -0
- package/dist/libs/crud-sharding/ShardingTableCreator.d.ts +146 -0
- package/dist/libs/crud-sharding/ShardingTableCreator.js +805 -0
- package/dist/libs/crud-sharding/ShardingUtils.d.ts +38 -0
- package/dist/libs/crud-sharding/ShardingUtils.js +77 -0
- package/dist/libs/crud-sharding/index.d.ts +45 -0
- package/dist/libs/crud-sharding/index.js +55 -0
- package/dist/models/StandardColumns.d.ts +71 -0
- package/dist/models/StandardColumns.js +28 -0
- package/dist/service/SysAppService.js +2 -2
- package/dist/service/SysConfigService.js +1 -1
- package/dist/service/SysDictDataService.js +2 -2
- package/dist/service/SysMenuService.js +1 -1
- package/dist/service/UserAccountService.d.ts +1 -1
- package/dist/service/crudstd/CrudStdService.d.ts +0 -1
- package/dist/service/crudstd/CrudStdService.js +0 -27
- package/dist/service/curd/CrudProQuick.d.ts +134 -4
- package/dist/service/curd/CrudProQuick.js +155 -3
- package/dist/service/curd/CurdMixService.d.ts +2 -1
- package/dist/service/curd/CurdMixService.js +5 -1
- package/dist/service/curd/CurdProService.d.ts +44 -2
- package/dist/service/curd/CurdProService.js +53 -1
- package/dist/service/curd/README.md +1001 -0
- package/dist/service/curd/fixSoftDelete.d.ts +14 -0
- package/dist/service/curd/fixSoftDelete.js +29 -11
- package/dist/service/flow/FlowConfigService.js +1 -1
- package/dist/service/flow/FlowInstanceCrudService.js +1 -1
- package/package.json +3 -1
- package/src/controller/gateway/AsyncTaskController.ts +1 -1
- package/src/controller/manage/CrudStandardDesignApi.ts +16 -100
- package/src/index.ts +3 -0
- package/src/libs/crud-pro/CrudPro.ts +19 -1
- package/src/libs/crud-pro/README.md +809 -0
- package/src/libs/crud-pro/README_FUNC.md +193 -0
- package/src/libs/crud-pro/exceptions.ts +2 -0
- package/src/libs/crud-pro/interfaces.ts +38 -1
- package/src/libs/crud-pro/models/ExecuteContext.ts +6 -3
- package/src/libs/crud-pro/models/RequestModel.ts +108 -44
- package/src/libs/crud-pro/models/ResModel.ts +10 -4
- package/src/libs/crud-pro/models/ServiceHub.ts +2 -0
- package/src/libs/crud-pro/models/keys.ts +5 -0
- package/src/libs/crud-pro/services/CrudProDataTypeConvertService.ts +171 -0
- package/src/libs/crud-pro/services/CrudProExecuteSqlService.ts +24 -1
- package/src/libs/crud-pro/services/CrudProFieldValidateService.ts +53 -1
- package/src/libs/crud-pro/services/CrudProGenSqlService.ts +51 -7
- package/src/libs/crud-pro/services/CrudProOriginToExecuteSql.ts +159 -2
- package/src/libs/crud-pro/services/CrudProTableMetaService.ts +139 -1
- package/src/libs/crud-pro/services/CurdProServiceHub.ts +16 -1
- package/src/libs/crud-pro/utils/DateTimeUtils.ts +3 -0
- package/src/libs/crud-pro/utils/MixinUtils.ts +97 -1
- package/src/libs/crud-pro/utils/ValidateUtils.ts +1 -1
- package/src/libs/crud-sharding/ROUTING_LOGIC.md +944 -0
- package/src/libs/crud-sharding/ShardingConfig.ts +240 -0
- package/src/libs/crud-sharding/ShardingCountCache.ts +200 -0
- package/src/libs/crud-sharding/ShardingCrudPro.ts +856 -0
- package/src/libs/crud-sharding/ShardingMerger.ts +382 -0
- package/src/libs/crud-sharding/ShardingRouter.ts +512 -0
- package/src/libs/crud-sharding/ShardingTableCreator.ts +1007 -0
- package/src/libs/crud-sharding/ShardingUtils.ts +84 -0
- package/src/libs/crud-sharding/index.ts +64 -0
- package/src/models/StandardColumns.ts +76 -0
- package/src/service/FileCenterService.ts +1 -1
- package/src/service/SysAppService.ts +2 -2
- package/src/service/SysConfigService.ts +1 -1
- package/src/service/SysDictDataService.ts +2 -2
- package/src/service/SysMenuService.ts +2 -2
- package/src/service/WorkbenchService.ts +1 -1
- package/src/service/anyapi/AnyApiService.ts +1 -1
- package/src/service/asyncTask/AsyncTaskRunnerService.ts +1 -1
- package/src/service/crudstd/CrudStdService.ts +0 -32
- package/src/service/curd/CrudProQuick.ts +164 -5
- package/src/service/curd/CurdMixService.ts +7 -2
- package/src/service/curd/CurdProService.ts +62 -3
- package/src/service/curd/README.md +1001 -0
- package/src/service/curd/fixCfgModel.ts +1 -2
- package/src/service/curd/fixSoftDelete.ts +38 -16
- package/src/service/flow/FlowConfigService.ts +1 -1
- package/src/service/flow/FlowInstanceCrudService.ts +1 -1
|
@@ -7,6 +7,7 @@ const keys_1 = require("../models/keys");
|
|
|
7
7
|
class CrudProTableMetaCache {
|
|
8
8
|
constructor() {
|
|
9
9
|
this.cacheMap = {};
|
|
10
|
+
this.tableInfoCacheMap = {};
|
|
10
11
|
}
|
|
11
12
|
getCacheKey(query) {
|
|
12
13
|
return `${query.sqlDatabase}:::${query.sqlSchema}:::${query.sqlDbType}:::${query.sqlTable}`;
|
|
@@ -23,6 +24,19 @@ class CrudProTableMetaCache {
|
|
|
23
24
|
const cacheKey = this.getCacheKey(query);
|
|
24
25
|
this.cacheMap[cacheKey] = metaObj;
|
|
25
26
|
}
|
|
27
|
+
getTableInfos(cacheKey) {
|
|
28
|
+
const cached = this.tableInfoCacheMap[cacheKey];
|
|
29
|
+
if (cached && cached.expiredTime > Date.now()) {
|
|
30
|
+
return cached.tableInfos;
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
setTableInfos(cacheKey, tableInfos, cacheTime) {
|
|
35
|
+
this.tableInfoCacheMap[cacheKey] = {
|
|
36
|
+
tableInfos,
|
|
37
|
+
expiredTime: Date.now() + cacheTime,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
26
40
|
}
|
|
27
41
|
const metaCache = new CrudProTableMetaCache();
|
|
28
42
|
class CrudProTableMetaService extends CrudProServiceBase_1.CrudProServiceBase {
|
|
@@ -34,6 +48,99 @@ class CrudProTableMetaService extends CrudProServiceBase_1.CrudProServiceBase {
|
|
|
34
48
|
}
|
|
35
49
|
return obj;
|
|
36
50
|
}
|
|
51
|
+
// ============ 获取表和视图信息(带类型) ============
|
|
52
|
+
/**
|
|
53
|
+
* 获取数据库所有表和视图信息(包含类型)
|
|
54
|
+
*
|
|
55
|
+
* @param query 数据库查询参数
|
|
56
|
+
* @param options 缓存控制选项
|
|
57
|
+
* - skipCache: 跳过缓存,直接查询数据库
|
|
58
|
+
* - refreshCache: 查询后更新缓存
|
|
59
|
+
*/
|
|
60
|
+
async getAllTableInfos(query, options = {}) {
|
|
61
|
+
const { skipCache = false, refreshCache = false } = options;
|
|
62
|
+
// 1. 尝试从缓存获取(使用独立的缓存key)
|
|
63
|
+
const cacheKey = this.getTableInfoCacheKey(query);
|
|
64
|
+
if (!skipCache) {
|
|
65
|
+
const cached = metaCache.getTableInfos(cacheKey);
|
|
66
|
+
if (cached) {
|
|
67
|
+
return cached;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// 2. 查询数据库
|
|
71
|
+
const result = await this.loadAllTableInfos(query);
|
|
72
|
+
// 3. 更新缓存
|
|
73
|
+
if (!skipCache || refreshCache) {
|
|
74
|
+
const { tableMetaCacheTime } = this.getContextCfg();
|
|
75
|
+
metaCache.setTableInfos(cacheKey, result, tableMetaCacheTime || 3600000);
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
getTableInfoCacheKey(query) {
|
|
80
|
+
return `tableInfo:::${query.sqlDatabase}:::${query.sqlSchema || 'public'}:::${query.sqlDbType}`;
|
|
81
|
+
}
|
|
82
|
+
async loadAllTableInfos(query) {
|
|
83
|
+
const { sqlDbType } = query;
|
|
84
|
+
if (sqlDbType === keys_1.SqlDbType.mysql) {
|
|
85
|
+
return this.loadMySQLAllTableInfos(query);
|
|
86
|
+
}
|
|
87
|
+
else if (sqlDbType === keys_1.SqlDbType.postgres) {
|
|
88
|
+
return this.loadPostgreSQLAllTableInfos(query);
|
|
89
|
+
}
|
|
90
|
+
else if (sqlDbType === keys_1.SqlDbType.sqlserver) {
|
|
91
|
+
return this.loadSQLServerAllTableInfos(query);
|
|
92
|
+
}
|
|
93
|
+
throw new Error('暂不支持的数据库类型:' + sqlDbType);
|
|
94
|
+
}
|
|
95
|
+
async loadMySQLAllTableInfos(query) {
|
|
96
|
+
const dbUtil = { sqlDatabase: query.sqlDatabase, sqlDbType: query.sqlDbType };
|
|
97
|
+
// 获取物理表
|
|
98
|
+
const tableSql = `SHOW TABLES FROM ${query.sqlDatabase}`;
|
|
99
|
+
const tableRes = await this.executeUnsafeQuery(dbUtil, tableSql);
|
|
100
|
+
const tableNames = (tableRes.rows || []).map((row) => Object.values(row)[0]);
|
|
101
|
+
// 获取视图
|
|
102
|
+
const viewSql = `SHOW FULL TABLES FROM ${query.sqlDatabase} WHERE Table_type = 'VIEW'`;
|
|
103
|
+
const viewRes = await this.executeUnsafeQuery(dbUtil, viewSql);
|
|
104
|
+
const viewNames = (viewRes.rows || []).map((row) => Object.values(row)[0]);
|
|
105
|
+
const tables = [
|
|
106
|
+
...tableNames.map(name => ({ name, tableType: 'table' })),
|
|
107
|
+
...viewNames.map(name => ({ name, tableType: 'view' })),
|
|
108
|
+
];
|
|
109
|
+
return { tables, tableNames, viewNames };
|
|
110
|
+
}
|
|
111
|
+
async loadPostgreSQLAllTableInfos(query) {
|
|
112
|
+
const schema = query.sqlSchema || 'public';
|
|
113
|
+
const dbUtil = { sqlDatabase: query.sqlDatabase, sqlDbType: query.sqlDbType };
|
|
114
|
+
// 获取物理表
|
|
115
|
+
const tableSql = `SELECT tablename FROM pg_tables WHERE schemaname = '${schema}' ORDER BY tablename`;
|
|
116
|
+
const tableRes = await this.executeUnsafeQuery(dbUtil, tableSql);
|
|
117
|
+
const tableNames = (tableRes.rows || []).map((row) => row.tablename);
|
|
118
|
+
// 获取视图
|
|
119
|
+
const viewSql = `SELECT viewname FROM pg_views WHERE schemaname = '${schema}' ORDER BY viewname`;
|
|
120
|
+
const viewRes = await this.executeUnsafeQuery(dbUtil, viewSql);
|
|
121
|
+
const viewNames = (viewRes.rows || []).map((row) => row.viewname);
|
|
122
|
+
const tables = [
|
|
123
|
+
...tableNames.map(name => ({ name, tableType: 'table' })),
|
|
124
|
+
...viewNames.map(name => ({ name, tableType: 'view' })),
|
|
125
|
+
];
|
|
126
|
+
return { tables, tableNames, viewNames };
|
|
127
|
+
}
|
|
128
|
+
async loadSQLServerAllTableInfos(query) {
|
|
129
|
+
const dbUtil = { sqlDatabase: query.sqlDatabase, sqlDbType: query.sqlDbType };
|
|
130
|
+
// 获取物理表
|
|
131
|
+
const tableSql = `SELECT name FROM sys.tables`;
|
|
132
|
+
const tableRes = await this.executeUnsafeQuery(dbUtil, tableSql);
|
|
133
|
+
const tableNames = (tableRes.rows || []).map((row) => row.name);
|
|
134
|
+
// 获取视图
|
|
135
|
+
const viewSql = `SELECT name FROM sys.views`;
|
|
136
|
+
const viewRes = await this.executeUnsafeQuery(dbUtil, viewSql);
|
|
137
|
+
const viewNames = (viewRes.rows || []).map((row) => row.name);
|
|
138
|
+
const tables = [
|
|
139
|
+
...tableNames.map(name => ({ name, tableType: 'table' })),
|
|
140
|
+
...viewNames.map(name => ({ name, tableType: 'view' })),
|
|
141
|
+
];
|
|
142
|
+
return { tables, tableNames, viewNames };
|
|
143
|
+
}
|
|
37
144
|
async loadTableMeta(query) {
|
|
38
145
|
const { tableMetaCacheTime } = this.getContextCfg();
|
|
39
146
|
const obj = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IFuncCfgModel, IRequestCfgModel, ISqlCfgModel, ITableMeta, ITableMetaQuery } from '../interfaces';
|
|
1
|
+
import { IFuncCfgModel, IRequestCfgModel, ISqlCfgModel, ITableListResult, ITableMeta, ITableMetaQuery, ITableNamesOptions, ITableNamesQuery } from '../interfaces';
|
|
2
2
|
import { RequestModel } from '../models/RequestModel';
|
|
3
3
|
import { ExecuteContext } from '../models/ExecuteContext';
|
|
4
4
|
import { SqlCfgModel } from '../models/SqlCfgModel';
|
|
@@ -16,11 +16,13 @@ declare class CurdProServiceHub implements ICurdProServiceHub {
|
|
|
16
16
|
private readonly executeFuncService;
|
|
17
17
|
private readonly tableMetaService;
|
|
18
18
|
private readonly dataFilterService;
|
|
19
|
+
private readonly dataTypeConvertService;
|
|
19
20
|
constructor(executeContext: ExecuteContext);
|
|
20
21
|
getExecuteContext(): ExecuteContext;
|
|
21
22
|
validateByAllow(cfgModel: RequestCfgModel, reqModel: RequestModel): void;
|
|
22
23
|
validateByReject(cfgModel: RequestCfgModel, reqModel: RequestModel): void;
|
|
23
24
|
validateByCfg(cfgModel: RequestCfgModel, reqModel: RequestModel): void;
|
|
25
|
+
validateDataType(cfgModel: RequestCfgModel, reqModel: RequestModel): void;
|
|
24
26
|
validateByAuthCfg(cfgModel: RequestCfgModel, reqModel: RequestModel): Promise<any>;
|
|
25
27
|
updateByCfg(cfgModel: RequestCfgModel, reqModel: RequestModel): void;
|
|
26
28
|
getCachedCfgByMethod(method: string, isEnableCache: boolean): Promise<IRequestCfgModel>;
|
|
@@ -29,6 +31,8 @@ declare class CurdProServiceHub implements ICurdProServiceHub {
|
|
|
29
31
|
convertOriginToExecuteSql(sqlCfgModel: SqlCfgModel): Promise<void>;
|
|
30
32
|
executeFuncCfg(funCfg: IFuncCfgModel, funcContext: FuncContext): any;
|
|
31
33
|
getTableMeta(query: ITableMetaQuery): Promise<ITableMeta>;
|
|
34
|
+
getAllTableInfos(query: ITableNamesQuery, options?: ITableNamesOptions): Promise<ITableListResult>;
|
|
32
35
|
filterDataByTableMeta(data: Record<string, any>, sqlCfgModel: ISqlCfgModel | SqlCfgModel): Promise<Record<string, any>>;
|
|
36
|
+
convertDataTypeByTableMeta(reqModel: RequestModel, cfgModel: RequestCfgModel): Promise<void>;
|
|
33
37
|
}
|
|
34
38
|
export { CurdProServiceHub };
|
|
@@ -10,6 +10,7 @@ const CrudProOriginToExecuteSql_1 = require("./CrudProOriginToExecuteSql");
|
|
|
10
10
|
const CrudProExecuteFuncService_1 = require("./CrudProExecuteFuncService");
|
|
11
11
|
const CrudProTableMetaService_1 = require("./CrudProTableMetaService");
|
|
12
12
|
const CrudProDataFilterService_1 = require("./CrudProDataFilterService");
|
|
13
|
+
const CrudProDataTypeConvertService_1 = require("./CrudProDataTypeConvertService");
|
|
13
14
|
class CurdProServiceHub {
|
|
14
15
|
constructor(executeContext) {
|
|
15
16
|
this.executeContext = executeContext;
|
|
@@ -22,6 +23,7 @@ class CurdProServiceHub {
|
|
|
22
23
|
this.executeFuncService = new CrudProExecuteFuncService_1.CrudProExecuteFuncService(this);
|
|
23
24
|
this.tableMetaService = new CrudProTableMetaService_1.CrudProTableMetaService(this);
|
|
24
25
|
this.dataFilterService = new CrudProDataFilterService_1.CrudProDataFilterService(this);
|
|
26
|
+
this.dataTypeConvertService = new CrudProDataTypeConvertService_1.CrudProDataTypeConvertService(this);
|
|
25
27
|
}
|
|
26
28
|
getExecuteContext() {
|
|
27
29
|
return this.executeContext;
|
|
@@ -35,6 +37,9 @@ class CurdProServiceHub {
|
|
|
35
37
|
validateByCfg(cfgModel, reqModel) {
|
|
36
38
|
return this.fieldValidateService.validateByCfg(cfgModel, reqModel);
|
|
37
39
|
}
|
|
40
|
+
validateDataType(cfgModel, reqModel) {
|
|
41
|
+
return this.fieldValidateService.validateDataType(cfgModel, reqModel);
|
|
42
|
+
}
|
|
38
43
|
async validateByAuthCfg(cfgModel, reqModel) {
|
|
39
44
|
const contextFunc = this.executeContext.contextFunc;
|
|
40
45
|
if (contextFunc && contextFunc.validateByAuthCfg) {
|
|
@@ -62,8 +67,14 @@ class CurdProServiceHub {
|
|
|
62
67
|
async getTableMeta(query) {
|
|
63
68
|
return await this.tableMetaService.getTableMeta(query);
|
|
64
69
|
}
|
|
70
|
+
async getAllTableInfos(query, options) {
|
|
71
|
+
return await this.tableMetaService.getAllTableInfos(query, options);
|
|
72
|
+
}
|
|
65
73
|
async filterDataByTableMeta(data, sqlCfgModel) {
|
|
66
74
|
return await this.dataFilterService.filterDataByTableMeta(data, sqlCfgModel);
|
|
67
75
|
}
|
|
76
|
+
async convertDataTypeByTableMeta(reqModel, cfgModel) {
|
|
77
|
+
return await this.dataTypeConvertService.convertDataTypeByTableMeta(reqModel, cfgModel);
|
|
78
|
+
}
|
|
68
79
|
}
|
|
69
80
|
exports.CurdProServiceHub = CurdProServiceHub;
|
|
@@ -1,3 +1,20 @@
|
|
|
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
|
+
/**
|
|
13
|
+
* 生成 UUID v4 字符串(纯随机,无外部依赖)
|
|
14
|
+
* 格式:xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,其中 y 为 8/9/a/b 之一
|
|
15
|
+
* @returns 符合 RFC 4122 v4 规范的 UUID 字符串
|
|
16
|
+
*/
|
|
17
|
+
declare function uuid(): string;
|
|
1
18
|
declare const MixinUtils: {
|
|
2
19
|
isNil(obj: any): boolean;
|
|
3
20
|
isNotNil(obj: any): boolean;
|
|
@@ -36,5 +53,20 @@ declare const MixinUtils: {
|
|
|
36
53
|
selectNotEmpty(a: any, b: any): any;
|
|
37
54
|
parseValueByType(value: any, targetType: string): any;
|
|
38
55
|
sleepMs(ms: number): Promise<any>;
|
|
56
|
+
/**
|
|
57
|
+
* 生成 UUID v4 字符串(纯随机,无外部依赖)
|
|
58
|
+
* 格式:xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,其中 y 为 8/9/a/b 之一
|
|
59
|
+
* @returns 符合 RFC 4122 v4 规范的 UUID 字符串
|
|
60
|
+
*/
|
|
61
|
+
uuid: typeof uuid;
|
|
62
|
+
/**
|
|
63
|
+
* 生成雪花ID(64位整数,以字符串返回)
|
|
64
|
+
* 结构:1位符号 + 41位时间戳(ms) + 10位机器ID + 12位序列号
|
|
65
|
+
* 同一毫秒内可生成 4096 个不重复ID,单机每秒可生成约 400 万个
|
|
66
|
+
*
|
|
67
|
+
* @param machineId 机器ID(0-1023),不传则依次从环境变量 SNOWFLAKE_MACHINE_ID、process.pid 获取
|
|
68
|
+
* @returns 雪花ID字符串
|
|
69
|
+
*/
|
|
70
|
+
generateSnowflakeId: typeof generateSnowflakeId;
|
|
39
71
|
};
|
|
40
72
|
export { MixinUtils };
|
|
@@ -4,6 +4,75 @@ exports.MixinUtils = void 0;
|
|
|
4
4
|
const exceptions_1 = require("../exceptions");
|
|
5
5
|
// 至少需要2个字符
|
|
6
6
|
const FIELD_NAME_REG_EXP = /^[a-zA-Z][0-9a-zA-Z_]+$/;
|
|
7
|
+
// ===================== 雪花ID =====================
|
|
8
|
+
let snowflakeSeq = 0;
|
|
9
|
+
let snowflakeLastTs = -1;
|
|
10
|
+
/**
|
|
11
|
+
* 生成雪花ID(64位整数,JS 中以 string 返回)
|
|
12
|
+
* 结构:1位符号 + 41位时间戳(ms) + 10位机器ID + 12位序列号
|
|
13
|
+
* - 时间戳:相对于 2024-01-01 00:00:00 的毫秒偏移,可用约 69 年
|
|
14
|
+
* - 机器ID:0-1023,优先取参数 > 环境变量 SNOWFLAKE_MACHINE_ID > process.pid 低10位
|
|
15
|
+
* - 序列号:0-4095,同一毫秒内自增
|
|
16
|
+
*
|
|
17
|
+
* @param machineId 机器ID(0-1023),不传则依次从环境变量 SNOWFLAKE_MACHINE_ID、process.pid 获取
|
|
18
|
+
* @returns 雪花ID字符串
|
|
19
|
+
*/
|
|
20
|
+
function generateSnowflakeId(machineId) {
|
|
21
|
+
const EPOCH = 1704067200000; // 2024-01-01 00:00:00 UTC
|
|
22
|
+
let mid = machineId;
|
|
23
|
+
if (mid === undefined || mid === null) {
|
|
24
|
+
// 优先从环境变量获取,适配多实例部署场景
|
|
25
|
+
const envMid = typeof process !== 'undefined' && process.env && process.env.SNOWFLAKE_MACHINE_ID
|
|
26
|
+
? parseInt(process.env.SNOWFLAKE_MACHINE_ID, 10)
|
|
27
|
+
: NaN;
|
|
28
|
+
mid = !isNaN(envMid) ? envMid : (typeof process !== 'undefined' && process.pid ? process.pid & 0x3ff : 0);
|
|
29
|
+
}
|
|
30
|
+
mid = mid & 0x3ff; // 确保在 0-1023 范围
|
|
31
|
+
let now = Date.now();
|
|
32
|
+
let ts = now - EPOCH;
|
|
33
|
+
if (ts === snowflakeLastTs) {
|
|
34
|
+
snowflakeSeq = (snowflakeSeq + 1) & 0xfff; // 0-4095 循环
|
|
35
|
+
if (snowflakeSeq === 0) {
|
|
36
|
+
// 本毫秒序列号耗尽,等待下一毫秒
|
|
37
|
+
while (now <= Date.now()) {
|
|
38
|
+
now = Date.now();
|
|
39
|
+
}
|
|
40
|
+
ts = now - EPOCH;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
snowflakeSeq = 0;
|
|
45
|
+
}
|
|
46
|
+
snowflakeLastTs = ts;
|
|
47
|
+
// 雪花ID超过JS安全整数范围(2^53),不能用Number位运算,采用字符串拼接
|
|
48
|
+
const tsPart = ts * 4194304; // ts << 22,等价于 ts * 2^22
|
|
49
|
+
const midPart = mid * 4096; // mid << 12,等价于 mid * 2^12
|
|
50
|
+
return '' + (tsPart + midPart + snowflakeSeq);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 生成 UUID v4 字符串(纯随机,无外部依赖)
|
|
54
|
+
* 格式:xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,其中 y 为 8/9/a/b 之一
|
|
55
|
+
* @returns 符合 RFC 4122 v4 规范的 UUID 字符串
|
|
56
|
+
*/
|
|
57
|
+
function uuid() {
|
|
58
|
+
// crypto.getRandomValues 在 Node.js >= 11 和现代浏览器中可用
|
|
59
|
+
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
60
|
+
const bytes = new Uint8Array(16);
|
|
61
|
+
crypto.getRandomValues(bytes);
|
|
62
|
+
// 版本位:第6字节高4位设为 0100 (v4)
|
|
63
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
|
64
|
+
// 变体位:第8字节高2位设为 10
|
|
65
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
66
|
+
const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
|
|
67
|
+
return hex.slice(0, 8) + '-' + hex.slice(8, 12) + '-' + hex.slice(12, 16) + '-' + hex.slice(16, 20) + '-' + hex.slice(20);
|
|
68
|
+
}
|
|
69
|
+
// 降级方案:Math.random
|
|
70
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
|
71
|
+
const r = Math.random() * 16 | 0;
|
|
72
|
+
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
73
|
+
return v.toString(16);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
7
76
|
const MixinUtils = {
|
|
8
77
|
isNil(obj) {
|
|
9
78
|
return typeof obj === 'undefined' || obj === null;
|
|
@@ -254,6 +323,21 @@ const MixinUtils = {
|
|
|
254
323
|
},
|
|
255
324
|
sleepMs(ms) {
|
|
256
325
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
257
|
-
}
|
|
326
|
+
},
|
|
327
|
+
/**
|
|
328
|
+
* 生成 UUID v4 字符串(纯随机,无外部依赖)
|
|
329
|
+
* 格式:xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,其中 y 为 8/9/a/b 之一
|
|
330
|
+
* @returns 符合 RFC 4122 v4 规范的 UUID 字符串
|
|
331
|
+
*/
|
|
332
|
+
uuid: uuid,
|
|
333
|
+
/**
|
|
334
|
+
* 生成雪花ID(64位整数,以字符串返回)
|
|
335
|
+
* 结构:1位符号 + 41位时间戳(ms) + 10位机器ID + 12位序列号
|
|
336
|
+
* 同一毫秒内可生成 4096 个不重复ID,单机每秒可生成约 400 万个
|
|
337
|
+
*
|
|
338
|
+
* @param machineId 机器ID(0-1023),不传则依次从环境变量 SNOWFLAKE_MACHINE_ID、process.pid 获取
|
|
339
|
+
* @returns 雪花ID字符串
|
|
340
|
+
*/
|
|
341
|
+
generateSnowflakeId: generateSnowflakeId,
|
|
258
342
|
};
|
|
259
343
|
exports.MixinUtils = MixinUtils;
|
|
@@ -50,7 +50,7 @@ const validatorUtils = {
|
|
|
50
50
|
return false;
|
|
51
51
|
},
|
|
52
52
|
isMomentValid(itemCfg, itemValue) {
|
|
53
|
-
const cfgPart = itemCfg.substring(keys_1.KeysOfValidators.
|
|
53
|
+
const cfgPart = itemCfg.substring(keys_1.KeysOfValidators.MOMENT.length).trim();
|
|
54
54
|
return moment(itemValue, cfgPart, true).isValid();
|
|
55
55
|
},
|
|
56
56
|
isEnumValid(itemCfg, itemValue) {
|