midway-fatcms 0.0.1-beta.42 → 0.0.1-beta.45
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/configuration.js +2 -2
- package/dist/controller/manage/CrudStandardDesignApi.d.ts +8 -0
- package/dist/controller/manage/CrudStandardDesignApi.js +54 -9
- package/dist/controller/manage/UserAccountManageApi.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/libs/global-config/global-config.d.ts +13 -2
- package/dist/libs/global-config/global-config.js +2 -1
- package/dist/libs/utils/parseCreateSql.d.ts +6 -1
- package/dist/libs/utils/parseCreateSql.js +2 -1
- package/dist/middleware/forbidden.middleware.js +2 -2
- package/dist/middleware/rediscache.middleware.d.ts +3 -0
- package/dist/middleware/rediscache.middleware.js +77 -0
- package/dist/middleware/redislock.middleware.d.ts +7 -0
- package/dist/middleware/redislock.middleware.js +72 -0
- package/dist/models/RedisKeys.d.ts +1 -0
- package/dist/models/RedisKeys.js +1 -0
- package/dist/models/bizmodels.d.ts +1 -0
- package/dist/models/userSession.d.ts +1 -0
- package/dist/service/UserSessionService.d.ts +2 -1
- package/dist/service/UserSessionService.js +2 -1
- package/dist/service/crudstd/CrudStdService.js +5 -2
- package/dist/service/curd/CurdMixService.d.ts +3 -2
- package/dist/service/curd/CurdProService.js +2 -0
- package/package.json +1 -1
package/dist/configuration.js
CHANGED
|
@@ -20,7 +20,7 @@ const view = require("@midwayjs/view-ejs");
|
|
|
20
20
|
const redis = require("@midwayjs/redis");
|
|
21
21
|
const crossDomain = require("@midwayjs/cross-domain");
|
|
22
22
|
const _ = require("lodash");
|
|
23
|
-
const
|
|
23
|
+
const node_path_1 = require("node:path");
|
|
24
24
|
// import { DefaultErrorFilter } from './filter/default.filter';
|
|
25
25
|
// import { NotFoundFilter } from './filter/notfound.filter';
|
|
26
26
|
const global_middleware_1 = require("./middleware/global.middleware");
|
|
@@ -107,7 +107,7 @@ ContainerLifeCycle = __decorate([
|
|
|
107
107
|
component: info,
|
|
108
108
|
},
|
|
109
109
|
],
|
|
110
|
-
importConfigs: [(0,
|
|
110
|
+
importConfigs: [(0, node_path_1.join)(__dirname, './config')],
|
|
111
111
|
})
|
|
112
112
|
], ContainerLifeCycle);
|
|
113
113
|
exports.ContainerLifeCycle = ContainerLifeCycle;
|
|
@@ -35,4 +35,12 @@ export declare class CrudStandardDesignApi extends BaseApiController {
|
|
|
35
35
|
private getTableListOfPostgreSQL;
|
|
36
36
|
private getTableFieldsOfSqlServer;
|
|
37
37
|
private getTableFieldsOfPostgreSQL;
|
|
38
|
+
/**
|
|
39
|
+
* 获取PostgreSQL建表语句的注释
|
|
40
|
+
* @param dbName
|
|
41
|
+
* @param schemaname
|
|
42
|
+
* @param tableName
|
|
43
|
+
* @returns
|
|
44
|
+
*/
|
|
45
|
+
private getTableFieldsCommentsMapOfPostgreSQL;
|
|
38
46
|
}
|
|
@@ -254,14 +254,14 @@ let CrudStandardDesignApi = class CrudStandardDesignApi extends BaseApiControlle
|
|
|
254
254
|
throw new exceptions_1.CommonException('DB_NOT_FOUND', '数据库配置没有找到:' + dbName);
|
|
255
255
|
}
|
|
256
256
|
const schemaname = 'public';
|
|
257
|
-
const columnArraySql = `
|
|
258
|
-
|
|
259
|
-
SELECT
|
|
260
|
-
*
|
|
261
|
-
FROM information_schema.columns
|
|
262
|
-
WHERE table_schema = $1 and table_name = $2
|
|
263
|
-
ORDER BY ordinal_position;
|
|
264
|
-
|
|
257
|
+
const columnArraySql = `
|
|
258
|
+
|
|
259
|
+
SELECT
|
|
260
|
+
*
|
|
261
|
+
FROM information_schema.columns
|
|
262
|
+
WHERE table_schema = $1 and table_name = $2
|
|
263
|
+
ORDER BY ordinal_position;
|
|
264
|
+
|
|
265
265
|
`.trim();
|
|
266
266
|
const dbType = keys_1.SqlDbType.postgres;
|
|
267
267
|
const columnArray = await this.curdMixService.executeSQL({
|
|
@@ -271,11 +271,12 @@ let CrudStandardDesignApi = class CrudStandardDesignApi extends BaseApiControlle
|
|
|
271
271
|
crudType: keys_1.KeyOfCrudTypes.SYS_QUERY,
|
|
272
272
|
executeSqlArgs: [schemaname, tableName],
|
|
273
273
|
});
|
|
274
|
+
const commentMap = await this.getTableFieldsCommentsMapOfPostgreSQL(dbName, schemaname, tableName);
|
|
274
275
|
const fields = columnArray.map(columnObj => {
|
|
275
276
|
const { column_name, is_nullable, column_default, data_type, is_identity, ...others } = columnObj;
|
|
276
277
|
return {
|
|
277
278
|
fieldIndex: column_name || '',
|
|
278
|
-
fieldTitle: column_name || '',
|
|
279
|
+
fieldTitle: commentMap[column_name] || column_name || '',
|
|
279
280
|
isNullable: is_nullable,
|
|
280
281
|
defaultValue: column_default || '',
|
|
281
282
|
extra: others,
|
|
@@ -293,6 +294,50 @@ let CrudStandardDesignApi = class CrudStandardDesignApi extends BaseApiControlle
|
|
|
293
294
|
},
|
|
294
295
|
};
|
|
295
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* 获取PostgreSQL建表语句的注释
|
|
299
|
+
* @param dbName
|
|
300
|
+
* @param schemaname
|
|
301
|
+
* @param tableName
|
|
302
|
+
* @returns
|
|
303
|
+
*/
|
|
304
|
+
async getTableFieldsCommentsMapOfPostgreSQL(dbName, schemaname, tableName) {
|
|
305
|
+
const commentArraySql = `
|
|
306
|
+
SELECT
|
|
307
|
+
n.nspname AS schema_name,
|
|
308
|
+
c.relname AS table_name,
|
|
309
|
+
a.attname AS column_name,
|
|
310
|
+
d.description AS column_comment
|
|
311
|
+
FROM
|
|
312
|
+
pg_class c
|
|
313
|
+
JOIN
|
|
314
|
+
pg_namespace n ON c.relnamespace = n.oid
|
|
315
|
+
JOIN
|
|
316
|
+
pg_attribute a ON c.oid = a.attrelid
|
|
317
|
+
LEFT JOIN
|
|
318
|
+
pg_description d ON c.oid = d.objoid AND a.attnum = d.objsubid
|
|
319
|
+
WHERE
|
|
320
|
+
n.nspname = $1
|
|
321
|
+
AND c.relname = $2
|
|
322
|
+
AND a.attnum > 0
|
|
323
|
+
ORDER BY
|
|
324
|
+
a.attnum
|
|
325
|
+
`;
|
|
326
|
+
const dbType = keys_1.SqlDbType.postgres;
|
|
327
|
+
const commentArray = await this.curdMixService.executeSQL({
|
|
328
|
+
executeSql: commentArraySql,
|
|
329
|
+
sqlDatabase: dbName,
|
|
330
|
+
sqlDbType: dbType,
|
|
331
|
+
crudType: keys_1.KeyOfCrudTypes.SYS_QUERY,
|
|
332
|
+
executeSqlArgs: [schemaname, tableName],
|
|
333
|
+
});
|
|
334
|
+
const map = {};
|
|
335
|
+
commentArray.forEach(commentObj => {
|
|
336
|
+
const { column_name, column_comment } = commentObj;
|
|
337
|
+
map[column_name] = (0, parseCreateSql_1.parseTableFieldTitleFromComment)(column_comment);
|
|
338
|
+
});
|
|
339
|
+
return map;
|
|
340
|
+
}
|
|
296
341
|
};
|
|
297
342
|
__decorate([
|
|
298
343
|
(0, core_1.Config)('mysql2'),
|
|
@@ -28,7 +28,7 @@ function checkAccountCreateBlacklist(value) {
|
|
|
28
28
|
throw new exceptions_1.CommonException(exceptions_1.Exceptions.VALIDATE_EXCEPTION, '用户名或昵称不能使用具有管理员歧义的词语');
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
const LOGIN_NAME_VALIDATE = [keys_1.KeysOfValidators.STRING, keys_1.KeysOfValidators.NAME, 'length:
|
|
31
|
+
const LOGIN_NAME_VALIDATE = [keys_1.KeysOfValidators.STRING, keys_1.KeysOfValidators.NAME, 'length:5,50', checkAccountCreateBlacklist];
|
|
32
32
|
let UserAccountManageApi = class UserAccountManageApi extends BaseApiController_1.BaseApiController {
|
|
33
33
|
async getUserAccountList() {
|
|
34
34
|
return this.executeSysSimpleSQL(SystemTables_1.SystemTables.sys_user_account, keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_PAGE, {
|
package/dist/index.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export * from './middleware/forbidden.middleware';
|
|
|
41
41
|
export * from './middleware/global.middleware';
|
|
42
42
|
export * from './middleware/tx.middleware';
|
|
43
43
|
export * from './middleware/permission.middleware';
|
|
44
|
+
export * from './middleware/redislock.middleware';
|
|
44
45
|
export * from './service/AuthService';
|
|
45
46
|
export * from './service/EnumInfoService';
|
|
46
47
|
export * from './service/FileCenterService';
|
package/dist/index.js
CHANGED
|
@@ -59,6 +59,7 @@ __exportStar(require("./middleware/forbidden.middleware"), exports);
|
|
|
59
59
|
__exportStar(require("./middleware/global.middleware"), exports);
|
|
60
60
|
__exportStar(require("./middleware/tx.middleware"), exports);
|
|
61
61
|
__exportStar(require("./middleware/permission.middleware"), exports);
|
|
62
|
+
__exportStar(require("./middleware/redislock.middleware"), exports);
|
|
62
63
|
__exportStar(require("./service/AuthService"), exports);
|
|
63
64
|
__exportStar(require("./service/EnumInfoService"), exports);
|
|
64
65
|
__exportStar(require("./service/FileCenterService"), exports);
|
|
@@ -1,13 +1,24 @@
|
|
|
1
|
+
import { IRequestCfgModel, IRequestModel } from '../crud-pro/interfaces';
|
|
2
|
+
import { ExecuteContext } from '../crud-pro/models/ExecuteContext';
|
|
1
3
|
import { SqlDbType } from '../crud-pro/models/keys';
|
|
4
|
+
import { Context } from '@midwayjs/koa';
|
|
2
5
|
interface IGlobalStaticConfig {
|
|
3
6
|
/**
|
|
4
|
-
* CrudStd:
|
|
7
|
+
* CrudStd: 业务系统自定义的修改:查询前的查询条件:cfgModel
|
|
5
8
|
* @param reqJson
|
|
6
9
|
* @param cfgModel
|
|
7
10
|
* @param appInfo
|
|
8
11
|
* @param ctx
|
|
9
12
|
*/
|
|
10
|
-
bizUpdateCfgModelForCrudStd(reqJson:
|
|
13
|
+
bizUpdateCfgModelForCrudStd(reqJson: IRequestModel, cfgModel: IRequestCfgModel, appInfo: any, ctx: Context): Promise<any>;
|
|
14
|
+
/**
|
|
15
|
+
* CrudStd: 业务系统自定义的修改:查询后的返回值。
|
|
16
|
+
* @param reqJson
|
|
17
|
+
* @param cfgModel
|
|
18
|
+
* @param appInfo
|
|
19
|
+
* @param ctx
|
|
20
|
+
*/
|
|
21
|
+
bizUpdateExecuteContextForCrudStd(reqJson: IRequestModel, cfgModel: IRequestCfgModel, appInfo: any, ctx: Context, executeContext: ExecuteContext): Promise<any>;
|
|
11
22
|
/**
|
|
12
23
|
* CrudMtd: 业务系统自定义的修改cfgModel
|
|
13
24
|
* @param reqJson
|
|
@@ -9,6 +9,7 @@ class GlobalStaticConfig {
|
|
|
9
9
|
constructor() {
|
|
10
10
|
this.configObject = {
|
|
11
11
|
bizUpdateCfgModelForCrudStd: noop,
|
|
12
|
+
bizUpdateExecuteContextForCrudStd: noop,
|
|
12
13
|
bizUpdateCfgModelForCrudMtd: noop,
|
|
13
14
|
bizUpdateCfgModelForCrudPro: noop,
|
|
14
15
|
generateUserAccountId: null,
|
|
@@ -17,7 +18,7 @@ class GlobalStaticConfig {
|
|
|
17
18
|
},
|
|
18
19
|
SystemDbName: 'fatcms',
|
|
19
20
|
SystemDbType: keys_1.SqlDbType.mysql,
|
|
20
|
-
maxPageSizeOfExportExcel: 1000
|
|
21
|
+
maxPageSizeOfExportExcel: 1000,
|
|
21
22
|
};
|
|
22
23
|
}
|
|
23
24
|
getConfig() {
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 移除引号
|
|
3
|
+
* @param s
|
|
4
|
+
*/
|
|
5
|
+
declare function parseTableFieldTitleFromComment(s: string): string;
|
|
1
6
|
declare function parseCreateSqlToTitleMap(createSqlStr: string): {
|
|
2
7
|
tableTitle: string;
|
|
3
8
|
fieldsTitleMap: {};
|
|
4
9
|
};
|
|
5
|
-
export { parseCreateSqlToTitleMap };
|
|
10
|
+
export { parseCreateSqlToTitleMap, parseTableFieldTitleFromComment };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseCreateSqlToTitleMap = void 0;
|
|
3
|
+
exports.parseTableFieldTitleFromComment = exports.parseCreateSqlToTitleMap = void 0;
|
|
4
4
|
function isChineseChar(char) {
|
|
5
5
|
const reg = /[\u4e00-\u9fff]/;
|
|
6
6
|
return reg.test(char);
|
|
@@ -34,6 +34,7 @@ function parseTableFieldTitleFromComment(s) {
|
|
|
34
34
|
}
|
|
35
35
|
return arr.join('');
|
|
36
36
|
}
|
|
37
|
+
exports.parseTableFieldTitleFromComment = parseTableFieldTitleFromComment;
|
|
37
38
|
/**
|
|
38
39
|
* 从最后一行中提取表格的标题
|
|
39
40
|
* @param arr
|
|
@@ -20,7 +20,7 @@ let ForbiddenMiddleware = class ForbiddenMiddleware {
|
|
|
20
20
|
if (path === '/') {
|
|
21
21
|
return false;
|
|
22
22
|
}
|
|
23
|
-
if (path.startsWith('/ns/')) {
|
|
23
|
+
if (path.startsWith('/ns/') || path.startsWith('/pages/')) {
|
|
24
24
|
return false;
|
|
25
25
|
}
|
|
26
26
|
for (let i = 0; i < blackEqualList.length; i++) {
|
|
@@ -35,7 +35,7 @@ let ForbiddenMiddleware = class ForbiddenMiddleware {
|
|
|
35
35
|
return true;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
return !!(path.includes('/wp-includes/') || path.endsWith('.php') || path.endsWith('/.git/config'));
|
|
38
|
+
return !!(path.includes('/wp-includes/') || path.includes('/wp-admin/') || path.includes('/wp-content/') || path.endsWith('.php') || path.endsWith('/.git/config'));
|
|
39
39
|
}
|
|
40
40
|
resolve() {
|
|
41
41
|
return async (ctx, next) => {
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.redisCache = void 0;
|
|
4
|
+
const redis_1 = require("@midwayjs/redis");
|
|
5
|
+
const _ = require("lodash");
|
|
6
|
+
const md5 = require("md5");
|
|
7
|
+
const RedisKeys_1 = require("../models/RedisKeys");
|
|
8
|
+
const exceptions_1 = require("../libs/crud-pro/exceptions");
|
|
9
|
+
const getRedisService = async (ctx) => {
|
|
10
|
+
const service = await ctx.requestContext.getAsync(redis_1.RedisService);
|
|
11
|
+
if (!service) {
|
|
12
|
+
return await ctx.requestContext.getAsync('redisService');
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const createError = () => {
|
|
16
|
+
return new exceptions_1.CommonException('redis_cache_middleware_error_config', 'redisCache中间件的第一个参数必须是一个字符串数组, 并且以“query.”或“body.”开头');
|
|
17
|
+
};
|
|
18
|
+
const checkCacheKeyConfigList = (cacheKeyConfigList) => {
|
|
19
|
+
if (!Array.isArray(cacheKeyConfigList)) {
|
|
20
|
+
throw createError();
|
|
21
|
+
}
|
|
22
|
+
for (let i = 0; i < cacheKeyConfigList.length; i++) {
|
|
23
|
+
const cacheKeyConfig = cacheKeyConfigList[i];
|
|
24
|
+
if (typeof cacheKeyConfig !== 'string') {
|
|
25
|
+
throw createError();
|
|
26
|
+
}
|
|
27
|
+
if (!cacheKeyConfig.startsWith('query.') && !cacheKeyConfig.startsWith('body.')) {
|
|
28
|
+
throw createError();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
// {middleware:[redisCache(['query.id', 'body.id'])]}
|
|
33
|
+
const toCacheKey = (ctx, cacheKeyConfigList) => {
|
|
34
|
+
checkCacheKeyConfigList(cacheKeyConfigList);
|
|
35
|
+
const path = ctx.path;
|
|
36
|
+
const query = ctx.query || {};
|
|
37
|
+
const body = ctx.request.body || {};
|
|
38
|
+
const newCtx = { path, query, body };
|
|
39
|
+
// 至少要根据path缓存
|
|
40
|
+
const cacheKeyConfigList2 = ['path', ...cacheKeyConfigList];
|
|
41
|
+
const strArray = cacheKeyConfigList2.map((key) => {
|
|
42
|
+
const value = _.get(newCtx, key);
|
|
43
|
+
return { key, value };
|
|
44
|
+
});
|
|
45
|
+
const strArrayStr = JSON.stringify(strArray);
|
|
46
|
+
const strMd5 = md5(strArrayStr);
|
|
47
|
+
return RedisKeys_1.RedisKeys.REDIS_LOCK_MIDDILEWARE + strMd5;
|
|
48
|
+
};
|
|
49
|
+
function toCacheDataString(resData) {
|
|
50
|
+
throw new Error('Function not implemented.');
|
|
51
|
+
}
|
|
52
|
+
function parseCacheData(cacheData) {
|
|
53
|
+
throw new Error('Function not implemented.');
|
|
54
|
+
}
|
|
55
|
+
function redisCache(cacheKeyConfigList, cacheTimeSecond) {
|
|
56
|
+
return async (ctx, next) => {
|
|
57
|
+
const redisService = await getRedisService(ctx);
|
|
58
|
+
const cacheKey = toCacheKey(ctx, cacheKeyConfigList);
|
|
59
|
+
let cacheTime = typeof cacheTimeSecond === 'number' ? cacheTimeSecond : 60; // 默认缓存1分钟
|
|
60
|
+
cacheTime = Math.max(cacheTimeSecond, 1); // 至少缓存1秒。
|
|
61
|
+
cacheTime = Math.min(cacheTimeSecond, 60 * 60); // 最长缓存1小时
|
|
62
|
+
const cacheData = await redisService.get(cacheKey);
|
|
63
|
+
if (cacheData) {
|
|
64
|
+
return parseCacheData(cacheData);
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const resData = await next();
|
|
68
|
+
const resDataStr = toCacheDataString(resData);
|
|
69
|
+
await redisService.set(cacheKey, resDataStr, 'EX', cacheTime);
|
|
70
|
+
return resData;
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
console.error('redisCache', e);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
exports.redisCache = redisCache;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { NextFunction, Context } from '@midwayjs/koa';
|
|
2
|
+
declare function redisLock(lockKeyConfigList: string[], lockTimeSecond: number): (ctx: Context, next: NextFunction) => Promise<{
|
|
3
|
+
success: boolean;
|
|
4
|
+
message: string;
|
|
5
|
+
code: string;
|
|
6
|
+
}>;
|
|
7
|
+
export { redisLock };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.redisLock = void 0;
|
|
4
|
+
const redis_1 = require("@midwayjs/redis");
|
|
5
|
+
const _ = require("lodash");
|
|
6
|
+
const md5 = require("md5");
|
|
7
|
+
const RedisKeys_1 = require("../models/RedisKeys");
|
|
8
|
+
const exceptions_1 = require("../libs/crud-pro/exceptions");
|
|
9
|
+
const getRedisService = async (ctx) => {
|
|
10
|
+
const service = await ctx.requestContext.getAsync(redis_1.RedisService);
|
|
11
|
+
if (!service) {
|
|
12
|
+
return await ctx.requestContext.getAsync('redisService');
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const createError = () => {
|
|
16
|
+
return new exceptions_1.CommonException('redis_lock_middleware_error_config', 'redisLock中间件的第一个参数必须是一个字符串数组, 并且以“query.”或“body.”开头');
|
|
17
|
+
};
|
|
18
|
+
const checkLockKeyConfigList = (lockKeyConfigList) => {
|
|
19
|
+
if (!Array.isArray(lockKeyConfigList)) {
|
|
20
|
+
throw createError();
|
|
21
|
+
}
|
|
22
|
+
for (let i = 0; i < lockKeyConfigList.length; i++) {
|
|
23
|
+
const lockKeyConfig = lockKeyConfigList[i];
|
|
24
|
+
if (typeof lockKeyConfig !== 'string') {
|
|
25
|
+
throw createError();
|
|
26
|
+
}
|
|
27
|
+
if (!lockKeyConfig.startsWith('query.') && !lockKeyConfig.startsWith('body.')) {
|
|
28
|
+
throw createError();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
// {middleware:[redisLock(['query.id', 'body.id'])]}
|
|
33
|
+
const toLockKey = (ctx, lockKeyConfigList) => {
|
|
34
|
+
checkLockKeyConfigList(lockKeyConfigList);
|
|
35
|
+
const path = ctx.path;
|
|
36
|
+
const query = ctx.query || {};
|
|
37
|
+
const body = ctx.request.body || {};
|
|
38
|
+
const newCtx = { path, query, body };
|
|
39
|
+
// 至少要根据path锁
|
|
40
|
+
const lockKeyConfigList2 = ['path', ...lockKeyConfigList];
|
|
41
|
+
const strArray = lockKeyConfigList2.map((key) => {
|
|
42
|
+
const value = _.get(newCtx, key);
|
|
43
|
+
return { key, value };
|
|
44
|
+
});
|
|
45
|
+
const strArrayStr = JSON.stringify(strArray);
|
|
46
|
+
const strMd5 = md5(strArrayStr);
|
|
47
|
+
return RedisKeys_1.RedisKeys.REDIS_LOCK_MIDDILEWARE + strMd5;
|
|
48
|
+
};
|
|
49
|
+
function redisLock(lockKeyConfigList, lockTimeSecond) {
|
|
50
|
+
return async (ctx, next) => {
|
|
51
|
+
const redisService = await getRedisService(ctx);
|
|
52
|
+
const lockKey = toLockKey(ctx, lockKeyConfigList);
|
|
53
|
+
let lockTime = typeof lockTimeSecond === 'number' ? lockTimeSecond : 60; // 默认锁住1分钟(失败的情况)
|
|
54
|
+
lockTime = Math.max(lockTimeSecond, 1); // 至少锁一秒 (失败的情况)
|
|
55
|
+
lockTime = Math.min(lockTimeSecond, 5 * 60); // 最长锁 5分钟(失败的情况)
|
|
56
|
+
const lock = await redisService.set(lockKey, 1, 'EX', lockTime, 'NX');
|
|
57
|
+
if (lock !== 'OK') {
|
|
58
|
+
return {
|
|
59
|
+
success: false,
|
|
60
|
+
message: '您请求的接口当前正在处理中,请稍后再试',
|
|
61
|
+
code: 'redis_lock_middleware_error_locked',
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
await next();
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
await redisService.del(lockKey); // 正常运行完成,立即释放锁。
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
exports.redisLock = redisLock;
|
package/dist/models/RedisKeys.js
CHANGED
|
@@ -69,9 +69,12 @@ let CrudStdService = class CrudStdService extends ApiBaseService_1.ApiBaseServic
|
|
|
69
69
|
await this.crudStdRelationService.addCfgModelColumnsRelation(cfgModel, appInfo);
|
|
70
70
|
// 根据表结构的数据类型,修正数据类型
|
|
71
71
|
await this.fixDataFieldTypeBySqlTableField(params, cfgModel, appInfo, { dbType, dbName });
|
|
72
|
-
//
|
|
72
|
+
// 业务系统自定义的修改:查询前的查询条件:cfgModel
|
|
73
73
|
await global_config_1.GLOBAL_STATIC_CONFIG.getConfig().bizUpdateCfgModelForCrudStd(params, cfgModel, appInfo, this.ctx);
|
|
74
|
-
|
|
74
|
+
const crudExeCtx = await this.curdMixService.executeCrudByCfg(params, cfgModel);
|
|
75
|
+
// 业务系统自定义的修改:查询后的返回值。
|
|
76
|
+
await global_config_1.GLOBAL_STATIC_CONFIG.getConfig().bizUpdateExecuteContextForCrudStd(params, cfgModel, appInfo, this.ctx, crudExeCtx);
|
|
77
|
+
return crudExeCtx;
|
|
75
78
|
}
|
|
76
79
|
/**
|
|
77
80
|
* 获取appInfo 并且拿到当前settingKey相关的信息
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ColumnRelation, IRequestCfgModel, IRequestModel, ISqlCfgModel } from '../../libs/crud-pro/interfaces';
|
|
2
2
|
import { IRequestCfgModel2 } from '../../models/bizmodels';
|
|
3
3
|
import { SqlDbType } from '../../libs/crud-pro/models/keys';
|
|
4
|
+
import { ExecuteContext } from '../../libs/crud-pro/models/ExecuteContext';
|
|
4
5
|
export interface ILinkColumnRelationParam {
|
|
5
6
|
columnsRelations: ColumnRelation[];
|
|
6
7
|
}
|
|
@@ -12,10 +13,10 @@ export declare class CurdMixService {
|
|
|
12
13
|
private curdMixByWorkbenchService;
|
|
13
14
|
private curdMixByLinkToCustomService;
|
|
14
15
|
private prepare;
|
|
15
|
-
executeCrudByCfg(reqJson: IRequestModel, cfgModel: IRequestCfgModel2): Promise<
|
|
16
|
+
executeCrudByCfg(reqJson: IRequestModel, cfgModel: IRequestCfgModel2): Promise<ExecuteContext>;
|
|
16
17
|
getBbUtil(sqlDatabase: string, sqlDbType: SqlDbType, sqlTable?: string): import("./CrudProQuick").CrudProQuick;
|
|
17
18
|
executeSQL(sqlCfgModel: ISqlCfgModel): Promise<any>;
|
|
18
|
-
executeCrud(reqJson: IRequestModel): Promise<
|
|
19
|
+
executeCrud(reqJson: IRequestModel): Promise<ExecuteContext>;
|
|
19
20
|
getCachedCfgByMethod(method: string): Promise<IRequestCfgModel>;
|
|
20
21
|
/**
|
|
21
22
|
* 根据配置的关联关系,直接关联数据
|
|
@@ -37,6 +37,7 @@ function toVisitor(ctx) {
|
|
|
37
37
|
roleCodes: [],
|
|
38
38
|
functionCodes: [],
|
|
39
39
|
workbenchCode: (workbenchInfo === null || workbenchInfo === void 0 ? void 0 : workbenchInfo.workbench_code) || '',
|
|
40
|
+
bizExt: {}
|
|
40
41
|
};
|
|
41
42
|
}
|
|
42
43
|
const sessionInfo = userSession.getSessionInfo();
|
|
@@ -50,6 +51,7 @@ function toVisitor(ctx) {
|
|
|
50
51
|
roleCodes: sessionInfo.roleCodes || [],
|
|
51
52
|
functionCodes: sessionInfo.functionCodes || [],
|
|
52
53
|
workbenchCode: (workbenchInfo === null || workbenchInfo === void 0 ? void 0 : workbenchInfo.workbench_code) || '',
|
|
54
|
+
bizExt: sessionInfo.bizExt || {}
|
|
53
55
|
};
|
|
54
56
|
}
|
|
55
57
|
class MyContextFunc extends ExecuteContextFunc_1.BaseExecuteContextFunc {
|