q-koa 7.7.2

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 (116) hide show
  1. package/core/app.js +1813 -0
  2. package/core/config.js +124 -0
  3. package/core/file/plugins/administrator/config.js +17 -0
  4. package/core/file/plugins/administrator/controller.js +264 -0
  5. package/core/file/plugins/administrator/model.js +53 -0
  6. package/core/file/plugins/administrator/validate.js +41 -0
  7. package/core/file/plugins/alipay/controller.js +68 -0
  8. package/core/file/plugins/alipay/validate.js +9 -0
  9. package/core/file/plugins/cache/service.js +16 -0
  10. package/core/file/plugins/cloudfunction/config.js +4 -0
  11. package/core/file/plugins/cloudfunction/model.js +15 -0
  12. package/core/file/plugins/common/controller.js +398 -0
  13. package/core/file/plugins/common/validate.js +47 -0
  14. package/core/file/plugins/douyin/config.js +3 -0
  15. package/core/file/plugins/douyin/controller.js +521 -0
  16. package/core/file/plugins/douyin/validate.js +40 -0
  17. package/core/file/plugins/douyin_user/config.js +15 -0
  18. package/core/file/plugins/douyin_user/model.js +72 -0
  19. package/core/file/plugins/good_sku/controller.js +80 -0
  20. package/core/file/plugins/h5_user/config.js +19 -0
  21. package/core/file/plugins/h5_user/model.js +71 -0
  22. package/core/file/plugins/lang/config.js +4 -0
  23. package/core/file/plugins/lang/model.js +15 -0
  24. package/core/file/plugins/language/config.js +5 -0
  25. package/core/file/plugins/language/model.js +54 -0
  26. package/core/file/plugins/log/config.js +25 -0
  27. package/core/file/plugins/log/controller.js +31 -0
  28. package/core/file/plugins/log/model.js +51 -0
  29. package/core/file/plugins/model/config.js +12 -0
  30. package/core/file/plugins/model/controller.js +69 -0
  31. package/core/file/plugins/model/model.js +169 -0
  32. package/core/file/plugins/model/service.js +218 -0
  33. package/core/file/plugins/model/validate.js +42 -0
  34. package/core/file/plugins/model_attributes/config.js +12 -0
  35. package/core/file/plugins/model_attributes/model.js +114 -0
  36. package/core/file/plugins/mp_user/config.js +19 -0
  37. package/core/file/plugins/mp_user/model.js +59 -0
  38. package/core/file/plugins/permission/config.js +15 -0
  39. package/core/file/plugins/permission/model.js +91 -0
  40. package/core/file/plugins/role/config.js +27 -0
  41. package/core/file/plugins/role/controller.js +26 -0
  42. package/core/file/plugins/role/model.js +58 -0
  43. package/core/file/plugins/role_permission/config.js +12 -0
  44. package/core/file/plugins/role_permission/controller.js +27 -0
  45. package/core/file/plugins/role_permission/model.js +24 -0
  46. package/core/file/plugins/routes/config.js +17 -0
  47. package/core/file/plugins/routes/controller.js +153 -0
  48. package/core/file/plugins/routes/model.js +70 -0
  49. package/core/file/plugins/routes/service.js +22 -0
  50. package/core/file/plugins/setting/afterExecute.js +14 -0
  51. package/core/file/plugins/setting/config.js +14 -0
  52. package/core/file/plugins/setting/controller.js +50 -0
  53. package/core/file/plugins/setting/model.js +118 -0
  54. package/core/file/plugins/setting/validate.js +42 -0
  55. package/core/file/plugins/system/controller.js +501 -0
  56. package/core/file/plugins/system/service.js +148 -0
  57. package/core/file/plugins/system/validate.js +40 -0
  58. package/core/file/plugins/todolist/config.js +31 -0
  59. package/core/file/plugins/todolist/model.js +69 -0
  60. package/core/file/plugins/toutiao/controller.js +201 -0
  61. package/core/file/plugins/toutiao_user/config.js +15 -0
  62. package/core/file/plugins/toutiao_user/model.js +66 -0
  63. package/core/file/plugins/user/afterExecute.js +38 -0
  64. package/core/file/plugins/user/config.js +9 -0
  65. package/core/file/plugins/user/controller.js +329 -0
  66. package/core/file/plugins/user/model.js +96 -0
  67. package/core/file/plugins/user/test.js +71 -0
  68. package/core/file/plugins/user/validate.js +44 -0
  69. package/core/file/plugins/video/config.js +3 -0
  70. package/core/file/plugins/video/controller.js +15 -0
  71. package/core/file/plugins/video/validate.js +12 -0
  72. package/core/file/plugins/weixin/config.js +3 -0
  73. package/core/file/plugins/weixin/controller.js +994 -0
  74. package/core/file/plugins/weixin/service.js +105 -0
  75. package/core/file/plugins/weixin/validate.js +111 -0
  76. package/core/file/services/aliSms.js +45 -0
  77. package/core/file/services/alipay.js +123 -0
  78. package/core/file/services/amap.js +95 -0
  79. package/core/file/services/card.js +24 -0
  80. package/core/file/services/config.js +38 -0
  81. package/core/file/services/douyin.js +151 -0
  82. package/core/file/services/email.js +45 -0
  83. package/core/file/services/express.js +37 -0
  84. package/core/file/services/geo.js +71 -0
  85. package/core/file/services/qqVideo.js +64 -0
  86. package/core/file/services/toutiao.js +102 -0
  87. package/core/file/services/weixin.js +79 -0
  88. package/core/file/services/weixinArticle.js +53 -0
  89. package/core/file/services/weixinCrypt.js +34 -0
  90. package/core/file/services/weixinMP.js +435 -0
  91. package/core/file/services/weixinPay.js +35 -0
  92. package/core/file/services/xml.js +33 -0
  93. package/core/file/task/shop/index.js +589 -0
  94. package/core/file/task/shop/static/562e45760a44632de6fa7219bab78cce.png +0 -0
  95. package/core/file/task/shop/static/d7aeaeb6bfd68f71a00a83c0f5548363.png +0 -0
  96. package/core/file/utils/index.js +61 -0
  97. package/core/middlewares.js +120 -0
  98. package/core/restc/.npminstall.done +1 -0
  99. package/core/restc/LICENSE +21 -0
  100. package/core/restc/README.md +48 -0
  101. package/core/restc/faas/index.html +1112 -0
  102. package/core/restc/faas/index.txt +31 -0
  103. package/core/restc/faas/install_production.sh +6 -0
  104. package/core/restc/index.d.ts +7 -0
  105. package/core/restc/index.js +9 -0
  106. package/core/restc/lib/express.js +7 -0
  107. package/core/restc/lib/hapi.js +17 -0
  108. package/core/restc/lib/hapiLegacy.js +15 -0
  109. package/core/restc/lib/index.js +46 -0
  110. package/core/restc/lib/koa.js +9 -0
  111. package/core/restc/lib/koa2.js +9 -0
  112. package/core/restc/lib/utils/gateway.js +51 -0
  113. package/core/restc/package.json +41 -0
  114. package/core/validator.js +15 -0
  115. package/index.js +1 -0
  116. package/package.json +65 -0
@@ -0,0 +1,501 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+ const { VM } = require('vm2')
4
+ const axios = require('axios')
5
+ const cheerio = require('cheerio')
6
+ const {
7
+ lodash,
8
+ getAppByCtx,
9
+ getConfig,
10
+ Sequelize,
11
+ } = require('multiple-quick-koa')
12
+
13
+ exports.initModel = async (ctx) => {
14
+ const { app } = getAppByCtx(ctx)
15
+ const { model, option } = ctx.request.body
16
+ const config = option
17
+ ? {
18
+ [option]: true,
19
+ }
20
+ : {
21
+ alter: true,
22
+ }
23
+ if (model === 'all') {
24
+ const modelList = Object.keys(app.model)
25
+ await Promise.all(modelList.map((m) => app.model[m].sync(config)))
26
+ return ctx.SUCCESS('ok')
27
+ }
28
+ if (app.model[model]) {
29
+ if (Object.keys(app.model[model]).length === 0)
30
+ return ctx.ERROR('请检查,model为空')
31
+ const result = await app.model[model].sync(config)
32
+ return ctx.SUCCESS(result)
33
+ }
34
+ return ctx.SUCCESS(null)
35
+ }
36
+
37
+ exports.customRouter = async (ctx) => {
38
+ // const {
39
+ // app,
40
+ // appName,
41
+ // } = getAppByCtx(ctx);
42
+
43
+ // const list = [{
44
+ // path: 'jiangong_statis',
45
+ // name: '数据面板'
46
+ // }]
47
+ const list = []
48
+ ctx.SUCCESS(list)
49
+ return list
50
+ }
51
+
52
+ exports.showTables = async (ctx) => {
53
+ const { app, appName } = getAppByCtx(ctx)
54
+
55
+ if (app.cache && app.cache.get('showTables')) {
56
+ ctx.SUCCESS(app.cache.get('showTables'))
57
+ return app.cache.get('showTables')
58
+ }
59
+
60
+ const pluginDir = path.resolve(
61
+ __dirname,
62
+ `${process.cwd()}/app/${appName}/plugins`
63
+ )
64
+ let aliasModelList = []
65
+ fs.readdirSync(pluginDir).forEach((folder) => {
66
+ const isFolder = fs.lstatSync(path.resolve(pluginDir, folder)).isDirectory()
67
+ const hasConfig = fs.existsSync(
68
+ path.resolve(
69
+ __dirname,
70
+ `${process.cwd()}/app/${appName}/plugins/${folder}/config.js`
71
+ )
72
+ )
73
+ let hasModel = false
74
+ if (hasConfig) {
75
+ const folderConfig = require(`${process.cwd()}/app/${appName}/plugins/${folder}/config.js`)
76
+ if (folderConfig.model) {
77
+ hasModel = true
78
+ }
79
+ }
80
+
81
+ if (
82
+ isFolder &&
83
+ hasConfig &&
84
+ hasModel &&
85
+ !Object.keys(app.model).includes(folder)
86
+ ) {
87
+ aliasModelList = [...aliasModelList, folder]
88
+ }
89
+ })
90
+ const modelList = [...Object.keys(app.model), ...aliasModelList]
91
+ const models = modelList.map((_model) => {
92
+ const defaultExcludes = [
93
+ 'id',
94
+ 'created_at',
95
+ 'updated_at',
96
+ 'deleted_at',
97
+ 'createdid',
98
+ ]
99
+ const mock = !lodash.isEmpty(
100
+ app.mock && app.mock[_model] && app.mock[_model]()
101
+ )
102
+ const defaultConfigPath = path.resolve(__dirname, `../${_model}/config.js`)
103
+ const defaultConfigExist = fs.existsSync(defaultConfigPath)
104
+ const target =
105
+ Object.keys(app.config[_model]).length === 0 && defaultConfigExist
106
+ ? require(defaultConfigPath)
107
+ : app.config[_model]
108
+ // const target = Object.keys(app.config[model])
109
+
110
+ // console.log(model,mock,app.mock && app.mock[model] && app.mock[model]())
111
+ const model = target.model ? target.model : _model
112
+ return {
113
+ modelName: _model,
114
+ model,
115
+ name: target ? target.name : '',
116
+ // 属于哪个分类
117
+ belongs: lodash.get(target, 'belongs', 'page'),
118
+ // list切换tab显示 ex lanuage
119
+ limit: lodash.get(target, 'limit', 20),
120
+ excludeAuth: lodash.get(target, 'excludeAuth', []),
121
+ // 可排序字段
122
+ order: lodash.get(target, 'order', []),
123
+ // 默认排序
124
+ defaultOrder: lodash.get(target, 'defaultOrder', []),
125
+ // 下拉筛选
126
+ select: lodash.get(target, 'select', []),
127
+ // 是否可以选择批量删除
128
+ multiple: lodash.get(target, 'multiple', true),
129
+ // 是否后台拆分sql
130
+ is_split: lodash.get(target, 'is_split', false),
131
+ // 是否后台拆分count
132
+ is_split_count: lodash.get(target, 'is_split_count', false),
133
+ // 是否后台显示虚拟字段
134
+ show_virtual: lodash.get(target, 'show_virtual', false),
135
+ // 忽略字段
136
+ excludes:
137
+ _model === 'setting'
138
+ ? lodash.get(target, 'excludes', [])
139
+ : lodash.difference(
140
+ lodash.uniq([
141
+ ...defaultExcludes,
142
+ ...lodash.get(target, 'excludes', []),
143
+ ]),
144
+ lodash.get(target, 'order', [])
145
+ ),
146
+ // reference admin components
147
+ reference: lodash.get(target, 'reference', []),
148
+ // reference admin components
149
+ personal: lodash.get(target, 'personal', []),
150
+ // sortOrder router
151
+ sortOrder: lodash.get(target, 'sortOrder', 1),
152
+
153
+ attributes: lodash.mapValues(
154
+ app.attributes[model],
155
+ (item) => item.comment
156
+ ),
157
+
158
+ // include for admin
159
+ include: lodash.get(target, 'include', ''),
160
+ // only include exsit, and for custom like user_distribute has two user model
161
+ relate: lodash.get(target, 'relate', ''),
162
+ // can be mock boolean
163
+ mock,
164
+ // reference model query
165
+ referenceSelect: lodash.get(target, 'referenceSelect', []),
166
+ // 是否可以选择批量删除
167
+ availableSort: lodash.get(target, 'availableSort', false),
168
+ // 用于后台管理不要查询太多数据,常用于表多的model
169
+ autoData: lodash.get(target, 'autoData', null),
170
+ // 有些model需要前置查询其它model数据
171
+ initList: lodash.get(target, 'initList', []),
172
+ // 局部更新列表
173
+ editInline: lodash.get(target, 'editInline', {}),
174
+ // 有些model需要前置查询其它model数据
175
+ comment: lodash.get(target, 'comment', {}),
176
+ // 默认查询,覆盖之前
177
+ modelQuery: lodash.get(target, 'modelQuery', {}),
178
+ // 删除时检查是不是含有
179
+ deleteCheckList: lodash.get(target, 'deleteCheckList', []),
180
+ }
181
+ })
182
+
183
+ ctx.SUCCESS(models)
184
+ app.cache && app.cache.set('showTables', models)
185
+ return models
186
+ }
187
+
188
+ exports.getTable = async (ctx) => {
189
+ const { app } = getAppByCtx(ctx)
190
+
191
+ const { model: _model, show_virtual = false } = ctx.request.body
192
+
193
+ if (app.cache && app.cache.get(`${_model}-table`)) {
194
+ return ctx.SUCCESS(app.cache.get(`${_model}-table`))
195
+ }
196
+
197
+ const model = app.config[_model].model || _model
198
+
199
+ const _result = await app.sequelize.getQueryInterface().describeTable(model)
200
+
201
+ const result = lodash.pick(_result, [
202
+ ...Object.keys(app.attributes[model]),
203
+ 'id',
204
+ 'createdid',
205
+ 'updated_at',
206
+ 'created_at',
207
+ ])
208
+
209
+ const obj = {}
210
+ if (show_virtual) {
211
+ Array.from(
212
+ new Set([...Object.keys(result), ...Object.keys(app.attributes[model])])
213
+ ).forEach((attr) => {
214
+ obj[attr] = lodash.merge(
215
+ app.attributes[model][attr],
216
+ result[attr],
217
+ app.config[_model].comment && app.config[_model].comment
218
+ ? app.config[_model].comment[attr]
219
+ : {}
220
+ )
221
+ })
222
+ } else {
223
+ Object.keys(result).forEach((attr) => {
224
+ obj[attr] = lodash.merge(
225
+ app.attributes[model][attr],
226
+ result[attr],
227
+ app.config[_model].comment && app.config[_model].comment
228
+ ? app.config[_model].comment[attr]
229
+ : {}
230
+ )
231
+ })
232
+ }
233
+
234
+ app.cache && app.cache.set(`${_model}-table`, obj)
235
+ return ctx.SUCCESS(obj)
236
+ }
237
+
238
+ exports.dropModel = async (ctx) => {
239
+ const { app } = getAppByCtx(ctx)
240
+
241
+ const { model } = ctx.request.body
242
+ const result = await app.model[model].drop()
243
+ return ctx.SUCCESS(result)
244
+ }
245
+
246
+ exports.getImage = async (ctx) => {
247
+ const { app } = getAppByCtx(ctx)
248
+
249
+ const appConfig = getConfig(app)
250
+
251
+ const { site_host } = await appConfig.getObject('base')
252
+ // const { dir, upload } = app.config.static;
253
+ const targetDir = `${path.resolve(
254
+ __dirname,
255
+ `${process.cwd()}/public/upload`
256
+ )}`
257
+ const files = fs.readdirSync(targetDir)
258
+ const images = files.filter((file) =>
259
+ /\w(\.gif|\.jpeg|\.png|\.jpg|\.bmp)/i.test(file)
260
+ )
261
+ const result = []
262
+ for (let i = 0; i < images.length; i++) {
263
+ const image = `${path.resolve(
264
+ __dirname,
265
+ `${process.cwd()}/public/upload/${images[i]}`
266
+ )}`
267
+
268
+ result.push({
269
+ img: `http://${site_host || 'api.kuashou.com'}/upload/${images[i]}`,
270
+ name: images[i],
271
+ ...fs.statSync(image),
272
+ })
273
+ }
274
+
275
+ ctx.SUCCESS(result)
276
+ }
277
+
278
+ exports.mock = async (ctx) => {
279
+ const { app } = getAppByCtx(ctx)
280
+
281
+ const { model } = ctx.request.body
282
+ const result = app.mock && app.mock[model] && app.mock[model]()
283
+ return ctx.SUCCESS(!lodash.isEmpty(result))
284
+ }
285
+
286
+ exports.table = async (ctx) => {
287
+ const { app } = getAppByCtx(ctx)
288
+ const { model } = ctx.request.body
289
+ if (!model) {
290
+ const result = Object.keys(app.model).map((m) => ({
291
+ [m]: lodash.mapValues(app.attributes[m], (item) => item.comment),
292
+ }))
293
+ ctx.SUCCESS(result)
294
+ } else {
295
+ const result = app.attributes[model]
296
+ ctx.SUCCESS(result)
297
+ }
298
+ }
299
+
300
+ exports.showAllSchemas = async (ctx) => {
301
+ const { app } = getAppByCtx(ctx)
302
+
303
+ const { model } = ctx.request.body
304
+ const result = await app.sequelize.getQueryInterface().describeTable(model)
305
+ return ctx.SUCCESS(result)
306
+ }
307
+
308
+ exports.initDataWithCache = exports.initData = async (ctx) => {
309
+ const { app } = getAppByCtx(ctx)
310
+ const { includes, excludes = [] } = ctx.request.body
311
+ const result = await app.service.system.initData({
312
+ app,
313
+ includes,
314
+ excludes,
315
+ ctx,
316
+ })
317
+
318
+ return ctx.SUCCESS(result)
319
+ }
320
+
321
+ exports.recentlyError = async (ctx) => {
322
+ // const {
323
+ // app,
324
+ // appName,
325
+ // } = getAppByCtx(ctx);
326
+
327
+ if (ctx.ws) {
328
+ const ws = await ctx.ws()
329
+ const send = (data) => ws.send(JSON.stringify(data))
330
+ ctx.app.on('error', async (err) => {
331
+ console.log(err)
332
+ try {
333
+ send({
334
+ type: 'error',
335
+ payload: err ? err.errorData : {},
336
+ })
337
+ } catch (e) {
338
+ console.log(e)
339
+ }
340
+ })
341
+ } else {
342
+ throw new Error('这是一个websocket url')
343
+ }
344
+ }
345
+
346
+ exports.sandbox = async (ctx) => {
347
+ const code = `
348
+ module.exports = async (callback)=>{
349
+ callback({
350
+ name:1
351
+ })
352
+ }
353
+ `
354
+ // const { code } = ctx.request.body;
355
+ const vm = new VM({
356
+ sandbox: {
357
+ axios,
358
+ cheerio,
359
+ module,
360
+ setTimeout,
361
+ sleep: (time) =>
362
+ new Promise((resolve) => setTimeout(resolve, time * 1000)),
363
+ },
364
+ })
365
+ vm.run(code)(ctx.SUCCESS)
366
+ }
367
+
368
+ exports.onlineChat = async (ctx) => {
369
+ if (ctx.ws) {
370
+ const ws = await ctx.ws()
371
+ const send = (data) => ws.send(JSON.stringify(data))
372
+ ws.on('message', async (code) => {
373
+ const vm = new VM({
374
+ sandbox: {
375
+ send: (data) => ws.send(JSON.stringify(data)),
376
+ axios,
377
+ cheerio,
378
+ },
379
+ })
380
+ vm.run(code)
381
+ const unhandledRejections = {}
382
+
383
+ process.on('unhandledRejection', (reason) => {
384
+ if (unhandledRejections[reason]) {
385
+ console.log('====?', reason)
386
+ } else {
387
+ send({
388
+ type: 'error',
389
+ payload: `${reason}`,
390
+ })
391
+ unhandledRejections[reason] = true
392
+ }
393
+ })
394
+ })
395
+ } else {
396
+ throw new Error('这是一个websocket url')
397
+ }
398
+ }
399
+
400
+ exports.chat = async (ctx) => {
401
+ const { app } = getAppByCtx(ctx)
402
+ if (ctx.ws) {
403
+ const ws = await ctx.ws()
404
+ const send = (data) => ws.send(JSON.stringify(data))
405
+ ws.on('message', async (payload) => {
406
+ const message = JSON.parse(payload)
407
+ const result = await app.model.ask.create({
408
+ user_id: message.payload.user_id,
409
+ content: message.payload.content,
410
+ is_ask: Boolean(message.payload.user_id),
411
+ })
412
+
413
+ send({
414
+ type: 'message',
415
+ payload: result,
416
+ })
417
+ })
418
+ } else {
419
+ throw new Error('这是一个websocket url')
420
+ }
421
+ }
422
+
423
+ exports.task = async (ctx) => {
424
+ const { app } = getAppByCtx(ctx)
425
+
426
+ const { task } = ctx.request.body
427
+
428
+ if (app.task && app.task[task]) {
429
+ await app.task[task](app)
430
+ }
431
+ ctx.SUCCESS(task)
432
+ }
433
+
434
+ exports.dashboard = async (ctx) => {
435
+ // const {
436
+ // app,
437
+ // } = getAppByCtx(ctx);
438
+
439
+ const result = [
440
+ // {
441
+ // name: '用户',
442
+ // number: 5,
443
+ // route: 'page/user'
444
+ // }
445
+ ]
446
+ ctx.SUCCESS(result)
447
+ }
448
+
449
+ exports.drop = async (ctx) => {
450
+ const { app, appName } = getAppByCtx(ctx)
451
+
452
+ const result = await app.sequelize.showAllSchemas()
453
+ const list = result.map((item) => item[`Tables_in_${appName}`])
454
+ const filterList = list.filter((item) => !app.model[item])
455
+ await Promise.all(
456
+ filterList.map((folder) => {
457
+ const model = app.sequelize.define(
458
+ folder,
459
+ {
460
+ id: {
461
+ type: Sequelize.INTEGER(11),
462
+ allowNull: false,
463
+ primaryKey: true,
464
+ autoIncrement: true,
465
+ },
466
+ },
467
+ {
468
+ freezeTableName: true,
469
+ comment: folder,
470
+ createdAt: 'created_at',
471
+ updatedAt: 'updated_at',
472
+ name: {
473
+ singular: folder,
474
+ plural: `${folder}s`,
475
+ },
476
+ }
477
+ )
478
+ return model.drop()
479
+ })
480
+ )
481
+
482
+ ctx.SUCCESS(`删除${filterList.length}个无用表`)
483
+ }
484
+
485
+ exports.mockPay = async (ctx) => {
486
+ const { app } = getAppByCtx(ctx)
487
+ const { order_id, order_price, prefix, ...rest } = ctx.request.body
488
+ const model = prefix ? `${prefix}_order` : 'order'
489
+ console.log(model, 'model')
490
+ if (!(app.service[model] && app.service[model].notify)) {
491
+ throw new Error(`没配置${model}支付回调notify`)
492
+ }
493
+ await app.service[model].notify({
494
+ app,
495
+ order_id,
496
+ order: model,
497
+ order_price,
498
+ ...rest,
499
+ })
500
+ ctx.SUCCESS('ok')
501
+ }
@@ -0,0 +1,148 @@
1
+ const { getConfig, lodash } = require('multiple-quick-koa')
2
+ const formatPostFunction = (str) => `eval(${str})`
3
+ const nodeVm = require('vm')
4
+
5
+ exports.initData = async ({ includes, excludes, app, ctx }) => {
6
+ const appConfig = getConfig(app)
7
+ const { version: cacheVersion } = await appConfig.getObject('base')
8
+ const apiVersion = ctx.request.header.version
9
+
10
+ if (!(excludes instanceof Array)) {
11
+ excludes = [excludes]
12
+ }
13
+ const result = await Promise.all(
14
+ Object.keys(includes)
15
+ .filter((item) => excludes.includes(item) || excludes.length === 0)
16
+ .map((item) => {
17
+ const route = includes[item]
18
+ if (lodash.isObject(route)) {
19
+ const {
20
+ url,
21
+ data,
22
+ order,
23
+ limit,
24
+ include,
25
+ excludeInclude,
26
+ autoInclude = true,
27
+ } = route
28
+ const [model, fn] = url.split('/')
29
+
30
+ let myInclude
31
+
32
+ if (include) {
33
+ const _str = formatPostFunction(include)
34
+ const postInclude = nodeVm.runInNewContext(_str)
35
+ // const postInclude = include.toFunction();
36
+ myInclude =
37
+ app.include && app.include[model]
38
+ ? [
39
+ ...postInclude(app),
40
+ ...(autoInclude ? app.include[model] : []),
41
+ ]
42
+ : postInclude(app)
43
+ } else {
44
+ myInclude = autoInclude ? app.include[model] : []
45
+ }
46
+
47
+ if (
48
+ excludeInclude &&
49
+ Array.isArray(excludeInclude) &&
50
+ excludeInclude.length > 0
51
+ ) {
52
+ myInclude = myInclude.filter((i) => {
53
+ if (excludeInclude.includes(model)) return false
54
+ if (excludeInclude.includes(i.as)) return false
55
+ return (
56
+ (excludeInclude.every((m) => {
57
+ return app.model[m] !== i.model
58
+ }) ||
59
+ i.as) &&
60
+ !(
61
+ i.as &&
62
+ data.attributes &&
63
+ data.attributes.exclude &&
64
+ data.attributes.exclude.includes(i.as + '_id')
65
+ )
66
+ )
67
+ })
68
+ }
69
+
70
+ if (app.controller[model] && app.controller[model][fn]) {
71
+ return app.controller[model][fn](ctx, data).then((result) => {
72
+ if (!result) {
73
+ console.log(`需要在控制器${fn}中返回`)
74
+ }
75
+ return {
76
+ [item]: result,
77
+ }
78
+ })
79
+ } else if (app.model[model]) {
80
+ return app.model[model][fn]
81
+ ? app.model[model][fn]({
82
+ order,
83
+ limit,
84
+ include: myInclude,
85
+ ...data,
86
+ }).then((result) => {
87
+ const list =
88
+ data && data.omit && Array.isArray(data.omit)
89
+ ? result.map((obj) => {
90
+ return lodash.omit(obj.toJSON(), data.omit)
91
+ })
92
+ : result
93
+ return {
94
+ [item]: list,
95
+ }
96
+ })
97
+ : Promise.resolve({
98
+ [item]: [],
99
+ })
100
+ } else {
101
+ return Promise.resolve({
102
+ [item]: [],
103
+ })
104
+ }
105
+ }
106
+ const [model, fn] = route.split('/')
107
+ if (app.cache && app.cache.get(`${model}`)) {
108
+ return Promise.resolve({
109
+ [item]: app.cache.get(`${model}`),
110
+ })
111
+ }
112
+ return app.model[model][fn]({
113
+ include: app.include[model],
114
+ ...(app.config[model] ? app.config[model].autoData : {}),
115
+ }).then((res) => {
116
+ app.cache && app.cache.set(`${model}`, res)
117
+ const cacheModel = lodash.get(app, 'appConfig.cacheModel', [])
118
+ app.appConfig.cacheModel = Array.from(new Set([...cacheModel, model]))
119
+ return {
120
+ [item]: res,
121
+ }
122
+ })
123
+ })
124
+ )
125
+
126
+ const obj = result.reduce(
127
+ (a, b) => ({
128
+ ...a,
129
+ ...b,
130
+ }),
131
+ {}
132
+ )
133
+ if (obj.setting && apiVersion && cacheVersion) {
134
+ return {
135
+ ...obj,
136
+ setting: obj.setting.map((i) => {
137
+ if (i.code === 'is_check' && i.value === false) {
138
+ return {
139
+ ...i.toJSON(),
140
+ value: apiVersion === cacheVersion,
141
+ }
142
+ }
143
+ return i
144
+ }),
145
+ }
146
+ }
147
+ return obj
148
+ }
@@ -0,0 +1,40 @@
1
+ const { Validator, getAppByCtx } = require('multiple-quick-koa');
2
+
3
+ exports.initModel = async (ctx) => {
4
+ const params = {
5
+ model: {
6
+ type: 'string',
7
+ required: true,
8
+ message: '请输入model',
9
+ },
10
+ };
11
+ await new Validator(params).validate(ctx.request.body);
12
+ };
13
+
14
+ exports.showAllSchemas = async (ctx) => {
15
+ const {app,appName} = getAppByCtx(ctx)
16
+
17
+ const params = {
18
+ model: {
19
+ type: 'string',
20
+ required: true,
21
+ message: '请输入model',
22
+ validator: (rule, value) => ((app[appName].model && app[appName].model[value]) ? Promise.resolve() : Promise.reject('没有这个模型')),
23
+ },
24
+ };
25
+ await new Validator(params).validate(ctx.request.body);
26
+ };
27
+
28
+ exports.dropModel = async (ctx) => {
29
+ const {app,appName} = getAppByCtx(ctx)
30
+
31
+ const params = {
32
+ model: {
33
+ type: 'string',
34
+ required: true,
35
+ message: '请输入model',
36
+ validator: (rule, value) => ((app[appName].model && app[appName].model[value]) ? Promise.resolve() : Promise.reject('没有这个模型')),
37
+ },
38
+ };
39
+ await new Validator(params).validate(ctx.request.body);
40
+ };
@@ -0,0 +1,31 @@
1
+ module.exports = {
2
+ name: '需求排期',
3
+ belongs: 'auth',
4
+ multiple: false,
5
+ availableSort: false,
6
+ order: [],
7
+ select: [
8
+ {
9
+ key: 'name',
10
+ symbol: '$like',
11
+ },
12
+ {
13
+ key: 'status',
14
+ },
15
+ {
16
+ key: 'type',
17
+ },
18
+ ],
19
+ excludes: [],
20
+ limit: 20,
21
+ defaultOrder: [
22
+ { sort: 'ascending', type: 'status' },
23
+ { sort: 'descending', type: 'important_rate' },
24
+ ],
25
+ sortOrder: 1,
26
+ reference: [],
27
+ excludeAuth: [],
28
+ initList: [],
29
+ is_split: false,
30
+ show_virtual: false,
31
+ }