q-koa 8.6.0 → 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 {
@@ -743,12 +743,14 @@ exports.h5_pay = async (ctx) => {
743
743
  } = ctx.request.body
744
744
 
745
745
  const appConfig = getConfig(app)
746
- const { appId, key, mchId } = await appConfig.getObject(pay_config)
746
+ const { appId, key, mchId, partner_key } = await appConfig.getObject(
747
+ pay_config
748
+ )
747
749
  const { is_dev, site_host } = await appConfig.getObject('base')
748
750
 
749
751
  const payObj = new WeixinPay({
750
752
  appId,
751
- key,
753
+ key: key.length > 10 ? key : partner_key,
752
754
  mchId,
753
755
  })
754
756
  const result = await payObj.run({
@@ -803,7 +805,7 @@ exports.mp_pay = async (ctx) => {
803
805
  }
804
806
  const appConfig = getConfig(app)
805
807
 
806
- const { mchId, key } = await appConfig.getObject(pay_config)
808
+ const { mchId, key, partner_key } = await appConfig.getObject(pay_config)
807
809
  const { is_dev, site_host } = await appConfig.getObject('base')
808
810
  // 公众号支付用 服务号 appid,其他用小程序 appid
809
811
  const app_id =
@@ -814,7 +816,7 @@ exports.mp_pay = async (ctx) => {
814
816
  const wxpay = WXPay({
815
817
  appid: app_id,
816
818
  mch_id: mchId,
817
- partner_key: key, // 微信商户平台API密钥
819
+ partner_key: key.length > 10 ? key : partner_key, // 微信商户平台API密钥
818
820
  })
819
821
 
820
822
  const pay = (options) =>
@@ -1152,12 +1154,12 @@ exports.checkPay = async (ctx) => {
1152
1154
 
1153
1155
  const appConfig = getConfig(app)
1154
1156
  const app_id = (await appConfig.getObject(config)).app_id
1155
- const { mchId, key } = await appConfig.getObject(pay_config)
1157
+ const { mchId, key, partner_key } = await appConfig.getObject(pay_config)
1156
1158
 
1157
1159
  const wxpay = WXPay({
1158
1160
  appid: app_id,
1159
1161
  mch_id: mchId,
1160
- partner_key: key, // 微信商户平台API密钥
1162
+ partner_key: key.length > 10 ? key : partner_key, // 微信商户平台API密钥
1161
1163
  })
1162
1164
 
1163
1165
  const checkOrder = (obj) => {
@@ -18,13 +18,15 @@ exports.refund = async ({
18
18
  }) => {
19
19
  const { app, appName } = getAppByCtx(ctx)
20
20
  const appConfig = getConfig(app)
21
- const { mchId, key, appId } = await appConfig.getObject(pay_config)
21
+ const { mchId, key, appId, partner_key } = await appConfig.getObject(
22
+ pay_config
23
+ )
22
24
  const { site_host } = await appConfig.getObject('base')
23
25
 
24
26
  const payObj = new Pay({
25
27
  appId: appId,
26
28
  mchId: mchId,
27
- key: key, // 微信商户平台API密钥,
29
+ key: key.length > 10 ? key : partner_key, // 微信商户平台API密钥,
28
30
  pfx: await fsPromise.readFile(
29
31
  path.resolve(
30
32
  __dirname,
@@ -72,14 +74,16 @@ exports.cash = async ({
72
74
  }) => {
73
75
  const { app, appName } = getAppByCtx(ctx)
74
76
  const appConfig = getConfig(app)
75
- const { mchId, key, appId } = await appConfig.getObject(pay_config)
77
+ const { mchId, key, appId, partner_key } = await appConfig.getObject(
78
+ pay_config
79
+ )
76
80
 
77
81
  const { is_dev } = await appConfig.getObject('base')
78
82
 
79
83
  const payObj = new Pay({
80
84
  appId: appId,
81
85
  mchId: mchId,
82
- key: key, // 微信商户平台API密钥,
86
+ key: key.length > 10 ? key : partner_key, // 微信商户平台API密钥,
83
87
  pfx: await fsPromise.readFile(
84
88
  path.resolve(
85
89
  __dirname,
@@ -24,6 +24,21 @@ exports.getObject = (config, app) => async (type) => {
24
24
  ) {
25
25
  return applicationList.find((item) => item.config === type)
26
26
  }
27
+
28
+ if (!applicationList) {
29
+ if (app.model.application) {
30
+ const result = await app.model.application.findAll()
31
+
32
+ if (result.length > 0) {
33
+ app.cache.set('application', JSON.parse(JSON.stringify(result)))
34
+
35
+ const target = result.find((item) => item.config === type)
36
+ if (target) {
37
+ return target
38
+ }
39
+ }
40
+ }
41
+ }
27
42
  }
28
43
  const obj = config.find((i) => i.code === type)
29
44
  if (!obj) throw new Error(`找不到${type}相关设置`)
@@ -125,3 +140,13 @@ exports.getImageType = (fileBuffer) => {
125
140
  // 未能识别到该文件类型
126
141
  return ''
127
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.0",
3
+ "version": "8.6.3",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {