q-koa 8.6.2 → 8.6.3

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.
@@ -42,6 +42,13 @@ exports.availableSort = {
42
42
  defaultValue: false,
43
43
  }
44
44
 
45
+ exports.referenceSelect = {
46
+ type: Sequelize.JSON,
47
+ comment: '筛选',
48
+ allowNull: false,
49
+ defaultValue: [],
50
+ }
51
+
45
52
  exports.select = {
46
53
  type: Sequelize.JSON,
47
54
  comment: '筛选',
@@ -1,255 +1,220 @@
1
- const { getConfig, lodash } = require('q-koa')
2
- const formatPostFunction = (str) => `eval(${str})`
3
- const nodeVm = require('vm')
4
- const { is } = require('cheerio/lib/api/traversing')
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+ const fsPromise = require('fs/promises')
4
+ exports.loadModel = async ({ app, appName }) => {
5
+ const data = await fsPromise.readdir(
6
+ path.resolve(__dirname, `${process.cwd()}/app/${appName}/plugins`)
7
+ )
5
8
 
6
- exports.initData = async ({ includes, excludes, app, ctx }) => {
7
- const appConfig = getConfig(app)
8
- const { version: cacheVersion } = await appConfig.getObject('base')
9
- const apiVersion = ctx.request.header.version
10
- const config = ctx.request.header.config
9
+ // const modelList = await app.model.model.findAll({ raw: true })
11
10
 
12
- if (!(excludes instanceof Array)) {
13
- excludes = [excludes]
14
- }
15
- const result = await Promise.all(
16
- Object.keys(includes)
17
- .filter((item) => excludes.includes(item) || excludes.length === 0)
18
- .map((item) => {
19
- const route = includes[item]
20
- if (lodash.isObject(route)) {
21
- const {
22
- url,
23
- data,
24
- order,
25
- limit,
26
- include,
27
- excludeInclude,
28
- autoInclude = true,
29
- } = route
30
- const [model, fn] = url.split('/')
11
+ await Promise.all(
12
+ ['model', 'model_attributes'].map((item) =>
13
+ app.model[item].sync({
14
+ force: true,
15
+ })
16
+ )
17
+ )
31
18
 
32
- let myInclude
19
+ const dataList = []
20
+ const result = data.filter(
21
+ (item) => !['model', 'model_attributes'].includes(item)
22
+ )
23
+ for (let i = 0; i < result.length; i++) {
24
+ const filePath = path.resolve(
25
+ __dirname,
26
+ `${process.cwd()}/app/${appName}/plugins/${result[i]}/model.js`
27
+ )
28
+ const configPath = path.resolve(
29
+ __dirname,
30
+ `${process.cwd()}/app/${appName}/plugins/${result[i]}/config.js`
31
+ )
32
+ const defaultFilePath = path.resolve(__dirname, `../${result[i]}/model.js`)
33
+ const defaultConfigPath = path.resolve(
34
+ __dirname,
35
+ `../${result[i]}/config.js`
36
+ )
37
+ const modelExist = fs.existsSync(filePath)
38
+ const defaultModelExist = fs.existsSync(defaultFilePath)
39
+ const configExist = fs.existsSync(configPath)
40
+ if (configExist) {
41
+ const config = (await fsPromise.readFile(configPath, 'utf-8'))
42
+ ? require(configPath)
43
+ : require(defaultConfigPath)
33
44
 
34
- if (include) {
35
- const _str = formatPostFunction(include)
36
- const postInclude = nodeVm.runInNewContext(_str)
37
- // const postInclude = include.toFunction();
38
- myInclude =
39
- app.include && app.include[model]
40
- ? [
41
- ...postInclude(app),
42
- ...(autoInclude ? app.include[model] : []),
43
- ]
44
- : postInclude(app)
45
- } else {
46
- myInclude = autoInclude ? app.include[model] : []
47
- }
45
+ const modelFile =
46
+ defaultModelExist || modelExist
47
+ ? (await fsPromise.readFile(filePath, 'utf-8'))
48
+ ? await fsPromise.readFile(filePath, 'utf-8')
49
+ : await fsPromise.readFile(defaultFilePath, 'utf-8')
50
+ : null
48
51
 
49
- if (
50
- excludeInclude &&
51
- Array.isArray(excludeInclude) &&
52
- excludeInclude.length > 0
53
- ) {
54
- myInclude = myInclude.filter((i) => {
55
- if (excludeInclude.includes(model)) return false
56
- if (excludeInclude.includes(i.as)) return false
57
- return (
58
- (excludeInclude.every((m) => {
59
- return app.model[m] !== i.model
60
- }) ||
61
- i.as) &&
62
- !(
63
- i.as &&
64
- data.attributes &&
65
- data.attributes.exclude &&
66
- data.attributes.exclude.includes(i.as + '_id')
67
- )
68
- )
69
- })
70
- }
52
+ const model = modelFile
53
+ ? (await fsPromise.readFile(filePath, 'utf-8'))
54
+ ? require(filePath)
55
+ : require(defaultFilePath)
56
+ : {}
57
+ const attributes = modelFile ? modelFile.match(/exports.(.*)=/g) : []
58
+ const types = modelFile ? modelFile.match(/Sequelize.(.*),\n/g) : {}
71
59
 
72
- if (app.controller[model] && app.controller[model][fn]) {
73
- return app.controller[model][fn](ctx, data).then((result) => {
74
- if (!result && process.env.NODE_ENV !== 'production') {
75
- console.log(`需要在控制器${fn}中返回`)
76
- }
77
- return {
78
- [item]: result,
79
- }
80
- })
81
- } else if (app.model[model]) {
82
- if (app.model[model][fn]) {
83
- if (
84
- data &&
85
- data.cache_level &&
86
- data.cache_level === 2 &&
87
- app.model.cache
88
- ) {
89
- return app.model.cache
90
- .findOne({
91
- where: {
92
- key: JSON.stringify({
93
- order,
94
- limit,
95
- include: myInclude,
96
- ...data,
97
- }),
98
- },
99
- })
100
- .then((res) => {
101
- if (res && res.result) {
102
- console.log(`${model}有cache`)
103
- return Promise.resolve({
104
- [item]: res.result,
105
- })
106
- } else {
107
- return app.model[model][fn]({
108
- order,
109
- limit,
110
- include: myInclude,
111
- ...data,
112
- }).then((result) => {
113
- const list =
114
- data && data.omit && Array.isArray(data.omit)
115
- ? result.map((obj) => {
116
- return lodash.omit(obj.toJSON(), data.omit)
117
- })
118
- : result
119
- if (
120
- data &&
121
- data.cache_level &&
122
- data.cache_level === 2 &&
123
- list.length > 0
124
- ) {
125
- app.model.cache &&
126
- app.model.cache.create({
127
- key: JSON.stringify({
128
- order,
129
- limit,
130
- include: myInclude,
131
- ...data,
132
- }),
133
- result: list,
134
- })
135
- }
136
- return {
137
- [item]: list,
138
- }
139
- })
140
- }
141
- })
142
- } else {
143
- return app.model[model][fn]({
144
- order,
145
- limit,
146
- include: myInclude,
147
- ...data,
148
- }).then((result) => {
149
- const list =
150
- data && data.omit && Array.isArray(data.omit)
151
- ? result.map((obj) => {
152
- return lodash.omit(obj.toJSON(), data.omit)
153
- })
154
- : result
155
- if (
156
- data &&
157
- data.cache_level &&
158
- data.cache_level === 1 &&
159
- list.length > 0
160
- ) {
161
- app.model.cache &&
162
- app.model.cache.update(
163
- {
164
- result: list,
165
- },
166
- {
167
- where: {
168
- key: JSON.stringify({
169
- order,
170
- limit,
171
- include: myInclude,
172
- ...data,
173
- }),
174
- },
175
- }
176
- )
177
- }
178
- return {
179
- [item]: list,
180
- }
181
- })
182
- }
183
- } else {
184
- return Promise.resolve({
185
- [item]: [],
186
- })
60
+ // const ori_target = modelList.find((m) => m.model === result[i])
61
+ // const id = ori_target ? ori_target.id : null
62
+ const id = i + 1
63
+ const obj = {
64
+ id,
65
+ model: result[i],
66
+ name: config.name,
67
+ belongs: config.belongs || 'page',
68
+ order: config.order,
69
+ multiple: config.multiple,
70
+ availableSort: config.availableSort,
71
+ limit: config.limit || 20,
72
+ select: config.select,
73
+ excludes: config.excludes,
74
+ initList: config.initList,
75
+ defaultOrder: config.defaultOrder,
76
+ excludeAuth: config.excludeAuth,
77
+ comment: config.comment,
78
+ reference: config.reference,
79
+ include: config.include,
80
+ sortOrder: config.sortOrder,
81
+ personal: config.personal,
82
+ autoData: config.autoData,
83
+ is_split: config.is_split,
84
+ is_split_count: config.is_split_count,
85
+ show_virtual: config.show_virtual,
86
+ modelQuery: config.modelQuery,
87
+ referenceSelect: config.referenceSelect,
88
+ editInline: config.editInline,
89
+ deleteCheckList: config.deleteCheckList,
90
+ bulkCreateList: config.bulkCreateList,
91
+ list: attributes.map((attr, index) => {
92
+ const name = attr.match(/exports.(.*)=/)[1].trim()
93
+ let defaultValue = ''
94
+ if (model[name] && model[name].hasOwnProperty('defaultValue')) {
95
+ if (
96
+ typeof model[name].defaultValue === 'boolean' &&
97
+ model[name].defaultValue === true
98
+ ) {
99
+ defaultValue = 'true'
100
+ }
101
+ if (
102
+ typeof model[name].defaultValue === 'boolean' &&
103
+ model[name].defaultValue === false
104
+ ) {
105
+ defaultValue = 'false'
106
+ }
107
+ if (typeof model[name].defaultValue === 'number') {
108
+ defaultValue = `${model[name].defaultValue}`
109
+ }
110
+ if (Array.isArray(model[name].defaultValue)) {
111
+ defaultValue = JSON.stringify(model[name].defaultValue)
112
+ }
113
+ if (
114
+ Object.prototype.toString.call(model[name].defaultValue) ===
115
+ '[object Object]'
116
+ ) {
117
+ defaultValue = '{}'
118
+ }
119
+ if (
120
+ typeof model[name].defaultValue === 'string' &&
121
+ model[name].defaultValue === ''
122
+ ) {
123
+ defaultValue = "''"
124
+ }
125
+ if (
126
+ typeof model[name].defaultValue === 'string' &&
127
+ model[name].defaultValue !== ''
128
+ ) {
129
+ defaultValue = `'${model[name].defaultValue}'`
130
+ }
131
+ if (
132
+ !model[name].defaultValue &&
133
+ typeof model[name].defaultValue !== 'undefined' &&
134
+ model[name].defaultValue != 0
135
+ ) {
136
+ defaultValue = 'null'
137
+ }
138
+ if (
139
+ types[index] &&
140
+ types[index].includes('DATE') &&
141
+ model[name].allowNull === true
142
+ ) {
143
+ defaultValue = 'null'
187
144
  }
188
- } else {
189
- return Promise.resolve({
190
- [item]: [],
191
- })
145
+ } else if (
146
+ model[name] &&
147
+ !model[name].hasOwnProperty('defaultValue')
148
+ ) {
149
+ defaultValue = "''"
192
150
  }
193
- }
194
- const [model, fn] = route.split('/')
195
- if (app.cache && app.cache.get(`${model}`)) {
196
- return Promise.resolve({
197
- [item]: app.cache.get(`${model}`),
198
- })
199
- }
200
- return app.model[model][fn]({
201
- include: app.include[model],
202
- ...(app.config[model] ? app.config[model].autoData : {}),
203
- }).then((res) => {
204
- app.cache && app.cache.set(`${model}`, res)
205
- const cacheModel = lodash.get(app, 'appConfig.cacheModel', [])
206
- app.appConfig.cacheModel = Array.from(new Set([...cacheModel, model]))
151
+
207
152
  return {
208
- [item]: res,
153
+ model_id: id || i + 1,
154
+ name,
155
+ type: types[index] ? types[index].replace(/,\n/, '') : '',
156
+ comment: model[name] ? model[name].comment : '',
157
+ is_mock:
158
+ model[name] && model[name].is_mock
159
+ ? model[name].is_mock
160
+ : !!(model[name] && model[name].mock),
161
+ allowNull:
162
+ model[name] && model[name].allowNull
163
+ ? model[name].allowNull
164
+ : false,
165
+ defaultValue,
166
+ sortOrder:
167
+ model[name] && model[name].sortOrder
168
+ ? Number(model[name].sortOrder)
169
+ : 1,
170
+ mock:
171
+ model[name] && model[name].mock
172
+ ? model[name].mock.toString()
173
+ : '',
174
+ set:
175
+ model[name] && model[name].set ? model[name].set.toString() : '',
176
+ get:
177
+ model[name] && model[name].get ? model[name].get.toString() : '',
178
+ belongsTo: model[name] ? model[name].belongsTo : '',
179
+ unique: !!(model[name] && model[name].hasOwnProperty('unique')),
180
+ hasOne: !!(model[name] && model[name].hasOwnProperty('hasOne')),
181
+ validate:
182
+ model[name] && model[name].validate
183
+ ? JSON.stringify(model[name].validate)
184
+ : null,
185
+ extra:
186
+ model[name] && model[name].extra
187
+ ? JSON.stringify(model[name].extra)
188
+ : null,
209
189
  }
210
- })
211
- })
212
- )
213
-
214
- const obj = result.reduce(
215
- (a, b) => ({
216
- ...a,
217
- ...b,
218
- }),
219
- {}
220
- )
221
- if (obj.setting && apiVersion && cacheVersion) {
222
- let target = null
223
- if (config) {
224
- const application = app.cache.get('application')
225
- if (application) {
226
- target = application.find((a) => a.config === config)
190
+ }),
227
191
  }
192
+ // if (obj.model === 'user_free') {
193
+ // console.log(obj)
194
+ // }
195
+ dataList.push(obj)
228
196
  }
197
+ }
229
198
 
230
- return {
231
- ...obj,
232
- setting: obj.setting.map((i) => {
233
- if (i.code === 'is_check' && i.value === false) {
234
- return {
235
- ...(i.toJSON ? i.toJSON() : i),
236
- value: apiVersion === cacheVersion,
237
- }
238
- }
199
+ const promise1 = app.model.model.bulkCreate(
200
+ dataList.map((item) => {
201
+ return {
202
+ ...item,
203
+ list: item.list.filter((t) => t.type),
204
+ }
205
+ })
206
+ )
207
+ const promise2 = app.model.model_attributes.bulkCreate(
208
+ dataList
209
+ .filter((item) => item.list.every((t) => t.type))
210
+ .reduce((a, b) => [...a, ...b.list], [])
211
+ )
239
212
 
240
- if (
241
- target &&
242
- target.hasOwnProperty(i.code) &&
243
- i.hasOwnProperty('value')
244
- ) {
245
- return {
246
- ...(i.toJSON ? i.toJSON() : i),
247
- value: target[i.code],
248
- }
249
- }
250
- return i
251
- }),
252
- }
213
+ await Promise.all([promise1, promise2])
214
+ console.log('lodaModel success!')
215
+ if (app.service.routes && app.model.routes) {
216
+ await app.service.routes.initRouter({ app })
217
+ } else {
218
+ console.warn('routes可能没有service.js')
253
219
  }
254
- return obj
255
220
  }
@@ -1,6 +1,6 @@
1
1
  const md5 = require('js-md5')
2
2
  const { getAppByCtx, getConfig, lodash } = require('q-koa')
3
-
3
+ const { getAppConfig } = require('../../utils')
4
4
  exports.login = async (ctx) => {
5
5
  const { app, appName } = getAppByCtx(ctx)
6
6
  const { mobile, password, ...rest } = ctx.request.body
@@ -259,11 +259,20 @@ exports.checkLogin = async (ctx) => {
259
259
  return app.model[m] !== i.model
260
260
  })
261
261
  })
262
+ const { exclude_list = [] } = await getAppConfig({ app, config })
263
+ const attributes = {
264
+ exclude: Array.from(
265
+ new Set([
266
+ ...app.appConfig.loginData.attributes.exclude,
267
+ ...(Array.isArray(exclude_list) ? exclude_list : []),
268
+ ])
269
+ ),
270
+ }
262
271
  result = await app.model.user.findOne({
263
272
  where: {
264
273
  id: ctx.request[`${appName}-user`].id,
265
274
  },
266
- attributes: app.appConfig.loginData.attributes,
275
+ attributes,
267
276
  include,
268
277
  })
269
278
  } else {
@@ -140,3 +140,13 @@ exports.getImageType = (fileBuffer) => {
140
140
  // 未能识别到该文件类型
141
141
  return ''
142
142
  }
143
+
144
+ exports.getAppConfig = async ({ app, config }) => {
145
+ if (!config || !app) return null
146
+ const application =
147
+ app.cache.get('application') || (await app.model.application.findAll())
148
+
149
+ const target = application.find((a) => a.config === config)
150
+
151
+ return target
152
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "q-koa",
3
- "version": "8.6.2",
3
+ "version": "8.6.3",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {