midway-fatcms 0.0.7 → 0.0.9
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/.qoder/skills/midway-fatcms/01-quick-start.md +231 -0
- package/.qoder/skills/midway-fatcms/02-crud-quick.md +375 -0
- package/.qoder/skills/midway-fatcms/03-crud-sharding.md +489 -0
- package/.qoder/skills/midway-fatcms/04-condition-operators.md +93 -0
- package/.qoder/skills/midway-fatcms/05-configuration.md +290 -0
- package/.qoder/skills/midway-fatcms/06-builtin-functions.md +241 -0
- package/.qoder/skills/midway-fatcms/07-examples.md +504 -0
- package/.qoder/skills/midway-fatcms/SKILL.md +96 -0
- package/README.md +9 -9
- package/dist/configuration.d.ts +10 -0
- package/dist/configuration.js +26 -0
- package/dist/controller/base/BaseApiController.d.ts +1 -2
- package/dist/controller/base/BaseApiController.js +0 -4
- package/dist/controller/gateway/DocGatewayController.js +1 -1
- package/dist/controller/helpers.controller.d.ts +6 -0
- package/dist/controller/helpers.controller.js +19 -0
- package/dist/controller/manage/FlowConfigManageApi.js +4 -2
- package/dist/controller/manage/SysConfigMangeApi.js +6 -1
- package/dist/controller/manage/UserAccountManageApi.js +7 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/libs/crud-pro/CrudPro.d.ts +51 -3
- package/dist/libs/crud-pro/CrudPro.js +111 -4
- package/dist/libs/crud-pro/exceptions.d.ts +7 -0
- package/dist/libs/crud-pro/exceptions.js +7 -0
- package/dist/libs/crud-pro/interfaces.d.ts +83 -12
- package/dist/libs/crud-pro/models/CrudResult.d.ts +116 -0
- package/dist/libs/crud-pro/models/CrudResult.js +126 -0
- package/dist/libs/crud-pro/models/RequestModel.d.ts +2 -2
- package/dist/libs/crud-pro/models/ServiceHub.d.ts +2 -0
- package/dist/libs/crud-pro/services/CrudProDataTypeConvertService.d.ts +70 -2
- package/dist/libs/crud-pro/services/CrudProDataTypeConvertService.js +205 -13
- package/dist/libs/crud-pro/services/CrudProExecuteSqlService.js +36 -2
- package/dist/libs/crud-pro/services/CrudProGenSqlCondition.js +8 -4
- package/dist/libs/crud-pro/services/CrudProTableMetaService.d.ts +36 -0
- package/dist/libs/crud-pro/services/CrudProTableMetaService.js +97 -4
- package/dist/libs/crud-pro/services/CurdProServiceHub.d.ts +2 -0
- package/dist/libs/crud-pro/services/CurdProServiceHub.js +6 -0
- package/dist/libs/crud-pro-quick/CrudProQuick.d.ts +382 -0
- package/dist/libs/crud-pro-quick/CrudProQuick.js +689 -0
- package/dist/libs/crud-pro-quick/fixSoftDelete.d.ts +30 -0
- package/dist/{service/curd → libs/crud-pro-quick}/fixSoftDelete.js +3 -6
- package/dist/libs/crud-pro-quick/index.d.ts +36 -0
- package/dist/libs/crud-pro-quick/index.js +49 -0
- package/dist/libs/crud-pro-quick/models.d.ts +33 -0
- package/dist/libs/crud-pro-quick/models.js +2 -0
- package/dist/libs/crud-sharding/ShardingBase.d.ts +78 -0
- package/dist/libs/crud-sharding/ShardingBase.js +179 -0
- package/dist/libs/crud-sharding/ShardingByCustomCrud.d.ts +35 -0
- package/dist/libs/crud-sharding/ShardingByCustomCrud.js +297 -0
- package/dist/libs/crud-sharding/ShardingByHashCrud.d.ts +38 -0
- package/dist/libs/crud-sharding/ShardingByHashCrud.js +86 -0
- package/dist/libs/crud-sharding/ShardingByKeyCrud.d.ts +39 -0
- package/dist/libs/crud-sharding/ShardingByKeyCrud.js +74 -0
- package/dist/libs/crud-sharding/ShardingByTimeCrud.d.ts +66 -0
- package/dist/libs/crud-sharding/ShardingByTimeCrud.js +524 -0
- package/dist/libs/crud-sharding/ShardingConfig.d.ts +25 -10
- package/dist/libs/crud-sharding/ShardingConfig.js +5 -5
- package/dist/libs/crud-sharding/ShardingMerger.d.ts +10 -18
- package/dist/libs/crud-sharding/ShardingMerger.js +27 -44
- package/dist/libs/crud-sharding/ShardingResult.d.ts +33 -0
- package/dist/libs/crud-sharding/ShardingResult.js +16 -0
- package/dist/libs/crud-sharding/ShardingTableCreator.d.ts +21 -4
- package/dist/libs/crud-sharding/ShardingTableCreator.js +193 -59
- package/dist/libs/crud-sharding/ShardingUtils.d.ts +48 -0
- package/dist/libs/crud-sharding/ShardingUtils.js +122 -1
- package/dist/libs/crud-sharding/TIME_COLUMN_CLEAN_SPEC.md +488 -0
- package/dist/libs/crud-sharding/index.d.ts +13 -15
- package/dist/libs/crud-sharding/index.js +33 -17
- package/dist/models/RedisKeys.d.ts +1 -0
- package/dist/models/RedisKeys.js +1 -0
- package/dist/models/bizmodels.d.ts +2 -6
- package/dist/service/SysAppService.d.ts +2 -2
- package/dist/service/SysAppService.js +16 -5
- package/dist/service/SysConfigService.d.ts +1 -1
- package/dist/service/SysConfigService.js +7 -2
- package/dist/service/SysDictDataService.js +14 -4
- package/dist/service/SysMenuService.js +7 -2
- package/dist/service/TableMetaCacheRedisSubscriber.d.ts +31 -0
- package/dist/service/TableMetaCacheRedisSubscriber.js +98 -0
- package/dist/service/curd/CurdMixService.d.ts +6 -4
- package/dist/service/curd/CurdMixService.js +16 -2
- package/dist/service/curd/CurdProService.d.ts +149 -29
- package/dist/service/curd/CurdProService.js +157 -38
- package/dist/service/flow/FlowConfigService.js +7 -2
- package/dist/service/flow/FlowInstanceCrudService.js +22 -19
- package/package.json +1 -1
- package/src/configuration.ts +27 -0
- package/src/controller/base/BaseApiController.ts +0 -5
- package/src/controller/gateway/DocGatewayController.ts +1 -1
- package/src/controller/helpers.controller.ts +15 -0
- package/src/controller/manage/CrudStandardDesignApi.ts +4 -3
- package/src/controller/manage/FlowConfigManageApi.ts +4 -2
- package/src/controller/manage/SysConfigMangeApi.ts +6 -1
- package/src/controller/manage/UserAccountManageApi.ts +7 -2
- package/src/index.ts +2 -2
- package/src/libs/crud-pro/CrudPro.ts +134 -7
- package/src/libs/crud-pro/exceptions.ts +8 -0
- package/src/libs/crud-pro/interfaces.ts +111 -15
- package/src/libs/crud-pro/models/CrudResult.ts +178 -0
- package/src/libs/crud-pro/models/RequestModel.ts +2 -2
- package/src/libs/crud-pro/models/ServiceHub.ts +4 -0
- package/src/libs/crud-pro/services/CrudProDataTypeConvertService.ts +238 -15
- package/src/libs/crud-pro/services/CrudProExecuteSqlService.ts +41 -2
- package/src/libs/crud-pro/services/CrudProGenSqlCondition.ts +11 -7
- package/src/libs/crud-pro/services/CrudProTableMetaService.ts +110 -3
- package/src/libs/crud-pro/services/CurdProServiceHub.ts +8 -0
- package/src/libs/crud-pro-quick/CrudProQuick.ts +782 -0
- package/src/{service/curd → libs/crud-pro-quick}/fixSoftDelete.ts +23 -13
- package/src/libs/crud-pro-quick/index.ts +52 -0
- package/src/libs/crud-pro-quick/models.ts +35 -0
- package/src/libs/crud-sharding/ShardingBase.ts +256 -0
- package/src/libs/crud-sharding/ShardingByCustomCrud.ts +329 -0
- package/src/libs/crud-sharding/ShardingByHashCrud.ts +111 -0
- package/src/libs/crud-sharding/ShardingByKeyCrud.ts +97 -0
- package/src/libs/crud-sharding/ShardingByTimeCrud.ts +628 -0
- package/src/libs/crud-sharding/ShardingConfig.ts +28 -10
- package/src/libs/crud-sharding/ShardingMerger.ts +35 -63
- package/src/libs/crud-sharding/ShardingResult.ts +29 -0
- package/src/libs/crud-sharding/ShardingTableCreator.ts +214 -71
- package/src/libs/crud-sharding/ShardingUtils.ts +137 -0
- package/src/libs/crud-sharding/TIME_COLUMN_CLEAN_SPEC.md +488 -0
- package/src/libs/crud-sharding/index.ts +30 -16
- package/src/models/RedisKeys.ts +1 -0
- package/src/models/bizmodels.ts +4 -7
- package/src/service/SysAppService.ts +18 -7
- package/src/service/SysConfigService.ts +8 -3
- package/src/service/SysDictDataService.ts +14 -4
- package/src/service/SysMenuService.ts +7 -2
- package/src/service/TableMetaCacheRedisSubscriber.ts +105 -0
- package/src/service/crudstd/CrudStdService.ts +2 -2
- package/src/service/curd/CurdMixService.ts +26 -5
- package/src/service/curd/CurdProService.ts +186 -45
- package/src/service/flow/FlowConfigService.ts +7 -2
- package/src/service/flow/FlowInstanceCrudService.ts +23 -20
- package/.qoder/skills/midway-fatcms-crud/SKILL.md +0 -375
- package/.qoder/skills/midway-fatcms-crud/examples.md +0 -990
- package/.qoder/skills/midway-fatcms-crud/reference.md +0 -568
- package/dist/libs/crud-pro/README.md +0 -809
- package/dist/libs/crud-pro/README_FUNC.md +0 -193
- package/dist/libs/crud-sharding/ROUTING_LOGIC.md +0 -944
- package/dist/libs/crud-sharding/ShardingCrudPro.d.ts +0 -363
- package/dist/libs/crud-sharding/ShardingCrudPro.js +0 -675
- package/dist/libs/crud-sharding/ShardingRouter.d.ts +0 -69
- package/dist/libs/crud-sharding/ShardingRouter.js +0 -377
- package/dist/models/StandardColumns.d.ts +0 -71
- package/dist/models/StandardColumns.js +0 -28
- package/dist/service/curd/CrudProQuick.d.ts +0 -190
- package/dist/service/curd/CrudProQuick.js +0 -319
- package/dist/service/curd/README.md +0 -1100
- package/dist/service/curd/fixSoftDelete.d.ts +0 -20
- package/src/libs/crud-pro/README.md +0 -809
- package/src/libs/crud-pro/README_FUNC.md +0 -193
- package/src/libs/crud-sharding/ROUTING_LOGIC.md +0 -944
- package/src/libs/crud-sharding/ShardingCrudPro.ts +0 -835
- package/src/libs/crud-sharding/ShardingRouter.ts +0 -512
- package/src/models/StandardColumns.ts +0 -76
- package/src/service/curd/CrudProQuick.ts +0 -360
- package/src/service/curd/README.md +0 -1100
|
@@ -20,10 +20,14 @@ export class SysConfigService extends BaseService {
|
|
|
20
20
|
|
|
21
21
|
private get sysConfigsDao(){
|
|
22
22
|
const { SystemDbName, SystemDbType } = GLOBAL_STATIC_CONFIG.getConfig();
|
|
23
|
-
return this.curdProService.getQuickCrud(
|
|
23
|
+
return this.curdProService.getQuickCrud({
|
|
24
|
+
sqlDatabase: SystemDbName,
|
|
25
|
+
sqlDbType: SystemDbType,
|
|
26
|
+
sqlTable: SystemTables.sys_configs,
|
|
27
|
+
})
|
|
24
28
|
}
|
|
25
29
|
|
|
26
|
-
async getSysConfigOne(config_code: string): Promise<any
|
|
30
|
+
async getSysConfigOne(config_code: string): Promise<Record<string, any>> {
|
|
27
31
|
if (!config_code || typeof config_code !== 'string') {
|
|
28
32
|
throw new Error('[getSysAppOne] config_code required');
|
|
29
33
|
}
|
|
@@ -31,9 +35,10 @@ export class SysConfigService extends BaseService {
|
|
|
31
35
|
cacheKey: config_code,
|
|
32
36
|
cacheName: CacheNameEnum.GetSysConfigOne,
|
|
33
37
|
getter: async () => {
|
|
34
|
-
|
|
38
|
+
const res = await this.sysConfigsDao.findOne({
|
|
35
39
|
condition: {config_code, deleted_at: 0}
|
|
36
40
|
});
|
|
41
|
+
return res.row;
|
|
37
42
|
},
|
|
38
43
|
});
|
|
39
44
|
}
|
|
@@ -17,12 +17,20 @@ export class SysDictDataService extends BaseService {
|
|
|
17
17
|
|
|
18
18
|
private get sys_data_dict_item() {
|
|
19
19
|
const { SystemDbName, SystemDbType } = GLOBAL_STATIC_CONFIG.getConfig();
|
|
20
|
-
return this.curdProService.getQuickCrud(
|
|
20
|
+
return this.curdProService.getQuickCrud({
|
|
21
|
+
sqlDatabase: SystemDbName,
|
|
22
|
+
sqlDbType: SystemDbType,
|
|
23
|
+
sqlTable: SystemTables.sys_data_dict_item,
|
|
24
|
+
})
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
// private get sys_data_dict(){
|
|
24
28
|
// const { SystemDbName, SystemDbType } = GLOBAL_STATIC_CONFIG.getConfig();
|
|
25
|
-
// return this.curdProService.getQuickCrud(
|
|
29
|
+
// return this.curdProService.getQuickCrud({
|
|
30
|
+
// sqlDatabase: SystemDbName,
|
|
31
|
+
// sqlDbType: SystemDbType,
|
|
32
|
+
// sqlTable: SystemTables.sys_data_dict,
|
|
33
|
+
// })
|
|
26
34
|
// }
|
|
27
35
|
|
|
28
36
|
|
|
@@ -34,15 +42,17 @@ export class SysDictDataService extends BaseService {
|
|
|
34
42
|
cacheKey: dict_code,
|
|
35
43
|
cacheName: CacheNameEnum.GetDataDictItemsByDictCode,
|
|
36
44
|
getter: async () => {
|
|
37
|
-
|
|
45
|
+
const res = await this.sys_data_dict_item.findList({
|
|
38
46
|
condition: { dict_code, status: 1, deleted_at: 0 }
|
|
39
47
|
});
|
|
48
|
+
return res.rows;
|
|
40
49
|
},
|
|
41
50
|
});
|
|
42
51
|
}
|
|
43
52
|
|
|
44
53
|
public async removeCacheByDictItemId(dict_item_id: string) {
|
|
45
|
-
const
|
|
54
|
+
const res = await this.sys_data_dict_item.findOne({ condition: { id: dict_item_id } });
|
|
55
|
+
const dictItemObj = res.row;
|
|
46
56
|
return this.removeCacheByDictCode(dictItemObj['dict_code']);
|
|
47
57
|
}
|
|
48
58
|
|
|
@@ -57,7 +57,11 @@ export class SysMenuService extends BaseService {
|
|
|
57
57
|
|
|
58
58
|
private get sys_menus_table() {
|
|
59
59
|
const { SystemDbName, SystemDbType } = GLOBAL_STATIC_CONFIG.getConfig();
|
|
60
|
-
return this.curdProService.getQuickCrud(
|
|
60
|
+
return this.curdProService.getQuickCrud({
|
|
61
|
+
sqlDatabase: SystemDbName,
|
|
62
|
+
sqlDbType: SystemDbType,
|
|
63
|
+
sqlTable: SystemTables.sys_menus,
|
|
64
|
+
})
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
|
|
@@ -70,9 +74,10 @@ export class SysMenuService extends BaseService {
|
|
|
70
74
|
cacheKey: CacheNameEnum.GetSysMenusList,
|
|
71
75
|
cacheName: CacheNameEnum.GetSysMenusList,
|
|
72
76
|
getter: async () => {
|
|
73
|
-
|
|
77
|
+
const res = await this.sys_menus_table.findList({
|
|
74
78
|
condition: {}
|
|
75
79
|
});
|
|
80
|
+
return res.rows;
|
|
76
81
|
},
|
|
77
82
|
});
|
|
78
83
|
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { RedisService } from '@midwayjs/redis';
|
|
2
|
+
import { clearTableMetaCache } from '@/libs/crud-pro/services/CrudProTableMetaService';
|
|
3
|
+
import { RedisKeys } from '@/models/RedisKeys';
|
|
4
|
+
|
|
5
|
+
const CHANNEL = RedisKeys.TABLE_META_CACHE_INVALIDATE_CHANNEL;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 本节点唯一标识,用于区分是自己发出的广播还是其他节点发出的
|
|
9
|
+
* 避免重复清空(本节点已在发布前清空过)
|
|
10
|
+
*/
|
|
11
|
+
const NODE_ID = `node_${process.pid}_${Date.now()}`;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 用于发布消息的 Redis 客户端(复用 @midwayjs/redis 注入的实例)
|
|
15
|
+
*/
|
|
16
|
+
let publishClient: RedisService | null = null;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 用于订阅的 Redis 客户端(独立连接,ioredis 规定订阅连接不能执行普通命令)
|
|
20
|
+
*/
|
|
21
|
+
let subscribeClient: RedisService | null = null;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 初始化发布客户端
|
|
25
|
+
*
|
|
26
|
+
* 在 Midway 容器初始化完成后调用,注入已有的 RedisService 实例
|
|
27
|
+
* @param client RedisService 实例
|
|
28
|
+
*/
|
|
29
|
+
export function initTableMetaCachePublishClient(client: RedisService): void {
|
|
30
|
+
publishClient = client;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 初始化 Redis 订阅,监听缓存失效广播
|
|
35
|
+
*
|
|
36
|
+
* 使用 RedisService.duplicate() 创建独立的订阅连接。
|
|
37
|
+
* 收到广播后自动清空本节点的本地缓存。
|
|
38
|
+
*
|
|
39
|
+
* @param mainClient 已有的 RedisService 实例,用于 duplicate 出订阅连接
|
|
40
|
+
*/
|
|
41
|
+
export function initTableMetaCacheSubscriber(mainClient: RedisService): void {
|
|
42
|
+
if (subscribeClient) {
|
|
43
|
+
return; // 防止重复初始化
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// duplicate() 创建一个同配置的独立连接
|
|
47
|
+
subscribeClient = mainClient.duplicate() as RedisService;
|
|
48
|
+
|
|
49
|
+
subscribeClient.subscribe(CHANNEL).catch((err: Error) => {
|
|
50
|
+
console.error('[TableMetaCacheRedis] subscribe failed:', err.message);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
subscribeClient.on('message', (channel: string, message: string) => {
|
|
54
|
+
if (channel !== CHANNEL) return;
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
const data = JSON.parse(message);
|
|
58
|
+
// 跳过自己发出的广播(本节点已在发布前清空过)
|
|
59
|
+
if (data.nodeId === NODE_ID) return;
|
|
60
|
+
|
|
61
|
+
const stats = clearTableMetaCache();
|
|
62
|
+
console.info(`[TableMetaCacheRedis] 收到其他节点(${data.nodeId})的缓存清空广播,已清空本地缓存:`, stats);
|
|
63
|
+
} catch (e) {
|
|
64
|
+
console.error('[TableMetaCacheRedis] 处理缓存失效广播异常:', e);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
subscribeClient.on('error', (err: Error) => {
|
|
69
|
+
console.error('[TableMetaCacheRedis] subscriber connection error:', err.message);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
console.info('[TableMetaCacheRedis] 订阅已启动,监听频道:', CHANNEL);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 清空本节点缓存并广播通知集群中其他节点
|
|
77
|
+
*
|
|
78
|
+
* 调用流程:
|
|
79
|
+
* 1. 清空本节点本地缓存
|
|
80
|
+
* 2. 通过 Redis PUBLISH 广播消息
|
|
81
|
+
* 3. 其他节点收到消息后清空各自的本地缓存
|
|
82
|
+
*
|
|
83
|
+
* @returns 清空前的缓存统计
|
|
84
|
+
*/
|
|
85
|
+
export function clearTableMetaCacheWithBroadcast(): { metaCacheCount: number; tableInfoCacheCount: number } {
|
|
86
|
+
// 1. 清空本节点缓存
|
|
87
|
+
const stats = clearTableMetaCache();
|
|
88
|
+
|
|
89
|
+
// 2. 广播通知其他节点
|
|
90
|
+
if (publishClient && typeof publishClient.publish === 'function') {
|
|
91
|
+
const message = JSON.stringify({
|
|
92
|
+
nodeId: NODE_ID,
|
|
93
|
+
timestamp: Date.now(),
|
|
94
|
+
beforeClear: stats,
|
|
95
|
+
});
|
|
96
|
+
publishClient.publish(CHANNEL, message).catch((err: Error) => {
|
|
97
|
+
console.error('[TableMetaCacheRedis] publish failed:', err.message);
|
|
98
|
+
});
|
|
99
|
+
} else {
|
|
100
|
+
// 没有 Redis 连接时仅清空本地(单节点部署降级)
|
|
101
|
+
console.info('[TableMetaCacheRedis] 无 Redis 发布客户端,仅清空本节点缓存');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return stats;
|
|
105
|
+
}
|
|
@@ -98,7 +98,7 @@ export class CrudStdService extends ApiBaseService {
|
|
|
98
98
|
if (!appInfo || appInfo.status !== 1) {
|
|
99
99
|
throw new BizException('应用不存在或已下线:' + appCode);
|
|
100
100
|
}
|
|
101
|
-
|
|
101
|
+
|
|
102
102
|
const stdCrudCfgObj = appInfo.stdCrudCfgObj;
|
|
103
103
|
|
|
104
104
|
//删除策略
|
|
@@ -296,7 +296,7 @@ export class CrudStdService extends ApiBaseService {
|
|
|
296
296
|
if (!appInfo) {
|
|
297
297
|
return null;
|
|
298
298
|
}
|
|
299
|
-
const { app_schema, ...others } = appInfo;
|
|
299
|
+
const { app_schema, ...others } = appInfo as any;
|
|
300
300
|
const stdCrudCfgObj = parseJsonObject(app_schema);
|
|
301
301
|
|
|
302
302
|
const handleArrayCfg = (arrayCfg: any[]) => {
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { Inject, Provide } from '@midwayjs/core';
|
|
2
2
|
import { CurdProService } from './CurdProService';
|
|
3
3
|
import { CurdMixByDictService } from './CurdMixByDictService';
|
|
4
|
-
import { ColumnRelation, IRequestCfgModel, IRequestModel, ISqlCfgModel, ITableListResult, ITableNamesOptions, ITableNamesQuery } from '@/libs/crud-pro/interfaces';
|
|
4
|
+
import { ColumnRelation, IRequestCfgModel, IRequestModel, ISqlCfgModel, ITableListResult, ITableNamesOptions, ITableNamesQuery, ExecuteSQLResult } from '@/libs/crud-pro/interfaces';
|
|
5
5
|
import { CurdMixBySysConfigService } from './CurdMixBySysConfigService';
|
|
6
6
|
import { CurdMixByAccountService } from './CurdMixByAccountService';
|
|
7
7
|
import { RelatedType } from './CurdMixUtils';
|
|
8
8
|
import { CurdMixByWorkbenchService } from './CurdMixByWorkbenchService';
|
|
9
9
|
import { IRequestCfgModel2 } from '@/models/bizmodels';
|
|
10
10
|
import { CurdMixByLinkToCustomService } from './CurdMixByLinkToCustomService';
|
|
11
|
-
import { SqlDbType } from '@/libs/crud-pro/models/keys';
|
|
11
|
+
// import { SqlDbType } from '@/libs/crud-pro/models/keys';
|
|
12
12
|
import { ExecuteContext, IExecuteContextCustom } from '@/libs/crud-pro/models/ExecuteContext';
|
|
13
|
+
import { ShardingBase } from "@/libs/crud-sharding";
|
|
14
|
+
import { IGetQuickCrudParam, IGetShardingCrudParam } from './CurdProService';
|
|
13
15
|
|
|
14
16
|
export interface ILinkColumnRelationParam {
|
|
15
17
|
columnsRelations: ColumnRelation[];
|
|
@@ -48,12 +50,31 @@ export class CurdMixService {
|
|
|
48
50
|
return this.curdProService.executeCrudByCfg(reqJson, cfgModel);
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
|
|
54
|
+
// /**
|
|
55
|
+
// * @deprecated 请使用 getQuickCrud 替代
|
|
56
|
+
// * @param sqlDatabase
|
|
57
|
+
// * @param sqlDbType
|
|
58
|
+
// * @param sqlTable
|
|
59
|
+
// */
|
|
60
|
+
// getBbUtil(sqlDatabase: string, sqlDbType: SqlDbType, sqlTable?: string) {
|
|
61
|
+
// this.prepare();
|
|
62
|
+
// return this.curdProService.getQuickCrud({ sqlDatabase, sqlDbType, sqlTable });
|
|
63
|
+
// }
|
|
64
|
+
|
|
65
|
+
getQuickCrud(param: IGetQuickCrudParam) {
|
|
52
66
|
this.prepare();
|
|
53
|
-
return this.curdProService.getQuickCrud(
|
|
67
|
+
return this.curdProService.getQuickCrud(param);
|
|
54
68
|
}
|
|
55
69
|
|
|
56
|
-
|
|
70
|
+
|
|
71
|
+
public getShardingCrud(param: IGetShardingCrudParam): ShardingBase {
|
|
72
|
+
this.prepare();
|
|
73
|
+
return this.curdProService.getShardingCrud(param);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
async executeSQL(sqlCfgModel: ISqlCfgModel): Promise<ExecuteSQLResult> {
|
|
57
78
|
this.prepare();
|
|
58
79
|
return this.curdProService.executeSQL(sqlCfgModel);
|
|
59
80
|
}
|
|
@@ -2,7 +2,7 @@ import * as _ from 'lodash';
|
|
|
2
2
|
import { Config, Inject, Provide } from '@midwayjs/core';
|
|
3
3
|
import { CrudPro } from '@/libs/crud-pro/CrudPro';
|
|
4
4
|
import { Context } from '@midwayjs/koa';
|
|
5
|
-
import { IConnectionPool, ICrudProCfg, IRequestCfgModel, IRequestModel, ISqlCfgModel, ITableListResult, ITableNamesOptions, ITableNamesQuery } from '@/libs/crud-pro/interfaces';
|
|
5
|
+
import { IConnectionPool, ICrudProCfg, IRequestCfgModel, IRequestModel, ISqlCfgModel, ITableListResult, ITableNamesOptions, ITableNamesQuery, ExecuteSQLResult } from '@/libs/crud-pro/interfaces';
|
|
6
6
|
import { SqlCfgModel } from '@/libs/crud-pro/models/SqlCfgModel';
|
|
7
7
|
import { getConnectionPool as getMySQLConnectionPool } from '../../libs/crud-pro/utils/pool/MySQLUtils';
|
|
8
8
|
import { getConnectionPool as getPostgresConnectionPool } from '../../libs/crud-pro/utils/pool/PostgresUtils';
|
|
@@ -16,11 +16,35 @@ import { RelatedType } from './CurdMixUtils';
|
|
|
16
16
|
import { BaseService } from '../base/BaseService';
|
|
17
17
|
import { IRequestCfgModel2, IVisitorExt } from '@/models/bizmodels';
|
|
18
18
|
import { IWorkbenchEntity } from '@/models/SystemEntities';
|
|
19
|
-
import { CrudProQuick } from '
|
|
20
|
-
import {
|
|
19
|
+
import { CrudProQuick } from '@/libs/crud-pro-quick';
|
|
20
|
+
import { ShardingBase, ShardingByTimeCrud, ShardingByHashCrud, ShardingByKeyCrud, ShardingByCustomCrud, ShardingType, IShardingConfig } from '@/libs/crud-sharding';
|
|
21
21
|
import { fixCfgModel } from './fixCfgModel';
|
|
22
22
|
import { GLOBAL_STATIC_CONFIG } from '@/libs/global-config/global-config';
|
|
23
|
-
import { fixSoftDelete } from "@/
|
|
23
|
+
import { fixSoftDelete } from "@/libs/crud-pro-quick/fixSoftDelete";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* getQuickCrud 参数接口
|
|
27
|
+
*/
|
|
28
|
+
export interface IGetQuickCrudParam {
|
|
29
|
+
/** 数据库名 */
|
|
30
|
+
sqlDatabase: string;
|
|
31
|
+
/** 数据库类型 */
|
|
32
|
+
sqlDbType: SqlDbType;
|
|
33
|
+
/** 表名(可选) */
|
|
34
|
+
sqlTable?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* getShardingCrud 参数接口
|
|
39
|
+
*/
|
|
40
|
+
export interface IGetShardingCrudParam {
|
|
41
|
+
/** 数据库名 */
|
|
42
|
+
sqlDatabase: string;
|
|
43
|
+
/** 数据库类型 */
|
|
44
|
+
sqlDbType: SqlDbType;
|
|
45
|
+
/** 分表配置 */
|
|
46
|
+
shardingConfig: IShardingConfig;
|
|
47
|
+
}
|
|
24
48
|
|
|
25
49
|
function toVisitor(ctx: Context): IVisitorExt {
|
|
26
50
|
const workbenchInfo: IWorkbenchEntity = ctx.workbenchInfo;
|
|
@@ -148,10 +172,40 @@ export class CurdProService extends BaseService {
|
|
|
148
172
|
|
|
149
173
|
private responseCfgHandlers: Record<RelatedType, IExecuteContextHandler> = {} as any;
|
|
150
174
|
|
|
175
|
+
/**
|
|
176
|
+
* 注册“响应配置处理器”(response cfg handler)。
|
|
177
|
+
*
|
|
178
|
+
* 这些处理器会在一次 CRUD/SQL 执行完成后被调用,用于对 `ExecuteContext` 做统一的二次加工,
|
|
179
|
+
* 例如:追加扩展数据、做字段脱敏、统一包装返回结构等。
|
|
180
|
+
*
|
|
181
|
+
* @param key 处理器类型标识(业务自定义枚举/常量)
|
|
182
|
+
* @param handler 处理器实现
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* curdProService.setResponseCfgHandlers(RelatedType.USER, {
|
|
186
|
+
* async handleExecuteContextPrepare(ctx) {
|
|
187
|
+
* // 可在执行结果处理前做准备
|
|
188
|
+
* },
|
|
189
|
+
* async handleExecuteContext(ctx) {
|
|
190
|
+
* // 对 ctx.result / ctx.data 等进行二次加工
|
|
191
|
+
* },
|
|
192
|
+
* });
|
|
193
|
+
*/
|
|
151
194
|
public setResponseCfgHandlers(key: RelatedType, handler: IExecuteContextHandler) {
|
|
152
195
|
this.responseCfgHandlers[key] = handler;
|
|
153
196
|
}
|
|
154
197
|
|
|
198
|
+
/**
|
|
199
|
+
* 获取当前已注册的“响应配置处理器”集合。
|
|
200
|
+
*
|
|
201
|
+
* 一般用于调试或在外层框架中统一检查/复用已有 handler。
|
|
202
|
+
*
|
|
203
|
+
* @returns 以 `RelatedType` 为 key 的处理器映射表
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* const handlers = curdProService.getResponseCfgHandlers();
|
|
207
|
+
* const userHandler = handlers[RelatedType.USER];
|
|
208
|
+
*/
|
|
155
209
|
public getResponseCfgHandlers(): Record<RelatedType, IExecuteContextHandler> {
|
|
156
210
|
return this.responseCfgHandlers;
|
|
157
211
|
}
|
|
@@ -189,8 +243,21 @@ export class CurdProService extends BaseService {
|
|
|
189
243
|
}
|
|
190
244
|
|
|
191
245
|
/**
|
|
192
|
-
*
|
|
193
|
-
*
|
|
246
|
+
* 通过 `method` 走配置化 CRUD 执行(从缓存/加载的配置中解析)。
|
|
247
|
+
*
|
|
248
|
+
* 适用于:前端/调用方只传 `method` + 入参,由服务端根据 `method` 找到对应的 CRUD 配置并执行。
|
|
249
|
+
* 在非调试模式下会启用配置缓存(调试模式关闭缓存,便于开发即时生效)。
|
|
250
|
+
*
|
|
251
|
+
* @param reqJson 请求模型,必须包含 `method`
|
|
252
|
+
* @returns `ExecuteContext`(包含执行过程与结果数据)
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* const ctx = await curdProService.executeCrud({
|
|
256
|
+
* method: 'user.list',
|
|
257
|
+
* pageNo: 1,
|
|
258
|
+
* pageSize: 20,
|
|
259
|
+
* });
|
|
260
|
+
* console.log(ctx.result);
|
|
194
261
|
*/
|
|
195
262
|
async executeCrud(reqJson: IRequestModel): Promise<ExecuteContext> {
|
|
196
263
|
if (!reqJson.method) {
|
|
@@ -204,87 +271,161 @@ export class CurdProService extends BaseService {
|
|
|
204
271
|
return curdPro.executeCrud(reqJson, isEnableCache);
|
|
205
272
|
}
|
|
206
273
|
|
|
207
|
-
|
|
208
|
-
|
|
274
|
+
/**
|
|
275
|
+
* 直接执行一段 SQL(不依赖 `method` 配置)。
|
|
276
|
+
*
|
|
277
|
+
* 适用于:后台管理/运维脚本/内部工具需要直接跑 SQL 的场景(仍会复用本服务的连接池、日志、visitor、事务等上下文)。
|
|
278
|
+
*
|
|
279
|
+
* @param sqlCfgModel SQL 执行配置(数据库、类型、SQL、参数等)
|
|
280
|
+
* @returns SQL 执行结果
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* const res = await curdProService.executeSQL({
|
|
284
|
+
* sqlDbType: SqlDbType.mysql,
|
|
285
|
+
* sqlDatabase: 'mydb',
|
|
286
|
+
* executeSql: 'select * from t_user where id = ?',
|
|
287
|
+
* executeSqlArgs: [1],
|
|
288
|
+
* });
|
|
289
|
+
*/
|
|
290
|
+
public async executeSQL(sqlCfgModel: ISqlCfgModel): Promise<ExecuteSQLResult> {
|
|
209
291
|
const curdPro = this.getCrudPro();
|
|
210
292
|
return curdPro.executeSQL(sqlCfgModel);
|
|
211
293
|
}
|
|
212
294
|
|
|
213
|
-
|
|
295
|
+
/**
|
|
296
|
+
* 直接按指定配置执行一次 CRUD(不走缓存查找)。
|
|
297
|
+
*
|
|
298
|
+
* 适用于:调用方已经拿到了/动态生成了本次要执行的 CRUD 配置,想直接执行并得到结果。
|
|
299
|
+
* 该方法会对 `cfgModel` 做两类标准化处理:
|
|
300
|
+
* - 统一修正/补全配置(`fixCfgModel`)
|
|
301
|
+
* - 应用软删除规则(`fixSoftDelete`)
|
|
302
|
+
*
|
|
303
|
+
* @param reqJson 本次请求入参
|
|
304
|
+
* @param cfgModel 本次请求对应的 CRUD 配置
|
|
305
|
+
* @returns `ExecuteContext`
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* const cfg = await curdProService.getCachedCfgByMethod('user.list');
|
|
309
|
+
* const ctx = await curdProService.executeCrudByCfg(
|
|
310
|
+
* { method: 'user.list', pageNo: 1, pageSize: 20 },
|
|
311
|
+
* cfg as any
|
|
312
|
+
* );
|
|
313
|
+
*/
|
|
214
314
|
public async executeCrudByCfg(reqJson: IRequestModel, cfgModel: IRequestCfgModel2): Promise<ExecuteContext> {
|
|
215
315
|
this.logInfo('executeCrudByCfg', cfgModel);
|
|
216
316
|
const curdPro = this.getCrudPro();
|
|
217
317
|
// 应用标准的updateCfg。
|
|
218
318
|
fixCfgModel(cfgModel);
|
|
219
319
|
// 应用软删除动作。
|
|
220
|
-
fixSoftDelete(cfgModel.sqlSimpleName, cfgModel, reqJson,
|
|
320
|
+
fixSoftDelete(cfgModel.sqlSimpleName, cfgModel, reqJson, curdPro.getVisitor());
|
|
221
321
|
return await curdPro.executeCrudByCfg(reqJson, cfgModel);
|
|
222
322
|
}
|
|
223
323
|
|
|
224
|
-
/**
|
|
225
|
-
* 获取 CrudProQuick 工具类(已废弃)
|
|
226
|
-
*
|
|
227
|
-
* @deprecated 请使用 getQuickCrud 替代
|
|
228
|
-
* @param sqlDatabase 数据库名
|
|
229
|
-
* @param sqlDbType 数据库类型
|
|
230
|
-
* @param sqlTable 表名(可选)
|
|
231
|
-
* @returns CrudProQuick 实例
|
|
232
|
-
*/
|
|
233
|
-
public getBbUtil(sqlDatabase: string, sqlDbType: SqlDbType, sqlTable?: string): CrudProQuick {
|
|
234
|
-
return this.getQuickCrud(sqlDatabase, sqlDbType, sqlTable);
|
|
235
|
-
}
|
|
236
324
|
|
|
237
325
|
/**
|
|
238
326
|
* 获取 CrudProQuick 工具类
|
|
239
327
|
*
|
|
240
328
|
* 提供快速 CRUD 操作的便捷方法,封装了常用的数据库操作。
|
|
241
329
|
*
|
|
242
|
-
* @param
|
|
243
|
-
* @param sqlDbType 数据库类型
|
|
244
|
-
* @param sqlTable 表名(可选)
|
|
330
|
+
* @param param 参数对象
|
|
245
331
|
* @returns CrudProQuick 实例
|
|
246
332
|
*
|
|
247
333
|
* @example
|
|
248
|
-
* const quick = curdProService.getQuickCrud(
|
|
249
|
-
*
|
|
334
|
+
* const quick = curdProService.getQuickCrud({
|
|
335
|
+
* sqlDatabase: 'mydb',
|
|
336
|
+
* sqlDbType: SqlDbType.mysql,
|
|
337
|
+
* sqlTable: 't_user',
|
|
338
|
+
* });
|
|
339
|
+
* const users = await quick.find({ status: 'active' });
|
|
250
340
|
*/
|
|
251
|
-
public getQuickCrud(
|
|
252
|
-
const
|
|
253
|
-
|
|
341
|
+
public getQuickCrud(param: IGetQuickCrudParam): CrudProQuick {
|
|
342
|
+
const { sqlDatabase, sqlDbType, sqlTable } = param;
|
|
343
|
+
// 传入工厂函数,每次需要时创建新的 CrudPro 实例
|
|
344
|
+
return new CrudProQuick({
|
|
345
|
+
crudProFactory: () => this.getCrudPro(),
|
|
346
|
+
sqlDatabase,
|
|
347
|
+
sqlDbType,
|
|
348
|
+
sqlTable,
|
|
349
|
+
});
|
|
254
350
|
}
|
|
255
351
|
|
|
256
352
|
/**
|
|
257
353
|
* 获取分表 CRUD 操作器
|
|
258
354
|
*
|
|
259
|
-
* @param
|
|
260
|
-
* @
|
|
261
|
-
* @param shardingConfig 分表配置
|
|
262
|
-
* @returns ShardingCrudPro 实例
|
|
355
|
+
* @param param 参数对象
|
|
356
|
+
* @returns ShardingBase 实例(实际类型根据 shardingConfig.type 决定)
|
|
263
357
|
*
|
|
264
358
|
* @example
|
|
265
|
-
* const sharding = curdProService.getShardingCrud(
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
359
|
+
* const sharding = curdProService.getShardingCrud({
|
|
360
|
+
* sqlDatabase: 'mydb',
|
|
361
|
+
* sqlDbType: SqlDbType.mysql,
|
|
362
|
+
* shardingConfig: {
|
|
363
|
+
* type: ShardingType.MONTH,
|
|
364
|
+
* baseTable: 't_order',
|
|
365
|
+
* timeColumn: 'created_at',
|
|
366
|
+
* },
|
|
269
367
|
* });
|
|
270
368
|
*/
|
|
271
|
-
public getShardingCrud(
|
|
272
|
-
sqlDatabase
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
369
|
+
public getShardingCrud(param: IGetShardingCrudParam): ShardingBase {
|
|
370
|
+
const { sqlDatabase, sqlDbType, shardingConfig } = param;
|
|
371
|
+
const factory = () => this.getCrudPro();
|
|
372
|
+
|
|
373
|
+
let sharding: ShardingBase;
|
|
374
|
+
switch (shardingConfig.type) {
|
|
375
|
+
case ShardingType.YEAR:
|
|
376
|
+
case ShardingType.MONTH:
|
|
377
|
+
case ShardingType.DAY:
|
|
378
|
+
sharding = new ShardingByTimeCrud(factory, shardingConfig);
|
|
379
|
+
break;
|
|
380
|
+
case ShardingType.HASH:
|
|
381
|
+
sharding = new ShardingByHashCrud(factory, shardingConfig);
|
|
382
|
+
break;
|
|
383
|
+
case ShardingType.KEY:
|
|
384
|
+
sharding = new ShardingByKeyCrud(factory, shardingConfig);
|
|
385
|
+
break;
|
|
386
|
+
case ShardingType.CUSTOM:
|
|
387
|
+
sharding = new ShardingByCustomCrud(factory, shardingConfig);
|
|
388
|
+
break;
|
|
389
|
+
default:
|
|
390
|
+
throw new Error(`[CurdProService] 不支持的分表类型: ${shardingConfig.type}`);
|
|
391
|
+
}
|
|
392
|
+
|
|
278
393
|
sharding.setBaseCfg({ sqlDatabase, sqlDbType });
|
|
279
394
|
return sharding;
|
|
280
395
|
}
|
|
281
396
|
|
|
397
|
+
/**
|
|
398
|
+
* 根据 `method` 获取(可能来自缓存的)CRUD 配置。
|
|
399
|
+
*
|
|
400
|
+
* 适用于:你只想先拿到配置做检查/二次加工/审计,再决定是否执行。
|
|
401
|
+
* 非调试模式会启用缓存(调试模式关闭缓存)。
|
|
402
|
+
*
|
|
403
|
+
* @param method 配置方法名,例如:`user.list`
|
|
404
|
+
* @returns CRUD 配置模型
|
|
405
|
+
*
|
|
406
|
+
* @example
|
|
407
|
+
* const cfg = await curdProService.getCachedCfgByMethod('user.list');
|
|
408
|
+
* console.log(cfg.sqlSimpleName);
|
|
409
|
+
*/
|
|
282
410
|
public async getCachedCfgByMethod(method: string): Promise<IRequestCfgModel> {
|
|
283
411
|
const curdPro = this.getCrudPro();
|
|
284
412
|
const isEnableCache = !this.isEnableDebug(); // 开发环境不使用缓存
|
|
285
413
|
return curdPro.getCachedCfgByMethod(method, isEnableCache);
|
|
286
414
|
}
|
|
287
415
|
|
|
416
|
+
/**
|
|
417
|
+
* 获取数据库的表/视图等结构信息列表(用于数据源探测、表选择器、代码生成等场景)。
|
|
418
|
+
*
|
|
419
|
+
* @param query 查询条件(例如:指定数据库、关键字过滤、分页等)
|
|
420
|
+
* @param options 可选项(例如:是否包含视图/系统表、大小写处理等,具体以接口定义为准)
|
|
421
|
+
* @returns 表信息列表结果
|
|
422
|
+
*
|
|
423
|
+
* @example
|
|
424
|
+
* const tables = await curdProService.getAllTableInfos(
|
|
425
|
+
* { sqlDbType: SqlDbType.mysql, sqlDatabase: 'mydb' },
|
|
426
|
+
* { skipCache: true }
|
|
427
|
+
* );
|
|
428
|
+
*/
|
|
288
429
|
public async getAllTableInfos(query: ITableNamesQuery, options?: ITableNamesOptions): Promise<ITableListResult> {
|
|
289
430
|
const curdPro = this.getCrudPro();
|
|
290
431
|
return curdPro.getAllTableInfos(query, options);
|
|
@@ -62,7 +62,11 @@ export class FlowConfigService extends BaseService {
|
|
|
62
62
|
|
|
63
63
|
private get flow_config(){
|
|
64
64
|
const { SystemDbName, SystemDbType } = GLOBAL_STATIC_CONFIG.getConfig();
|
|
65
|
-
return this.curdProService.getQuickCrud(
|
|
65
|
+
return this.curdProService.getQuickCrud({
|
|
66
|
+
sqlDatabase: SystemDbName,
|
|
67
|
+
sqlDbType: SystemDbType,
|
|
68
|
+
sqlTable: FLOW_TABLES.flow_config,
|
|
69
|
+
})
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
private toCacheKey(flow_code: string, flow_version: number): string {
|
|
@@ -81,9 +85,10 @@ export class FlowConfigService extends BaseService {
|
|
|
81
85
|
cacheKey: cacheKey,
|
|
82
86
|
cacheName: CacheNameEnum.GetFlowConfigOne,
|
|
83
87
|
getter: async () => {
|
|
84
|
-
|
|
88
|
+
const res = await this.flow_config.findUniqueOne({
|
|
85
89
|
condition: {flow_code, flow_version, deleted_at: 0}
|
|
86
90
|
});
|
|
91
|
+
return res.row;
|
|
87
92
|
},
|
|
88
93
|
});
|
|
89
94
|
}
|