midway-fatcms 0.0.11 → 0.0.13
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.d.ts +0 -2
- package/dist/configuration.js +14 -12
- package/dist/controller/gateway/CrudMtdGatewayController.js +2 -1
- package/dist/controller/gateway/DocGatewayController.js +7 -5
- package/dist/controller/gateway/PublicApiController.js +32 -3
- package/dist/controller/gateway/StaticController.d.ts +0 -2
- package/dist/controller/gateway/StaticController.js +4 -39
- package/dist/controller/home.controller.js +2 -1
- package/dist/controller/manage/AccountRoleManageApi.d.ts +2 -1
- package/dist/controller/manage/AccountRoleManageApi.js +34 -0
- package/dist/controller/manage/DataDictManageApi.d.ts +2 -0
- package/dist/controller/manage/DataDictManageApi.js +41 -9
- package/dist/controller/manage/DocManageApi.js +2 -2
- package/dist/controller/manage/UserAccountManageApi.js +4 -3
- package/dist/controller/render/AppRenderController.js +7 -6
- package/dist/libs/crud-pro/CrudPro.d.ts +0 -1
- package/dist/libs/crud-pro/CrudPro.js +2 -11
- package/dist/libs/crud-pro/exceptions.d.ts +6 -0
- package/dist/libs/crud-pro/exceptions.js +6 -0
- package/dist/libs/crud-pro/models/keys.d.ts +1 -0
- package/dist/libs/crud-pro/models/keys.js +1 -0
- package/dist/libs/crud-pro/services/CrudProExecuteFuncService.js +2 -2
- package/dist/libs/crud-pro/services/CrudProFieldUpdateService.js +3 -0
- package/dist/libs/crud-pro/services/CrudProTableMetaService.js +2 -2
- package/dist/libs/crud-pro/utils/DatabaseName.js +11 -0
- package/dist/libs/crud-pro/utils/DateTimeUtils.js +1 -1
- package/dist/libs/crud-pro/utils/SqlErrorParseUtils.d.ts +22 -0
- package/dist/libs/crud-pro/utils/SqlErrorParseUtils.js +219 -0
- package/dist/libs/utils/functions.d.ts +8 -1
- package/dist/libs/utils/functions.js +29 -1
- package/dist/service/AuthService.js +1 -1
- package/dist/service/anyapi/AnyApiService.js +1 -1
- package/dist/service/crudstd/CrudStdService.js +8 -3
- package/dist/service/curd/CurdMixByDictService.js +1 -1
- package/dist/service/curd/CurdMixBySysConfigService.js +1 -1
- package/dist/service/curd/CurdMixByWorkbenchService.js +1 -1
- package/dist/service/curd/fixCfgModel.js +3 -1
- package/dist/service/proxyapi/ProxyApiLoadService.js +3 -0
- package/package.json +1 -1
- package/src/configuration.ts +18 -11
- package/src/controller/gateway/CrudMtdGatewayController.ts +2 -1
- package/src/controller/gateway/DocGatewayController.ts +9 -5
- package/src/controller/gateway/PublicApiController.ts +39 -4
- package/src/controller/gateway/StaticController.ts +11 -40
- package/src/controller/home.controller.ts +3 -1
- package/src/controller/manage/AccountRoleManageApi.ts +38 -0
- package/src/controller/manage/DataDictManageApi.ts +48 -11
- package/src/controller/manage/DocManageApi.ts +2 -2
- package/src/controller/manage/UserAccountManageApi.ts +4 -3
- package/src/controller/render/AppRenderController.ts +9 -7
- package/src/libs/crud-pro/CrudPro.ts +2 -12
- package/src/libs/crud-pro/exceptions.ts +6 -0
- package/src/libs/crud-pro/models/keys.ts +1 -0
- package/src/libs/crud-pro/services/CrudProExecuteFuncService.ts +3 -2
- package/src/libs/crud-pro/services/CrudProFieldUpdateService.ts +5 -0
- package/src/libs/crud-pro/services/CrudProTableMetaService.ts +2 -2
- package/src/libs/crud-pro/utils/DatabaseName.ts +12 -0
- package/src/libs/crud-pro/utils/DateTimeUtils.ts +1 -1
- package/src/libs/crud-pro/utils/SqlErrorParseUtils.ts +236 -0
- package/src/libs/utils/functions.ts +37 -2
- package/src/service/AuthService.ts +2 -2
- package/src/service/anyapi/AnyApiService.ts +2 -2
- package/src/service/crudstd/CrudStdService.ts +9 -4
- package/src/service/curd/CurdMixByDictService.ts +1 -1
- package/src/service/curd/CurdMixBySysConfigService.ts +1 -1
- package/src/service/curd/CurdMixByWorkbenchService.ts +1 -1
- package/src/service/curd/fixCfgModel.ts +3 -1
- package/src/service/proxyapi/ProxyApiLoadService.ts +4 -1
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { CommonException, Exceptions } from '../exceptions';
|
|
2
|
+
|
|
3
|
+
interface ISqlErrorRule {
|
|
4
|
+
code: string;
|
|
5
|
+
match: (e: any, message: string) => boolean;
|
|
6
|
+
message: string | ((message: string) => string);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const SqlErrorParseUtils = {
|
|
10
|
+
/**
|
|
11
|
+
* 从驱动原始错误中提取可读 SQL 错误信息(兼容 MySQL / PostgreSQL / SQL Server)
|
|
12
|
+
*/
|
|
13
|
+
getSqlErrorMessage(e: any): string {
|
|
14
|
+
return '' + (e?.sqlMessage || e?.message || '');
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
isDuplicateEntryError(e: any, sqlMessage?: string): boolean {
|
|
18
|
+
const message = sqlMessage ?? SqlErrorParseUtils.getSqlErrorMessage(e);
|
|
19
|
+
if (e?.code === Exceptions.RUN_SQL_EXCEPTION_ER_DUP_ENTRY) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
// MySQL
|
|
23
|
+
if (e?.code === 'ER_DUP_ENTRY' || e?.errno === 1062) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
// PostgreSQL
|
|
27
|
+
if (e?.code === '23505') {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
// SQL Server
|
|
31
|
+
if (e?.number === 2627 || e?.number === 2601) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return /duplicate key/i.test(message)
|
|
35
|
+
|| /unique constraint/i.test(message)
|
|
36
|
+
|| /unique key constraint/i.test(message)
|
|
37
|
+
|| message.startsWith('Duplicate entry');
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
isNoSuchTableError(e: any, sqlMessage?: string): boolean {
|
|
41
|
+
const message = sqlMessage ?? SqlErrorParseUtils.getSqlErrorMessage(e);
|
|
42
|
+
if (e?.code === Exceptions.RUN_SQL_EXCEPTION_ER_NO_SUCH_TABLE) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
// MySQL
|
|
46
|
+
if (e?.code === 'ER_NO_SUCH_TABLE' || e?.errno === 1146) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
// PostgreSQL
|
|
50
|
+
if (e?.code === '42P01') {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
// SQL Server
|
|
54
|
+
if (e?.number === 208) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
return /doesn't exist/i.test(message)
|
|
58
|
+
|| /does not exist/i.test(message)
|
|
59
|
+
|| /invalid object name/i.test(message)
|
|
60
|
+
|| /no such table/i.test(message);
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
/** 外键约束:父记录被引用,无法删除或修改 */
|
|
64
|
+
isForeignKeyParentReferencedError(e: any, sqlMessage?: string): boolean {
|
|
65
|
+
const message = sqlMessage ?? SqlErrorParseUtils.getSqlErrorMessage(e);
|
|
66
|
+
if (e?.code === Exceptions.RUN_SQL_EXCEPTION_ER_FK_PARENT_REFERENCED) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
if (e?.code === 'ER_ROW_IS_REFERENCED_2' || e?.errno === 1451) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
return /Cannot delete or update a parent row/i.test(message)
|
|
73
|
+
|| /update or delete on table .* violates foreign key constraint/i.test(message)
|
|
74
|
+
|| /DELETE statement conflicted with the REFERENCE constraint/i.test(message)
|
|
75
|
+
|| /UPDATE statement conflicted with the REFERENCE constraint/i.test(message);
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
/** 外键约束:关联的主数据不存在 */
|
|
79
|
+
isForeignKeyParentNotFoundError(e: any, sqlMessage?: string): boolean {
|
|
80
|
+
const message = sqlMessage ?? SqlErrorParseUtils.getSqlErrorMessage(e);
|
|
81
|
+
if (e?.code === Exceptions.RUN_SQL_EXCEPTION_ER_FK_PARENT_NOT_FOUND) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
if (e?.code === 'ER_NO_REFERENCED_ROW_2' || e?.errno === 1452) {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
// PostgreSQL / SQL Server 与父记录被引用共用错误码,需靠消息区分
|
|
88
|
+
if (e?.code === '23503' || e?.number === 547) {
|
|
89
|
+
return /insert or update on table/i.test(message)
|
|
90
|
+
|| /INSERT statement conflicted with the FOREIGN KEY constraint/i.test(message)
|
|
91
|
+
|| /INSERT statement conflicted with the REFERENCE constraint/i.test(message)
|
|
92
|
+
|| /violates foreign key constraint/i.test(message);
|
|
93
|
+
}
|
|
94
|
+
return /Cannot add or update a child row/i.test(message)
|
|
95
|
+
|| /insert or update on table .* violates foreign key constraint/i.test(message);
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
isNotNullViolationError(e: any, sqlMessage?: string): boolean {
|
|
99
|
+
const message = sqlMessage ?? SqlErrorParseUtils.getSqlErrorMessage(e);
|
|
100
|
+
if (e?.code === Exceptions.RUN_SQL_EXCEPTION_ER_NOT_NULL) {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
if (e?.code === 'ER_BAD_NULL_ERROR' || e?.errno === 1048) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
if (e?.code === '23502') {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
if (e?.number === 515) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
return /cannot be null/i.test(message)
|
|
113
|
+
|| /null value in column/i.test(message)
|
|
114
|
+
|| /violates not-null constraint/i.test(message)
|
|
115
|
+
|| /Cannot insert the value NULL into column/i.test(message);
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
isDataTooLongError(e: any, sqlMessage?: string): boolean {
|
|
119
|
+
const message = sqlMessage ?? SqlErrorParseUtils.getSqlErrorMessage(e);
|
|
120
|
+
if (e?.code === Exceptions.RUN_SQL_EXCEPTION_ER_DATA_TOO_LONG) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
if (e?.code === 'ER_DATA_TOO_LONG' || e?.errno === 1406) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
if (e?.code === '22001') {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
if (e?.number === 2628 || e?.number === 8152) {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
return /data too long/i.test(message)
|
|
133
|
+
|| /value too long/i.test(message)
|
|
134
|
+
|| /string data, right truncation/i.test(message)
|
|
135
|
+
|| /would be truncated/i.test(message);
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
isBadFieldError(e: any, sqlMessage?: string): boolean {
|
|
139
|
+
const message = sqlMessage ?? SqlErrorParseUtils.getSqlErrorMessage(e);
|
|
140
|
+
if (e?.code === Exceptions.RUN_SQL_EXCEPTION_ER_BAD_FIELD) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
if (e?.code === 'ER_BAD_FIELD_ERROR' || e?.errno === 1054) {
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
if (e?.code === '42703') {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
if (e?.number === 207) {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
return /unknown column/i.test(message)
|
|
153
|
+
|| /Invalid column name/i.test(message);
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
isDeadlockError(e: any, sqlMessage?: string): boolean {
|
|
157
|
+
const message = sqlMessage ?? SqlErrorParseUtils.getSqlErrorMessage(e);
|
|
158
|
+
if (e?.code === Exceptions.RUN_SQL_EXCEPTION_ER_DEADLOCK) {
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
if (e?.code === 'ER_LOCK_DEADLOCK' || e?.errno === 1213) {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
if (e?.code === '40P01') {
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
if (e?.number === 1205) {
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
return /deadlock/i.test(message);
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* 将数据库驱动原始错误规范化为 CommonException
|
|
175
|
+
*/
|
|
176
|
+
parseRunSqlException(e: any): CommonException {
|
|
177
|
+
if (e instanceof CommonException) {
|
|
178
|
+
return e;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const sqlMessage = SqlErrorParseUtils.getSqlErrorMessage(e);
|
|
182
|
+
const rules: ISqlErrorRule[] = [
|
|
183
|
+
{
|
|
184
|
+
code: Exceptions.RUN_SQL_EXCEPTION_ER_DUP_ENTRY,
|
|
185
|
+
match: SqlErrorParseUtils.isDuplicateEntryError,
|
|
186
|
+
message: '此条数据已存在,不能重复创建',
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
code: Exceptions.RUN_SQL_EXCEPTION_ER_NO_SUCH_TABLE,
|
|
190
|
+
match: SqlErrorParseUtils.isNoSuchTableError,
|
|
191
|
+
message: (message) => '查询的表不存在:' + message,
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
code: Exceptions.RUN_SQL_EXCEPTION_ER_FK_PARENT_REFERENCED,
|
|
195
|
+
match: SqlErrorParseUtils.isForeignKeyParentReferencedError,
|
|
196
|
+
message: '无法删除或修改:该数据已被其他记录引用,请先解除关联后再试',
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
code: Exceptions.RUN_SQL_EXCEPTION_ER_FK_PARENT_NOT_FOUND,
|
|
200
|
+
match: SqlErrorParseUtils.isForeignKeyParentNotFoundError,
|
|
201
|
+
message: '无法保存:所关联的数据不存在或已被删除',
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
code: Exceptions.RUN_SQL_EXCEPTION_ER_NOT_NULL,
|
|
205
|
+
match: SqlErrorParseUtils.isNotNullViolationError,
|
|
206
|
+
message: '操作失败:必填字段不能为空',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
code: Exceptions.RUN_SQL_EXCEPTION_ER_DATA_TOO_LONG,
|
|
210
|
+
match: SqlErrorParseUtils.isDataTooLongError,
|
|
211
|
+
message: '操作失败:输入内容超出字段长度限制',
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
code: Exceptions.RUN_SQL_EXCEPTION_ER_BAD_FIELD,
|
|
215
|
+
match: SqlErrorParseUtils.isBadFieldError,
|
|
216
|
+
message: '操作失败:字段配置有误,请联系管理员检查表结构或接口配置',
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
code: Exceptions.RUN_SQL_EXCEPTION_ER_DEADLOCK,
|
|
220
|
+
match: SqlErrorParseUtils.isDeadlockError,
|
|
221
|
+
message: '操作失败:系统繁忙,请稍后重试',
|
|
222
|
+
},
|
|
223
|
+
];
|
|
224
|
+
|
|
225
|
+
for (const rule of rules) {
|
|
226
|
+
if (rule.match(e, sqlMessage)) {
|
|
227
|
+
const message = typeof rule.message === 'function' ? rule.message(sqlMessage) : rule.message;
|
|
228
|
+
return new CommonException(rule.code, message);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return e;
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
export { SqlErrorParseUtils };
|
|
@@ -7,7 +7,7 @@ function createUniqueId(): string {
|
|
|
7
7
|
if (createUniqueIdIndex > Date.now()) {
|
|
8
8
|
createUniqueIdIndex = 0;
|
|
9
9
|
}
|
|
10
|
-
const p1 = md5(Date.now() + '' + Math.random() + '_' + createUniqueIdIndex + '_' +
|
|
10
|
+
const p1 = md5(Date.now() + '' + Math.random() + '_' + createUniqueIdIndex + '_' + Math.random());
|
|
11
11
|
const p2 = `${Date.now().toString(32)}`.padStart(10, '0');
|
|
12
12
|
const p3 = `${createUniqueIdIndex.toString(32)}`.padStart(10, '0');
|
|
13
13
|
return p1 + p2 + p3;
|
|
@@ -106,4 +106,39 @@ function isOnlyAscii(str: string): boolean {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
/**
|
|
110
|
+
* 如果entity不存在删除属性或属性为0,表示未删除
|
|
111
|
+
* @param entity
|
|
112
|
+
* @returns
|
|
113
|
+
*/
|
|
114
|
+
function isEntityDeleted(entity: any): boolean {
|
|
115
|
+
if (!entity) {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const deletedAt = Number(entity.deleted_at);
|
|
120
|
+
if (deletedAt && deletedAt > 0) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const deletedAt2 = Number(entity.deletedAt);
|
|
125
|
+
if (deletedAt2 && deletedAt2 > 0) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
function isEntityOK(entity: any): boolean {
|
|
133
|
+
if(!entity) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
const isOK = entity?.status === 1 || entity?.status === '1';
|
|
137
|
+
return isOK && !isEntityDeleted(entity);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
export { createUniqueId, parseJsonObject, parseStringTrimArray, getCurrentFullMoment, isOnlyAscii, isEntityDeleted, isEntityOK };
|
|
@@ -142,8 +142,8 @@ export class AuthService extends BaseService {
|
|
|
142
142
|
const { publicKey, privateKey } = await AsymmetricCrypto.generateKeyPair();
|
|
143
143
|
|
|
144
144
|
const sessionInfo: ISessionInfo = {
|
|
145
|
-
nickName: userAccount.nick_name,
|
|
146
|
-
avatar: userAccount.avatar,
|
|
145
|
+
nickName: userAccount.nick_name ,
|
|
146
|
+
avatar: userAccount.avatar || "",
|
|
147
147
|
roleCodes,
|
|
148
148
|
functionCodes,
|
|
149
149
|
loginName,
|
|
@@ -7,7 +7,7 @@ import { BizException } from '@/models/devops';
|
|
|
7
7
|
import { CurdMixService } from '../curd/CurdMixService';
|
|
8
8
|
import { ISysAnyApiEntity } from '@/models/SystemEntities';
|
|
9
9
|
import { AnyApiSandboxService, IRunInSandboxParams } from './AnyApiSandboxService';
|
|
10
|
-
import { parseJsonObject } from '@/libs/utils/functions';
|
|
10
|
+
import { isEntityOK, parseJsonObject } from '@/libs/utils/functions';
|
|
11
11
|
import * as _ from 'lodash';
|
|
12
12
|
import { MixinUtils } from '@/libs/crud-pro/utils/MixinUtils';
|
|
13
13
|
import { WorkbenchService } from '../WorkbenchService';
|
|
@@ -37,7 +37,7 @@ export class AnyApiService extends ApiBaseService {
|
|
|
37
37
|
|
|
38
38
|
async executeAnyApiMethod(methodCode: string, headers: any, body: any, query: any) {
|
|
39
39
|
const anyApi = await this.getAnyApiMethod(methodCode);
|
|
40
|
-
if (!anyApi
|
|
40
|
+
if (!isEntityOK(anyApi)) {
|
|
41
41
|
throw new BizException('接口不存在或已下线:' + methodCode);
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -6,7 +6,7 @@ import { Context } from '@midwayjs/koa';
|
|
|
6
6
|
import { CurdMixService } from '../curd/CurdMixService';
|
|
7
7
|
import { IRequestCfgModel, IRequestModel } from '@/libs/crud-pro/interfaces';
|
|
8
8
|
import { KeysOfAuthType, KeysOfSimpleSQL, SqlDbType } from '@/libs/crud-pro/models/keys';
|
|
9
|
-
import { parseJsonObject } from '@/libs/utils/functions';
|
|
9
|
+
import { isEntityOK, parseJsonObject } from '@/libs/utils/functions';
|
|
10
10
|
import { ICrudStdAppInfo, ICrudStdAppInfoForSettingKey, IRequestCfgModel2 } from '@/models/bizmodels';
|
|
11
11
|
import { BizException } from '@/models/devops';
|
|
12
12
|
import { ExecuteContext } from '@/libs/crud-pro/models/ExecuteContext';
|
|
@@ -95,7 +95,7 @@ export class CrudStdService extends ApiBaseService {
|
|
|
95
95
|
const appCode = stdAction.appCode;
|
|
96
96
|
const appInfo = await this.getParsedCrudStdAppForSettingKey(stdAction);
|
|
97
97
|
|
|
98
|
-
if (!appInfo
|
|
98
|
+
if (!isEntityOK(appInfo)) {
|
|
99
99
|
throw new BizException('应用不存在或已下线:' + appCode);
|
|
100
100
|
}
|
|
101
101
|
|
|
@@ -103,6 +103,9 @@ export class CrudStdService extends ApiBaseService {
|
|
|
103
103
|
|
|
104
104
|
//删除策略
|
|
105
105
|
const deleteStrategy = _.get(stdCrudCfgObj, 'othersSetting.values.deleteStrategy');
|
|
106
|
+
// 自动
|
|
107
|
+
const enableStandardUpdateCfg: string[] = _.get(stdCrudCfgObj, 'othersSetting.values.enableStandardUpdateCfg');
|
|
108
|
+
const enableStandardUpdateCfgCondition: string[] = _.get(stdCrudCfgObj, 'othersSetting.values.enableStandardUpdateCfgCondition');
|
|
106
109
|
|
|
107
110
|
const databaseName = stdCrudCfgObj.tableBaseInfo.databaseName;
|
|
108
111
|
|
|
@@ -114,7 +117,9 @@ export class CrudStdService extends ApiBaseService {
|
|
|
114
117
|
sqlTable: getExecuteTableNameBySettingKey(appInfo, stdAction, sqlSimpleName),
|
|
115
118
|
sqlSimpleName,
|
|
116
119
|
updateCfg: {},
|
|
117
|
-
enableSoftDelete: deleteStrategy === 'soft' // 软删除
|
|
120
|
+
enableSoftDelete: deleteStrategy === 'soft', // 软删除
|
|
121
|
+
enableStandardUpdateCfg: Array.isArray(enableStandardUpdateCfg) && enableStandardUpdateCfg.length > 0 ? enableStandardUpdateCfg : ['by', 'at'], // 默认为 ['by', 'at']
|
|
122
|
+
enableStandardUpdateCfgCondition: Array.isArray(enableStandardUpdateCfgCondition) && enableStandardUpdateCfgCondition.length > 0 ? enableStandardUpdateCfgCondition : false, // 默认为false
|
|
118
123
|
};
|
|
119
124
|
|
|
120
125
|
// 接口返回最大值
|
|
@@ -274,7 +279,7 @@ export class CrudStdService extends ApiBaseService {
|
|
|
274
279
|
*/
|
|
275
280
|
public async executeStdActionByReq(stdAction: ICrudStdActionParams, params: IRequestModelCrudProExt): Promise<ExecuteContext> {
|
|
276
281
|
const appInfo = await this.getParsedCrudStdAppForSettingKey(stdAction);
|
|
277
|
-
if (!appInfo
|
|
282
|
+
if (!isEntityOK(appInfo)) {
|
|
278
283
|
throw new BizException('应用不存在或已下线:' + stdAction.appCode);
|
|
279
284
|
}
|
|
280
285
|
|
|
@@ -68,7 +68,7 @@ export class CurdMixByDictService implements IExecuteContextHandler {
|
|
|
68
68
|
if (noCacheCodes.length > 0) {
|
|
69
69
|
const res1 = await this.curdProService.executeCrudByCfg(
|
|
70
70
|
{
|
|
71
|
-
condition: { dict_code: { $in: noCacheCodes }, deleted_at: 0 },
|
|
71
|
+
condition: { dict_code: { $in: noCacheCodes }, deleted_at: 0, status: 1 },
|
|
72
72
|
},
|
|
73
73
|
{
|
|
74
74
|
sqlTable: SystemTables.sys_data_dict_item,
|
|
@@ -60,7 +60,7 @@ export class CurdMixBySysConfigService implements IExecuteContextHandler {
|
|
|
60
60
|
const { SystemDbName, SystemDbType } = GLOBAL_STATIC_CONFIG.getConfig();
|
|
61
61
|
const res1 = await this.curdProService.executeCrudByCfg(
|
|
62
62
|
{
|
|
63
|
-
condition: { config_code: { $in: notCachedCodes }, deleted_at: 0 },
|
|
63
|
+
condition: { config_code: { $in: notCachedCodes }, deleted_at: 0, status: 1 },
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
66
|
sqlTable: SystemTables.sys_configs,
|
|
@@ -38,7 +38,7 @@ export class CurdMixByWorkbenchService implements IExecuteContextHandler {
|
|
|
38
38
|
const service: CurdMixByWorkbenchService = await ctx.requestContext.getAsync(CurdMixByWorkbenchService);
|
|
39
39
|
const reqJson = {
|
|
40
40
|
columns: 'workbench_code,workbench_name,workbench_domain',
|
|
41
|
-
condition: { deleted_at: 0 },
|
|
41
|
+
condition: { deleted_at: 0, status: 1 },
|
|
42
42
|
};
|
|
43
43
|
const res = await service.curdProService.executeCrudByCfg(reqJson, {
|
|
44
44
|
sqlTable: SystemTables.sys_workbench,
|
|
@@ -34,7 +34,7 @@ function fixCfgModel(cfgModel: IRequestCfgModel2) {
|
|
|
34
34
|
return enableStandardUpdateCfg;
|
|
35
35
|
}
|
|
36
36
|
// update 、insert 添加 by
|
|
37
|
-
return ['by']; // 创建/修改语句默认添加by
|
|
37
|
+
return ['by', 'at']; // 创建/修改语句默认添加by
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
const getConditionCfgArray = () => {
|
|
@@ -55,11 +55,13 @@ function fixCfgModel(cfgModel: IRequestCfgModel2) {
|
|
|
55
55
|
'condition.created_by': { contextAsString: CTX_VISITOR_ID },
|
|
56
56
|
'condition.created_account_type': { contextAsString: CTX_VISITOR_ACCOUNT_TYPE },
|
|
57
57
|
|
|
58
|
+
'data.created_at': { functionName: 'getCurrentTimeString' },
|
|
58
59
|
'data.created_by': { contextAsString: CTX_VISITOR_ID },
|
|
59
60
|
'data.created_avatar': { contextAsString: CTX_VISITOR_AVATAR },
|
|
60
61
|
'data.created_nickname': { contextAsString: CTX_VISITOR_NICKNAME },
|
|
61
62
|
'data.created_account_type': { contextAsString: CTX_VISITOR_ACCOUNT_TYPE },
|
|
62
63
|
|
|
64
|
+
'data.modified_at': { functionName: 'getCurrentTimeString' },
|
|
63
65
|
'data.modified_by': { contextAsString: CTX_VISITOR_ID },
|
|
64
66
|
'data.modified_avatar': { contextAsString: CTX_VISITOR_AVATAR },
|
|
65
67
|
'data.modified_nickname': { contextAsString: CTX_VISITOR_NICKNAME },
|
|
@@ -8,7 +8,7 @@ import { CurdProService } from '../curd/CurdProService';
|
|
|
8
8
|
import { SystemTables } from '../../models/SystemTables';
|
|
9
9
|
import { KeysOfSimpleSQL } from '../../libs/crud-pro/models/keys';
|
|
10
10
|
import { IProxyApiEntity, IUpstreamInfo } from '../../models/SystemEntities';
|
|
11
|
-
import { parseJsonObject } from '../../libs/utils/functions';
|
|
11
|
+
import { isEntityOK, parseJsonObject } from '../../libs/utils/functions';
|
|
12
12
|
import { BALANCE_STRATEGY } from './ProxyApiUtils';
|
|
13
13
|
import { WeightedRandom } from './WeightedRandom';
|
|
14
14
|
import { WeightedRoundRobin } from './WeightedRoundRobin';
|
|
@@ -131,6 +131,9 @@ export class ProxyApiLoadService extends BaseService {
|
|
|
131
131
|
const rows0 = res.getResRows() as IProxyApiEntity[];
|
|
132
132
|
|
|
133
133
|
const rows = rows0.filter(s => {
|
|
134
|
+
if (!isEntityOK(s)) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
134
137
|
if (!s.workbench_code_array) {
|
|
135
138
|
throw new CommonException('IS_SUPPORT_CURRENT_WORKBENCH', '未配置支持的站点字段');
|
|
136
139
|
}
|