midway-fatcms 0.0.1-beta.24 → 0.0.1-beta.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/models/RedisKeys.d.ts +1 -0
- package/dist/models/RedisKeys.js +2 -1
- package/dist/service/EnumInfoService.js +2 -1
- package/dist/service/anyapi/AnyApiSandboxService.js +12 -12
- package/dist/service/asyncTask/AsyncTaskRunnerService.js +3 -3
- package/dist/service/asyncTask/handler/ExportExcelAsyncTaskHandler.js +36 -17
- package/package.json +1 -1
- package/src/models/AsyncTaskModel.ts +82 -82
- package/src/models/RedisKeys.ts +2 -1
- package/src/service/AuthService.ts +272 -275
- package/src/service/EnumInfoService.ts +5 -4
- package/src/service/FileCenterService.ts +4 -4
- package/src/service/anyapi/AnyApiSandboxService.ts +121 -121
- package/src/service/anyapi/AnyApiService.ts +186 -187
- package/src/service/asyncTask/AsyncTaskRunnerService.ts +3 -3
- package/src/service/asyncTask/handler/ExportExcelAsyncTaskHandler.ts +37 -16
|
@@ -1,121 +1,121 @@
|
|
|
1
|
-
import { Inject, Provide } from '@midwayjs/core';
|
|
2
|
-
import { Context } from '@midwayjs/koa';
|
|
3
|
-
import * as vm from 'node:vm';
|
|
4
|
-
import { LRUCache } from 'lru-cache';
|
|
5
|
-
import { BaseService } from '../base/BaseService';
|
|
6
|
-
import { CurdMixService } from '../curd/CurdMixService';
|
|
7
|
-
import { ISysAnyApiEntity } from '../../models/SystemEntities';
|
|
8
|
-
import axios from 'axios';
|
|
9
|
-
import * as _ from 'lodash';
|
|
10
|
-
import * as moment from 'moment';
|
|
11
|
-
import * as nodemailer from 'nodemailer';
|
|
12
|
-
|
|
13
|
-
const scriptCacheOptions = {
|
|
14
|
-
max: 500,
|
|
15
|
-
ttl: 1000 * 60 * 5,
|
|
16
|
-
allowStale: false,
|
|
17
|
-
updateAgeOnGet: true,
|
|
18
|
-
updateAgeOnHas: true,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const scriptCache = new LRUCache<string, vm.Script>(scriptCacheOptions);
|
|
22
|
-
|
|
23
|
-
function getCompiledScript(anyApi: ISysAnyApiEntity, code: string): vm.Script {
|
|
24
|
-
const { id, func_code_md5 } = anyApi;
|
|
25
|
-
const cacheKey = id + '_' + func_code_md5;
|
|
26
|
-
const oldScript = scriptCache.get(cacheKey);
|
|
27
|
-
if (oldScript) {
|
|
28
|
-
return oldScript;
|
|
29
|
-
}
|
|
30
|
-
const script = new vm.Script(code);
|
|
31
|
-
scriptCache.set(cacheKey, script);
|
|
32
|
-
return script;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface IRunInSandboxParams {
|
|
36
|
-
body: any;
|
|
37
|
-
query: any;
|
|
38
|
-
headers: any;
|
|
39
|
-
params?: any;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
@Provide()
|
|
43
|
-
export class AnyApiSandboxService extends BaseService {
|
|
44
|
-
@Inject()
|
|
45
|
-
protected ctx: Context;
|
|
46
|
-
|
|
47
|
-
@Inject()
|
|
48
|
-
private curdMixService: CurdMixService;
|
|
49
|
-
|
|
50
|
-
public async runInSandbox(anyApi: ISysAnyApiEntity, allParams: IRunInSandboxParams) {
|
|
51
|
-
const { func_code, method } = anyApi;
|
|
52
|
-
|
|
53
|
-
return new Promise((resolve, reject) => {
|
|
54
|
-
const logger = this.getPrefixContextLogger(`[AnyApiSandboxService][method=${method}]`);
|
|
55
|
-
// 创建一个沙盒上下文
|
|
56
|
-
const proc = process;
|
|
57
|
-
const newContext = {
|
|
58
|
-
sandbox: {
|
|
59
|
-
allParams,
|
|
60
|
-
logger,
|
|
61
|
-
moment,
|
|
62
|
-
axios,
|
|
63
|
-
nodemailer,
|
|
64
|
-
_,
|
|
65
|
-
userSession: this.ctx.userSession,
|
|
66
|
-
ctx: this.ctx,
|
|
67
|
-
curdMixService: this.curdMixService,
|
|
68
|
-
redisService: this.redisService,
|
|
69
|
-
publicOSSService: this.getPublicOSSService(),
|
|
70
|
-
privateOSSService: this.getPrivateOSSService(),
|
|
71
|
-
returnSuccess: resolve,
|
|
72
|
-
returnError: reject,
|
|
73
|
-
processInfo: {
|
|
74
|
-
version: proc.version,
|
|
75
|
-
versions: proc.versions,
|
|
76
|
-
env: process.env,
|
|
77
|
-
argv: process.argv,
|
|
78
|
-
cwd: process.cwd(),
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
console: logger,
|
|
82
|
-
JSON: JSON,
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const nextLine100 = new Array(10).fill('\n').join('');
|
|
86
|
-
const bindCode = this.toBindCodeString('httpController', newContext, 'sandbox');
|
|
87
|
-
const code = `
|
|
88
|
-
(async () => {
|
|
89
|
-
${nextLine100}${func_code}; // 必须有一个 class HttpController { async handleRequest(params){} }
|
|
90
|
-
${nextLine100}
|
|
91
|
-
try {
|
|
92
|
-
const httpController = new HttpController();
|
|
93
|
-
${bindCode}
|
|
94
|
-
const res = await httpController.handleRequest(sandbox.allParams.params);
|
|
95
|
-
sandbox.returnSuccess(res);
|
|
96
|
-
} catch (e) {
|
|
97
|
-
sandbox.returnError(e)
|
|
98
|
-
}
|
|
99
|
-
})(); `;
|
|
100
|
-
|
|
101
|
-
try {
|
|
102
|
-
const script = getCompiledScript(anyApi, code);
|
|
103
|
-
script.runInNewContext(newContext, {
|
|
104
|
-
filename: 'method',
|
|
105
|
-
timeout: anyApi.timeout_ms || 1000 * 60 * 5,
|
|
106
|
-
});
|
|
107
|
-
} catch (e) {
|
|
108
|
-
reject(e);
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
private toBindCodeString(toName: string, newContext: any, fromName: any): string {
|
|
114
|
-
const keys = Object.keys(newContext[fromName]);
|
|
115
|
-
return keys
|
|
116
|
-
.map(key => {
|
|
117
|
-
return `${toName}.${key} = ${fromName}.${key};\n`;
|
|
118
|
-
})
|
|
119
|
-
.join('');
|
|
120
|
-
}
|
|
121
|
-
}
|
|
1
|
+
import { Inject, Provide } from '@midwayjs/core';
|
|
2
|
+
import { Context } from '@midwayjs/koa';
|
|
3
|
+
import * as vm from 'node:vm';
|
|
4
|
+
import { LRUCache } from 'lru-cache';
|
|
5
|
+
import { BaseService } from '../base/BaseService';
|
|
6
|
+
import { CurdMixService } from '../curd/CurdMixService';
|
|
7
|
+
import { ISysAnyApiEntity } from '../../models/SystemEntities';
|
|
8
|
+
import axios from 'axios';
|
|
9
|
+
import * as _ from 'lodash';
|
|
10
|
+
import * as moment from 'moment';
|
|
11
|
+
import * as nodemailer from 'nodemailer';
|
|
12
|
+
|
|
13
|
+
const scriptCacheOptions = {
|
|
14
|
+
max: 500,
|
|
15
|
+
ttl: 1000 * 60 * 5,
|
|
16
|
+
allowStale: false,
|
|
17
|
+
updateAgeOnGet: true,
|
|
18
|
+
updateAgeOnHas: true,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const scriptCache = new LRUCache<string, vm.Script>(scriptCacheOptions);
|
|
22
|
+
|
|
23
|
+
function getCompiledScript(anyApi: ISysAnyApiEntity, code: string): vm.Script {
|
|
24
|
+
const { id, func_code_md5 } = anyApi;
|
|
25
|
+
const cacheKey = id + '_' + func_code_md5;
|
|
26
|
+
const oldScript = scriptCache.get(cacheKey);
|
|
27
|
+
if (oldScript) {
|
|
28
|
+
return oldScript;
|
|
29
|
+
}
|
|
30
|
+
const script = new vm.Script(code);
|
|
31
|
+
scriptCache.set(cacheKey, script);
|
|
32
|
+
return script;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface IRunInSandboxParams {
|
|
36
|
+
body: any;
|
|
37
|
+
query: any;
|
|
38
|
+
headers: any;
|
|
39
|
+
params?: any;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@Provide()
|
|
43
|
+
export class AnyApiSandboxService extends BaseService {
|
|
44
|
+
@Inject()
|
|
45
|
+
protected ctx: Context;
|
|
46
|
+
|
|
47
|
+
@Inject()
|
|
48
|
+
private curdMixService: CurdMixService;
|
|
49
|
+
|
|
50
|
+
public async runInSandbox(anyApi: ISysAnyApiEntity, allParams: IRunInSandboxParams) {
|
|
51
|
+
const { func_code, method } = anyApi;
|
|
52
|
+
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
const logger = this.getPrefixContextLogger(`[AnyApiSandboxService][method=${method}]`);
|
|
55
|
+
// 创建一个沙盒上下文
|
|
56
|
+
const proc = process;
|
|
57
|
+
const newContext = {
|
|
58
|
+
sandbox: {
|
|
59
|
+
allParams,
|
|
60
|
+
logger,
|
|
61
|
+
moment,
|
|
62
|
+
axios,
|
|
63
|
+
nodemailer,
|
|
64
|
+
_,
|
|
65
|
+
userSession: this.ctx.userSession,
|
|
66
|
+
ctx: this.ctx,
|
|
67
|
+
curdMixService: this.curdMixService,
|
|
68
|
+
redisService: this.redisService,
|
|
69
|
+
publicOSSService: this.getPublicOSSService(),
|
|
70
|
+
privateOSSService: this.getPrivateOSSService(),
|
|
71
|
+
returnSuccess: resolve,
|
|
72
|
+
returnError: reject,
|
|
73
|
+
processInfo: {
|
|
74
|
+
version: proc.version,
|
|
75
|
+
versions: proc.versions,
|
|
76
|
+
env: process.env,
|
|
77
|
+
argv: process.argv,
|
|
78
|
+
cwd: process.cwd(),
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
console: logger,
|
|
82
|
+
JSON: JSON,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const nextLine100 = new Array(10).fill('\n').join('');
|
|
86
|
+
const bindCode = this.toBindCodeString('httpController', newContext, 'sandbox');
|
|
87
|
+
const code = `
|
|
88
|
+
(async () => {
|
|
89
|
+
${nextLine100}${func_code}; // 必须有一个 class HttpController { async handleRequest(params){} }
|
|
90
|
+
${nextLine100}
|
|
91
|
+
try {
|
|
92
|
+
const httpController = new HttpController();
|
|
93
|
+
${bindCode}
|
|
94
|
+
const res = await httpController.handleRequest(sandbox.allParams.params);
|
|
95
|
+
sandbox.returnSuccess(res);
|
|
96
|
+
} catch (e) {
|
|
97
|
+
sandbox.returnError(e)
|
|
98
|
+
}
|
|
99
|
+
})(); `;
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
const script = getCompiledScript(anyApi, code);
|
|
103
|
+
script.runInNewContext(newContext, {
|
|
104
|
+
filename: 'method',
|
|
105
|
+
timeout: anyApi.timeout_ms || 1000 * 60 * 5,
|
|
106
|
+
});
|
|
107
|
+
} catch (e) {
|
|
108
|
+
reject(e);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private toBindCodeString(toName: string, newContext: any, fromName: any): string {
|
|
114
|
+
const keys = Object.keys(newContext[fromName]);
|
|
115
|
+
return keys
|
|
116
|
+
.map(key => {
|
|
117
|
+
return `${toName}.${key} = ${fromName}.${key};\n`;
|
|
118
|
+
})
|
|
119
|
+
.join('');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -1,187 +1,186 @@
|
|
|
1
|
-
import { Inject, Provide } from '@midwayjs/core';
|
|
2
|
-
import { Context } from '@midwayjs/koa';
|
|
3
|
-
import { KeysOfSimpleSQL } from '@/libs/crud-pro/models/keys';
|
|
4
|
-
import { SystemTables} from '@/models/SystemTables';
|
|
5
|
-
import { LRUCache } from 'lru-cache';
|
|
6
|
-
import { BizException } from '@/models/devops';
|
|
7
|
-
import { CurdMixService } from '../curd/CurdMixService';
|
|
8
|
-
import { ISysAnyApiEntity } from '@/models/SystemEntities';
|
|
9
|
-
import { AnyApiSandboxService, IRunInSandboxParams } from './AnyApiSandboxService';
|
|
10
|
-
import { parseJsonObject } from '@/libs/utils/functions';
|
|
11
|
-
import * as _ from 'lodash';
|
|
12
|
-
import { MixinUtils } from '@/libs/crud-pro/utils/MixinUtils';
|
|
13
|
-
import { WorkbenchService } from '../WorkbenchService';
|
|
14
|
-
import { validateByCfgString } from '@/libs/crud-pro/utils/ValidateUtils';
|
|
15
|
-
import { API_BASE_TYPE, ApiBaseService } from '../base/ApiBaseService';
|
|
16
|
-
import { GLOBAL_STATIC_CONFIG } from '@/libs/global-config/global-config';
|
|
17
|
-
|
|
18
|
-
const lruCache = new LRUCache<string, any>({
|
|
19
|
-
max: 500,
|
|
20
|
-
ttl: 1000 * 60,
|
|
21
|
-
ttlAutopurge: true,
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
@Provide()
|
|
25
|
-
export class AnyApiService extends ApiBaseService {
|
|
26
|
-
@Inject()
|
|
27
|
-
protected ctx: Context;
|
|
28
|
-
|
|
29
|
-
@Inject()
|
|
30
|
-
private curdMixService: CurdMixService;
|
|
31
|
-
|
|
32
|
-
@Inject()
|
|
33
|
-
private anyApiSandboxService: AnyApiSandboxService;
|
|
34
|
-
|
|
35
|
-
@Inject()
|
|
36
|
-
protected workbenchService: WorkbenchService;
|
|
37
|
-
|
|
38
|
-
async executeAnyApiMethod(methodCode: string, headers: any, body: any, query: any) {
|
|
39
|
-
const anyApi = await this.getAnyApiMethod(methodCode);
|
|
40
|
-
if (!anyApi || anyApi.status !== 1) {
|
|
41
|
-
throw new BizException('接口不存在或已下线:' + methodCode);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const isSupport = await this.workbenchService.isSupportCurrentWorkbench(anyApi.workbench_code_array);
|
|
45
|
-
if (!isSupport) {
|
|
46
|
-
throw new BizException('此接口不支持在当前站点打开:' + methodCode);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
await super.beforeCheckApiAccessibility(API_BASE_TYPE.PROXY_API, anyApi);
|
|
50
|
-
|
|
51
|
-
if (!anyApi.func_code) {
|
|
52
|
-
throw new BizException('没有配置代码:' + methodCode);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (!this.checkFuncCode(anyApi.func_code)) {
|
|
56
|
-
throw new BizException('接口代码校验失败:不满足形式: class HttpController { async handleRequest(params){} }; ');
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const allParams: IRunInSandboxParams = { headers, body, query };
|
|
60
|
-
allParams.params = this.toAnyApiParams(anyApi, allParams); // 组合参数
|
|
61
|
-
|
|
62
|
-
// 执行代码
|
|
63
|
-
const funcRes = await this.executeFunctionCode(anyApi, allParams);
|
|
64
|
-
return funcRes;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
private async getAnyApiMethod(methodCode: string): Promise<ISysAnyApiEntity> {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
{
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
*
|
|
107
|
-
* @param
|
|
108
|
-
* @
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
*
|
|
141
|
-
* @param
|
|
142
|
-
* @
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
let
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
1
|
+
import { Inject, Provide } from '@midwayjs/core';
|
|
2
|
+
import { Context } from '@midwayjs/koa';
|
|
3
|
+
import { KeysOfSimpleSQL } from '@/libs/crud-pro/models/keys';
|
|
4
|
+
import { SystemTables } from '@/models/SystemTables';
|
|
5
|
+
import { LRUCache } from 'lru-cache';
|
|
6
|
+
import { BizException } from '@/models/devops';
|
|
7
|
+
import { CurdMixService } from '../curd/CurdMixService';
|
|
8
|
+
import { ISysAnyApiEntity } from '@/models/SystemEntities';
|
|
9
|
+
import { AnyApiSandboxService, IRunInSandboxParams } from './AnyApiSandboxService';
|
|
10
|
+
import { parseJsonObject } from '@/libs/utils/functions';
|
|
11
|
+
import * as _ from 'lodash';
|
|
12
|
+
import { MixinUtils } from '@/libs/crud-pro/utils/MixinUtils';
|
|
13
|
+
import { WorkbenchService } from '../WorkbenchService';
|
|
14
|
+
import { validateByCfgString } from '@/libs/crud-pro/utils/ValidateUtils';
|
|
15
|
+
import { API_BASE_TYPE, ApiBaseService } from '../base/ApiBaseService';
|
|
16
|
+
import { GLOBAL_STATIC_CONFIG } from '@/libs/global-config/global-config';
|
|
17
|
+
|
|
18
|
+
const lruCache = new LRUCache<string, any>({
|
|
19
|
+
max: 500,
|
|
20
|
+
ttl: 1000 * 60,
|
|
21
|
+
ttlAutopurge: true,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
@Provide()
|
|
25
|
+
export class AnyApiService extends ApiBaseService {
|
|
26
|
+
@Inject()
|
|
27
|
+
protected ctx: Context;
|
|
28
|
+
|
|
29
|
+
@Inject()
|
|
30
|
+
private curdMixService: CurdMixService;
|
|
31
|
+
|
|
32
|
+
@Inject()
|
|
33
|
+
private anyApiSandboxService: AnyApiSandboxService;
|
|
34
|
+
|
|
35
|
+
@Inject()
|
|
36
|
+
protected workbenchService: WorkbenchService;
|
|
37
|
+
|
|
38
|
+
async executeAnyApiMethod(methodCode: string, headers: any, body: any, query: any) {
|
|
39
|
+
const anyApi = await this.getAnyApiMethod(methodCode);
|
|
40
|
+
if (!anyApi || anyApi.status !== 1) {
|
|
41
|
+
throw new BizException('接口不存在或已下线:' + methodCode);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const isSupport = await this.workbenchService.isSupportCurrentWorkbench(anyApi.workbench_code_array);
|
|
45
|
+
if (!isSupport) {
|
|
46
|
+
throw new BizException('此接口不支持在当前站点打开:' + methodCode);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
await super.beforeCheckApiAccessibility(API_BASE_TYPE.PROXY_API, anyApi);
|
|
50
|
+
|
|
51
|
+
if (!anyApi.func_code) {
|
|
52
|
+
throw new BizException('没有配置代码:' + methodCode);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!this.checkFuncCode(anyApi.func_code)) {
|
|
56
|
+
throw new BizException('接口代码校验失败:不满足形式: class HttpController { async handleRequest(params){} }; ');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const allParams: IRunInSandboxParams = { headers, body, query };
|
|
60
|
+
allParams.params = this.toAnyApiParams(anyApi, allParams); // 组合参数
|
|
61
|
+
|
|
62
|
+
// 执行代码
|
|
63
|
+
const funcRes = await this.executeFunctionCode(anyApi, allParams);
|
|
64
|
+
return funcRes;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private async getAnyApiMethod(methodCode: string): Promise<ISysAnyApiEntity> {
|
|
68
|
+
// 开发环境,不使用缓存
|
|
69
|
+
if (this.isEnableDebug()) {
|
|
70
|
+
return this._getAnyApiMethod(methodCode);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 线上环境可以使用缓存
|
|
74
|
+
let anyApi = lruCache.get(methodCode);
|
|
75
|
+
if (!anyApi) {
|
|
76
|
+
anyApi = await this._getAnyApiMethod(methodCode);
|
|
77
|
+
lruCache.set(methodCode, anyApi);
|
|
78
|
+
}
|
|
79
|
+
return anyApi;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private async _getAnyApiMethod(methodCode: string): Promise<ISysAnyApiEntity> {
|
|
83
|
+
const { SystemDbName, SystemDbType } = GLOBAL_STATIC_CONFIG.getConfig();
|
|
84
|
+
|
|
85
|
+
const res = await this.curdMixService.executeCrudByCfg(
|
|
86
|
+
{ condition: { method: methodCode } },
|
|
87
|
+
{
|
|
88
|
+
sqlTable: SystemTables.sys_anyapi,
|
|
89
|
+
method: `get_sys_anyapi_${methodCode}`,
|
|
90
|
+
sqlSimpleName: KeysOfSimpleSQL.SIMPLE_QUERY_ONE,
|
|
91
|
+
sqlDatabase: SystemDbName,
|
|
92
|
+
sqlDbType: SystemDbType,
|
|
93
|
+
updateCfg: {},
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
const obj: ISysAnyApiEntity = res.getOneObj();
|
|
97
|
+
if (!obj) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
obj.parsedOthers = parseJsonObject(obj.others);
|
|
101
|
+
return obj;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* 构造参数
|
|
106
|
+
* @param anyApi
|
|
107
|
+
* @param allParams
|
|
108
|
+
* @private
|
|
109
|
+
*/
|
|
110
|
+
private toAnyApiParams(anyApi: ISysAnyApiEntity, allParams: IRunInSandboxParams): any {
|
|
111
|
+
if (!anyApi.req_params) {
|
|
112
|
+
return {};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const configs = anyApi.parsedOthers?.req_params || [];
|
|
116
|
+
const params = {};
|
|
117
|
+
for (let i = 0; i < configs.length; i++) {
|
|
118
|
+
const { name, fromType, fromKey, validate_required, validate_cfg_list, valueType, defaultValue } = configs[i];
|
|
119
|
+
const value = _.get(allParams, [fromType, fromKey], defaultValue);
|
|
120
|
+
if (validate_required && MixinUtils.isEmpty(value)) {
|
|
121
|
+
throw new BizException(`参数校验失败:${name} 不能为空`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 参数校验
|
|
125
|
+
if (Array.isArray(validate_cfg_list)) {
|
|
126
|
+
for (let j = 0; j < validate_cfg_list.length; j++) {
|
|
127
|
+
const validateCfg = validate_cfg_list[j];
|
|
128
|
+
validateByCfgString(validateCfg, value, name);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 格式转换
|
|
133
|
+
params[name] = MixinUtils.parseValueByType(value, valueType);
|
|
134
|
+
}
|
|
135
|
+
return params;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* 运行代码
|
|
140
|
+
* @param anyApiEntity
|
|
141
|
+
* @param allParams
|
|
142
|
+
* @private
|
|
143
|
+
*/
|
|
144
|
+
private async executeFunctionCode(anyApiEntity: ISysAnyApiEntity, allParams: IRunInSandboxParams): Promise<any> {
|
|
145
|
+
return this.anyApiSandboxService.runInSandbox(anyApiEntity, allParams);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private checkFuncCode(func_code: string): boolean {
|
|
149
|
+
if (!func_code) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const lineHasKey = (lineTrim: string, target: string): boolean => {
|
|
154
|
+
const words = lineTrim.split(/[\s{}();]/);
|
|
155
|
+
for (let i = 0; i < words.length; i++) {
|
|
156
|
+
const word = words[i];
|
|
157
|
+
if (word && word === target) {
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return false;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
let hasClass = false;
|
|
165
|
+
let hasMethod = false;
|
|
166
|
+
const lines = func_code.split('\n');
|
|
167
|
+
for (let i = 0; i < lines.length; i++) {
|
|
168
|
+
const line = lines[i];
|
|
169
|
+
if (line) {
|
|
170
|
+
const lineTrim = line.trim();
|
|
171
|
+
if (lineTrim) {
|
|
172
|
+
if (lineHasKey(lineTrim, 'class') && lineHasKey(lineTrim, 'HttpController')) {
|
|
173
|
+
hasClass = true;
|
|
174
|
+
}
|
|
175
|
+
if (lineHasKey(lineTrim, 'async') && lineHasKey(lineTrim, 'handleRequest')) {
|
|
176
|
+
hasMethod = true;
|
|
177
|
+
}
|
|
178
|
+
if (lineTrim.startsWith('handleRequest')) {
|
|
179
|
+
hasMethod = true;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return hasMethod && hasClass;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
@@ -59,7 +59,7 @@ class AsyncTaskRunner {
|
|
|
59
59
|
completed_at: getCurrentFullMoment(),
|
|
60
60
|
});
|
|
61
61
|
} catch (error) {
|
|
62
|
-
ANONYMOUS_CONTEXT.getApp().getCoreLogger().error('executeTaskList error', error);
|
|
62
|
+
ANONYMOUS_CONTEXT.getApp().getCoreLogger().error('[AsyncTaskRunner] executeTaskList error', error);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -205,7 +205,7 @@ export class AsyncTaskRunnerService extends BaseService implements IScheduleServ
|
|
|
205
205
|
|
|
206
206
|
// 开始执行。
|
|
207
207
|
ASYNC_TASK_RUNNER.executeTaskList(taskList).then(() => {
|
|
208
|
-
console.log('ASYNC_TASK_RUNNER finished taskIds ==> ' + JSON.stringify(taskIds));
|
|
208
|
+
console.log('[AsyncTaskRunnerService] ASYNC_TASK_RUNNER finished taskIds ==> ' + JSON.stringify(taskIds));
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
211
|
|
|
@@ -231,7 +231,7 @@ export class AsyncTaskRunnerService extends BaseService implements IScheduleServ
|
|
|
231
231
|
try {
|
|
232
232
|
await this.fetchPendingTasks();
|
|
233
233
|
} catch (e) {
|
|
234
|
-
console.error('fetchPendingTasks error', errorToString(e));
|
|
234
|
+
console.error('[AsyncTaskRunnerService] fetchPendingTasks error', errorToString(e));
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
await this.redisService.del(ASYNC_TASK_LOCK);
|