@hlw-midway/core 1.0.0
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/README.md +4 -0
- package/dist/bin/check.d.ts +4 -0
- package/dist/bin/check.js +41 -0
- package/dist/bin/entity.d.ts +8 -0
- package/dist/bin/entity.js +50 -0
- package/dist/bin/index.d.ts +2 -0
- package/dist/bin/index.js +49 -0
- package/dist/bin/obfuscate.d.ts +1 -0
- package/dist/bin/obfuscate.js +69 -0
- package/dist/cache/store.d.ts +18 -0
- package/dist/cache/store.js +38 -0
- package/dist/config/config.default.d.ts +8 -0
- package/dist/config/config.default.js +22 -0
- package/dist/configuration.d.ts +17 -0
- package/dist/configuration.js +106 -0
- package/dist/constant/global.d.ts +59 -0
- package/dist/constant/global.js +85 -0
- package/dist/controller/base.d.ts +107 -0
- package/dist/controller/base.js +236 -0
- package/dist/decorator/cache.d.ts +2 -0
- package/dist/decorator/cache.js +10 -0
- package/dist/decorator/controller.d.ts +71 -0
- package/dist/decorator/controller.js +169 -0
- package/dist/decorator/event.d.ts +21 -0
- package/dist/decorator/event.js +39 -0
- package/dist/decorator/index.d.ts +22 -0
- package/dist/decorator/index.js +120 -0
- package/dist/decorator/tag.d.ts +22 -0
- package/dist/decorator/tag.js +40 -0
- package/dist/decorator/transaction.d.ts +8 -0
- package/dist/decorator/transaction.js +10 -0
- package/dist/entity/base.d.ts +10 -0
- package/dist/entity/base.js +41 -0
- package/dist/entity/mongo.d.ts +10 -0
- package/dist/entity/mongo.js +35 -0
- package/dist/entity/typeorm.d.ts +3 -0
- package/dist/entity/typeorm.js +7 -0
- package/dist/event/index.d.ts +53 -0
- package/dist/event/index.js +188 -0
- package/dist/exception/base.d.ts +8 -0
- package/dist/exception/base.js +15 -0
- package/dist/exception/comm.d.ts +7 -0
- package/dist/exception/comm.js +15 -0
- package/dist/exception/core.d.ts +7 -0
- package/dist/exception/core.js +15 -0
- package/dist/exception/filter.d.ts +11 -0
- package/dist/exception/filter.js +42 -0
- package/dist/exception/validate.d.ts +7 -0
- package/dist/exception/validate.js +15 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +60 -0
- package/dist/interface.d.ts +432 -0
- package/dist/interface.js +24 -0
- package/dist/module/config.d.ts +21 -0
- package/dist/module/config.js +109 -0
- package/dist/module/import.d.ts +64 -0
- package/dist/module/import.js +244 -0
- package/dist/module/menu.d.ts +54 -0
- package/dist/module/menu.js +178 -0
- package/dist/rest/eps.d.ts +51 -0
- package/dist/rest/eps.js +269 -0
- package/dist/service/base.d.ts +167 -0
- package/dist/service/base.js +281 -0
- package/dist/service/mysql.d.ts +143 -0
- package/dist/service/mysql.js +524 -0
- package/dist/service/postgres.d.ts +160 -0
- package/dist/service/postgres.js +639 -0
- package/dist/service/sqlite.d.ts +142 -0
- package/dist/service/sqlite.js +560 -0
- package/dist/tag/data.d.ts +25 -0
- package/dist/tag/data.js +85 -0
- package/dist/util/func.d.ts +8 -0
- package/dist/util/func.js +44 -0
- package/dist/util/location.d.ts +26 -0
- package/dist/util/location.js +113 -0
- package/index.d.ts +10 -0
- package/package.json +68 -0
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.BasePgService = void 0;
|
|
13
|
+
const core_1 = require("@midwayjs/core");
|
|
14
|
+
const validate_1 = require("../exception/validate");
|
|
15
|
+
const global_1 = require("../constant/global");
|
|
16
|
+
const core_2 = require("@midwayjs/core");
|
|
17
|
+
const typeorm_1 = require("@midwayjs/typeorm");
|
|
18
|
+
const typeorm_2 = require("typeorm");
|
|
19
|
+
const _ = require("lodash");
|
|
20
|
+
const event_1 = require("../event");
|
|
21
|
+
/**
|
|
22
|
+
* 服务基类
|
|
23
|
+
*/
|
|
24
|
+
let BasePgService = class BasePgService {
|
|
25
|
+
// 设置模型
|
|
26
|
+
setEntity(entity) {
|
|
27
|
+
this.entity = entity;
|
|
28
|
+
}
|
|
29
|
+
// 设置请求上下文
|
|
30
|
+
setCtx(ctx) {
|
|
31
|
+
this.baseCtx = ctx;
|
|
32
|
+
}
|
|
33
|
+
// 设置应用对象
|
|
34
|
+
setApp(app) {
|
|
35
|
+
this.baseApp = app;
|
|
36
|
+
}
|
|
37
|
+
// 初始化
|
|
38
|
+
init() {
|
|
39
|
+
this.sqlParams = [];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 设置sql
|
|
43
|
+
* @param condition 条件是否成立
|
|
44
|
+
* @param sql sql语句
|
|
45
|
+
* @param params 参数
|
|
46
|
+
*/
|
|
47
|
+
setSql(condition, sql, params) {
|
|
48
|
+
let rSql = false;
|
|
49
|
+
if (condition || condition === 0) {
|
|
50
|
+
rSql = true;
|
|
51
|
+
for (let i = 0; i < params.length; i++) {
|
|
52
|
+
const param = params[i];
|
|
53
|
+
if (param instanceof Array) {
|
|
54
|
+
// 将这个? 替换成 $1,$2,$3
|
|
55
|
+
const replaceStr = [];
|
|
56
|
+
for (let j = 0; j < param.length; j++) {
|
|
57
|
+
replaceStr.push('$' + (this.sqlParams.length + j + 1));
|
|
58
|
+
}
|
|
59
|
+
this.sqlParams = this.sqlParams.concat(...params);
|
|
60
|
+
sql = sql.replace('?', replaceStr.join(','));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
sql = sql.replace('?', '$' + (this.sqlParams.length + 1));
|
|
64
|
+
this.sqlParams.push(param);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return rSql ? sql : '';
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 获得查询个数的SQL
|
|
72
|
+
* @param sql
|
|
73
|
+
*/
|
|
74
|
+
getCountSql(sql) {
|
|
75
|
+
sql = sql
|
|
76
|
+
.replace(new RegExp('LIMIT', 'gm'), 'limit ')
|
|
77
|
+
.replace(new RegExp('\n', 'gm'), ' ');
|
|
78
|
+
if (sql.includes('limit')) {
|
|
79
|
+
const sqlArr = sql.split('limit ');
|
|
80
|
+
sqlArr.pop();
|
|
81
|
+
sql = sqlArr.join('limit ');
|
|
82
|
+
}
|
|
83
|
+
return `select count(*) as count from (${sql}) a`;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 参数安全性检查
|
|
87
|
+
* @param params
|
|
88
|
+
*/
|
|
89
|
+
async paramSafetyCheck(params) {
|
|
90
|
+
const lp = params.toLowerCase();
|
|
91
|
+
return !(lp.indexOf('update ') > -1 ||
|
|
92
|
+
lp.indexOf('select ') > -1 ||
|
|
93
|
+
lp.indexOf('delete ') > -1 ||
|
|
94
|
+
lp.indexOf('insert ') > -1);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* 原生查询
|
|
98
|
+
* @param sql
|
|
99
|
+
* @param params
|
|
100
|
+
* @param connectionName
|
|
101
|
+
*/
|
|
102
|
+
async nativeQuery(sql, params, connectionName) {
|
|
103
|
+
sql = this.convertToPostgres(sql);
|
|
104
|
+
if (_.isEmpty(params)) {
|
|
105
|
+
params = this.sqlParams;
|
|
106
|
+
}
|
|
107
|
+
let newParams = [];
|
|
108
|
+
// sql没处理过?的情况下
|
|
109
|
+
if (sql.includes('?')) {
|
|
110
|
+
for (const item of params) {
|
|
111
|
+
// 如果是数组,将这个? 替换成 $1,$2,$3
|
|
112
|
+
if (item instanceof Array) {
|
|
113
|
+
const replaceStr = [];
|
|
114
|
+
for (let i = 0; i < item.length; i++) {
|
|
115
|
+
replaceStr.push('$' + (newParams.length + i + 1));
|
|
116
|
+
}
|
|
117
|
+
newParams.push(...item);
|
|
118
|
+
sql = sql.replace('?', replaceStr.join(','));
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
sql = sql.replace('?', '$' + (newParams.length + 1));
|
|
122
|
+
newParams.push(item);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
newParams = params;
|
|
128
|
+
}
|
|
129
|
+
this.sqlParams = [];
|
|
130
|
+
return await this.getOrmManager(connectionName).query(sql, newParams || []);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 获得ORM管理
|
|
134
|
+
* @param connectionName 连接名称
|
|
135
|
+
*/
|
|
136
|
+
getOrmManager(connectionName = 'default') {
|
|
137
|
+
return this.typeORMDataSourceManager.getDataSource(connectionName);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* 操作entity获得分页数据,不用写sql
|
|
141
|
+
* @param find QueryBuilder
|
|
142
|
+
* @param query
|
|
143
|
+
* @param autoSort
|
|
144
|
+
* @param connectionName
|
|
145
|
+
*/
|
|
146
|
+
async entityRenderPage(find, query, autoSort = true) {
|
|
147
|
+
const { size = this._hlwConfig.crud.pageSize, page = 1, order = 'id', sort = 'desc', isExport = false, maxExportLimit, } = query;
|
|
148
|
+
const count = await find.getCount();
|
|
149
|
+
let dataFind;
|
|
150
|
+
if (isExport && maxExportLimit > 0) {
|
|
151
|
+
dataFind = find.limit(maxExportLimit);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
dataFind = find.offset((page - 1) * size).limit(size);
|
|
155
|
+
}
|
|
156
|
+
if (autoSort) {
|
|
157
|
+
find.addOrderBy(order, sort.toUpperCase());
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
list: await dataFind.getRawMany(),
|
|
161
|
+
pagination: {
|
|
162
|
+
page: parseInt(page),
|
|
163
|
+
size: parseInt(size),
|
|
164
|
+
total: count,
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* 将mysql语句转换为postgres语句
|
|
170
|
+
* @param sql
|
|
171
|
+
* @returns
|
|
172
|
+
*/
|
|
173
|
+
convertToPostgres(sql) {
|
|
174
|
+
// 首先确保表名被正确引用
|
|
175
|
+
sql = sql.replace(/(?<!")(\b\w+\b)\.(?!\w+")/g, '"$1".');
|
|
176
|
+
// 然后确保字段名被正确引用
|
|
177
|
+
return sql.replace(/\.(\w+)(?!\w)/g, '."$1"');
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* 查询sql中的参数个数
|
|
181
|
+
* @param sql
|
|
182
|
+
* @returns
|
|
183
|
+
*/
|
|
184
|
+
countDollarSigns(sql) {
|
|
185
|
+
const matches = sql.match(/\$\d+/g);
|
|
186
|
+
return matches ? matches.length : 0;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* 执行SQL并获得分页数据
|
|
190
|
+
* @param sql 执行的sql语句
|
|
191
|
+
* @param query 分页查询条件
|
|
192
|
+
* @param autoSort 是否自动排序
|
|
193
|
+
* @param connectionName 连接名称
|
|
194
|
+
*/
|
|
195
|
+
async sqlRenderPage(sql, query, autoSort = true, connectionName) {
|
|
196
|
+
const { size = this._hlwConfig.crud.pageSize, page = 1, order = 'id', sort = 'desc', isExport = false, maxExportLimit, } = query;
|
|
197
|
+
sql = `SELECT * FROM (${sql}) a `;
|
|
198
|
+
if (order && sort && autoSort) {
|
|
199
|
+
if (!(await this.paramSafetyCheck(order + sort))) {
|
|
200
|
+
throw new validate_1.HlwValidateException('非法传参~');
|
|
201
|
+
}
|
|
202
|
+
sql += `ORDER BY a."${order}" ${this.checkSort(sort)}`;
|
|
203
|
+
}
|
|
204
|
+
let cutParams = 0;
|
|
205
|
+
const paramCount = this.countDollarSigns(sql);
|
|
206
|
+
if (isExport && maxExportLimit > 0) {
|
|
207
|
+
this.sqlParams.push(parseInt(maxExportLimit));
|
|
208
|
+
cutParams = 1;
|
|
209
|
+
sql += ` LIMIT $${paramCount + 1}`;
|
|
210
|
+
}
|
|
211
|
+
if (!isExport) {
|
|
212
|
+
this.sqlParams.push(parseInt(size));
|
|
213
|
+
this.sqlParams.push((page - 1) * size);
|
|
214
|
+
cutParams = 2;
|
|
215
|
+
sql += ` LIMIT $${paramCount + 1} OFFSET $${paramCount + 2}`;
|
|
216
|
+
}
|
|
217
|
+
let params = [];
|
|
218
|
+
params = params.concat(this.sqlParams);
|
|
219
|
+
const result = await this.nativeQuery(sql, params, connectionName);
|
|
220
|
+
params = params.slice(0, -cutParams);
|
|
221
|
+
const countResult = await this.nativeQuery(this.getCountSql(sql), params, connectionName);
|
|
222
|
+
return {
|
|
223
|
+
list: result,
|
|
224
|
+
pagination: {
|
|
225
|
+
page: parseInt(page),
|
|
226
|
+
size: parseInt(size),
|
|
227
|
+
total: parseInt(countResult[0] ? countResult[0].count : 0),
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* 检查排序
|
|
233
|
+
* @param sort 排序
|
|
234
|
+
* @returns
|
|
235
|
+
*/
|
|
236
|
+
checkSort(sort) {
|
|
237
|
+
if (!['desc', 'asc'].includes(sort.toLowerCase())) {
|
|
238
|
+
throw new validate_1.HlwValidateException('sort 非法传参~');
|
|
239
|
+
}
|
|
240
|
+
return sort;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* 获得单个ID
|
|
244
|
+
* @param id ID
|
|
245
|
+
* @param infoIgnoreProperty 忽略返回属性
|
|
246
|
+
*/
|
|
247
|
+
async info(id, infoIgnoreProperty) {
|
|
248
|
+
if (!this.entity)
|
|
249
|
+
throw new validate_1.HlwValidateException(global_1.ERRINFO.NOENTITY);
|
|
250
|
+
if (!id) {
|
|
251
|
+
throw new validate_1.HlwValidateException(global_1.ERRINFO.NOID);
|
|
252
|
+
}
|
|
253
|
+
const info = await this.entity.findOneBy({ id });
|
|
254
|
+
if (info && infoIgnoreProperty) {
|
|
255
|
+
for (const property of infoIgnoreProperty) {
|
|
256
|
+
delete info[property];
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return info;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* 删除
|
|
263
|
+
* @param ids 删除的ID集合 如:[1,2,3] 或者 1,2,3
|
|
264
|
+
*/
|
|
265
|
+
async delete(ids) {
|
|
266
|
+
var _a;
|
|
267
|
+
if (!this.entity)
|
|
268
|
+
throw new validate_1.HlwValidateException(global_1.ERRINFO.NOENTITY);
|
|
269
|
+
if (ids instanceof String) {
|
|
270
|
+
ids = ids.split(',');
|
|
271
|
+
}
|
|
272
|
+
// 启动软删除发送事件
|
|
273
|
+
if ((_a = this._hlwConfig.crud) === null || _a === void 0 ? void 0 : _a.softDelete) {
|
|
274
|
+
this.softDelete(ids);
|
|
275
|
+
}
|
|
276
|
+
await this.entity.delete(ids);
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* 软删除
|
|
280
|
+
* @param ids 删除的ID数组
|
|
281
|
+
* @param entity 实体
|
|
282
|
+
*/
|
|
283
|
+
async softDelete(ids, entity) {
|
|
284
|
+
const data = await this.entity.find({
|
|
285
|
+
where: {
|
|
286
|
+
id: (0, typeorm_2.In)(ids),
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
if (_.isEmpty(data))
|
|
290
|
+
return;
|
|
291
|
+
const _entity = entity ? entity : this.entity;
|
|
292
|
+
const params = {
|
|
293
|
+
data,
|
|
294
|
+
ctx: this.baseCtx,
|
|
295
|
+
entity: _entity,
|
|
296
|
+
};
|
|
297
|
+
if (data.length > 0) {
|
|
298
|
+
this.hlwEventManager.emit(global_1.EVENT.SOFT_DELETE, params);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* 新增|修改
|
|
303
|
+
* @param param 数据
|
|
304
|
+
*/
|
|
305
|
+
async addOrUpdate(param, type = 'add') {
|
|
306
|
+
var _a;
|
|
307
|
+
if (!this.entity)
|
|
308
|
+
throw new validate_1.HlwValidateException(global_1.ERRINFO.NOENTITY);
|
|
309
|
+
delete param.createdAt;
|
|
310
|
+
// 判断是否是批量操作
|
|
311
|
+
if (param instanceof Array) {
|
|
312
|
+
param.forEach(item => {
|
|
313
|
+
item.updatedAt = new Date();
|
|
314
|
+
if (type == 'add') {
|
|
315
|
+
item.createdAt = new Date();
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
await this.entity.save(param);
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
const upsert = ((_a = this._hlwConfig.crud) === null || _a === void 0 ? void 0 : _a.upsert) || 'normal';
|
|
322
|
+
if (type == 'update') {
|
|
323
|
+
if (upsert == 'save') {
|
|
324
|
+
const info = await this.entity.findOneBy({ id: (0, typeorm_2.Equal)(param.id) });
|
|
325
|
+
if (!info) {
|
|
326
|
+
throw new validate_1.HlwValidateException(global_1.ERRINFO.NOTFOUND);
|
|
327
|
+
}
|
|
328
|
+
param = {
|
|
329
|
+
...info,
|
|
330
|
+
...param,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
param.updatedAt = new Date();
|
|
334
|
+
upsert == 'normal'
|
|
335
|
+
? await this.entity.update(param.id, param)
|
|
336
|
+
: await this.entity.save(param);
|
|
337
|
+
}
|
|
338
|
+
if (type == 'add') {
|
|
339
|
+
param.createdAt = new Date();
|
|
340
|
+
param.updatedAt = new Date();
|
|
341
|
+
upsert == 'normal'
|
|
342
|
+
? await this.entity.insert(param)
|
|
343
|
+
: await this.entity.save(param);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* 非分页查询
|
|
349
|
+
* @param query 查询条件
|
|
350
|
+
* @param option 查询配置
|
|
351
|
+
* @param connectionName 连接名
|
|
352
|
+
*/
|
|
353
|
+
async list(query, option, connectionName) {
|
|
354
|
+
if (!this.entity)
|
|
355
|
+
throw new validate_1.HlwValidateException(global_1.ERRINFO.NOENTITY);
|
|
356
|
+
const sql = await this.getOptionFind(query, option);
|
|
357
|
+
return this.nativeQuery(sql, [], connectionName);
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* 分页查询
|
|
361
|
+
* @param query 查询条件
|
|
362
|
+
* @param option 查询配置
|
|
363
|
+
* @param connectionName 连接名
|
|
364
|
+
*/
|
|
365
|
+
async page(query, option, connectionName) {
|
|
366
|
+
if (!this.entity)
|
|
367
|
+
throw new validate_1.HlwValidateException(global_1.ERRINFO.NOENTITY);
|
|
368
|
+
const sql = await this.getOptionFind(query, option);
|
|
369
|
+
return this.sqlRenderPage(sql, query, false, connectionName);
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* 构建查询配置
|
|
373
|
+
* @param query 前端查询
|
|
374
|
+
* @param option
|
|
375
|
+
*/
|
|
376
|
+
async getOptionFind(query, option) {
|
|
377
|
+
let { order = 'id', sort = 'desc', keyWord = '' } = query;
|
|
378
|
+
const sqlArr = ['SELECT'];
|
|
379
|
+
const selects = ['a.*'];
|
|
380
|
+
const find = this.entity.createQueryBuilder('a');
|
|
381
|
+
if (option) {
|
|
382
|
+
if (typeof option === 'function') {
|
|
383
|
+
// @ts-ignore
|
|
384
|
+
option = await option(this.baseCtx, this.baseApp);
|
|
385
|
+
}
|
|
386
|
+
// 判断是否有关联查询,有的话取个别名
|
|
387
|
+
if (!_.isEmpty(option.join)) {
|
|
388
|
+
for (const item of option.join) {
|
|
389
|
+
selects.push(`${item.alias}.*`);
|
|
390
|
+
find[item.type || 'leftJoin'](item.entity, item.alias, item.condition);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
// 默认条件
|
|
394
|
+
if (option.where) {
|
|
395
|
+
const wheres = typeof option.where === 'function'
|
|
396
|
+
? await option.where(this.baseCtx, this.baseApp)
|
|
397
|
+
: option.where;
|
|
398
|
+
if (!_.isEmpty(wheres)) {
|
|
399
|
+
for (const item of wheres) {
|
|
400
|
+
if (item.length == 2 ||
|
|
401
|
+
(item.length == 3 && (item[2] || item[2] === 0))) {
|
|
402
|
+
for (const key in item[1]) {
|
|
403
|
+
this.sqlParams.push(item[1][key]);
|
|
404
|
+
}
|
|
405
|
+
find.andWhere(item[0], item[1]);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
// 附加排序
|
|
411
|
+
if (!_.isEmpty(option.addOrderBy)) {
|
|
412
|
+
for (const key in option.addOrderBy) {
|
|
413
|
+
if (order && order == key) {
|
|
414
|
+
sort = option.addOrderBy[key].toUpperCase();
|
|
415
|
+
}
|
|
416
|
+
find.addOrderBy(`${this.matchColumn(option === null || option === void 0 ? void 0 : option.select, key)}.${key}`, this.checkSort(option.addOrderBy[key].toUpperCase()));
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
// 关键字模糊搜索
|
|
420
|
+
if (keyWord || keyWord === 0) {
|
|
421
|
+
keyWord = `%${keyWord}%`;
|
|
422
|
+
find.andWhere(new typeorm_2.Brackets(qb => {
|
|
423
|
+
var _a;
|
|
424
|
+
const keyWordLikeFields = option.keyWordLikeFields || [];
|
|
425
|
+
for (let i = 0; i < ((_a = option.keyWordLikeFields) === null || _a === void 0 ? void 0 : _a.length) || 0; i++) {
|
|
426
|
+
let column = keyWordLikeFields[i];
|
|
427
|
+
column = column.includes('.') ? column : `a.${column}`;
|
|
428
|
+
const values = {};
|
|
429
|
+
values[`keyWord${i}`] = keyWord;
|
|
430
|
+
qb.orWhere(`${column} like :keyWord${i}`, values);
|
|
431
|
+
this.sqlParams.push(keyWord);
|
|
432
|
+
}
|
|
433
|
+
}));
|
|
434
|
+
}
|
|
435
|
+
// 筛选字段
|
|
436
|
+
if (!_.isEmpty(option.select)) {
|
|
437
|
+
sqlArr.push(option.select.join(','));
|
|
438
|
+
find.select(option.select);
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
sqlArr.push(selects.join(','));
|
|
442
|
+
}
|
|
443
|
+
// 字段全匹配
|
|
444
|
+
if (!_.isEmpty(option.fieldEq)) {
|
|
445
|
+
for (let key of option.fieldEq) {
|
|
446
|
+
const c = {};
|
|
447
|
+
let column;
|
|
448
|
+
// 如果key有包含.的情况下操作
|
|
449
|
+
if (typeof key === 'string' && key.includes('.')) {
|
|
450
|
+
const keys = key.split('.');
|
|
451
|
+
const lastKey = keys.pop();
|
|
452
|
+
key = { requestParam: lastKey, column: key };
|
|
453
|
+
column = key;
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
column = `a.${key}`;
|
|
457
|
+
}
|
|
458
|
+
// 单表字段无别名的情况下操作
|
|
459
|
+
if (typeof key === 'string') {
|
|
460
|
+
if (query[key] || query[key] == 0) {
|
|
461
|
+
c[key] = query[key];
|
|
462
|
+
const eq = query[key] instanceof Array ? 'in' : '=';
|
|
463
|
+
if (eq === 'in') {
|
|
464
|
+
find.andWhere(`${column} ${eq} (:...${key})`, c);
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
find.andWhere(`${column} ${eq} :${key}`, c);
|
|
468
|
+
}
|
|
469
|
+
this.sqlParams.push(query[key]);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
if (query[key.requestParam] || query[key.requestParam] == 0) {
|
|
474
|
+
c[key.column] = query[key.requestParam];
|
|
475
|
+
const eq = query[key.requestParam] instanceof Array ? 'in' : '=';
|
|
476
|
+
if (eq === 'in') {
|
|
477
|
+
find.andWhere(`${key.column} ${eq} (:${key.column})`, c);
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
find.andWhere(`${key.column} ${eq} :${key.column}`, c);
|
|
481
|
+
}
|
|
482
|
+
this.sqlParams.push(query[key.requestParam]);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
// 字段模糊查询
|
|
488
|
+
if (!_.isEmpty(option.fieldLike)) {
|
|
489
|
+
for (let key of option.fieldLike) {
|
|
490
|
+
const c = {};
|
|
491
|
+
let column;
|
|
492
|
+
// 如果key有包含.的情况下操作
|
|
493
|
+
if (typeof key === 'string' && key.includes('.')) {
|
|
494
|
+
const keys = key.split('.');
|
|
495
|
+
const lastKey = keys.pop();
|
|
496
|
+
key = { requestParam: lastKey, column: key };
|
|
497
|
+
column = key;
|
|
498
|
+
}
|
|
499
|
+
else {
|
|
500
|
+
column = `a.${key}`;
|
|
501
|
+
}
|
|
502
|
+
// 单表字段无别名的情况下操作
|
|
503
|
+
if (typeof key === 'string') {
|
|
504
|
+
if (query[key] || query[key] == 0) {
|
|
505
|
+
c[key] = query[key];
|
|
506
|
+
find.andWhere(`${column} like :${key}`, {
|
|
507
|
+
[key]: `%${query[key]}%`,
|
|
508
|
+
});
|
|
509
|
+
this.sqlParams.push(`%${query[key]}%`);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
else {
|
|
513
|
+
if (query[key.requestParam] || query[key.requestParam] == 0) {
|
|
514
|
+
c[key.column] = query[key.requestParam];
|
|
515
|
+
find.andWhere(`${key.column} like :${key.column}`, {
|
|
516
|
+
[key.column]: `%${query[key.requestParam]}%`,
|
|
517
|
+
});
|
|
518
|
+
this.sqlParams.push(`%${query[key.requestParam]}%`);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
sqlArr.push(selects.join(','));
|
|
526
|
+
}
|
|
527
|
+
// 接口请求的排序
|
|
528
|
+
if (sort && order) {
|
|
529
|
+
const sorts = sort.toUpperCase().split(',');
|
|
530
|
+
const orders = order.split(',');
|
|
531
|
+
if (sorts.length != orders.length) {
|
|
532
|
+
throw new validate_1.HlwValidateException(global_1.ERRINFO.SORTFIELD);
|
|
533
|
+
}
|
|
534
|
+
for (const i in sorts) {
|
|
535
|
+
find.addOrderBy(`${this.matchColumn(option === null || option === void 0 ? void 0 : option.select, orders[i])}.${orders[i]}`, this.checkSort(sorts[i]));
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
if (option === null || option === void 0 ? void 0 : option.extend) {
|
|
539
|
+
await (option === null || option === void 0 ? void 0 : option.extend(find, this.baseCtx, this.baseApp));
|
|
540
|
+
}
|
|
541
|
+
const sqls = find.getSql().split('FROM');
|
|
542
|
+
sqlArr.push('FROM');
|
|
543
|
+
// 取sqls的最后一个
|
|
544
|
+
sqlArr.push(sqls[sqls.length - 1]);
|
|
545
|
+
sqlArr.forEach((item, index) => {
|
|
546
|
+
if (item.includes('ORDER BY')) {
|
|
547
|
+
sqlArr[index] = this.replaceOrderByPrefix(item);
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
return sqlArr.join(' ');
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* 替换sql中的表别名
|
|
554
|
+
* @param sql
|
|
555
|
+
* @returns
|
|
556
|
+
*/
|
|
557
|
+
replaceOrderByPrefix(sql) {
|
|
558
|
+
// 使用正则表达式匹配 ORDER BY 后面的部分
|
|
559
|
+
// 这里假设 ORDER BY 后面跟着的是由空格分隔的字段名,且字段名由双引号包围
|
|
560
|
+
const orderByRegex = /ORDER BY\s+("[^"]+_[^"]+")(\s*(ASC|DESC)?\s*(,\s*"[^"]+_[^"]+")*)/gi;
|
|
561
|
+
// 定义替换函数
|
|
562
|
+
// @ts-ignore
|
|
563
|
+
function replaceMatch(match, p1, p2) {
|
|
564
|
+
// 将 p1 中的 "a_" 替换为 "a."
|
|
565
|
+
const replacedField = p1.replace(/a_([^"]+)/g, 'a.$1');
|
|
566
|
+
// 如果有其他字段,递归调用替换函数
|
|
567
|
+
const replacedRest = p2.replace(/("[^"]+_)/g, (m, p) => p.replace('a_', 'a.'));
|
|
568
|
+
// 组合替换后的字段和其他部分
|
|
569
|
+
return `ORDER BY ${replacedField.replace(/"/g, '')}${replacedRest.replace(/"/g, '')}`;
|
|
570
|
+
}
|
|
571
|
+
// 使用替换函数替换匹配到的内容
|
|
572
|
+
const replacedOrderBySql = sql.replace(orderByRegex, replaceMatch);
|
|
573
|
+
// 移除所有双引号
|
|
574
|
+
const sqlWithoutQuotes = replacedOrderBySql.replace(/"/g, '');
|
|
575
|
+
return sqlWithoutQuotes;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* 筛选的字段匹配
|
|
579
|
+
* @param select 筛选的字段
|
|
580
|
+
* @param field 字段
|
|
581
|
+
* @returns 字段在哪个表中
|
|
582
|
+
*/
|
|
583
|
+
matchColumn(select = [], field) {
|
|
584
|
+
for (const column of select) {
|
|
585
|
+
// 检查字段是否有别名,考虑 'AS' 关键字的不同大小写形式
|
|
586
|
+
const aliasPattern = new RegExp(`\\b\\w+\\s+as\\s+${field}\\b`, 'i');
|
|
587
|
+
const aliasMatch = column.match(aliasPattern);
|
|
588
|
+
if (aliasMatch) {
|
|
589
|
+
// 提取别名前的字段和表名
|
|
590
|
+
const fieldPattern = new RegExp(`(\\w+)\\.(\\w+)\\s+as\\s+${field}`, 'i');
|
|
591
|
+
const fieldMatch = column.match(fieldPattern);
|
|
592
|
+
if (fieldMatch) {
|
|
593
|
+
// 返回匹配到的表名
|
|
594
|
+
return fieldMatch[1];
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
// 检查字段是否直接在选择列表中
|
|
598
|
+
const fieldPattern = new RegExp(`\\b(\\w+)\\.${field}\\b`, 'i');
|
|
599
|
+
const fieldMatch = column.match(fieldPattern);
|
|
600
|
+
if (fieldMatch) {
|
|
601
|
+
// 如果直接匹配到字段,返回字段所属的表名
|
|
602
|
+
return fieldMatch[1];
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
// 如果没有匹配到任何特定的表或别名,返回默认的 'a' 表
|
|
606
|
+
return 'a';
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
exports.BasePgService = BasePgService;
|
|
610
|
+
__decorate([
|
|
611
|
+
(0, core_1.Config)('hlw'),
|
|
612
|
+
__metadata("design:type", Object)
|
|
613
|
+
], BasePgService.prototype, "_hlwConfig", void 0);
|
|
614
|
+
__decorate([
|
|
615
|
+
(0, core_1.Inject)(),
|
|
616
|
+
__metadata("design:type", typeorm_1.TypeORMDataSourceManager)
|
|
617
|
+
], BasePgService.prototype, "typeORMDataSourceManager", void 0);
|
|
618
|
+
__decorate([
|
|
619
|
+
(0, core_1.Inject)(),
|
|
620
|
+
__metadata("design:type", event_1.HlwEventManager)
|
|
621
|
+
], BasePgService.prototype, "hlwEventManager", void 0);
|
|
622
|
+
__decorate([
|
|
623
|
+
(0, core_1.App)(),
|
|
624
|
+
__metadata("design:type", Object)
|
|
625
|
+
], BasePgService.prototype, "baseApp", void 0);
|
|
626
|
+
__decorate([
|
|
627
|
+
(0, core_1.Inject)('ctx'),
|
|
628
|
+
__metadata("design:type", Object)
|
|
629
|
+
], BasePgService.prototype, "baseCtx", void 0);
|
|
630
|
+
__decorate([
|
|
631
|
+
(0, core_1.Init)(),
|
|
632
|
+
__metadata("design:type", Function),
|
|
633
|
+
__metadata("design:paramtypes", []),
|
|
634
|
+
__metadata("design:returntype", void 0)
|
|
635
|
+
], BasePgService.prototype, "init", null);
|
|
636
|
+
exports.BasePgService = BasePgService = __decorate([
|
|
637
|
+
(0, core_1.Provide)(),
|
|
638
|
+
(0, core_2.Scope)(core_2.ScopeEnum.Request, { allowDowngrade: true })
|
|
639
|
+
], BasePgService);
|