q-koa 13.2.7 → 13.2.9
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/core/app.js +51 -5
- package/core/config.js +1 -0
- package/core/file/plugins/model/service.js +20 -20
- package/core/file/plugins/setting/controller.js +4 -0
- package/core/file/plugins/system/controller.js +55 -3
- package/core/file/plugins/system/service.js +42 -1
- package/core/file/services/print.js +2 -1
- package/core/file/utils/index.js +47 -0
- package/package.json +1 -1
package/core/app.js
CHANGED
|
@@ -55,6 +55,15 @@ const runVm = (_str) => {
|
|
|
55
55
|
return nodeVm.runInNewContext(_str)
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
const getLiteral = (str) => {
|
|
59
|
+
const reg = /literal\((.+)\)/
|
|
60
|
+
const result = str.match(reg)
|
|
61
|
+
if (result) {
|
|
62
|
+
return result[1] // 返回第一个捕获组
|
|
63
|
+
}
|
|
64
|
+
return ''
|
|
65
|
+
}
|
|
66
|
+
|
|
58
67
|
const memRunVm = _.memoize(runVm)
|
|
59
68
|
const connectDatabase = (database) => (config) => {
|
|
60
69
|
if (!database) throw new Error('请配置数据库名称')
|
|
@@ -90,7 +99,7 @@ class APP {
|
|
|
90
99
|
miLimit(config.rateLimit),
|
|
91
100
|
miStatic(config.static),
|
|
92
101
|
miAgent(),
|
|
93
|
-
miWebsocket(),
|
|
102
|
+
config.is_websocket ? miWebsocket() : null,
|
|
94
103
|
miCors(config.includes, config.ip),
|
|
95
104
|
// miRestc(config),
|
|
96
105
|
miBody(config.koaBody),
|
|
@@ -103,7 +112,7 @@ class APP {
|
|
|
103
112
|
miResponse(config.response),
|
|
104
113
|
// miToken(),
|
|
105
114
|
miErrors(),
|
|
106
|
-
]
|
|
115
|
+
].filter(Boolean)
|
|
107
116
|
}
|
|
108
117
|
|
|
109
118
|
async start() {
|
|
@@ -504,7 +513,15 @@ class APP {
|
|
|
504
513
|
) {
|
|
505
514
|
try {
|
|
506
515
|
this.app[appName].appConfig.router(router)(this.app[appName])
|
|
507
|
-
} catch (e) {
|
|
516
|
+
} catch (e) {
|
|
517
|
+
this.app[appName].service.log &&
|
|
518
|
+
this.app[appName].service.log.push({
|
|
519
|
+
app: this.app[appName],
|
|
520
|
+
appName,
|
|
521
|
+
message: e.message,
|
|
522
|
+
})
|
|
523
|
+
console.log(e.message)
|
|
524
|
+
}
|
|
508
525
|
}
|
|
509
526
|
|
|
510
527
|
if (this.config.defaultRouter) {
|
|
@@ -1053,7 +1070,7 @@ class APP {
|
|
|
1053
1070
|
}
|
|
1054
1071
|
}
|
|
1055
1072
|
|
|
1056
|
-
if (
|
|
1073
|
+
if (['findAll', 'findAndCountAll'].includes(fn)) {
|
|
1057
1074
|
const disabledFindAllList = _.get(
|
|
1058
1075
|
app[appName],
|
|
1059
1076
|
'appConfig.disabledFindAllList',
|
|
@@ -1067,7 +1084,7 @@ class APP {
|
|
|
1067
1084
|
(where && !_.isEmpty(where))
|
|
1068
1085
|
)
|
|
1069
1086
|
) {
|
|
1070
|
-
throw new Error(
|
|
1087
|
+
throw new Error('请使用条件')
|
|
1071
1088
|
}
|
|
1072
1089
|
}
|
|
1073
1090
|
|
|
@@ -1226,6 +1243,35 @@ class APP {
|
|
|
1226
1243
|
}
|
|
1227
1244
|
if (['findOne', 'findAll', 'findAndCountAll'].includes(fn)) {
|
|
1228
1245
|
// 拆分
|
|
1246
|
+
if (
|
|
1247
|
+
fn === 'findOne' &&
|
|
1248
|
+
attributes &&
|
|
1249
|
+
Array.isArray(attributes) &&
|
|
1250
|
+
attributes.length > 0 &&
|
|
1251
|
+
attributes.every(
|
|
1252
|
+
(attribute) =>
|
|
1253
|
+
Array.isArray(attribute) &&
|
|
1254
|
+
attribute.length === 2 &&
|
|
1255
|
+
attribute.some((o) => o.startsWith('literal'))
|
|
1256
|
+
)
|
|
1257
|
+
) {
|
|
1258
|
+
const target = await app[appName].model[controller][fn]({
|
|
1259
|
+
attributes: attributes.map((attribute) => {
|
|
1260
|
+
if (Array.isArray(attribute)) {
|
|
1261
|
+
return attribute.map((att) => {
|
|
1262
|
+
if (att.startsWith('literal')) {
|
|
1263
|
+
return Sequelize.literal(getLiteral(att))
|
|
1264
|
+
}
|
|
1265
|
+
return att
|
|
1266
|
+
})
|
|
1267
|
+
}
|
|
1268
|
+
return attribute
|
|
1269
|
+
}),
|
|
1270
|
+
where: _where,
|
|
1271
|
+
})
|
|
1272
|
+
|
|
1273
|
+
return ctx.SUCCESS(target)
|
|
1274
|
+
}
|
|
1229
1275
|
if (is_split) {
|
|
1230
1276
|
if (fn === 'findAndCountAll') {
|
|
1231
1277
|
const requiredInclude = myInclude
|
package/core/config.js
CHANGED
|
@@ -60,25 +60,25 @@ exports.loadModel = async ({ app, appName }) => {
|
|
|
60
60
|
// const id = ori_target ? ori_target.id : null
|
|
61
61
|
const id = i + 1
|
|
62
62
|
|
|
63
|
-
let countNumber = 0
|
|
64
|
-
if (!['setting', 'auth'].includes(config.belongs)) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
63
|
+
// let countNumber = 0
|
|
64
|
+
// if (!['setting', 'auth'].includes(config.belongs)) {
|
|
65
|
+
// if (currentDisabledFindAllList.length === 0 && app.model[result[i]]) {
|
|
66
|
+
// countNumber = await app.model[result[i]].count()
|
|
67
|
+
// }
|
|
68
|
+
// if (countNumber >= 500) {
|
|
69
|
+
// disabledFindAllList = [...disabledFindAllList, result[i]]
|
|
70
|
+
// const tableIndexList = await app.service.system.getTableIndex({
|
|
71
|
+
// app,
|
|
72
|
+
// model: result[i],
|
|
73
|
+
// })
|
|
74
|
+
// if (countNumber >= 100000) {
|
|
75
|
+
// console.warn('数据量大,请注意', result[i], countNumber)
|
|
76
|
+
// }
|
|
77
|
+
// if (tableIndexList.length <= 1) {
|
|
78
|
+
// console.warn(`${result[i]} count ${countNumber}没有索引`)
|
|
79
|
+
// }
|
|
80
|
+
// }
|
|
81
|
+
// }
|
|
82
82
|
|
|
83
83
|
const obj = {
|
|
84
84
|
id,
|
|
@@ -154,7 +154,7 @@ exports.loadModel = async ({ app, appName }) => {
|
|
|
154
154
|
if (
|
|
155
155
|
!model[name].defaultValue &&
|
|
156
156
|
typeof model[name].defaultValue !== 'undefined' &&
|
|
157
|
-
model[name].defaultValue
|
|
157
|
+
model[name].defaultValue != 0
|
|
158
158
|
) {
|
|
159
159
|
defaultValue = 'null'
|
|
160
160
|
}
|
|
@@ -39,9 +39,13 @@ const compareIndex = (tableIndexList, modelIndexList = [], model) => {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
const flag =
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
const flag =
|
|
43
|
+
tableIndexList.every((i) => {
|
|
44
|
+
return modelIndexList.some((m) => isSameArray(m.fields, i.fields, true))
|
|
45
|
+
}) &&
|
|
46
|
+
modelIndexList.every((i) => {
|
|
47
|
+
return tableIndexList.some((m) => isSameArray(m.fields, i.fields, true))
|
|
48
|
+
})
|
|
45
49
|
|
|
46
50
|
const intersection = lodash.intersectionWith(
|
|
47
51
|
tableIndexList,
|
|
@@ -883,3 +887,51 @@ exports.dropIndex = async (ctx) => {
|
|
|
883
887
|
|
|
884
888
|
ctx.SUCCESS(result)
|
|
885
889
|
}
|
|
890
|
+
|
|
891
|
+
exports.checkFrag = async (ctx) => {
|
|
892
|
+
const { app, appName } = getAppByCtx(ctx)
|
|
893
|
+
const { model } = ctx.request.body
|
|
894
|
+
if (!model) return ctx.ERROR(`model?`)
|
|
895
|
+
|
|
896
|
+
const query = `SELECT table_name, ROUND((data_free / data_length) * 100, 2) AS fragmentation_percentage
|
|
897
|
+
FROM information_schema.TABLES
|
|
898
|
+
WHERE table_schema = '${app.sequelize.config.database}' AND table_name = '${model}';`
|
|
899
|
+
|
|
900
|
+
const result = await app.sequelize.query(query)
|
|
901
|
+
|
|
902
|
+
if (result && result[0]) {
|
|
903
|
+
return ctx.SUCCESS(result[0][0])
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
return ctx.SUCCESS({})
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
exports.reset = async (ctx) => {
|
|
910
|
+
const { app, appName } = getAppByCtx(ctx)
|
|
911
|
+
const { model } = ctx.request.body
|
|
912
|
+
|
|
913
|
+
const count = await app.model[model].count()
|
|
914
|
+
if (count > 10000) {
|
|
915
|
+
return ctx.ERROR(`数据量太大,无法重置`)
|
|
916
|
+
}
|
|
917
|
+
const result = await app.model[model].findAll({
|
|
918
|
+
attributes: {
|
|
919
|
+
exclude: ['id'],
|
|
920
|
+
},
|
|
921
|
+
})
|
|
922
|
+
|
|
923
|
+
await app.model[model].sync({
|
|
924
|
+
force: true,
|
|
925
|
+
})
|
|
926
|
+
|
|
927
|
+
await app.model[model].bulkCreate(
|
|
928
|
+
result.map((item, index) => {
|
|
929
|
+
return {
|
|
930
|
+
...item.toJSON(),
|
|
931
|
+
id: index + 1,
|
|
932
|
+
}
|
|
933
|
+
})
|
|
934
|
+
)
|
|
935
|
+
|
|
936
|
+
ctx.SUCCESS(result.length)
|
|
937
|
+
}
|
|
@@ -8,7 +8,14 @@ const runVm = (_str) => {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
const memRunVm = lodash.memoize(runVm)
|
|
11
|
-
|
|
11
|
+
const getLiteral = (str) => {
|
|
12
|
+
const reg = /literal\((.+)\)/
|
|
13
|
+
const result = str.match(reg)
|
|
14
|
+
if (result) {
|
|
15
|
+
return result[1] // 返回第一个捕获组
|
|
16
|
+
}
|
|
17
|
+
return ''
|
|
18
|
+
}
|
|
12
19
|
exports.initData = async ({ includes, excludes, app, ctx }) => {
|
|
13
20
|
const appConfig = getConfig(app)
|
|
14
21
|
const { version: cacheVersion } = await appConfig.getObject('base')
|
|
@@ -211,6 +218,40 @@ exports.initData = async ({ includes, excludes, app, ctx }) => {
|
|
|
211
218
|
}
|
|
212
219
|
})
|
|
213
220
|
} else {
|
|
221
|
+
if (data && lodash.isObject(data)) {
|
|
222
|
+
if (
|
|
223
|
+
fn === 'findOne' &&
|
|
224
|
+
'attributes' in data &&
|
|
225
|
+
Array.isArray(data.attributes) &&
|
|
226
|
+
data.attributes.every((attribute) =>
|
|
227
|
+
Array.isArray(attribute)
|
|
228
|
+
) &&
|
|
229
|
+
data.attributes.some(
|
|
230
|
+
(attribute) =>
|
|
231
|
+
Array.isArray(attribute) &&
|
|
232
|
+
attribute.some((att) => att.startsWith('literal'))
|
|
233
|
+
)
|
|
234
|
+
) {
|
|
235
|
+
return app.model[model][fn]({
|
|
236
|
+
where: data.where,
|
|
237
|
+
attributes: data.attributes.map((attribute) => {
|
|
238
|
+
if (Array.isArray(attribute)) {
|
|
239
|
+
return attribute.map((att) => {
|
|
240
|
+
if (att.startsWith('literal')) {
|
|
241
|
+
return Sequelize.literal(getLiteral(att))
|
|
242
|
+
}
|
|
243
|
+
return att
|
|
244
|
+
})
|
|
245
|
+
}
|
|
246
|
+
return attribute
|
|
247
|
+
}),
|
|
248
|
+
}).then((res) => {
|
|
249
|
+
return {
|
|
250
|
+
[item]: res,
|
|
251
|
+
}
|
|
252
|
+
})
|
|
253
|
+
}
|
|
254
|
+
}
|
|
214
255
|
const formatData =
|
|
215
256
|
fn === 'findAll' &&
|
|
216
257
|
data &&
|
|
@@ -145,9 +145,10 @@ module.exports = class Singleton {
|
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
async getPrintList(
|
|
148
|
+
async getPrintList(_machineCode, pageIndex = 1, pageSize = 10) {
|
|
149
149
|
const app = this.config.app
|
|
150
150
|
const accessToken = await this.getAccessToken()
|
|
151
|
+
const machineCode = _machineCode || this.config.machine_code
|
|
151
152
|
try {
|
|
152
153
|
const RpcClient = new yly.RpcClient(accessToken, this.oauthConfig)
|
|
153
154
|
const Print = new yly.Printer(RpcClient)
|
package/core/file/utils/index.js
CHANGED
|
@@ -214,14 +214,45 @@ const isDateTime = (str) => {
|
|
|
214
214
|
/^(\d{4}-\d{2}-\d{2})([T\s](\d{2}:\d{2}(:\d{2}(\.\d+)?)?)([+-]\d{2}:\d{2}|Z)?)?$/
|
|
215
215
|
return dateRegex.test(str)
|
|
216
216
|
}
|
|
217
|
+
|
|
218
|
+
const getCol = (str) => {
|
|
219
|
+
const reg = /col\((.+)\)/
|
|
220
|
+
const result = str.match(reg)
|
|
221
|
+
if (result) {
|
|
222
|
+
return result[1] // 返回第一个捕获组
|
|
223
|
+
}
|
|
224
|
+
return ''
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const getLiteral = (str) => {
|
|
228
|
+
const reg = /literal\((.+)\)/
|
|
229
|
+
const result = str.match(reg)
|
|
230
|
+
if (result) {
|
|
231
|
+
return result[1] // 返回第一个捕获组
|
|
232
|
+
}
|
|
233
|
+
return ''
|
|
234
|
+
}
|
|
217
235
|
const $lt = {
|
|
218
236
|
check: (param) => typeof param === 'string',
|
|
219
237
|
result: (param, key) => {
|
|
238
|
+
if (getCol(param[key])) {
|
|
239
|
+
return {
|
|
240
|
+
[key]: Sequelize.col(getCol(param[key])),
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (getLiteral(param[key])) {
|
|
245
|
+
return {
|
|
246
|
+
[key]: Sequelize.literal(getLiteral(param[key])),
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
220
250
|
if (isDateTime(param[key])) {
|
|
221
251
|
return {
|
|
222
252
|
[key]: param[key],
|
|
223
253
|
}
|
|
224
254
|
}
|
|
255
|
+
|
|
225
256
|
return {
|
|
226
257
|
[key]: Sequelize.literal(param[key]),
|
|
227
258
|
}
|
|
@@ -230,6 +261,17 @@ const $lt = {
|
|
|
230
261
|
const $in = {
|
|
231
262
|
check: (param) => typeof param === 'string',
|
|
232
263
|
result: (param, key) => {
|
|
264
|
+
if (getCol(param[key])) {
|
|
265
|
+
return {
|
|
266
|
+
[key]: Sequelize.col(getCol(param[key])),
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (getLiteral(param[key])) {
|
|
271
|
+
return {
|
|
272
|
+
[key]: Sequelize.literal(getLiteral(param[key])),
|
|
273
|
+
}
|
|
274
|
+
}
|
|
233
275
|
return {
|
|
234
276
|
[key]: [Sequelize.literal(param[key])],
|
|
235
277
|
}
|
|
@@ -239,6 +281,11 @@ const $between = {
|
|
|
239
281
|
check: (param) =>
|
|
240
282
|
Array.isArray(param) && param.every((p) => typeof param === 'string'),
|
|
241
283
|
result: (param, key) => {
|
|
284
|
+
if (param[key].every((i) => getLiteral(i))) {
|
|
285
|
+
return {
|
|
286
|
+
[key]: param[key].map((item) => Sequelize.literal(getLiteral(item))),
|
|
287
|
+
}
|
|
288
|
+
}
|
|
242
289
|
if (param[key].every((i) => isDateTime(i))) {
|
|
243
290
|
return {
|
|
244
291
|
[key]: param[key],
|