midway-fatcms 0.0.1-beta.13 → 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.
Files changed (86) hide show
  1. package/README.md +7 -0
  2. package/dist/configuration.d.ts +1 -0
  3. package/dist/configuration.js +21 -8
  4. package/dist/controller/base/BaseApiController.d.ts +1 -1
  5. package/dist/controller/gateway/AsyncTaskController.js +17 -6
  6. package/dist/controller/gateway/CrudMtdGatewayController.d.ts +3 -3
  7. package/dist/controller/gateway/CrudMtdGatewayController.js +5 -5
  8. package/dist/index.d.ts +7 -0
  9. package/dist/index.js +7 -0
  10. package/dist/libs/crud-pro/CrudPro.d.ts +1 -0
  11. package/dist/libs/crud-pro/CrudPro.js +5 -0
  12. package/dist/libs/crud-pro/defaultConfigs.js +2 -0
  13. package/dist/libs/crud-pro/interfaces.d.ts +6 -0
  14. package/dist/libs/crud-pro/models/ExecuteContext.d.ts +2 -1
  15. package/dist/libs/crud-pro/models/ExecuteContextFunc.d.ts +8 -1
  16. package/dist/libs/crud-pro/models/ExecuteContextFunc.js +8 -0
  17. package/dist/libs/crud-pro/models/ResModel.d.ts +16 -0
  18. package/dist/libs/crud-pro/models/ResModel.js +2 -0
  19. package/dist/libs/crud-pro/services/CrudProCachedCfgService.d.ts +1 -0
  20. package/dist/libs/crud-pro/services/CrudProCachedCfgService.js +22 -11
  21. package/dist/libs/crud-pro/services/CrudProServiceBase.d.ts +2 -6
  22. package/dist/libs/crud-pro/services/CrudProServiceBase.js +3 -2
  23. package/dist/libs/crud-pro/services/CrudProTableMetaService.d.ts +1 -0
  24. package/dist/libs/crud-pro/services/CrudProTableMetaService.js +31 -7
  25. package/dist/libs/crud-pro/utils/DatabaseName.js +24 -3
  26. package/dist/libs/global-config/global-config.d.ts +6 -0
  27. package/dist/libs/global-config/global-config.js +1 -0
  28. package/dist/models/AsyncTaskModel.d.ts +13 -11
  29. package/dist/models/AsyncTaskModel.js +23 -23
  30. package/dist/schedule/anonymousContext.d.ts +13 -0
  31. package/dist/schedule/anonymousContext.js +59 -0
  32. package/dist/schedule/index.d.ts +4 -4
  33. package/dist/schedule/index.js +9 -68
  34. package/dist/schedule/runSchedule.d.ts +6 -0
  35. package/dist/schedule/runSchedule.js +34 -0
  36. package/dist/schedule/scheduleNames.d.ts +8 -0
  37. package/dist/schedule/scheduleNames.js +17 -0
  38. package/dist/service/asyncTask/AsyncTaskRunnerService.d.ts +14 -0
  39. package/dist/service/asyncTask/AsyncTaskRunnerService.js +66 -16
  40. package/dist/service/asyncTask/AsyncTaskService.js +2 -1
  41. package/dist/service/crudstd/CrudStdService.d.ts +1 -0
  42. package/dist/service/crudstd/CrudStdService.js +27 -0
  43. package/dist/service/curd/CrudProQuick.d.ts +24 -0
  44. package/dist/service/curd/CrudProQuick.js +105 -0
  45. package/dist/service/curd/CurdMixByLinkToCustomService.d.ts +10 -1
  46. package/dist/service/curd/CurdMixByLinkToCustomService.js +71 -23
  47. package/dist/service/curd/CurdMixService.d.ts +1 -1
  48. package/dist/service/curd/CurdMixService.js +2 -2
  49. package/dist/service/curd/CurdMixUtils.js +35 -28
  50. package/dist/service/curd/CurdProService.d.ts +2 -10
  51. package/dist/service/curd/CurdProService.js +28 -143
  52. package/dist/service/curd/fixCfgModel.d.ts +3 -0
  53. package/dist/service/curd/fixCfgModel.js +107 -0
  54. package/package.json +1 -1
  55. package/src/configuration.ts +30 -10
  56. package/src/controller/gateway/AnyApiGatewayController.ts +1 -1
  57. package/src/controller/gateway/AsyncTaskController.ts +21 -8
  58. package/src/controller/gateway/CrudMtdGatewayController.ts +5 -5
  59. package/src/controller/manage/DocManageApi.ts +5 -5
  60. package/src/index.ts +7 -0
  61. package/src/libs/crud-pro/CrudPro.ts +8 -0
  62. package/src/libs/crud-pro/defaultConfigs.ts +2 -0
  63. package/src/libs/crud-pro/interfaces.ts +10 -1
  64. package/src/libs/crud-pro/models/ExecuteContext.ts +5 -2
  65. package/src/libs/crud-pro/models/ExecuteContextFunc.ts +12 -1
  66. package/src/libs/crud-pro/models/ResModel.ts +24 -0
  67. package/src/libs/crud-pro/services/CrudProCachedCfgService.ts +26 -17
  68. package/src/libs/crud-pro/services/CrudProServiceBase.ts +5 -8
  69. package/src/libs/crud-pro/services/CrudProTableMetaService.ts +43 -9
  70. package/src/libs/crud-pro/utils/DatabaseName.ts +35 -15
  71. package/src/libs/global-config/global-config.ts +12 -1
  72. package/src/models/AsyncTaskModel.ts +14 -11
  73. package/src/schedule/anonymousContext.ts +79 -0
  74. package/src/schedule/index.ts +13 -72
  75. package/src/schedule/runSchedule.ts +35 -0
  76. package/src/schedule/scheduleNames.ts +20 -0
  77. package/src/service/asyncTask/AsyncTaskRunnerService.ts +91 -24
  78. package/src/service/asyncTask/AsyncTaskService.ts +3 -2
  79. package/src/service/base/BaseService.ts +2 -2
  80. package/src/service/crudstd/CrudStdService.ts +34 -6
  81. package/src/service/curd/CrudProQuick.ts +137 -0
  82. package/src/service/curd/CurdMixByLinkToCustomService.ts +100 -49
  83. package/src/service/curd/CurdMixService.ts +3 -3
  84. package/src/service/curd/CurdMixUtils.ts +51 -38
  85. package/src/service/curd/CurdProService.ts +42 -186
  86. package/src/service/curd/fixCfgModel.ts +139 -0
@@ -3,8 +3,8 @@ import { Context } from '@midwayjs/koa';
3
3
  import { RedisService } from '@midwayjs/redis';
4
4
  import { OSSService, OSSServiceFactory } from '@midwayjs/oss';
5
5
  import * as koa from '@midwayjs/koa';
6
- import { consoleLogger, ContextLogger, ILoggerContext } from '../../models/contextLogger';
7
- import { isEnableDebug, isLocalEnv } from '../../libs/utils/fatcms-request';
6
+ import { consoleLogger, ContextLogger, ILoggerContext } from '@/models/contextLogger';
7
+ import { isEnableDebug, isLocalEnv } from '@/libs/utils/fatcms-request';
8
8
 
9
9
 
10
10
  @Provide()
@@ -2,18 +2,19 @@ import { Inject, Provide } from '@midwayjs/core';
2
2
  import { Context } from '@midwayjs/koa';
3
3
  import { CurdMixService } from '../curd/CurdMixService';
4
4
  import { IRequestCfgModel, IRequestModel } from '../../libs/crud-pro/interfaces';
5
- import { KeysOfAuthType, KeysOfSimpleSQL } from '../../libs/crud-pro/models/keys';
5
+ import { KeysOfAuthType, KeysOfSimpleSQL, SqlDbType } from '../../libs/crud-pro/models/keys';
6
6
  import { parseJsonObject } from '../../libs/utils/functions';
7
7
  import { ICrudStdAppInfo, ICrudStdAppInfoForSettingKey } from '../../models/bizmodels';
8
8
  import { BizException } from '../../models/devops';
9
9
  import { ExecuteContext } from '../../libs/crud-pro/models/ExecuteContext';
10
- import { SystemTables} from '../../models/SystemTables';
10
+ import { SystemTables } from '../../models/SystemTables';
11
11
  import { CrudStdActionService } from './CrudStdActionService';
12
12
  import { CrudStdRelationService } from './CrudStdRelationService';
13
13
  import * as _ from 'lodash';
14
14
  import { ApiBaseService } from '../base/ApiBaseService';
15
- import {parseDatabaseName} from "../../libs/crud-pro/utils/DatabaseName";
15
+ import { parseDatabaseName } from '../../libs/crud-pro/utils/DatabaseName';
16
16
  import { GLOBAL_STATIC_CONFIG } from '../../libs/global-config/global-config';
17
+ import { MixinUtils } from '@/libs/crud-pro/utils/MixinUtils';
17
18
 
18
19
  export const SPECIAL_SETTING_KEY = {
19
20
  QUERY_LIST: 'QUERY_LIST',
@@ -69,6 +70,9 @@ export class CrudStdService extends ApiBaseService {
69
70
  // 根据用户配置,设置关联查询的数据信息。
70
71
  await this.crudStdRelationService.addCfgModelColumnsRelation(cfgModel, appInfo);
71
72
 
73
+ // 根据表结构的数据类型,修正数据类型
74
+ await this.fixDataFieldTypeBySqlTableField(params, cfgModel, appInfo, { dbType, dbName });
75
+
72
76
  // 业务系统自定义的修改cfgModel
73
77
  await GLOBAL_STATIC_CONFIG.getConfig().bizUpdateCfgModelForCrudStd(params, cfgModel, appInfo, this.ctx);
74
78
 
@@ -138,11 +142,8 @@ export class CrudStdService extends ApiBaseService {
138
142
  * @private
139
143
  */
140
144
  private async getCrudStdAppInfo(appCode?: string) {
141
-
142
145
  const { SystemDbName, SystemDbType } = GLOBAL_STATIC_CONFIG.getConfig();
143
146
 
144
-
145
-
146
147
  this.logInfo('getCrudStdAppInfo', appCode);
147
148
 
148
149
  const ss = {
@@ -195,4 +196,31 @@ export class CrudStdService extends ApiBaseService {
195
196
  }
196
197
  return true; // 无需鉴权
197
198
  }
199
+
200
+ private async fixDataFieldTypeBySqlTableField(params: IRequestModel, cfgModel: IRequestCfgModel, appInfo: ICrudStdAppInfoForSettingKey, arg3: { dbType: SqlDbType; dbName: string }) {
201
+ const tableFields = _.get(appInfo, 'stdCrudCfgObj.tableFields');
202
+
203
+ const tableFieldMap = MixinUtils.toMap(tableFields, (e: any) => {
204
+ return e.fieldIndex;
205
+ });
206
+
207
+ if (arg3.dbType === SqlDbType.postgres) {
208
+ if (cfgModel.sqlSimpleName === KeysOfSimpleSQL.SIMPLE_INSERT || cfgModel.sqlSimpleName === KeysOfSimpleSQL.SIMPLE_UPDATE) {
209
+ const data = params.data || {};
210
+ const dataKeys = Object.keys(data);
211
+ for (let index = 0; index < dataKeys.length; index++) {
212
+ const dataKey = dataKeys[index];
213
+ const dataValue = data[dataKey];
214
+ const fieldInfo = tableFieldMap[dataKey];
215
+ const fieldType = ('' + _.get(fieldInfo, 'type')).toUpperCase();
216
+ if (fieldType === 'ARRAY') {
217
+ const dataValueArray = parseJsonObject(dataValue);
218
+ if (Array.isArray(dataValueArray)) {
219
+ data[dataKey] = `{${dataValueArray.map(v => `"${v}"`).join(',')}}`;
220
+ }
221
+ }
222
+ }
223
+ }
224
+ }
225
+ }
198
226
  }
@@ -0,0 +1,137 @@
1
+ import { KeysOfSimpleSQL, SqlDbType } from "@/libs/crud-pro/models/keys";
2
+ import { IRequestCfgModel, IRequestModel, ISqlCfgModel } from "@/libs/crud-pro/interfaces";
3
+ import { IRequestCfgModel2 } from "@/models/bizmodels";
4
+ import { CrudPro } from "@/libs/crud-pro/CrudPro";
5
+ import { ResModelAffected, ResModelStandard } from "@/libs/crud-pro/models/ResModel";
6
+
7
+
8
+
9
+ export class CrudProQuick {
10
+ private readonly curdPro: CrudPro;
11
+ private readonly sqlDbType: SqlDbType;
12
+ private readonly sqlDatabase: string;
13
+ private readonly sqlTable?: string;
14
+ private baseCfgModel: IRequestCfgModel2 = {};
15
+
16
+ constructor(curdPro: CrudPro, sqlDatabase: string, sqlDbType: SqlDbType, sqlTable?: string) {
17
+ this.sqlDatabase = sqlDatabase;
18
+ this.sqlDbType = sqlDbType;
19
+ this.curdPro = curdPro;
20
+ this.sqlTable = sqlTable; // 全局sqlTable为空时,单独调用时就必须传sqlTable参数。
21
+ }
22
+
23
+ public setBaseCfgModel(baseCfgModel: IRequestCfgModel2) {
24
+ Object.assign(this.baseCfgModel, baseCfgModel);
25
+ }
26
+
27
+ private async executeCrudByCfg(reqJson: IRequestModel, cfgModel2: IRequestCfgModel2) {
28
+
29
+ const cfgModel = { ...this.baseCfgModel };
30
+ Object.assign(cfgModel, cfgModel2);
31
+
32
+ cfgModel.method = 'CrudProQuickAnonymous';
33
+ cfgModel.updateCfg = {};
34
+ cfgModel.sqlDatabase = this.sqlDatabase;
35
+ cfgModel.sqlDbType = this.sqlDbType;
36
+
37
+ if (!cfgModel.sqlTable) {
38
+ cfgModel.sqlTable = this.sqlTable;
39
+ }
40
+
41
+ if (!cfgModel.sqlTable) {
42
+ throw new Error('[CrudProQuick] sqlTable not found');
43
+ }
44
+
45
+ return await this.curdPro.executeCrudByCfg(reqJson, cfgModel);
46
+ }
47
+
48
+
49
+ public async getOne(reqJson: IRequestModel, sqlTable?: string): Promise<any> {
50
+ const cfgModel: IRequestCfgModel = {
51
+ sqlTable,
52
+ sqlSimpleName: KeysOfSimpleSQL.SIMPLE_QUERY_ONE,
53
+ };
54
+ const res = await this.executeCrudByCfg(reqJson, cfgModel);
55
+ return res.getOneObj();
56
+ }
57
+
58
+ public async getList(reqJson: IRequestModel, sqlTable?: string): Promise<any[]> {
59
+ const cfgModel: IRequestCfgModel = {
60
+ sqlTable,
61
+ sqlSimpleName: KeysOfSimpleSQL.SIMPLE_QUERY,
62
+ };
63
+ const res = await this.executeCrudByCfg(reqJson, cfgModel);
64
+ return res.getResRows();
65
+ }
66
+
67
+ public async getListPage(reqJson: IRequestModel, sqlTable?: string): Promise<ResModelStandard> {
68
+ const cfgModel: IRequestCfgModel = {
69
+ sqlTable,
70
+ sqlSimpleName: KeysOfSimpleSQL.SIMPLE_QUERY_PAGE,
71
+ };
72
+ const res = await this.executeCrudByCfg(reqJson, cfgModel);
73
+ return res.getResModel(); // 因为它有2个返回值
74
+ }
75
+
76
+ public async getTotalCount(reqJson: IRequestModel, sqlTable?: string): Promise<number> {
77
+ const cfgModel: IRequestCfgModel = {
78
+ sqlTable,
79
+ sqlSimpleName: KeysOfSimpleSQL.SIMPLE_QUERY_COUNT,
80
+ };
81
+ const res = await this.executeCrudByCfg(reqJson, cfgModel);
82
+ return res.getResModel().total_count;
83
+ }
84
+
85
+ public async insertObject(reqJson: IRequestModel, sqlTable?: string): Promise<ResModelAffected> {
86
+ const cfgModel: IRequestCfgModel = {
87
+ sqlTable,
88
+ sqlSimpleName: KeysOfSimpleSQL.SIMPLE_INSERT,
89
+ };
90
+ const res = await this.executeCrudByCfg(reqJson, cfgModel);
91
+ return res.getResModel().affected;
92
+ }
93
+
94
+ public async updateObject(reqJson: IRequestModel, sqlTable?: string): Promise<ResModelAffected> {
95
+ const cfgModel: IRequestCfgModel = {
96
+ sqlTable,
97
+ sqlSimpleName: KeysOfSimpleSQL.SIMPLE_UPDATE,
98
+ };
99
+ const res = await this.executeCrudByCfg(reqJson, cfgModel);
100
+ return res.getResModel().affected;
101
+ }
102
+
103
+ public async insertOrUpdate(reqJson: IRequestModel, sqlTable?: string): Promise<ResModelStandard> {
104
+ const cfgModel: IRequestCfgModel = {
105
+ sqlTable,
106
+ sqlSimpleName: KeysOfSimpleSQL.SIMPLE_INSERT_OR_UPDATE,
107
+ };
108
+ const res = await this.executeCrudByCfg(reqJson, cfgModel);
109
+ return res.getResModel(); // 因为它有三个返回值
110
+ }
111
+
112
+ public async deleteObject(reqJson: IRequestModel, sqlTable?: string): Promise<ResModelAffected> {
113
+ const cfgModel: IRequestCfgModel = {
114
+ sqlTable,
115
+ sqlSimpleName: KeysOfSimpleSQL.SIMPLE_DELETE,
116
+ };
117
+ const res = await this.executeCrudByCfg(reqJson, cfgModel);
118
+ return res.getResModel().affected;
119
+ }
120
+
121
+
122
+ public async executeSQL(executeSql: string, args?: any[]): Promise<any> {
123
+ const sqlCfgModel: ISqlCfgModel = {
124
+ executeSql: executeSql,
125
+ executeSqlArgs: args,
126
+ sqlDatabase: this.sqlDatabase,
127
+ sqlDbType: this.sqlDbType,
128
+ };
129
+ return await this.curdPro.executeSQL(sqlCfgModel);
130
+ }
131
+
132
+
133
+
134
+
135
+ }
136
+
137
+
@@ -1,19 +1,46 @@
1
- import {Inject, Provide} from '@midwayjs/core';
2
- import {Context} from '@midwayjs/koa';
1
+ import { Inject, Provide } from '@midwayjs/core';
2
+ import { Context } from '@midwayjs/koa';
3
3
  import * as _ from 'lodash';
4
- import {CurdProService} from './CurdProService';
5
- import {ExecuteContext, IExecuteContextHandler} from '../../libs/crud-pro/models/ExecuteContext';
6
- import {CrudMixUtils, RelatedType} from './CurdMixUtils';
7
- import {KeysOfSimpleSQL} from '../../libs/crud-pro/models/keys';
8
- import {ColumnRelation} from '../../libs/crud-pro/interfaces';
9
- import {BizException} from "../../models/devops";
10
- import {Exceptions} from "../../libs/crud-pro/exceptions";
11
- import {RedisCacheService} from "../base/RedisCacheService";
12
- import {parseDatabaseName} from "../../libs/crud-pro/utils/DatabaseName";
4
+ import { CurdProService } from './CurdProService';
5
+ import { ExecuteContext, IExecuteContextHandler } from '../../libs/crud-pro/models/ExecuteContext';
6
+ import { CrudMixUtils, RelatedType } from './CurdMixUtils';
7
+ import { KeysOfSimpleSQL } from '../../libs/crud-pro/models/keys';
8
+ import { ColumnRelation } from '../../libs/crud-pro/interfaces';
9
+ import { BizException } from '../../models/devops';
10
+ import { Exceptions } from '../../libs/crud-pro/exceptions';
11
+ import { RedisCacheService } from '../base/RedisCacheService';
12
+ import { parseDatabaseName } from '../../libs/crud-pro/utils/DatabaseName';
13
+ import { GLOBAL_STATIC_CONFIG } from '@/libs/global-config/global-config';
14
+ import { IRequestCfgModel2 } from '@/models/bizmodels';
13
15
 
14
16
  const linkToCustomMixUtils = new CrudMixUtils(RelatedType.linkToCustom);
15
17
  const TMP_CTX_KEY = _.uniqueId('CurdMixByLinkToCustomService');
16
18
 
19
+ function toMapObject(rows: any[], fieldsArr: string[]): Map<string, any> {
20
+ const valueKey = fieldsArr[0];
21
+ const labelKey = fieldsArr[1];
22
+
23
+ const isObjectMode = fieldsArr.length > 2 || labelKey === '*';
24
+
25
+ const map = new Map<string, any>();
26
+ for (let i = 0; i < rows.length; i++) {
27
+ const rowObj = rows[i];
28
+ const value = rowObj[valueKey];
29
+
30
+ if (typeof value !== 'undefined') {
31
+ const valueStr = '' + value;
32
+ if (isObjectMode) {
33
+ map.set(valueStr, rowObj);
34
+ } else {
35
+ const label = rowObj[labelKey];
36
+ if (label) {
37
+ map.set(valueStr, label);
38
+ }
39
+ }
40
+ }
41
+ }
42
+ return map;
43
+ }
17
44
 
18
45
  @Provide()
19
46
  export class CurdMixByLinkToCustomService implements IExecuteContextHandler {
@@ -26,7 +53,6 @@ export class CurdMixByLinkToCustomService implements IExecuteContextHandler {
26
53
  @Inject()
27
54
  protected redisCacheService: RedisCacheService;
28
55
 
29
-
30
56
  async handleExecuteContextPrepare(executeContext: ExecuteContext) {
31
57
  const relations = linkToCustomMixUtils.pickColumnRelations(executeContext);
32
58
 
@@ -37,7 +63,7 @@ export class CurdMixByLinkToCustomService implements IExecuteContextHandler {
37
63
  }
38
64
 
39
65
  async handleExecuteContext(executeContext: ExecuteContext): Promise<void> {
40
- const dataInfoMap = executeContext[TMP_CTX_KEY] as Map<string,Map<string,any>>
66
+ const dataInfoMap = executeContext[TMP_CTX_KEY] as Map<string, Map<string, any>>;
41
67
  if (!dataInfoMap || dataInfoMap.size === 0) {
42
68
  return;
43
69
  }
@@ -45,19 +71,17 @@ export class CurdMixByLinkToCustomService implements IExecuteContextHandler {
45
71
  const relatedCode = columnRelation.relatedCode;
46
72
  const dataMap = dataInfoMap.get(relatedCode);
47
73
  if (dataMap) {
48
-
49
74
  const sourceColumn = columnRelation.sourceColumn;
50
75
  const targetColumns = columnRelation.targetColumns;
51
76
  if (!Array.isArray(targetColumns) || targetColumns.length === 0) {
52
77
  columnRelation.targetColumns = [
53
78
  {
54
- "from": "*",
55
- "to": `${sourceColumn}_info[$ARRAY_INDEX]`
79
+ from: '*',
80
+ to: `${sourceColumn}_info[$ARRAY_INDEX]`,
56
81
  },
57
82
  ];
58
83
  }
59
84
 
60
-
61
85
  // this.ctx.logger.info("CurdMixByLinkToCustomService ==> dataMap", dataMap)
62
86
 
63
87
  linkToCustomMixUtils.copyColumnRelationToRowNoRelatedCode(row, dataMap, columnRelation);
@@ -65,11 +89,10 @@ export class CurdMixByLinkToCustomService implements IExecuteContextHandler {
65
89
  });
66
90
  }
67
91
 
68
-
69
- public async queryInfoByLinkToCustom(code: string): Promise<Map<string,any>> {
70
- const cacheKey = "linkToCustom@@"+code;
92
+ public async queryInfoByLinkToCustom(code: string): Promise<Map<string, any>> {
93
+ const cacheKey = 'linkToCustom@@' + code;
71
94
  let values;
72
- const expireSecond = 2 * 60 ; // 2分钟
95
+ const expireSecond = 2 * 60; // 2分钟
73
96
  const enumMap = await this.redisCacheService.getJsonObject(cacheKey);
74
97
  if (!enumMap || Object.keys(enumMap).length === 0) {
75
98
  values = await this.queryInfoByLinkToCustomImpl(code);
@@ -78,16 +101,21 @@ export class CurdMixByLinkToCustomService implements IExecuteContextHandler {
78
101
  return values;
79
102
  }
80
103
 
81
-
82
104
  /**
83
105
  * code形如:mysql_________fatcms~~~sys_perm_role~~~role_code,role_name,xxx_name
84
106
  * code形如:fatcms~~~sys_perm_role~~~role_code,role_name,xxx_name
85
107
  * code形如:fatcms~~~sys_perm_role~~~id,*
108
+ * code形如:GET_BY_CRUD_METHOD~~~GetActiveLineEnum~~~id,*
109
+ * code形如:GET_BY_CRUD_METHOD~~~GetActiveLineEnum~~~id,name
86
110
  * 【数据库】~~~【表名】~~~【value】,【label】,【style】
87
111
  * @param code
88
112
  * @private
89
113
  */
90
- private async queryInfoByLinkToCustomImpl(code: string): Promise<Map<string,any>>{
114
+ private async queryInfoByLinkToCustomImpl(code: string): Promise<Map<string, any>> {
115
+ if (code.startsWith('GET_BY_CRUD_METHOD')) {
116
+ return this.queryInfoByLinkToCustomByCrudMethod(code);
117
+ }
118
+
91
119
  const arr = code
92
120
  .split('~~~')
93
121
  .map(s => s.trim())
@@ -95,9 +123,10 @@ export class CurdMixByLinkToCustomService implements IExecuteContextHandler {
95
123
  if (arr.length !== 3) {
96
124
  throw new BizException('linkToCustom枚举值查询字符串,必须符合固定格式', Exceptions.CFG_ERROR);
97
125
  }
126
+
98
127
  const [sqlDatabase, sqlTable, fields] = arr;
99
128
 
100
- const {dbType, dbName} = parseDatabaseName(sqlDatabase);
129
+ const { dbType, dbName } = parseDatabaseName(sqlDatabase);
101
130
 
102
131
  const fieldsArr = fields
103
132
  .split(',')
@@ -108,15 +137,11 @@ export class CurdMixByLinkToCustomService implements IExecuteContextHandler {
108
137
  throw new BizException('linkToCustom枚举值查询字符串,fields字段必须符合固定格式', Exceptions.CFG_ERROR);
109
138
  }
110
139
 
111
- const valueKey = fieldsArr[0];
112
140
  const labelKey = fieldsArr[1];
113
-
114
- const isObjectMode = fieldsArr.length > 2 || labelKey === "*";
115
-
116
141
  const res1 = await this.curdProService.executeCrudByCfg(
117
142
  {
118
143
  condition: {},
119
- columns: labelKey === "*" ? null: fields,
144
+ columns: labelKey === '*' ? null : fields,
120
145
  limit: 4000,
121
146
  offset: 0,
122
147
  },
@@ -129,39 +154,65 @@ export class CurdMixByLinkToCustomService implements IExecuteContextHandler {
129
154
  }
130
155
  );
131
156
  const rows = res1.getResRows();
132
- const map = new Map<string, any>();
133
- for (let i = 0; i < rows.length; i++) {
134
- const rowObj = rows[i];
135
- const value = rowObj[valueKey];
136
-
137
- if (typeof value !== 'undefined') {
138
- const valueStr = "" +value;
139
- if (isObjectMode) {
140
- map.set(valueStr, rowObj);
141
- } else {
142
- const label = rowObj[labelKey];
143
- if (label){
144
- map.set(valueStr, label);
145
- }
146
- }
147
- }
157
+ const map = toMapObject(rows, fieldsArr);
158
+ return map;
159
+ }
148
160
 
161
+ /**
162
+ *
163
+ * @param code
164
+ * code形如:GET_BY_CRUD_METHOD~~~GetActiveLineEnum~~~id,*
165
+ * code形如:GET_BY_CRUD_METHOD~~~GetActiveLineEnum~~~id,name
166
+ */
167
+ private async queryInfoByLinkToCustomByCrudMethod(code: string): Promise<Map<string, any>> {
168
+ const arr = code
169
+ .split('~~~')
170
+ .map(s => s.trim())
171
+ .filter(Boolean);
172
+ if (arr.length !== 3) {
173
+ throw new BizException('linkToCustom枚举值查询字符串,必须符合固定格式。', Exceptions.CFG_ERROR);
174
+ }
175
+ const [prefix, methodCode, fields] = arr;
176
+
177
+ const fieldsArr = fields
178
+ .split(',')
179
+ .map(s => s.trim())
180
+ .filter(Boolean);
149
181
 
182
+ if (fieldsArr.length < 2) {
183
+ throw new BizException(`linkToCustom枚举值查询字符串,fields字段必须符合固定格式。${prefix}`, Exceptions.CFG_ERROR);
184
+ }
185
+
186
+ const methodInfo = (await this.curdProService.getCachedCfgByMethod(methodCode)) as any;
187
+ if (!methodInfo || methodInfo.status !== 1) {
188
+ throw new Error('接口不存在或已下线: ' + methodCode);
150
189
  }
190
+
191
+ const cfgModel = methodInfo as IRequestCfgModel2;
192
+ const { dbType, dbName } = parseDatabaseName(cfgModel.sqlDatabase);
193
+ cfgModel.sqlDatabase = dbName;
194
+ cfgModel.sqlDbType = dbType;
195
+
196
+ const reqJson = {};
197
+
198
+ await GLOBAL_STATIC_CONFIG.getConfig().bizUpdateCfgModelForCrudMtd(reqJson, cfgModel, methodInfo, this.ctx);
199
+
200
+ const exeCtx = await this.curdProService.executeCrudByCfg(reqJson, cfgModel);
201
+
202
+ const rows = exeCtx.getResRows();
203
+ const map = toMapObject(rows, fieldsArr);
151
204
  return map;
152
205
  }
153
206
 
154
-
155
- private async loadInfoByLinkToCustomMap(relations: ColumnRelation[]): Promise<Map<string,Map<string,any>>> {
207
+ private async loadInfoByLinkToCustomMap(relations: ColumnRelation[]): Promise<Map<string, Map<string, any>>> {
156
208
  const bigMap = new Map<string, Map<string, any>>();
157
209
  for (let i = 0; i < relations.length; i++) {
158
210
  const relation = relations[i];
159
- const code = relation.relatedCode || "";
211
+ const code = relation.relatedCode || '';
160
212
  const codeTrim = code.trim();
161
213
  const map = await this.queryInfoByLinkToCustom(codeTrim);
162
214
  bigMap.set(codeTrim, map);
163
215
  }
164
216
  return bigMap;
165
217
  }
166
-
167
218
  }
@@ -8,7 +8,7 @@ import { RelatedType } from './CurdMixUtils';
8
8
  import { CurdMixByWorkbenchService } from './CurdMixByWorkbenchService';
9
9
  import { IRequestCfgModel2 } from '../../models/bizmodels';
10
10
  import {CurdMixByLinkToCustomService} from "./CurdMixByLinkToCustomService";
11
- import {SqlDbType} from "../../libs/crud-pro/models/keys";
11
+ import {SqlDbType} from "@/libs/crud-pro/models/keys";
12
12
 
13
13
  @Provide()
14
14
  export class CurdMixService {
@@ -44,9 +44,9 @@ export class CurdMixService {
44
44
  return this.curdProService.executeCrudByCfg(reqJson, cfgModel);
45
45
  }
46
46
 
47
- getBbUtil(database: string, sqlDbType: SqlDbType) {
47
+ getBbUtil(sqlDatabase: string, sqlDbType: SqlDbType, sqlTable?: string) {
48
48
  this.prepare();
49
- return this.curdProService.getBbUtil(database, sqlDbType);
49
+ return this.curdProService.getBbUtil(sqlDatabase, sqlDbType, sqlTable);
50
50
  }
51
51
 
52
52
  async executeSQL(sqlCfgModel: ISqlCfgModel) {
@@ -1,12 +1,12 @@
1
- import { ColumnRelation, CopyAttr } from '../../libs/crud-pro/interfaces';
2
- import { ExecuteContext } from '../../libs/crud-pro/models/ExecuteContext';
3
- import { KeyOfCrudTypes } from '../../libs/crud-pro/models/keys';
4
- import { MixinUtils } from '../../libs/crud-pro/utils/MixinUtils';
5
- import { SqlCfgModel } from '../../libs/crud-pro/models/SqlCfgModel';
6
- import { RequestCfgModel } from '../../libs/crud-pro/models/RequestCfgModel';
1
+ import { ColumnRelation, CopyAttr } from '@/libs/crud-pro/interfaces';
2
+ import { ExecuteContext } from '@/libs/crud-pro/models/ExecuteContext';
3
+ import { KeyOfCrudTypes } from '@/libs/crud-pro/models/keys';
4
+ import { MixinUtils } from '@/libs/crud-pro/utils/MixinUtils';
5
+ import { SqlCfgModel } from '@/libs/crud-pro/models/SqlCfgModel';
6
+ import { RequestCfgModel } from '@/libs/crud-pro/models/RequestCfgModel';
7
7
  import * as _ from 'lodash';
8
- import { MultiKeyMap } from '../../libs/crud-pro/utils/MultiKeyMap';
9
- import { parseJsonObject } from '../../libs/utils/functions';
8
+ import { MultiKeyMap } from '@/libs/crud-pro/utils/MultiKeyMap';
9
+ import { parseJsonObject } from '@/libs/utils/functions';
10
10
 
11
11
  enum RelatedType {
12
12
  dict = 'dict', // 关联数据字典
@@ -59,45 +59,58 @@ function copyBySingleSourceValue(row: any, sourceValue: any, targetColumns: Copy
59
59
 
60
60
 
61
61
 
62
- function copyByArraySourceValue(row: any, sourceValue: any, targetColumns: CopyAttr[], getValue: any): boolean {
63
- let isSetArray = false;
64
- // 支持关联JSON数组
65
- if (typeof sourceValue === 'string' && sourceValue.startsWith('[') && sourceValue.endsWith(']')) {
66
- const codes = parseJsonObject(sourceValue);
67
- if (Array.isArray(codes)) {
68
- for (let codeIndex = 0; codeIndex < codes.length; codeIndex++) {
69
- const code = codes[codeIndex];
70
- // const codeObject = map.get(code);
71
- const codeObject = getValue(code);
72
- if (codeObject) {
73
- if (Array.isArray(targetColumns)) {
74
- for (let i = 0; i < targetColumns.length; i++) {
75
- const targetColumn = targetColumns[i];
76
-
77
- if (targetColumn.from === '*') {
78
-
79
- const toStr = targetColumn.to.replace('$ARRAY_INDEX', `${codeIndex}`);
80
- _.set(row, toStr, codeObject);
81
-
82
- isSetArray = true;
83
- } else {
84
- const dictAttrValue = _.get(codeObject, targetColumn.from);
85
- if (typeof dictAttrValue !== 'undefined' && dictAttrValue !== null) {
86
- const toStr = targetColumn.to.replace('$ARRAY_INDEX', `${codeIndex}`);
87
- _.set(row, toStr, dictAttrValue);
88
- isSetArray = true;
89
- }
90
- }
62
+
63
+
64
+
65
+
66
+ function copyByArraySourceValueInner(row: any, codes: any[], targetColumns: CopyAttr[], getValue: any, resultObj: any) {
67
+
68
+ for (let codeIndex = 0; codeIndex < codes.length; codeIndex++) {
69
+ const code = codes[codeIndex];
70
+ // const codeObject = map.get(code);
71
+ const codeObject = getValue(code);
72
+ if (codeObject) {
73
+ if (Array.isArray(targetColumns)) {
74
+ for (let i = 0; i < targetColumns.length; i++) {
75
+ const targetColumn = targetColumns[i];
76
+
77
+ if (targetColumn.from === '*') {
78
+
79
+ const toStr = targetColumn.to.replace('$ARRAY_INDEX', `${codeIndex}`);
80
+ _.set(row, toStr, codeObject);
81
+
82
+ resultObj.isSetArray = true;
83
+ } else {
84
+ const dictAttrValue = _.get(codeObject, targetColumn.from);
85
+ if (typeof dictAttrValue !== 'undefined' && dictAttrValue !== null) {
86
+ const toStr = targetColumn.to.replace('$ARRAY_INDEX', `${codeIndex}`);
87
+ _.set(row, toStr, dictAttrValue);
88
+ resultObj.isSetArray = true;
91
89
  }
92
90
  }
93
91
  }
94
92
  }
95
93
  }
96
94
  }
95
+ }
97
96
 
98
- return isSetArray;
97
+ function copyByArraySourceValue(row: any, sourceValue: any, targetColumns: CopyAttr[], getValue: any): boolean {
98
+ const resultObj = {isSetArray: false }
99
+ // 支持关联JSON数组。使用 字符串存储的类型
100
+ if (typeof sourceValue === 'string' && sourceValue.startsWith('[') && sourceValue.endsWith(']')) {
101
+ const codes = parseJsonObject(sourceValue);
102
+ if (Array.isArray(codes)) {
103
+ copyByArraySourceValueInner(row, codes, targetColumns, getValue, resultObj);
104
+ }
105
+ } else if(Array.isArray(sourceValue)) {
106
+ // 直接使用JSON或者postgres的数组存储的类型
107
+ copyByArraySourceValueInner(row, sourceValue, targetColumns, getValue, resultObj);
108
+ }
109
+ return resultObj.isSetArray;
99
110
  }
100
111
 
112
+
113
+
101
114
  class CrudMixUtils {
102
115
  private readonly relatedType: RelatedType;
103
116
  constructor(relatedType: RelatedType) {