midway-fatcms 0.0.1-beta.14 → 0.0.1-beta.16
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 +7 -0
- package/dist/configuration.d.ts +1 -0
- package/dist/configuration.js +21 -8
- package/dist/controller/base/BaseApiController.d.ts +1 -1
- package/dist/controller/gateway/AsyncTaskController.js +15 -4
- package/dist/controller/gateway/CrudMtdGatewayController.d.ts +3 -3
- package/dist/controller/gateway/CrudMtdGatewayController.js +5 -5
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/libs/crud-pro/CrudPro.d.ts +1 -0
- package/dist/libs/crud-pro/CrudPro.js +5 -0
- package/dist/libs/crud-pro/defaultConfigs.js +2 -0
- package/dist/libs/crud-pro/interfaces.d.ts +6 -0
- package/dist/libs/crud-pro/models/ExecuteContext.d.ts +2 -1
- package/dist/libs/crud-pro/models/ExecuteContextFunc.d.ts +8 -1
- package/dist/libs/crud-pro/models/ExecuteContextFunc.js +8 -0
- package/dist/libs/crud-pro/models/ResModel.d.ts +16 -0
- package/dist/libs/crud-pro/models/ResModel.js +2 -0
- package/dist/libs/crud-pro/services/CrudProCachedCfgService.d.ts +1 -0
- package/dist/libs/crud-pro/services/CrudProCachedCfgService.js +22 -11
- package/dist/libs/crud-pro/services/CrudProServiceBase.d.ts +2 -6
- package/dist/libs/crud-pro/services/CrudProServiceBase.js +3 -2
- package/dist/libs/crud-pro/services/CrudProTableMetaService.d.ts +1 -0
- package/dist/libs/crud-pro/services/CrudProTableMetaService.js +31 -7
- package/dist/libs/crud-pro/utils/DatabaseName.js +24 -3
- package/dist/libs/global-config/global-config.d.ts +6 -0
- package/dist/libs/global-config/global-config.js +1 -0
- package/dist/models/AsyncTaskModel.d.ts +4 -2
- package/dist/schedule/anonymousContext.d.ts +13 -0
- package/dist/schedule/anonymousContext.js +59 -0
- package/dist/schedule/index.d.ts +4 -4
- package/dist/schedule/index.js +9 -68
- package/dist/schedule/runSchedule.d.ts +6 -0
- package/dist/schedule/runSchedule.js +34 -0
- package/dist/schedule/scheduleNames.d.ts +8 -0
- package/dist/schedule/scheduleNames.js +17 -0
- package/dist/service/asyncTask/AsyncTaskRunnerService.d.ts +14 -0
- package/dist/service/asyncTask/AsyncTaskRunnerService.js +63 -13
- package/dist/service/asyncTask/AsyncTaskService.js +2 -1
- package/dist/service/crudstd/CrudStdService.d.ts +1 -0
- package/dist/service/crudstd/CrudStdService.js +27 -0
- package/dist/service/curd/CrudProQuick.d.ts +24 -0
- package/dist/service/curd/CrudProQuick.js +105 -0
- package/dist/service/curd/CurdMixByLinkToCustomService.d.ts +10 -1
- package/dist/service/curd/CurdMixByLinkToCustomService.js +71 -23
- package/dist/service/curd/CurdMixService.d.ts +1 -1
- package/dist/service/curd/CurdMixService.js +2 -2
- package/dist/service/curd/CurdMixUtils.js +35 -28
- package/dist/service/curd/CurdProService.d.ts +2 -10
- package/dist/service/curd/CurdProService.js +28 -143
- package/dist/service/curd/fixCfgModel.d.ts +3 -0
- package/dist/service/curd/fixCfgModel.js +107 -0
- package/package.json +1 -1
- package/src/configuration.ts +30 -10
- package/src/controller/gateway/AnyApiGatewayController.ts +1 -1
- package/src/controller/gateway/AsyncTaskController.ts +18 -5
- package/src/controller/gateway/CrudMtdGatewayController.ts +5 -5
- package/src/controller/manage/DocManageApi.ts +5 -5
- package/src/index.ts +3 -0
- package/src/libs/crud-pro/CrudPro.ts +8 -0
- package/src/libs/crud-pro/defaultConfigs.ts +2 -0
- package/src/libs/crud-pro/interfaces.ts +10 -1
- package/src/libs/crud-pro/models/ExecuteContext.ts +5 -2
- package/src/libs/crud-pro/models/ExecuteContextFunc.ts +12 -1
- package/src/libs/crud-pro/models/ResModel.ts +24 -0
- package/src/libs/crud-pro/services/CrudProCachedCfgService.ts +26 -17
- package/src/libs/crud-pro/services/CrudProServiceBase.ts +5 -8
- package/src/libs/crud-pro/services/CrudProTableMetaService.ts +43 -9
- package/src/libs/crud-pro/utils/DatabaseName.ts +35 -15
- package/src/libs/global-config/global-config.ts +12 -1
- package/src/models/AsyncTaskModel.ts +5 -2
- package/src/schedule/anonymousContext.ts +79 -0
- package/src/schedule/index.ts +13 -72
- package/src/schedule/runSchedule.ts +35 -0
- package/src/schedule/scheduleNames.ts +20 -0
- package/src/service/asyncTask/AsyncTaskRunnerService.ts +86 -19
- package/src/service/asyncTask/AsyncTaskService.ts +3 -2
- package/src/service/base/BaseService.ts +2 -2
- package/src/service/crudstd/CrudStdService.ts +34 -6
- package/src/service/curd/CrudProQuick.ts +137 -0
- package/src/service/curd/CurdMixByLinkToCustomService.ts +100 -49
- package/src/service/curd/CurdMixService.ts +3 -3
- package/src/service/curd/CurdMixUtils.ts +51 -38
- package/src/service/curd/CurdProService.ts +42 -186
- package/src/service/curd/fixCfgModel.ts +139 -0
package/src/configuration.ts
CHANGED
|
@@ -13,8 +13,9 @@ import { join } from 'path';
|
|
|
13
13
|
// import { NotFoundFilter } from './filter/notfound.filter';
|
|
14
14
|
import { GlobalMiddleware } from './middleware/global.middleware';
|
|
15
15
|
import { ForbiddenMiddleware } from './middleware/forbidden.middleware';
|
|
16
|
-
import {
|
|
16
|
+
import { startScheduleLoop } from './schedule';
|
|
17
17
|
import { privateAES } from './libs/utils/crypto-utils';
|
|
18
|
+
import { ALL_SCHEDULE_NAMES } from "@/schedule/scheduleNames";
|
|
18
19
|
|
|
19
20
|
@Configuration({
|
|
20
21
|
// namespace: 'fatcms',
|
|
@@ -63,16 +64,11 @@ export class ContainerLifeCycle {
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
async onReady() {
|
|
66
|
-
const logger = this.app.getLogger();
|
|
67
|
-
const config = this.app.getConfig();
|
|
68
|
-
|
|
69
|
-
if (config.fatcmsScheduleService) {
|
|
70
|
-
// 启动定时任务
|
|
71
|
-
const scheduleServiceList = ['proxyApiLoadService', 'workbenchService', 'visitStatService', 'asyncTaskRunnerService'];
|
|
72
|
-
await startSchedule(this.app, scheduleServiceList);
|
|
73
|
-
logger.info('ContainerLifeCycle ==> onReady 启动定时任务 ' );
|
|
74
|
-
}
|
|
75
67
|
|
|
68
|
+
/**
|
|
69
|
+
* 启动定时任务
|
|
70
|
+
*/
|
|
71
|
+
await this.startScheduleOnReady();
|
|
76
72
|
|
|
77
73
|
// add middleware
|
|
78
74
|
this.app.useMiddleware(ForbiddenMiddleware);
|
|
@@ -81,4 +77,28 @@ export class ContainerLifeCycle {
|
|
|
81
77
|
// add filter
|
|
82
78
|
// this.app.useFilter([NotFoundFilter, DefaultErrorFilter]);
|
|
83
79
|
}
|
|
80
|
+
|
|
81
|
+
private async startScheduleOnReady(){
|
|
82
|
+
const logger = this.app.getLogger();
|
|
83
|
+
const config = this.app.getConfig();
|
|
84
|
+
const fatcmsScheduleService: boolean | string[] = config.fatcmsScheduleService;
|
|
85
|
+
|
|
86
|
+
// 关闭定时任务
|
|
87
|
+
if (fatcmsScheduleService === false || fatcmsScheduleService === null) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
let scheduleServiceList = ALL_SCHEDULE_NAMES
|
|
93
|
+
|
|
94
|
+
// 启动部分定时任务
|
|
95
|
+
if (Array.isArray(fatcmsScheduleService)){
|
|
96
|
+
scheduleServiceList = fatcmsScheduleService;
|
|
97
|
+
}
|
|
98
|
+
await startScheduleLoop(scheduleServiceList);
|
|
99
|
+
logger.info('ContainerLifeCycle ==> onReady 启动定时任务 : ' + JSON.stringify(scheduleServiceList) );
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
84
104
|
}
|
|
@@ -2,7 +2,7 @@ import { All, Controller, Inject, Param } from '@midwayjs/core';
|
|
|
2
2
|
import { Context } from '@midwayjs/koa';
|
|
3
3
|
import { BaseApiController } from '../base/BaseApiController';
|
|
4
4
|
import * as _ from 'lodash';
|
|
5
|
-
import { AnyApiService } from '
|
|
5
|
+
import { AnyApiService } from '@/service/anyapi/AnyApiService';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* FaaS方式配置的接口
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Controller, Inject,
|
|
1
|
+
import { Controller, Inject, Post, Query } from '@midwayjs/core';
|
|
2
2
|
|
|
3
3
|
import { Context } from '@midwayjs/koa';
|
|
4
4
|
import { BaseApiController } from '../base/BaseApiController';
|
|
@@ -7,6 +7,15 @@ import {SysAsyncTaskEntity, SysAsyncTaskStatus} from "@/models/AsyncTaskModel";
|
|
|
7
7
|
import {KeysOfSimpleSQL} from "@/libs/crud-pro/models/keys";
|
|
8
8
|
import {SystemTables} from "@/models/SystemTables";
|
|
9
9
|
import {CommonException} from "@/libs/crud-pro/exceptions";
|
|
10
|
+
import {checkLogin} from "@/middleware/permission.middleware";
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
function fixMyTasksCondition(body:any,ctx: Context){
|
|
14
|
+
if(!body.condition) {
|
|
15
|
+
throw new CommonException("参数不正确");
|
|
16
|
+
}
|
|
17
|
+
body.condition.created_by = ctx.userSession.getSessionInfo().accountId;
|
|
18
|
+
}
|
|
10
19
|
|
|
11
20
|
|
|
12
21
|
function fixCancelBodyData(body:any, id: number) {
|
|
@@ -26,21 +35,24 @@ function fixCancelBodyData(body:any, id: number) {
|
|
|
26
35
|
}
|
|
27
36
|
|
|
28
37
|
|
|
29
|
-
function fixCreateBodyData(body:any) {
|
|
38
|
+
function fixCreateBodyData(body:any, ctx: Context) {
|
|
30
39
|
if(!body.data) {
|
|
31
40
|
throw new CommonException("参数不正确");
|
|
32
41
|
}
|
|
33
42
|
|
|
43
|
+
const sessionInfo = ctx.userSession.getSessionInfo();
|
|
34
44
|
// fix data
|
|
35
45
|
const dataObj: SysAsyncTaskEntity = (body.data || {}) as any;
|
|
36
46
|
dataObj.task_status = SysAsyncTaskStatus.PENDING;
|
|
47
|
+
dataObj.created_by = sessionInfo.accountId;
|
|
48
|
+
dataObj.created_user_session = JSON.stringify(sessionInfo); // 创建人的session信息。用于执行时的鉴权。
|
|
37
49
|
}
|
|
38
50
|
|
|
39
51
|
|
|
40
52
|
/**
|
|
41
53
|
* 异步任务框架
|
|
42
54
|
*/
|
|
43
|
-
@Controller('/ns/gw/AsyncTask')
|
|
55
|
+
@Controller('/ns/gw/AsyncTask', { middleware: [checkLogin()] })
|
|
44
56
|
export class AsyncTaskController extends BaseApiController {
|
|
45
57
|
@Inject()
|
|
46
58
|
protected ctx: Context;
|
|
@@ -49,15 +61,16 @@ export class AsyncTaskController extends BaseApiController {
|
|
|
49
61
|
private asyncTaskService: AsyncTaskService;
|
|
50
62
|
|
|
51
63
|
// 获取任务列表
|
|
52
|
-
@
|
|
64
|
+
@Post('/getMyTasks')
|
|
53
65
|
async getMyTasks() {
|
|
66
|
+
fixMyTasksCondition(this.ctx.request.body, this.ctx);
|
|
54
67
|
return this.executeSysSimpleSQL(SystemTables.sys_async_tasks, KeysOfSimpleSQL.SIMPLE_QUERY_PAGE);
|
|
55
68
|
}
|
|
56
69
|
|
|
57
70
|
// 创建任务
|
|
58
71
|
@Post('/createTask')
|
|
59
72
|
async createTask() {
|
|
60
|
-
fixCreateBodyData(this.ctx.request.body);
|
|
73
|
+
fixCreateBodyData(this.ctx.request.body, this.ctx);
|
|
61
74
|
const res = await this.executeSysSimpleSQL(SystemTables.sys_async_tasks, KeysOfSimpleSQL.SIMPLE_INSERT);
|
|
62
75
|
await this.asyncTaskService.startTask();
|
|
63
76
|
return res;
|
|
@@ -21,11 +21,11 @@ function pickAsQuery(query_as_pick: string, query: any): any {
|
|
|
21
21
|
return query;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
// /ns/gw/
|
|
24
|
+
// /ns/gw/crudApi/getUser?__query_as_condition__=id&_query_as_data__=name&&id=1&name=22
|
|
25
25
|
/**
|
|
26
|
-
* query形式1:GET: /ns/gw/
|
|
27
|
-
* query形式2:GET: /ns/gw/
|
|
28
|
-
* query形式3:GET: /ns/gw/
|
|
26
|
+
* query形式1:GET: /ns/gw/crudApi/getUser?__query_json__=%7B%22condition%22%3A%7B%22id%22%3A2%7D%7D
|
|
27
|
+
* query形式2:GET: /ns/gw/crudApi/getUser?__query_as__=condition&id=1&name=22
|
|
28
|
+
* query形式3:GET: /ns/gw/crudApi/createUser?__query_as__=data&__query_pick__=id,name&id=1&name=22
|
|
29
29
|
*
|
|
30
30
|
* 执行单个配置的接口
|
|
31
31
|
*/
|
|
@@ -57,7 +57,7 @@ export class CrudMtdGatewayController extends ApiBaseService {
|
|
|
57
57
|
return CommonResult.errorRes('接口不存在或已下线: ' + methodCode);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
this.logInfo(
|
|
60
|
+
this.logInfo('methodInfo=== ', methodInfo);
|
|
61
61
|
|
|
62
62
|
const workbench_code_array = methodInfo.workbench_code_array || methodInfo.workbenchCodeArray;
|
|
63
63
|
const isSupport = await this.workbenchService.isSupportCurrentWorkbench(workbench_code_array);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Controller, Inject, Post } from '@midwayjs/core';
|
|
2
2
|
import { Context } from '@midwayjs/koa';
|
|
3
|
-
import { KeysOfSimpleSQL, KeysOfValidators } from '
|
|
3
|
+
import { KeysOfSimpleSQL, KeysOfValidators } from '@/libs/crud-pro/models/keys';
|
|
4
4
|
import { BaseApiController } from '../base/BaseApiController';
|
|
5
|
-
import { checkPermission } from '
|
|
6
|
-
import { SystemFuncCode } from '
|
|
7
|
-
import { SystemTables } from '
|
|
8
|
-
import { CTX_VISITOR_ID, CTX_WORKBENCH_CODE } from '
|
|
5
|
+
import { checkPermission } from '@/middleware/permission.middleware';
|
|
6
|
+
import { SystemFuncCode } from '@/models/SystemPerm';
|
|
7
|
+
import { SystemTables } from '@/models/SystemTables';
|
|
8
|
+
import { CTX_VISITOR_ID, CTX_WORKBENCH_CODE } from '@/models/bizmodels';
|
|
9
9
|
|
|
10
10
|
const publishUpdateCfg = {
|
|
11
11
|
'data.last_publish_by': { contextAsString: CTX_VISITOR_ID },
|
package/src/index.ts
CHANGED
|
@@ -64,6 +64,7 @@ export * from './service/curd/CurdMixBySysConfigService';
|
|
|
64
64
|
export * from './service/curd/CurdMixByWorkbenchService';
|
|
65
65
|
export * from './service/curd/CurdMixService';
|
|
66
66
|
export * from './service/curd/CurdProService';
|
|
67
|
+
export * from './service/curd/CrudProQuick';
|
|
67
68
|
export * from './service/proxyapi/ProxyApiLoadService';
|
|
68
69
|
export * from './service/proxyapi/ProxyApiService';
|
|
69
70
|
export * from './service/asyncTask/AsyncTaskService';
|
|
@@ -76,6 +77,7 @@ export * from './models/contextLogger';
|
|
|
76
77
|
export * from './models/devops';
|
|
77
78
|
export * from './models/SystemTables';
|
|
78
79
|
export * from './models/AsyncTaskModel';
|
|
80
|
+
export * from './schedule/index';
|
|
79
81
|
|
|
80
82
|
|
|
81
83
|
export * from './libs/utils/common-dto';
|
|
@@ -99,5 +101,6 @@ export * from './libs/crud-pro/models/keys';
|
|
|
99
101
|
export * from './libs/crud-pro/models/ExecuteContextFunc';
|
|
100
102
|
export * from './libs/crud-pro/models/RequestCfgModel';
|
|
101
103
|
export * from './libs/crud-pro/models/SqlSegArg';
|
|
104
|
+
export * from './libs/crud-pro/models/ResModel';
|
|
102
105
|
|
|
103
106
|
export * from './libs/global-config/global-config';
|
|
@@ -89,6 +89,9 @@ class CrudPro {
|
|
|
89
89
|
const logger = this.executeContext.getLogger();
|
|
90
90
|
logger.info('CurdPro executeCrudByCfg', cfgJson);
|
|
91
91
|
|
|
92
|
+
// 在执行之前可以根据业务需要修改需要执行的内容。
|
|
93
|
+
await this.beforeExecuteSQLList(reqJson, cfgJson);
|
|
94
|
+
|
|
92
95
|
const exeCtx = this.executeContext;
|
|
93
96
|
|
|
94
97
|
if (!cfgJson.method) {
|
|
@@ -153,6 +156,11 @@ class CrudPro {
|
|
|
153
156
|
private async afterExecuteSQLList() {
|
|
154
157
|
return this.executeContext.contextFunc.afterExecuteSQLList();
|
|
155
158
|
}
|
|
159
|
+
|
|
160
|
+
private async beforeExecuteSQLList(reqJson: IRequestModel, cfgJson: IRequestCfgModel) {
|
|
161
|
+
return this.executeContext.contextFunc.beforeExecuteSQLList(reqJson, cfgJson);
|
|
162
|
+
}
|
|
163
|
+
|
|
156
164
|
}
|
|
157
165
|
|
|
158
166
|
export { CrudPro };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { ICrudProCfg } from './interfaces';
|
|
2
|
+
import { SqlDbType } from './models/keys';
|
|
2
3
|
|
|
3
4
|
export const defaultCrudProCfg: ICrudProCfg = {
|
|
4
5
|
sysDatabaseName: 'fatcms',
|
|
6
|
+
sysDatabaseDbType: SqlDbType.mysql, // 默认系统数据库名称,默认 mysql
|
|
5
7
|
sysConfigTableName: 'sys_configs', // 数据表:通用配置
|
|
6
8
|
dictItemTableName: 'sys_data_dict_item', // 数据表:数据字典,字典项。
|
|
7
9
|
methodsTableName: 'sys_crud_methods',
|
|
@@ -4,6 +4,7 @@ import {KeysOfAuthType, KeysOfSimpleSQL, KeysOfValidators, SqlDbType} from './mo
|
|
|
4
4
|
|
|
5
5
|
export interface ICrudProCfg {
|
|
6
6
|
sysDatabaseName?: string; // 默认系统数据库名称,默认 fatcms
|
|
7
|
+
sysDatabaseDbType?: SqlDbType; // 默认系统数据库名称,默认 mysql
|
|
7
8
|
methodsTableName?: string; // 方法配置的表名,默认 sys_crud_methods
|
|
8
9
|
methodsCacheTime?: number; //内存缓存时间默认 1分钟
|
|
9
10
|
dictItemTableName?: string; // 字典项表名称,默认:sys_data_dict_item
|
|
@@ -133,7 +134,7 @@ export interface ISqlCfgModel extends IBaseCfgModel {
|
|
|
133
134
|
originSql?: string; // 有特殊占位符的SQL, 原始的SQL
|
|
134
135
|
validate?: IFuncCfgModel; //执行前,进行校验,校验不通过就抛出异常. 校验函数可以返回 boolean或直接抛出异常
|
|
135
136
|
executeWhen?: IFuncCfgModel; //满足表达式的结果,才能执行。 默认:true 校验函数必须返回 boolean
|
|
136
|
-
executeSql?: string; // 可以运行的SQL
|
|
137
|
+
executeSql?: string; // 可以运行的SQL。在postgres/sqlserver环境下也可以使用问号。
|
|
137
138
|
executeSqlArgs?: any[]; //可以运行的SQL的参数
|
|
138
139
|
crudType?: string;
|
|
139
140
|
}
|
|
@@ -181,3 +182,11 @@ export interface ILogger {
|
|
|
181
182
|
error(msg: any, ...args: any[]): void;
|
|
182
183
|
warn(msg: any, ...args: any[]): void;
|
|
183
184
|
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
export interface IExecuteUnsafeQueryCtx {
|
|
189
|
+
sqlTable: string;
|
|
190
|
+
sqlDatabase: string;
|
|
191
|
+
sqlDbType: SqlDbType;
|
|
192
|
+
}
|
|
@@ -7,6 +7,7 @@ import { Transaction } from './Transaction';
|
|
|
7
7
|
import { ICrudProCfg, ILogger, IVisitor } from '../interfaces';
|
|
8
8
|
import { IExecuteContextFunc } from './ExecuteContextFunc';
|
|
9
9
|
import { defaultCrudProCfg } from '../defaultConfigs';
|
|
10
|
+
import { ResModelFlexible } from "./ResModel";
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class ExecuteContext {
|
|
@@ -20,7 +21,7 @@ class ExecuteContext {
|
|
|
20
21
|
// 运行时设置的。
|
|
21
22
|
private sqlCfgModels: SqlCfgModel[] = [];
|
|
22
23
|
private reqModel: RequestModel = null;
|
|
23
|
-
private resModel:
|
|
24
|
+
private resModel: ResModelFlexible = {};
|
|
24
25
|
private cfgModel: RequestCfgModel = null;
|
|
25
26
|
|
|
26
27
|
setTransaction(transaction: Transaction) {
|
|
@@ -62,7 +63,7 @@ class ExecuteContext {
|
|
|
62
63
|
this.reqModel = reqModel;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
getResModel():
|
|
66
|
+
getResModel(): ResModelFlexible {
|
|
66
67
|
return this.resModel;
|
|
67
68
|
}
|
|
68
69
|
|
|
@@ -108,4 +109,6 @@ interface IExecuteContextHandler {
|
|
|
108
109
|
handleExecuteContext(executeContext: ExecuteContext): Promise<void>;
|
|
109
110
|
}
|
|
110
111
|
|
|
112
|
+
|
|
113
|
+
|
|
111
114
|
export { ExecuteContext, IExecuteContextHandler };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {IConnectionPool, IRequestCfgModel, IRequestModel} from '../interfaces';
|
|
2
2
|
import { ExecuteContext } from './ExecuteContext';
|
|
3
3
|
import { SqlCfgModel } from './SqlCfgModel';
|
|
4
4
|
import { RequestCfgModel } from './RequestCfgModel';
|
|
@@ -14,6 +14,7 @@ export interface IExecuteContextFunc {
|
|
|
14
14
|
getFunctionMap(): any;
|
|
15
15
|
validateByAuthCfg(cfgModel: RequestCfgModel, reqModel: RequestModel): Promise<any>;
|
|
16
16
|
afterExecuteSQLList(): Promise<any>;
|
|
17
|
+
beforeExecuteSQLList(reqJson: IRequestModel, cfgJson: IRequestCfgModel): Promise<any>;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export class BaseExecuteContextFunc implements IExecuteContextFunc {
|
|
@@ -76,6 +77,16 @@ export class BaseExecuteContextFunc implements IExecuteContextFunc {
|
|
|
76
77
|
return null;
|
|
77
78
|
}
|
|
78
79
|
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* 在执行之前可以根据业务需要修改需要执行的内容
|
|
83
|
+
* @param reqJson
|
|
84
|
+
* @param cfgJson
|
|
85
|
+
*/
|
|
86
|
+
beforeExecuteSQLList(reqJson: IRequestModel, cfgJson: IRequestCfgModel): Promise<any> {
|
|
87
|
+
return Promise.resolve();
|
|
88
|
+
}
|
|
89
|
+
|
|
79
90
|
getExecuteContext(): ExecuteContext {
|
|
80
91
|
return this.executeContext;
|
|
81
92
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
interface ResModelAffected {
|
|
3
|
+
insertId?: string | number;
|
|
4
|
+
affectedRows: number;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface ResModelStandard {
|
|
8
|
+
row?: any,
|
|
9
|
+
rows?: any[],
|
|
10
|
+
total_count?: number,
|
|
11
|
+
affected?: ResModelAffected,
|
|
12
|
+
insert_affected?: ResModelAffected,
|
|
13
|
+
update_affected?: ResModelAffected,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type ResModelFlexible = ResModelStandard & {
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
ResModelAffected,
|
|
22
|
+
ResModelStandard,
|
|
23
|
+
ResModelFlexible
|
|
24
|
+
}
|
|
@@ -7,46 +7,54 @@ import MemoryRefreshCache from '../utils/MemoryRefreshCache';
|
|
|
7
7
|
|
|
8
8
|
const methodCache = new MemoryRefreshCache();
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
function parseMethodInfo(methodInfo: any): any {
|
|
12
11
|
const row: any = camelizeKeys(methodInfo as object); //转换成驼峰
|
|
13
12
|
const configObject = MixinUtils.parseJsonObject(row.moreConfig) || {};
|
|
14
13
|
const sqlCfgList = MixinUtils.parseJsonObject(row.sqlCfgList) || [];
|
|
15
|
-
return {...configObject, ...row, sqlCfgList};
|
|
14
|
+
return { ...configObject, ...row, sqlCfgList };
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
17
|
class CrudProCachedCfgService extends CrudProServiceBase {
|
|
21
18
|
constructor(serviceHub: ICurdProServiceHub) {
|
|
22
19
|
super(serviceHub);
|
|
23
20
|
}
|
|
24
21
|
|
|
25
22
|
public async getCachedCfgByMethod(method: string, isEnableCache: boolean): Promise<IRequestCfgModel | null> {
|
|
23
|
+
const methodInfo = await this.getCachedCfgByMethodInner(method, isEnableCache);
|
|
24
|
+
if (!methodInfo) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return { ...methodInfo };
|
|
28
|
+
}
|
|
26
29
|
|
|
30
|
+
private async getCachedCfgByMethodInner(method: string, isEnableCache: boolean): Promise<IRequestCfgModel | null> {
|
|
27
31
|
// 不使用缓存
|
|
28
32
|
if (!isEnableCache) {
|
|
29
|
-
return await this.loadMethodInfo(method)
|
|
33
|
+
return await this.loadMethodInfo(method);
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
methodCache.setProps({
|
|
33
|
-
keepTime:
|
|
37
|
+
keepTime: 1000 * 60 * 2, // 2分钟
|
|
34
38
|
requestFn: () => this.loadMethodInfoList(),
|
|
35
39
|
getKeyFn: item => item.method,
|
|
36
40
|
});
|
|
37
|
-
|
|
41
|
+
const methodInfo = await methodCache.getItem(method);
|
|
42
|
+
if (methodInfo) {
|
|
43
|
+
return methodInfo;
|
|
44
|
+
}
|
|
45
|
+
return await this.loadMethodInfo(method);
|
|
38
46
|
}
|
|
39
47
|
|
|
40
|
-
|
|
41
48
|
private async loadMethodInfo(method: string): Promise<any> {
|
|
42
|
-
const {methodsTableName, sysDatabaseName} = this.getContextCfg();
|
|
43
|
-
const sql = `select *
|
|
44
|
-
|
|
45
|
-
where method = ? `; // 全部加载到内存
|
|
49
|
+
const { methodsTableName, sysDatabaseName, sysDatabaseDbType } = this.getContextCfg();
|
|
50
|
+
const sql = `select * from ${methodsTableName} where method = ? `; // 全部加载到内存
|
|
51
|
+
|
|
46
52
|
const baseInfo = {
|
|
47
|
-
|
|
48
|
-
|
|
53
|
+
sqlTable: methodsTableName,
|
|
54
|
+
sqlDatabase: sysDatabaseName,
|
|
55
|
+
sqlDbType: sysDatabaseDbType,
|
|
49
56
|
};
|
|
57
|
+
|
|
50
58
|
const [rows] = await this.executeUnsafeQuery(baseInfo, sql, [method]);
|
|
51
59
|
const rows2: any[] = rows as object[];
|
|
52
60
|
if (rows2.length > 0) {
|
|
@@ -58,11 +66,12 @@ class CrudProCachedCfgService extends CrudProServiceBase {
|
|
|
58
66
|
|
|
59
67
|
|
|
60
68
|
private async loadMethodInfoList(): Promise<any[]> {
|
|
61
|
-
const { methodsTableName, sysDatabaseName } = this.getContextCfg();
|
|
69
|
+
const { methodsTableName, sysDatabaseName, sysDatabaseDbType } = this.getContextCfg();
|
|
62
70
|
const sql = `select * from ${methodsTableName}`; // 全部加载到内存
|
|
63
71
|
const baseInfo = {
|
|
64
|
-
|
|
65
|
-
|
|
72
|
+
sqlTable: methodsTableName,
|
|
73
|
+
sqlDatabase: sysDatabaseName,
|
|
74
|
+
sqlDbType: sysDatabaseDbType
|
|
66
75
|
};
|
|
67
76
|
const [rows] = await this.executeUnsafeQuery(baseInfo, sql);
|
|
68
77
|
const rows2: any[] = rows as object[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _ from 'lodash';
|
|
2
2
|
import { ICurdProServiceHub } from '../models/ServiceHub';
|
|
3
|
-
import {ICrudProCfg, ILogger, IPoolConnectionClient} from '../interfaces';
|
|
3
|
+
import {ICrudProCfg, IExecuteUnsafeQueryCtx, ILogger, IPoolConnectionClient} from '../interfaces';
|
|
4
4
|
import { SqlCfgModel } from '../models/SqlCfgModel';
|
|
5
5
|
import { ExecuteContext } from '../models/ExecuteContext';
|
|
6
6
|
import { MixinUtils } from '../utils/MixinUtils';
|
|
@@ -19,10 +19,6 @@ function createBuildInExecuteFuncMap() {
|
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
interface ExecuteUnsafeQueryCtx {
|
|
23
|
-
tableName: string;
|
|
24
|
-
dbName: string;
|
|
25
|
-
}
|
|
26
22
|
|
|
27
23
|
const buildInExecuteFuncMap = createBuildInExecuteFuncMap();
|
|
28
24
|
|
|
@@ -60,10 +56,11 @@ class CrudProServiceBase {
|
|
|
60
56
|
* @param values
|
|
61
57
|
* @protected
|
|
62
58
|
*/
|
|
63
|
-
protected async executeUnsafeQuery(obj:
|
|
59
|
+
protected async executeUnsafeQuery(obj: IExecuteUnsafeQueryCtx, sql: string, values?: any) {
|
|
64
60
|
const sqlCfgModel: any = {
|
|
65
|
-
sqlTable: obj.
|
|
66
|
-
sqlDatabase: obj.
|
|
61
|
+
sqlTable: obj.sqlTable,
|
|
62
|
+
sqlDatabase: obj.sqlDatabase,
|
|
63
|
+
sqlDbType: obj.sqlDbType,
|
|
67
64
|
columns: [],
|
|
68
65
|
columnsRelation: [],
|
|
69
66
|
maxLimit: DEFAULT_MAX_LIMIT,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { CrudProServiceBase } from './CrudProServiceBase';
|
|
2
2
|
import { SqlCfgModel } from '../models/SqlCfgModel';
|
|
3
|
-
import { ITableMeta } from '../interfaces';
|
|
3
|
+
import { IExecuteUnsafeQueryCtx, ITableMeta } from '../interfaces';
|
|
4
|
+
import { SqlDbType } from '../models/keys';
|
|
5
|
+
import { pickAndConvertPgRows } from '../utils/sqlConvert/convertPgType';
|
|
4
6
|
|
|
5
7
|
class CrudProTableMetaCache {
|
|
6
8
|
private cacheMap: Record<string, ITableMeta> = {};
|
|
@@ -42,18 +44,50 @@ class CrudProTableMetaService extends CrudProServiceBase {
|
|
|
42
44
|
tableColumns: [],
|
|
43
45
|
};
|
|
44
46
|
|
|
45
|
-
const baseInfo = {
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
const baseInfo: IExecuteUnsafeQueryCtx = {
|
|
48
|
+
sqlTable: sqlCfgModel.sqlTable,
|
|
49
|
+
sqlDatabase: sqlCfgModel.sqlDatabase,
|
|
50
|
+
sqlDbType: sqlCfgModel.sqlDbType
|
|
48
51
|
};
|
|
49
52
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
obj.tableColumns = tableDescribe2.map(fieldObj => {
|
|
53
|
-
return fieldObj['Field'];
|
|
54
|
-
});
|
|
53
|
+
obj.tableColumns = await this.loadTableColumnInfo(baseInfo);
|
|
54
|
+
|
|
55
55
|
return obj;
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
private async loadTableColumnInfo(baseInfo: IExecuteUnsafeQueryCtx): Promise<string[]>{
|
|
61
|
+
|
|
62
|
+
if(baseInfo.sqlDbType === SqlDbType.mysql) {
|
|
63
|
+
const [tableDescribe] = await this.executeUnsafeQuery(baseInfo, 'describe ' + baseInfo.sqlTable);
|
|
64
|
+
const tableDescribe2 = JSON.parse(JSON.stringify(tableDescribe));
|
|
65
|
+
return tableDescribe2.map(fieldObj => {
|
|
66
|
+
return fieldObj['Field'];
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
else if(baseInfo.sqlDbType === SqlDbType.postgres) {
|
|
71
|
+
const schemaname = 'public';
|
|
72
|
+
const columnArraySql = `
|
|
73
|
+
SELECT
|
|
74
|
+
*
|
|
75
|
+
FROM information_schema.columns
|
|
76
|
+
WHERE table_schema = '${schemaname}' and table_name = '${baseInfo.sqlTable}'
|
|
77
|
+
ORDER BY ordinal_position;
|
|
78
|
+
`.trim();
|
|
79
|
+
const queryRes = await this.executeUnsafeQuery(baseInfo, columnArraySql);
|
|
80
|
+
const rows = pickAndConvertPgRows(queryRes)
|
|
81
|
+
return rows.map(fieldObj => {
|
|
82
|
+
return fieldObj['column_name'];
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
throw new Error("暂不支持的数据库类型:" + baseInfo.sqlDbType)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
57
91
|
}
|
|
58
92
|
|
|
59
93
|
export { CrudProTableMetaService };
|
|
@@ -1,19 +1,45 @@
|
|
|
1
|
-
import { SqlDbType } from '../models/keys'
|
|
1
|
+
import { SqlDbType } from '../models/keys';
|
|
2
2
|
|
|
3
3
|
interface IDbTypeAndName {
|
|
4
|
-
dbType: SqlDbType
|
|
4
|
+
dbType: SqlDbType;
|
|
5
5
|
dbName: string;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
const SPLIT_CONST =
|
|
8
|
+
const SPLIT_CONST = '_________';
|
|
9
|
+
|
|
10
|
+
const PREFIX_MYSQL = `${SqlDbType.mysql}${SPLIT_CONST}`;
|
|
11
|
+
const PREFIX_POSTGRES = `${SqlDbType.postgres}${SPLIT_CONST}`;
|
|
12
|
+
const PREFIX_SQLSERVER = `${SqlDbType.sqlserver}${SPLIT_CONST}`;
|
|
9
13
|
|
|
10
14
|
function parseDatabaseName(databaseName: string): IDbTypeAndName {
|
|
11
15
|
const dbNameArr = databaseName.split(SPLIT_CONST);
|
|
16
|
+
|
|
17
|
+
if (databaseName.startsWith(PREFIX_MYSQL)) {
|
|
18
|
+
return {
|
|
19
|
+
dbType: SqlDbType.mysql,
|
|
20
|
+
dbName: dbNameArr[1],
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (databaseName.startsWith(PREFIX_POSTGRES)) {
|
|
25
|
+
return {
|
|
26
|
+
dbType: SqlDbType.postgres,
|
|
27
|
+
dbName: dbNameArr[1],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (databaseName.startsWith(PREFIX_SQLSERVER)) {
|
|
32
|
+
return {
|
|
33
|
+
dbType: SqlDbType.sqlserver,
|
|
34
|
+
dbName: dbNameArr[1],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
12
38
|
if (dbNameArr.length === 1) {
|
|
13
39
|
return {
|
|
14
40
|
dbType: SqlDbType.mysql, // 默认
|
|
15
|
-
dbName: dbNameArr[0]
|
|
16
|
-
}
|
|
41
|
+
dbName: dbNameArr[0],
|
|
42
|
+
};
|
|
17
43
|
}
|
|
18
44
|
|
|
19
45
|
if (dbNameArr.length > 1) {
|
|
@@ -21,20 +47,14 @@ function parseDatabaseName(databaseName: string): IDbTypeAndName {
|
|
|
21
47
|
const dbType = dbType0 as any;
|
|
22
48
|
return {
|
|
23
49
|
dbType,
|
|
24
|
-
dbName
|
|
25
|
-
}
|
|
50
|
+
dbName,
|
|
51
|
+
};
|
|
26
52
|
}
|
|
27
53
|
return null;
|
|
28
54
|
}
|
|
29
55
|
|
|
30
|
-
|
|
31
56
|
function toDatabaseNameStr(dbType: SqlDbType, dbName: string): string {
|
|
32
|
-
return [dbType, dbName].join(SPLIT_CONST)
|
|
57
|
+
return [dbType, dbName].join(SPLIT_CONST);
|
|
33
58
|
}
|
|
34
59
|
|
|
35
|
-
|
|
36
|
-
export {
|
|
37
|
-
SPLIT_CONST,
|
|
38
|
-
parseDatabaseName,
|
|
39
|
-
toDatabaseNameStr
|
|
40
|
-
}
|
|
60
|
+
export { SPLIT_CONST, parseDatabaseName, toDatabaseNameStr };
|
|
@@ -20,9 +20,19 @@ interface IGlobalStaticConfig {
|
|
|
20
20
|
bizUpdateCfgModelForCrudMtd(reqJson: any, cfgModel: any, methodInfo: any, ctx: any): Promise<any>;
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* CrudPro: 业务系统自定义的修改cfgModel。这是最底层的!!全局的!!全局的!!全局的!!!
|
|
26
|
+
* @param reqJson
|
|
27
|
+
* @param cfgModel
|
|
28
|
+
*/
|
|
29
|
+
bizUpdateCfgModelForCrudPro(reqJson: any, cfgModel: any): Promise<any>;
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
23
33
|
/**
|
|
24
34
|
* 生成用户的账号ID,业务系统可以生成类似工号的ID
|
|
25
|
-
* @param userSubmitData
|
|
35
|
+
* @param userSubmitData
|
|
26
36
|
*/
|
|
27
37
|
generateUserAccountId(userSubmitData: any): Promise<string>;
|
|
28
38
|
|
|
@@ -47,6 +57,7 @@ class GlobalStaticConfig {
|
|
|
47
57
|
this.configObject = {
|
|
48
58
|
bizUpdateCfgModelForCrudStd: noop,
|
|
49
59
|
bizUpdateCfgModelForCrudMtd: noop,
|
|
60
|
+
bizUpdateCfgModelForCrudPro: noop,
|
|
50
61
|
generateUserAccountId: null,
|
|
51
62
|
toFatcmsUserAccountId: (bizTableUserId: any) => {
|
|
52
63
|
return bizTableUserId;
|