midway-fatcms 0.0.1-beta.17 → 0.0.1-beta.19

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.
Files changed (131) hide show
  1. package/.eslintrc.json +3 -1
  2. package/dist/configuration.js +18 -7
  3. package/dist/controller/gateway/AsyncTaskController.js +3 -3
  4. package/dist/controller/gateway/DocGatewayController.js +1 -1
  5. package/dist/controller/gateway/PublicApiController.js +4 -6
  6. package/dist/controller/gateway/StaticController.js +25 -22
  7. package/dist/controller/helpers.controller.d.ts +1 -1
  8. package/dist/controller/manage/CrudStandardDesignApi.d.ts +1 -1
  9. package/dist/controller/manage/CrudStandardDesignApi.js +4 -16
  10. package/dist/controller/manage/DataDictManageApi.d.ts +1 -1
  11. package/dist/controller/manage/DeployManageApi.d.ts +1 -1
  12. package/dist/controller/manage/DeployManageApi.js +32 -30
  13. package/dist/controller/manage/MenuManageApi.js +1 -1
  14. package/dist/controller/manage/SuperAdminManageApi.d.ts +2 -2
  15. package/dist/controller/manage/SysConfigMangeApi.d.ts +1 -1
  16. package/dist/controller/manage/SysConfigMangeApi.js +3 -3
  17. package/dist/controller/manage/SystemInfoManageApi.d.ts +1 -1
  18. package/dist/controller/manage/SystemInfoManageApi.js +7 -1
  19. package/dist/controller/manage/UserAccountManageApi.d.ts +1 -1
  20. package/dist/controller/manage/WorkbenchMangeApi.js +1 -1
  21. package/dist/controller/myinfo/AuthController.js +1 -1
  22. package/dist/controller/render/AppRenderController.js +6 -2
  23. package/dist/controller/test.controller.d.ts +1 -1
  24. package/dist/controller/test.controller.js +4 -4
  25. package/dist/libs/crud-pro/models/ExecuteContext.d.ts +1 -1
  26. package/dist/libs/crud-pro/models/TransactionSqlServer.js +1 -1
  27. package/dist/libs/crud-pro/services/CrudProCachedCfgService.js +1 -1
  28. package/dist/libs/crud-pro/services/CrudProExecuteSqlService.js +7 -6
  29. package/dist/libs/crud-pro/services/CrudProGenSqlCondition.d.ts +1 -1
  30. package/dist/libs/crud-pro/services/CrudProGenSqlCondition.js +2 -4
  31. package/dist/libs/crud-pro/services/CrudProGenSqlService.js +6 -15
  32. package/dist/libs/crud-pro/services/CrudProOriginToExecuteSql.js +5 -4
  33. package/dist/libs/crud-pro/services/CrudProTableMetaService.js +2 -2
  34. package/dist/libs/crud-pro/utils/MixinUtils.js +1 -1
  35. package/dist/libs/crud-pro/utils/ValidateUtils.js +1 -1
  36. package/dist/libs/utils/fatcms-request.js +2 -2
  37. package/dist/middleware/forbidden.middleware.js +4 -20
  38. package/dist/middleware/global.middleware.js +1 -4
  39. package/dist/models/AsyncTaskModel.d.ts +2 -1
  40. package/dist/models/RedisKeys.d.ts +8 -0
  41. package/dist/models/RedisKeys.js +11 -0
  42. package/dist/schedule/index.d.ts +3 -3
  43. package/dist/schedule/index.js +3 -4
  44. package/dist/schedule/runSchedule.d.ts +11 -2
  45. package/dist/schedule/runSchedule.js +49 -15
  46. package/dist/schedule/scheduleNames.d.ts +8 -3
  47. package/dist/schedule/scheduleNames.js +12 -12
  48. package/dist/service/UserSessionService.js +2 -1
  49. package/dist/service/VisitStatService.d.ts +1 -1
  50. package/dist/service/VisitStatService.js +16 -25
  51. package/dist/service/asyncTask/AsyncTaskRunnerService.d.ts +9 -3
  52. package/dist/service/asyncTask/AsyncTaskRunnerService.js +57 -21
  53. package/dist/service/asyncTask/AsyncTaskService.d.ts +1 -1
  54. package/dist/service/asyncTask/AsyncTaskService.js +4 -3
  55. package/package.json +1 -1
  56. package/src/configuration.ts +23 -11
  57. package/src/controller/base/BaseApiController.ts +6 -6
  58. package/src/controller/gateway/AsyncTaskController.ts +17 -22
  59. package/src/controller/gateway/CrudMtdGatewayController.ts +7 -7
  60. package/src/controller/gateway/CrudStdGatewayController.ts +4 -4
  61. package/src/controller/gateway/DocGatewayController.ts +17 -17
  62. package/src/controller/gateway/FileController.ts +8 -9
  63. package/src/controller/gateway/ProxyApiGatewayController.ts +4 -4
  64. package/src/controller/gateway/PublicApiController.ts +19 -22
  65. package/src/controller/gateway/StaticController.ts +234 -264
  66. package/src/controller/helpers.controller.ts +1 -1
  67. package/src/controller/home.controller.ts +0 -5
  68. package/src/controller/manage/AnyApiMangeApi.ts +4 -4
  69. package/src/controller/manage/AppLogMangeApi.ts +3 -3
  70. package/src/controller/manage/AppMangeApi.ts +5 -5
  71. package/src/controller/manage/AppPageMangeApi.ts +3 -3
  72. package/src/controller/manage/AppSchemaHistoryApi.ts +1 -1
  73. package/src/controller/manage/CrudMethodsMangeApi.ts +3 -3
  74. package/src/controller/manage/CrudStandardDesignApi.ts +25 -77
  75. package/src/controller/manage/DataDictManageApi.ts +4 -4
  76. package/src/controller/manage/DeployManageApi.ts +84 -91
  77. package/src/controller/manage/DocLibManageApi.ts +3 -3
  78. package/src/controller/manage/DocManageApi.ts +3 -3
  79. package/src/controller/manage/MenuManageApi.ts +9 -14
  80. package/src/controller/manage/SuperAdminManageApi.ts +2 -10
  81. package/src/controller/manage/SysConfigMangeApi.ts +8 -11
  82. package/src/controller/manage/SystemInfoManageApi.ts +11 -6
  83. package/src/controller/manage/UserAccountManageApi.ts +2 -2
  84. package/src/controller/manage/WorkbenchMangeApi.ts +6 -6
  85. package/src/controller/myinfo/AuthController.ts +4 -8
  86. package/src/controller/render/AppRenderController.ts +8 -8
  87. package/src/controller/test.controller.ts +17 -17
  88. package/src/index.ts +0 -1
  89. package/src/libs/crud-pro/CrudPro.ts +0 -1
  90. package/src/libs/crud-pro/interfaces.ts +1 -3
  91. package/src/libs/crud-pro/models/ExecuteContext.ts +1 -4
  92. package/src/libs/crud-pro/models/ExecuteContextFunc.ts +1 -2
  93. package/src/libs/crud-pro/models/RequestModel.ts +1 -1
  94. package/src/libs/crud-pro/models/ResModel.ts +7 -12
  95. package/src/libs/crud-pro/models/SqlCfgModel.ts +1 -1
  96. package/src/libs/crud-pro/models/Transaction.ts +8 -9
  97. package/src/libs/crud-pro/models/TransactionPostgres.ts +1 -1
  98. package/src/libs/crud-pro/models/TransactionSqlServer.ts +8 -13
  99. package/src/libs/crud-pro/services/CrudProCachedCfgService.ts +1 -3
  100. package/src/libs/crud-pro/services/CrudProExecuteSqlService.ts +36 -48
  101. package/src/libs/crud-pro/services/CrudProGenSqlCondition.ts +19 -38
  102. package/src/libs/crud-pro/services/CrudProGenSqlService.ts +15 -32
  103. package/src/libs/crud-pro/services/CrudProOriginToExecuteSql.ts +23 -27
  104. package/src/libs/crud-pro/services/CrudProServiceBase.ts +1 -2
  105. package/src/libs/crud-pro/services/CrudProTableMetaService.ts +6 -14
  106. package/src/libs/crud-pro/utils/DateTimeUtils.ts +2 -2
  107. package/src/libs/crud-pro/utils/MixinUtils.ts +1 -1
  108. package/src/libs/crud-pro/utils/ValidateUtils.ts +1 -3
  109. package/src/libs/crud-pro/utils/pool/MySQLUtils.ts +1 -1
  110. package/src/libs/crud-pro/utils/pool/PostgresUtils.ts +3 -3
  111. package/src/libs/crud-pro/utils/pool/SqlServerUtils.ts +3 -3
  112. package/src/libs/global-config/global-config.ts +0 -5
  113. package/src/libs/utils/crypto-utils.ts +2 -4
  114. package/src/libs/utils/errorToString.ts +3 -8
  115. package/src/libs/utils/fatcms-request.ts +9 -21
  116. package/src/libs/utils/ordernum-utils.ts +2 -6
  117. package/src/libs/utils/parseConfig.ts +7 -15
  118. package/src/middleware/forbidden.middleware.ts +6 -25
  119. package/src/middleware/global.middleware.ts +10 -21
  120. package/src/models/AsyncTaskModel.ts +3 -2
  121. package/src/models/RedisKeys.ts +13 -0
  122. package/src/models/bizmodels.ts +1 -2
  123. package/src/schedule/index.ts +4 -6
  124. package/src/schedule/runSchedule.ts +65 -17
  125. package/src/schedule/scheduleNames.ts +12 -11
  126. package/src/service/UserSessionService.ts +5 -4
  127. package/src/service/VisitStatService.ts +55 -72
  128. package/src/service/anyapi/AnyApiService.ts +7 -7
  129. package/src/service/asyncTask/AsyncTaskRunnerService.ts +118 -87
  130. package/src/service/asyncTask/AsyncTaskService.ts +10 -10
  131. package/src/service/proxyapi/ProxyApiLoadService.ts +4 -3
@@ -32,13 +32,14 @@ class CrudProExecuteSqlService extends CrudProServiceBase_1.CrudProServiceBase {
32
32
  const executeSqlArgs = this.handleExecuteSqlArgsByResModel(exeCtx, sqlCfgModel.executeSqlArgs || []);
33
33
  let sqlRes;
34
34
  let queryRes;
35
- if (sqlCfgModel.sqlDbType === keys_1.SqlDbType.postgres) { // import { PoolClient } from 'pg';
35
+ if (sqlCfgModel.sqlDbType === keys_1.SqlDbType.postgres) {
36
+ // import { PoolClient } from 'pg';
36
37
  const pgClient = connection;
37
38
  const pgSql = (0, convertPgSql_1.replaceQuestionMarks)(sqlCfgModel.executeSql);
38
39
  this.logger.info('executeSqlCfgModel_postgres', pgSql, executeSqlArgs, sqlCfgModel.resPicker);
39
40
  queryRes = await pgClient.query({
40
41
  text: pgSql,
41
- values: executeSqlArgs || []
42
+ values: executeSqlArgs || [],
42
43
  });
43
44
  sqlRes = (0, convertPgType_1.pickAndConvertPgRows)(queryRes);
44
45
  }
@@ -59,7 +60,7 @@ class CrudProExecuteSqlService extends CrudProServiceBase_1.CrudProServiceBase {
59
60
  exeCtx.setResModelItem(sqlCfgModel.resName, resObject);
60
61
  }
61
62
  handleExecuteSqlArgsByResModel(exeCtx, executeSqlArgs) {
62
- return executeSqlArgs.map((arg) => {
63
+ return executeSqlArgs.map(arg => {
63
64
  if (arg && typeof arg === 'object' && typeof arg.___GENERATE_GET_RES_ATTR___ === 'string') {
64
65
  const word = arg.___GENERATE_GET_RES_ATTR___;
65
66
  if (word.startsWith(keys_1.KeysOfCustomSQL.SQL_PICK_RES_AS_NUMBER)) {
@@ -70,7 +71,7 @@ class CrudProExecuteSqlService extends CrudProServiceBase_1.CrudProServiceBase {
70
71
  }
71
72
  if (word.startsWith(keys_1.KeysOfCustomSQL.SQL_PICK_RES_AS_STRING)) {
72
73
  const resName = MixinUtils_1.MixinUtils.removeStringPrefix(word, keys_1.KeysOfCustomSQL.SQL_PICK_RES_AS_STRING);
73
- return String(exeCtx.getResModelItemLodash(resName) || "");
74
+ return String(exeCtx.getResModelItemLodash(resName) || '');
74
75
  }
75
76
  }
76
77
  return arg;
@@ -201,13 +202,13 @@ class CrudProExecuteSqlService extends CrudProServiceBase_1.CrudProServiceBase {
201
202
  if (sqlCfgModel.sqlDbType === keys_1.SqlDbType.postgres) {
202
203
  return {
203
204
  insertId: _.get(queryRes, 'rows[0].id'),
204
- affectedRows: _.get(queryRes, 'rowCount')
205
+ affectedRows: _.get(queryRes, 'rowCount'),
205
206
  };
206
207
  }
207
208
  if (sqlCfgModel.sqlDbType === keys_1.SqlDbType.sqlserver) {
208
209
  return {
209
210
  insertId: _.get(queryRes, 'recordset[0].id'),
210
- affectedRows: _.get(queryRes, 'rowsAffected[0]')
211
+ affectedRows: _.get(queryRes, 'rowsAffected[0]'),
211
212
  };
212
213
  }
213
214
  return sqlRes;
@@ -1,5 +1,5 @@
1
1
  import { SqlSegArg } from '../models/SqlSegArg';
2
- import { SqlCfgModel } from "../models/SqlCfgModel";
2
+ import { SqlCfgModel } from '../models/SqlCfgModel';
3
3
  declare class CrudProGenSqlCondition {
4
4
  private readonly sqlCfg;
5
5
  constructor(sqlCfg: SqlCfgModel);
@@ -16,10 +16,8 @@ const createFunc = (sqlCfg) => {
16
16
  },
17
17
  toMatchSqlColumnName: (columnName) => {
18
18
  const arr = columnName.split(',');
19
- return arr
20
- .map(s => (0, convertColumnName_1.toSqlColumnName)(s.trim(), sqlCfg))
21
- .join(',');
22
- }
19
+ return arr.map(s => (0, convertColumnName_1.toSqlColumnName)(s.trim(), sqlCfg)).join(',');
20
+ },
23
21
  };
24
22
  };
25
23
  class ValueChecker {
@@ -110,9 +110,11 @@ class CrudProGenSqlService extends CrudProServiceBase_1.CrudProServiceBase {
110
110
  if (!Array.isArray(uniqueColumn) || uniqueColumn.length === 0) {
111
111
  throw new exceptions_1.CommonException(exceptions_1.Exceptions.CFG_ERROR_POSTGRES_UNIQUE_COLUMNS_NULL);
112
112
  }
113
- const unique_column = uniqueColumn.map((s) => {
113
+ const unique_column = uniqueColumn
114
+ .map(s => {
114
115
  return `"${s}"`;
115
- }).join(",");
116
+ })
117
+ .join(',');
116
118
  return `insert into @@table ( @@asInsertKeys:data ) values( @@asInsertValues:data ) ON CONFLICT (${unique_column}) DO UPDATE set @@asUpdate:data `; // 关键字的前后,必须有空格
117
119
  }
118
120
  if (cfgModel.sqlDbType === keys_1.SqlDbType.sqlserver) {
@@ -121,19 +123,8 @@ class CrudProGenSqlService extends CrudProServiceBase_1.CrudProServiceBase {
121
123
  throw new exceptions_1.CommonException(exceptions_1.Exceptions.CFG_UNIQUE_COLUMN_COUNT_MUST_ONE);
122
124
  }
123
125
  const uniqueColumnStr = uniqueColumn[0];
124
- const uniqueColumnVal = "@@data." + uniqueColumnStr;
125
- const sql = "" +
126
- `IF EXISTS (SELECT 1 FROM @@table WHERE [${uniqueColumnStr}] = ${uniqueColumnVal})` +
127
- "BEGIN\n" +
128
- " UPDATE @@table\n" +
129
- " SET @@asUpdate:data\n" +
130
- ` WHERE [${uniqueColumnStr}] = ${uniqueColumnVal} ;\n` +
131
- "END\n" +
132
- "ELSE\n" +
133
- "BEGIN\n" +
134
- " INSERT INTO @@table ( @@asInsertKeys:data )\n" +
135
- " VALUES ( @@asInsertValues:data );\n" +
136
- "END";
126
+ const uniqueColumnVal = '@@data.' + uniqueColumnStr;
127
+ const sql = '' + `IF EXISTS (SELECT 1 FROM @@table WHERE [${uniqueColumnStr}] = ${uniqueColumnVal})` + 'BEGIN\n' + ' UPDATE @@table\n' + ' SET @@asUpdate:data\n' + ` WHERE [${uniqueColumnStr}] = ${uniqueColumnVal} ;\n` + 'END\n' + 'ELSE\n' + 'BEGIN\n' + ' INSERT INTO @@table ( @@asInsertKeys:data )\n' + ' VALUES ( @@asInsertValues:data );\n' + 'END';
137
128
  return sql;
138
129
  }
139
130
  return 'insert into @@table ( @@asInsertKeys:data ) values( @@asInsertValues:data ) on duplicate key update @@asUpdate:data '; // 关键字的前后,必须有空格
@@ -100,8 +100,7 @@ class CrudProOriginToExecuteSql extends CrudProServiceBase_1.CrudProServiceBase
100
100
  else if (word === keys_1.KeysOfCustomSQL.SQL_ORDER_BYS) {
101
101
  return this.generateOrderBys(reqModel, sqlCfg);
102
102
  }
103
- else if ((word.startsWith(keys_1.KeysOfCustomSQL.SQL_GET_DATA_ATTR_START) ||
104
- word.startsWith(keys_1.KeysOfCustomSQL.SQL_GET_CONDITION_ATTR_START)) && word.indexOf('.') > 0) {
103
+ else if ((word.startsWith(keys_1.KeysOfCustomSQL.SQL_GET_DATA_ATTR_START) || word.startsWith(keys_1.KeysOfCustomSQL.SQL_GET_CONDITION_ATTR_START)) && word.indexOf('.') > 0) {
105
104
  return this.generateGetAttr(reqModel, word); //// data.xxx, condition.xxx
106
105
  }
107
106
  else if (word.startsWith(keys_1.KeysOfCustomSQL.SQL_PICK_RES_AS_NUMBER) || word.startsWith(keys_1.KeysOfCustomSQL.SQL_PICK_RES_AS_STRING)) {
@@ -219,9 +218,11 @@ class CrudProOriginToExecuteSql extends CrudProServiceBase_1.CrudProServiceBase
219
218
  return new SqlSegArg_1.SqlSegArg(sql);
220
219
  }
221
220
  generatePickResAs(req, world) {
222
- return new SqlSegArg_1.SqlSegArg(' ? ', [{
221
+ return new SqlSegArg_1.SqlSegArg(' ? ', [
222
+ {
223
223
  ___GENERATE_GET_RES_ATTR___: world,
224
- }]);
224
+ },
225
+ ]);
225
226
  }
226
227
  generateGetAttr(req, word) {
227
228
  const attrName = MixinUtils_1.MixinUtils.removeStringPrefix(word, '@@');
@@ -43,7 +43,7 @@ class CrudProTableMetaService extends CrudProServiceBase_1.CrudProServiceBase {
43
43
  const baseInfo = {
44
44
  sqlTable: sqlCfgModel.sqlTable,
45
45
  sqlDatabase: sqlCfgModel.sqlDatabase,
46
- sqlDbType: sqlCfgModel.sqlDbType
46
+ sqlDbType: sqlCfgModel.sqlDbType,
47
47
  };
48
48
  obj.tableColumns = await this.loadTableColumnInfo(baseInfo);
49
49
  return obj;
@@ -71,7 +71,7 @@ class CrudProTableMetaService extends CrudProServiceBase_1.CrudProServiceBase {
71
71
  return fieldObj['column_name'];
72
72
  });
73
73
  }
74
- throw new Error("暂不支持的数据库类型:" + baseInfo.sqlDbType);
74
+ throw new Error('暂不支持的数据库类型:' + baseInfo.sqlDbType);
75
75
  }
76
76
  }
77
77
  exports.CrudProTableMetaService = CrudProTableMetaService;
@@ -43,7 +43,7 @@ const MixinUtils = {
43
43
  return !str1 && !str2;
44
44
  },
45
45
  startsWith(str1, str2) {
46
- if (typeof str1 === "string" && typeof str2 === "string") {
46
+ if (typeof str1 === 'string' && typeof str2 === 'string') {
47
47
  return str1.startsWith(str2);
48
48
  }
49
49
  return false;
@@ -147,7 +147,7 @@ function validateByCfgString(validateCfg, itemValue, errPath) {
147
147
  return;
148
148
  }
149
149
  // 必填
150
- if ("required" === validateCfg) {
150
+ if ('required' === validateCfg) {
151
151
  if (isEmpty(itemValue)) {
152
152
  throw new exceptions_1.CommonException(exceptions_1.Exceptions.VALIDATE_ERR, "'参数校验错误,字段 " + errPath + ' 不满足校验配置:' + validateCfg);
153
153
  }
@@ -84,7 +84,7 @@ async function isCsrfTokenValid(ctx) {
84
84
  const depryptToken = await crypto_utils_1.privateAES.time_decrypt_base64_utf8(fatcmscsrftoken);
85
85
  if (depryptToken) {
86
86
  const num = Number(depryptToken);
87
- if (num && ((num + 6 * 3600 * 1000) > Date.now())) {
87
+ if (num && num + 6 * 3600 * 1000 > Date.now()) {
88
88
  return true;
89
89
  }
90
90
  }
@@ -98,7 +98,7 @@ exports.isCsrfTokenValid = isCsrfTokenValid;
98
98
  async function assertCsrfToken(ctx) {
99
99
  const isOK = await isCsrfTokenValid(ctx);
100
100
  if (!isOK) {
101
- throw new exceptions_1.CommonException("ASSERT_CSRF_TOKEN_ERROR", "CSRF_TOKEN 验证失败");
101
+ throw new exceptions_1.CommonException('ASSERT_CSRF_TOKEN_ERROR', 'CSRF_TOKEN 验证失败');
102
102
  }
103
103
  }
104
104
  exports.assertCsrfToken = assertCsrfToken;
@@ -9,24 +9,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.ForbiddenMiddleware = void 0;
10
10
  const core_1 = require("@midwayjs/core");
11
11
  // 一些爬虫/漏洞分析工具会来请求这玩意。
12
- const blackEqualList = [
13
- '/config.json',
14
- '/backend/.env',
15
- '/application.yml',
16
- '/db.ini',
17
- '/.well-known/security.txt',
18
- ];
19
- const blackPrefixList = [
20
- '/.aws/',
21
- '/.git/',
22
- '/.svn/',
23
- '/.env/',
24
- '/src/',
25
- '/var/logs/',
26
- '/var/log/',
27
- '/cgi-bin/',
28
- '/php-cgi/',
29
- ];
12
+ const blackEqualList = ['/config.json', '/backend/.env', '/application.yml', '/db.ini', '/.well-known/security.txt'];
13
+ const blackPrefixList = ['/.aws/', '/.git/', '/.svn/', '/.env/', '/src/', '/var/logs/', '/var/log/', '/cgi-bin/', '/php-cgi/'];
30
14
  /**
31
15
  * 针对一些路径禁止访问。避免一些爬虫抓取网站内容,实际上这里枚举的路径,本身就是不存在的。只是为了提前拦截,为了服务器性能考虑。
32
16
  */
@@ -55,9 +39,9 @@ let ForbiddenMiddleware = class ForbiddenMiddleware {
55
39
  }
56
40
  resolve() {
57
41
  return async (ctx, next) => {
58
- ctx.set({ "content-type": "text/html; charset=utf-8" });
42
+ ctx.set({ 'content-type': 'text/html; charset=utf-8' });
59
43
  ctx.status = 404;
60
- ctx.body = "404!404!404!重要的事情说三遍!";
44
+ ctx.body = '404!404!404!重要的事情说三遍!';
61
45
  };
62
46
  }
63
47
  static getName() {
@@ -186,10 +186,7 @@ async function trackRequest(ctx) {
186
186
  console.error('trackRequestError', e);
187
187
  }
188
188
  }
189
- const excludePathPrefix = [
190
- '/ns/static/',
191
- '/ns/api/helpers'
192
- ];
189
+ const excludePathPrefix = ['/ns/static/', '/ns/api/helpers'];
193
190
  /**
194
191
  * 全局中间件
195
192
  */
@@ -31,6 +31,7 @@ export interface SysAsyncTaskEntity {
31
31
  completed_at: Date | null;
32
32
  created_user_session: string;
33
33
  }
34
+ export declare type SysAsyncTaskPartial = Partial<SysAsyncTaskEntity>;
34
35
  export declare enum SysAsyncTaskStatus {
35
36
  PENDING = "PENDING",
36
37
  RUNNING = "RUNNING",
@@ -56,7 +57,7 @@ export interface ISysAsyncTaskHandler {
56
57
  }
57
58
  export interface SysAsyncTaskContext {
58
59
  task: SysAsyncTaskEntity;
59
- updateTaskStatus: () => any;
60
+ updateTaskStatus: (sysAsyncTaskPartial: SysAsyncTaskPartial) => any;
60
61
  }
61
62
  export interface SysAsyncTaskHandlerConfig {
62
63
  taskType: string;
@@ -0,0 +1,8 @@
1
+ declare const RedisKeys: {
2
+ ASYNC_TASK_LOCK: string;
3
+ ASYNC_TASK_UPDATE_TIME: string;
4
+ USER_SESSION_PREFIX: string;
5
+ VISIT_STAT_LOCK_PREFIX: string;
6
+ VISIT_STAT_DATE_PREFIX: string;
7
+ };
8
+ export { RedisKeys };
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RedisKeys = void 0;
4
+ const RedisKeys = {
5
+ ASYNC_TASK_LOCK: "FatAsyncTaskLock",
6
+ ASYNC_TASK_UPDATE_TIME: "FatAsyncTaskUpdateTime",
7
+ USER_SESSION_PREFIX: "FatUserSession_",
8
+ VISIT_STAT_LOCK_PREFIX: "FatVsLock_",
9
+ VISIT_STAT_DATE_PREFIX: "FatVsDate_",
10
+ };
11
+ exports.RedisKeys = RedisKeys;
@@ -1,4 +1,4 @@
1
- import { startScheduleLoop, runScheduleTaskOnce } from './runSchedule';
1
+ import { SCHEDULE_QUEUE, runScheduleTaskOnce } from './runSchedule';
2
2
  import { ANONYMOUS_CONTEXT } from './anonymousContext';
3
- import { ALL_SCHEDULE_NAMES, SCHEDULE_NAMES } from './scheduleNames';
4
- export { ALL_SCHEDULE_NAMES, SCHEDULE_NAMES, ANONYMOUS_CONTEXT, startScheduleLoop, runScheduleTaskOnce };
3
+ import { INNER_SCHEDULE_INTERVAL } from './scheduleNames';
4
+ export { INNER_SCHEDULE_INTERVAL, ANONYMOUS_CONTEXT, SCHEDULE_QUEUE, runScheduleTaskOnce };
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runScheduleTaskOnce = exports.startScheduleLoop = exports.ANONYMOUS_CONTEXT = exports.SCHEDULE_NAMES = exports.ALL_SCHEDULE_NAMES = void 0;
3
+ exports.runScheduleTaskOnce = exports.SCHEDULE_QUEUE = exports.ANONYMOUS_CONTEXT = exports.INNER_SCHEDULE_INTERVAL = void 0;
4
4
  const runSchedule_1 = require("./runSchedule");
5
- Object.defineProperty(exports, "startScheduleLoop", { enumerable: true, get: function () { return runSchedule_1.startScheduleLoop; } });
5
+ Object.defineProperty(exports, "SCHEDULE_QUEUE", { enumerable: true, get: function () { return runSchedule_1.SCHEDULE_QUEUE; } });
6
6
  Object.defineProperty(exports, "runScheduleTaskOnce", { enumerable: true, get: function () { return runSchedule_1.runScheduleTaskOnce; } });
7
7
  const anonymousContext_1 = require("./anonymousContext");
8
8
  Object.defineProperty(exports, "ANONYMOUS_CONTEXT", { enumerable: true, get: function () { return anonymousContext_1.ANONYMOUS_CONTEXT; } });
9
9
  const scheduleNames_1 = require("./scheduleNames");
10
- Object.defineProperty(exports, "ALL_SCHEDULE_NAMES", { enumerable: true, get: function () { return scheduleNames_1.ALL_SCHEDULE_NAMES; } });
11
- Object.defineProperty(exports, "SCHEDULE_NAMES", { enumerable: true, get: function () { return scheduleNames_1.SCHEDULE_NAMES; } });
10
+ Object.defineProperty(exports, "INNER_SCHEDULE_INTERVAL", { enumerable: true, get: function () { return scheduleNames_1.INNER_SCHEDULE_INTERVAL; } });
@@ -2,5 +2,14 @@ declare function runScheduleTaskOnce(serviceName: string): Promise<{
2
2
  result: any;
3
3
  error: any;
4
4
  }>;
5
- declare function startScheduleLoop(serviceList: string[]): Promise<void>;
6
- export { startScheduleLoop, runScheduleTaskOnce };
5
+ declare class ScheduleQueue {
6
+ private scheduleIntervalMap;
7
+ setScheduleTask(serviceName: string, intervalTime: number): void;
8
+ removeScheduleTask(serviceName: string): void;
9
+ private isAlreadyTimeToExecute;
10
+ private runScheduleTaskOnceCheckTime;
11
+ private runScheduleServiceList;
12
+ startScheduleLoop(): Promise<void>;
13
+ }
14
+ declare const SCHEDULE_QUEUE: ScheduleQueue;
15
+ export { SCHEDULE_QUEUE, runScheduleTaskOnce };
@@ -1,7 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runScheduleTaskOnce = exports.startScheduleLoop = void 0;
3
+ exports.runScheduleTaskOnce = exports.SCHEDULE_QUEUE = void 0;
4
4
  const anonymousContext_1 = require("./anonymousContext");
5
+ // 上次执行时间
6
+ const lastExecuteTimeMap = {};
7
+ const DEFAULT_SCHEDULE_INTERVAL = 2 * 60 * 1000;
5
8
  async function runScheduleTaskOnce(serviceName) {
6
9
  return await anonymousContext_1.ANONYMOUS_CONTEXT.runServiceAtAnonymousContext(async (ctx) => {
7
10
  const serviceObject = await ctx.requestContext.getAsync(serviceName);
@@ -14,21 +17,52 @@ async function runScheduleTaskOnce(serviceName) {
14
17
  });
15
18
  }
16
19
  exports.runScheduleTaskOnce = runScheduleTaskOnce;
17
- async function runScheduleServiceList(serviceList) {
18
- for (let i = 0; i < serviceList.length; i++) {
19
- const serviceName = serviceList[i];
20
- try {
21
- await runScheduleTaskOnce(serviceName);
20
+ class ScheduleQueue {
21
+ constructor() {
22
+ this.scheduleIntervalMap = new Map();
23
+ }
24
+ setScheduleTask(serviceName, intervalTime) {
25
+ this.scheduleIntervalMap.set(serviceName, intervalTime);
26
+ }
27
+ removeScheduleTask(serviceName) {
28
+ this.scheduleIntervalMap.delete(serviceName);
29
+ }
30
+ isAlreadyTimeToExecute(serviceName) {
31
+ if (!lastExecuteTimeMap[serviceName]) {
32
+ return true; // 可以执行
33
+ }
34
+ const intervalTime1 = this.scheduleIntervalMap.get(serviceName);
35
+ const intervalTime = intervalTime1 || DEFAULT_SCHEDULE_INTERVAL; // 时间间隔
36
+ const lastExecuteTime = lastExecuteTimeMap[serviceName];
37
+ return (Date.now() - lastExecuteTime) >= intervalTime;
38
+ }
39
+ async runScheduleTaskOnceCheckTime(serviceName) {
40
+ // 还没有到可以执行时间
41
+ if (!this.isAlreadyTimeToExecute(serviceName)) {
42
+ return;
22
43
  }
23
- catch (e) {
24
- anonymousContext_1.ANONYMOUS_CONTEXT.getApp().getCoreLogger().error(`runSchedule error , serviceName = ${serviceName}`, e);
44
+ lastExecuteTimeMap[serviceName] = Date.now();
45
+ await runScheduleTaskOnce(serviceName);
46
+ }
47
+ async runScheduleServiceList() {
48
+ const serviceListKeys = this.scheduleIntervalMap.keys();
49
+ const serviceList = [...serviceListKeys];
50
+ for (let i = 0; i < serviceList.length; i++) {
51
+ const serviceName = serviceList[i];
52
+ try {
53
+ await this.runScheduleTaskOnceCheckTime(serviceName);
54
+ }
55
+ catch (e) {
56
+ anonymousContext_1.ANONYMOUS_CONTEXT.getApp().getCoreLogger().error(`runSchedule error , serviceName = ${serviceName}`, e);
57
+ }
25
58
  }
26
59
  }
60
+ async startScheduleLoop() {
61
+ await this.runScheduleServiceList();
62
+ setInterval(() => {
63
+ this.runScheduleServiceList();
64
+ }, 1000); // 最少1秒执行一次
65
+ }
27
66
  }
28
- async function startScheduleLoop(serviceList) {
29
- await runScheduleServiceList(serviceList);
30
- setInterval(() => {
31
- runScheduleServiceList(serviceList);
32
- }, 2 * 60 * 1000);
33
- }
34
- exports.startScheduleLoop = startScheduleLoop;
67
+ const SCHEDULE_QUEUE = new ScheduleQueue();
68
+ exports.SCHEDULE_QUEUE = SCHEDULE_QUEUE;
@@ -1,8 +1,13 @@
1
- declare const SCHEDULE_NAMES: {
1
+ declare const INNER_SCHEDULE_INTERVAL: {
2
+ proxyApiLoadService: number;
3
+ workbenchService: number;
4
+ visitStatService: number;
5
+ asyncTaskRunnerService: number;
6
+ };
7
+ declare const INNER_SCHEDULE_NAMES: {
2
8
  proxyApiLoadService: string;
3
9
  workbenchService: string;
4
10
  visitStatService: string;
5
11
  asyncTaskRunnerService: string;
6
12
  };
7
- declare const ALL_SCHEDULE_NAMES: string[];
8
- export { ALL_SCHEDULE_NAMES, SCHEDULE_NAMES, };
13
+ export { INNER_SCHEDULE_INTERVAL, INNER_SCHEDULE_NAMES };
@@ -1,17 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SCHEDULE_NAMES = exports.ALL_SCHEDULE_NAMES = void 0;
4
- const SCHEDULE_NAMES = {
3
+ exports.INNER_SCHEDULE_NAMES = exports.INNER_SCHEDULE_INTERVAL = void 0;
4
+ const INNER_SCHEDULE_INTERVAL = {
5
+ proxyApiLoadService: 2 * 60 * 1000,
6
+ workbenchService: 60 * 1000,
7
+ visitStatService: 10 * 60 * 1000,
8
+ asyncTaskRunnerService: 1000, // 1s可以执行
9
+ };
10
+ exports.INNER_SCHEDULE_INTERVAL = INNER_SCHEDULE_INTERVAL;
11
+ const INNER_SCHEDULE_NAMES = {
5
12
  proxyApiLoadService: 'proxyApiLoadService',
6
13
  workbenchService: 'workbenchService',
7
- visitStatService: 'visitStatService',
8
- asyncTaskRunnerService: 'asyncTaskRunnerService',
14
+ visitStatService: "visitStatService",
15
+ asyncTaskRunnerService: "asyncTaskRunnerService",
9
16
  };
10
- exports.SCHEDULE_NAMES = SCHEDULE_NAMES;
11
- const ALL_SCHEDULE_NAMES = [
12
- SCHEDULE_NAMES.proxyApiLoadService,
13
- SCHEDULE_NAMES.workbenchService,
14
- SCHEDULE_NAMES.visitStatService,
15
- SCHEDULE_NAMES.asyncTaskRunnerService
16
- ];
17
- exports.ALL_SCHEDULE_NAMES = ALL_SCHEDULE_NAMES;
17
+ exports.INNER_SCHEDULE_NAMES = INNER_SCHEDULE_NAMES;
@@ -14,6 +14,7 @@ const core_1 = require("@midwayjs/core");
14
14
  const functions_1 = require("../libs/utils/functions");
15
15
  const userSession_1 = require("../models/userSession");
16
16
  const RedisCacheService_1 = require("./base/RedisCacheService");
17
+ const RedisKeys_1 = require("../models/RedisKeys");
17
18
  function pickUserAvatar(avatar) {
18
19
  if (!avatar) {
19
20
  return null;
@@ -41,7 +42,7 @@ function pickUserAvatar(avatar) {
41
42
  }
42
43
  const SESSION_KEEP_TIME_SECOND = 3600 * 24 * 30;
43
44
  const toCacheKey = (sessionId) => {
44
- return `UserSession@@${sessionId}`;
45
+ return `${RedisKeys_1.RedisKeys.USER_SESSION_PREFIX}${sessionId}`;
45
46
  };
46
47
  let UserSessionService = class UserSessionService {
47
48
  async saveUserSession(sessionInfo) {
@@ -1,6 +1,6 @@
1
1
  import { Context } from '@midwayjs/koa';
2
2
  import { IScheduleService } from '../interface';
3
- import { BaseService } from "./base/BaseService";
3
+ import { BaseService } from './base/BaseService';
4
4
  export declare class VisitStatService extends BaseService implements IScheduleService {
5
5
  protected ctx: Context;
6
6
  private curdProService;
@@ -18,6 +18,7 @@ const keys_1 = require("../libs/crud-pro/models/keys");
18
18
  const bizmodels_1 = require("../models/bizmodels");
19
19
  const common_dto_1 = require("../libs/utils/common-dto");
20
20
  const global_config_1 = require("../libs/global-config/global-config");
21
+ const RedisKeys_1 = require("../models/RedisKeys");
21
22
  // 3天 的秒数
22
23
  const EXPIRE_TIME = 3 * 24 * 60 * 60;
23
24
  const STAT_TYPES = {
@@ -28,26 +29,26 @@ const STAT_TYPES = {
28
29
  let VisitStatService = class VisitStatService extends BaseService_1.BaseService {
29
30
  async runBySchedule() {
30
31
  const hours = new Date().getHours();
31
- this.logInfo("[VisitStatService] runBySchedule called, hours = " + hours);
32
+ this.logInfo('[VisitStatService] runBySchedule called, hours = ' + hours);
32
33
  return this.flushVisitStatToDB();
33
34
  }
34
35
  async flushVisitStatToDB() {
35
36
  const { SystemDbName, SystemDbType } = global_config_1.GLOBAL_STATIC_CONFIG.getConfig();
36
37
  // 统计昨天的数据。
37
38
  const stat_date = new Date(Date.now() - 24 * 3600 * 1000).toISOString().split('T')[0];
38
- const lockKey = `vs_lock_${stat_date}`;
39
+ const lockKey = `${RedisKeys_1.RedisKeys.VISIT_STAT_LOCK_PREFIX}${stat_date}`;
39
40
  // 每天只能执行一次
40
41
  const client = this.redisService;
41
42
  const nxRes = await client.set(lockKey, 1, 'EX', EXPIRE_TIME, 'NX');
42
43
  if (nxRes !== 'OK') {
43
- this.logInfo("[VisitStatService] flushVisitStatToDB 每天只能执行一次 ");
44
- return common_dto_1.CommonResult.errorRes("每天只能执行一次");
44
+ this.logInfo('[VisitStatService] flushVisitStatToDB 每天只能执行一次 ');
45
+ return common_dto_1.CommonResult.errorRes('每天只能执行一次');
45
46
  }
46
- this.logInfo("[VisitStatService] flushVisitStatToDB start ");
47
+ this.logInfo('[VisitStatService] flushVisitStatToDB start ');
47
48
  let totalCount = 0;
48
49
  let successCount = 0;
49
50
  try {
50
- const keys = await client.keys(`vs_${stat_date}::*`);
51
+ const keys = await client.keys(`${RedisKeys_1.RedisKeys.VISIT_STAT_DATE_PREFIX}${stat_date}::*`);
51
52
  // `vs_${date}::${req_host}::${resource_type}::${stat_type}::${resource}`;
52
53
  totalCount = keys.length;
53
54
  for (const key of keys) {
@@ -59,7 +60,7 @@ let VisitStatService = class VisitStatService extends BaseService_1.BaseService
59
60
  const stat_type = parts[3];
60
61
  const stat_resource = parts[4];
61
62
  let stat_count;
62
- if (stat_type === STAT_TYPES.uv_ip || stat_type == STAT_TYPES.uv_uid) {
63
+ if (stat_type === STAT_TYPES.uv_ip || stat_type === STAT_TYPES.uv_uid) {
63
64
  stat_count = await client.scard(key);
64
65
  }
65
66
  else {
@@ -72,8 +73,8 @@ let VisitStatService = class VisitStatService extends BaseService_1.BaseService
72
73
  stat_type,
73
74
  resource_type,
74
75
  stat_count,
75
- req_host
76
- }
76
+ req_host,
77
+ },
77
78
  }, {
78
79
  sqlSimpleName: keys_1.KeysOfSimpleSQL.SIMPLE_INSERT,
79
80
  sqlDatabase: SystemDbName,
@@ -94,7 +95,7 @@ let VisitStatService = class VisitStatService extends BaseService_1.BaseService
94
95
  this.logError('[VisitStatService] flushVisitStatToDB', error);
95
96
  console.log('[VisitStatService] flushVisitStatToDB', error);
96
97
  }
97
- this.logInfo("[VisitStatService] flushVisitStatToDB end ");
98
+ this.logInfo('[VisitStatService] flushVisitStatToDB end ');
98
99
  return common_dto_1.CommonResult.successRes({ successCount, totalCount });
99
100
  }
100
101
  /**
@@ -124,34 +125,24 @@ let VisitStatService = class VisitStatService extends BaseService_1.BaseService
124
125
  const client = this.redisService;
125
126
  const ip = this.ctx.headers['x-real-ip'];
126
127
  const userSession = this.ctx.userSession;
127
- const req_host = ((_b = (_a = this.ctx) === null || _a === void 0 ? void 0 : _a.request) === null || _b === void 0 ? void 0 : _b.host) || "null"; // 域名
128
+ const req_host = ((_b = (_a = this.ctx) === null || _a === void 0 ? void 0 : _a.request) === null || _b === void 0 ? void 0 : _b.host) || 'null'; // 域名
128
129
  const date = new Date().toISOString().split('T')[0];
129
130
  const toDateResourceKey = (stat_type) => {
130
- return `vs_${date}::${req_host}::${resource_type}::${stat_type}::${resource}`;
131
+ return `${RedisKeys_1.RedisKeys.VISIT_STAT_DATE_PREFIX}${date}::${req_host}::${resource_type}::${stat_type}::${resource}`;
131
132
  };
132
133
  const pv_key = toDateResourceKey(STAT_TYPES.pv);
133
134
  const uv_ip_key = toDateResourceKey(STAT_TYPES.uv_ip);
134
135
  const uv_uid_key = toDateResourceKey(STAT_TYPES.uv_uid);
135
136
  // 统计 PV
136
- await Promise.all([
137
- client.incr(pv_key),
138
- client.expire(pv_key, EXPIRE_TIME)
139
- ]);
137
+ await Promise.all([client.incr(pv_key), client.expire(pv_key, EXPIRE_TIME)]);
140
138
  // IP 访问 UV
141
- await Promise.all([
142
- client.sadd(uv_ip_key, `${ip}`),
143
- client.expire(uv_ip_key, EXPIRE_TIME)
144
- ]);
139
+ await Promise.all([client.sadd(uv_ip_key, `${ip}`), client.expire(uv_ip_key, EXPIRE_TIME)]);
145
140
  if (userSession && userSession.isLogin()) {
146
141
  const accountId = userSession.getSessionInfo().accountId;
147
142
  // 统计 UV
148
- await Promise.all([
149
- client.sadd(uv_uid_key, accountId),
150
- client.expire(uv_uid_key, EXPIRE_TIME)
151
- ]);
143
+ await Promise.all([client.sadd(uv_uid_key, accountId), client.expire(uv_uid_key, EXPIRE_TIME)]);
152
144
  }
153
145
  }
154
- ;
155
146
  };
156
147
  __decorate([
157
148
  (0, core_1.Inject)(),
@@ -1,7 +1,7 @@
1
1
  import { Context } from '@midwayjs/koa';
2
- import { BaseService } from "../../service/base/BaseService";
3
- import { IScheduleService } from "../../interface";
4
- import { ISysAsyncTaskHandler, SysAsyncTaskEntity } from "../../models/AsyncTaskModel";
2
+ import { BaseService } from '../../service/base/BaseService';
3
+ import { IScheduleService } from '../../interface';
4
+ import { ISysAsyncTaskHandler, SysAsyncTaskEntity } from '../../models/AsyncTaskModel';
5
5
  declare class AsyncTaskRunner {
6
6
  isBusy: boolean;
7
7
  taskHandlerMap: Map<string, ISysAsyncTaskHandler>;
@@ -10,6 +10,7 @@ declare class AsyncTaskRunner {
10
10
  /**
11
11
  * 更新任务状态或任务进度
12
12
  * @param taskElement
13
+ * @param updatePartials
13
14
  * @private
14
15
  */
15
16
  private updateTaskStatus;
@@ -27,5 +28,10 @@ export declare class AsyncTaskRunnerService extends BaseService implements ISche
27
28
  private curdProService;
28
29
  fetchPendingTasks(): Promise<void>;
29
30
  runBySchedule(): Promise<void>;
31
+ /**
32
+ * 是否存在新任务
33
+ * @private
34
+ */
35
+ private isExistNewTask;
30
36
  }
31
37
  export {};