q-koa 13.3.0 → 13.3.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.
package/core/app.js CHANGED
@@ -163,9 +163,12 @@ class APP {
163
163
  return ctx.ERROR('error')
164
164
  }
165
165
  const appName = url.split('/')[1]
166
- if (!appName || !(ctx.app[appName] && ctx.app[appName].appConfig)) {
167
- return ctx.ERROR('error')
166
+ if (appName !== '.well-known') {
167
+ if (!appName || !(ctx.app[appName] && ctx.app[appName].appConfig)) {
168
+ return ctx.ERROR('error')
169
+ }
168
170
  }
171
+
169
172
  const { secret, whiteList, _whiteList, tokenKey, expiresIn } =
170
173
  ctx.app[appName] && ctx.app[appName].appConfig
171
174
  ? ctx.app[appName].appConfig.jwt
@@ -286,10 +289,11 @@ class APP {
286
289
  typeof this.config.includes[0] === 'string'
287
290
  ? this.config.includes[0]
288
291
  : this.config.includes[0].app
289
- if (!this.app[appName])
292
+ if (!this.app[appName]) {
290
293
  throw new Error(
291
294
  `没有生成应用${this.config.includes[0]},请检查config includes`
292
295
  )
296
+ }
293
297
  this.server = this.app.listen(this.port, () => {
294
298
  console.log(
295
299
  `${moment().format(
@@ -518,9 +522,8 @@ class APP {
518
522
  this.app[appName].service.log.push({
519
523
  app: this.app[appName],
520
524
  appName,
521
- message: e.message,
525
+ message: e.stack,
522
526
  })
523
- console.log(e.message)
524
527
  }
525
528
  }
526
529
 
@@ -536,7 +539,10 @@ class APP {
536
539
  if (this.config.router) {
537
540
  this.config.router(router)
538
541
  }
539
- router.post('*', () => {
542
+ router.get('/.well-known/pki-validation/fileauth.txt', (ctx) => {
543
+ ctx.body = this.config.fileauth || '没找到config里的fileauth'
544
+ })
545
+ router.post('*', (ctx) => {
540
546
  throw new Error('接口路径不符合规范')
541
547
  })
542
548
  this.app.use(router.routes()).use(router.allowedMethods())
@@ -851,8 +857,8 @@ class APP {
851
857
 
852
858
  list.forEach((model1) => {
853
859
  if (this.app[appName].attributes[model][`${model1}_id`].belongsTo) {
854
- const myModel = this.app[appName].attributes[model][`${model1}_id`]
855
- .belongsTo
860
+ const myModel =
861
+ this.app[appName].attributes[model][`${model1}_id`].belongsTo
856
862
  this.app[appName].model[model].belongsTo(
857
863
  this.app[appName].model[myModel],
858
864
  {
@@ -961,6 +967,23 @@ class APP {
961
967
  return ctx.SUCCESS(await app[appName].mock[controller]())
962
968
  }
963
969
 
970
+ if (fn === 'groupCount') {
971
+ if (!ctx.request.body.group) throw new Error('必须要有group')
972
+ const result = await app[appName].model[controller].findAll({
973
+ attributes: [
974
+ ctx.request.body.group,
975
+ [
976
+ Sequelize.fn('count', Sequelize.col(ctx.request.body.group)),
977
+ 'count',
978
+ ],
979
+ ],
980
+ group: [ctx.request.body.group],
981
+ where: ctx.request.body.where,
982
+ order: [[Sequelize.literal('count'), 'DESC']],
983
+ })
984
+ ctx.SUCCESS(result)
985
+ return
986
+ }
964
987
  if (
965
988
  !_.get(app, `${appName}.model.${controller}.${fn}`) &&
966
989
  !_.get(app, `${appName}.controller.${controller}.${fn}`)
@@ -976,7 +999,13 @@ class APP {
976
999
  if (ctx.app[appName].redisClient) {
977
1000
  ctx.app[appName].redisClient.publish('cache clear', `${controller}`)
978
1001
  } else {
979
- ctx.app[appName].cache.set(`${controller}`, null)
1002
+ // ctx.app[appName].cache.set(`${controller}`, null)
1003
+ ctx.app[appName].service.cache &&
1004
+ ctx.app[appName].service.cache.init({
1005
+ app: ctx.app[appName],
1006
+ appName,
1007
+ model: controller,
1008
+ })
980
1009
  }
981
1010
  }
982
1011
  }
@@ -1103,8 +1132,9 @@ class APP {
1103
1132
  const strInclude = postInclude(app[appName])
1104
1133
  // const postInclude = include.toFunction();
1105
1134
 
1106
- if (!Array.isArray(strInclude))
1107
- throw new Error(`可能include不是一个数组`)
1135
+ if (!Array.isArray(strInclude)) {
1136
+ throw new Error('可能include不是一个数组')
1137
+ }
1108
1138
 
1109
1139
  myInclude =
1110
1140
  app[appName] &&
@@ -1654,9 +1684,8 @@ class APP {
1654
1684
  app[appName].attributes[modelName] &&
1655
1685
  app[appName].attributes[modelName][controller + '_id']
1656
1686
  ) {
1657
- const { required, include, where, ...rest } = myInclude[
1658
- j
1659
- ]
1687
+ const { required, include, where, ...rest } =
1688
+ myInclude[j]
1660
1689
  const list = await model.findAll({
1661
1690
  where: {
1662
1691
  [controller + '_id']: target.id,
@@ -1959,7 +1988,13 @@ class APP {
1959
1988
  `${controller}`
1960
1989
  )
1961
1990
  } else {
1962
- ctx.app[appName].cache.set(`${controller}`, null)
1991
+ // ctx.app[appName].cache.set(`${controller}`, null)
1992
+ ctx.app[appName].service.cache &&
1993
+ ctx.app[appName].service.cache.init({
1994
+ app: ctx.app[appName],
1995
+ appName,
1996
+ model: controller,
1997
+ })
1963
1998
  }
1964
1999
  }
1965
2000
  }
@@ -2016,7 +2051,13 @@ class APP {
2016
2051
  `${controller}`
2017
2052
  )
2018
2053
  } else {
2019
- ctx.app[appName].cache.set(`${controller}`, null)
2054
+ // ctx.app[appName].cache.set(`${controller}`, null)
2055
+ ctx.app[appName].service.cache &&
2056
+ ctx.app[appName].service.cache.init({
2057
+ app: ctx.app[appName],
2058
+ appName,
2059
+ model: controller,
2060
+ })
2020
2061
  }
2021
2062
  }
2022
2063
  }
@@ -2048,7 +2089,13 @@ class APP {
2048
2089
  `${controller}`
2049
2090
  )
2050
2091
  } else {
2051
- ctx.app[appName].cache.set(`${controller}`, null)
2092
+ // ctx.app[appName].cache.set(`${controller}`, null)
2093
+ ctx.app[appName].service.cache &&
2094
+ ctx.app[appName].service.cache.init({
2095
+ app: ctx.app[appName],
2096
+ appName,
2097
+ model: controller,
2098
+ })
2052
2099
  }
2053
2100
  }
2054
2101
  }
@@ -1,5 +1,7 @@
1
- exports.init = async ({ app, appName }) => {
2
- const cacheModel = app.appConfig.cacheModel
1
+ exports.init = async ({ app, appName, model = '' }) => {
2
+ const cacheModel = app.appConfig.cacheModel.filter((m) =>
3
+ model ? m === model : true
4
+ )
3
5
 
4
6
  const promiseFn = async (model) => {
5
7
  const result = await app.model[model].findAll({
@@ -90,7 +90,8 @@ exports.permission_id = {
90
90
  defaultValue: [],
91
91
  sortOrder: 5,
92
92
  get: function () {
93
- return this.getDataValue('permission_id') === null
93
+ return this.getDataValue('permission_id') === null ||
94
+ !Array.isArray(this.getDataValue('permission_id'))
94
95
  ? []
95
96
  : this.getDataValue('permission_id')
96
97
  },
@@ -80,14 +80,53 @@ exports.countAndMaxId = async (ctx, _data) => {
80
80
  return null
81
81
  }
82
82
  const count = await app.model[model].count()
83
- const result = await app.model[model].findOne({
83
+ const current = await app.model[model].findOne({
84
+ attributes: ['id', 'created_at'],
85
+ order: [['id', 'DESC']],
86
+ })
87
+
88
+ const current_max_id = current ? current.id : 0
89
+
90
+ const lastMonth = await app.model[model].findOne({
84
91
  attributes: ['id'],
92
+ where: {
93
+ created_at: {
94
+ $lt: moment().add(-1, 'months'),
95
+ },
96
+ },
85
97
  order: [['id', 'DESC']],
86
98
  })
87
99
 
100
+ const last_month_id = lastMonth ? lastMonth.id : 0
101
+
102
+ const _result = await app.sequelize.getQueryInterface().describeTable(model)
103
+ const type = _result.id.type
104
+
105
+ const mapper = {
106
+ TINYINT: 255,
107
+ SMALLINIT: 65535,
108
+ MEDIUMINT: 16777215,
109
+ INT: 4294967295,
110
+ }
111
+ let availableId = 0
112
+ for (const _type in mapper) {
113
+ if (type.startsWith(_type)) {
114
+ availableId = mapper[_type]
115
+ }
116
+ }
117
+
118
+ let availableMonth = 10000
119
+ const month_diff = current_max_id - last_month_id
120
+
121
+ if (month_diff) {
122
+ availableMonth = Math.floor((availableId - current_max_id) / month_diff)
123
+ }
124
+
88
125
  const payLoad = {
89
126
  count,
90
- max_id: result ? result.id : 0,
127
+ current_max_id,
128
+ availableId,
129
+ availableMonth,
91
130
  }
92
131
 
93
132
  ctx.SUCCESS(payLoad)
@@ -109,8 +148,9 @@ exports.initModel = async (ctx) => {
109
148
  const appConfig = getConfig(app)
110
149
  if (Array.isArray(model)) {
111
150
  const { is_dev } = await appConfig.getObject('base')
112
- if (!is_dev && option === 'force')
151
+ if (!is_dev && option === 'force') {
113
152
  throw new Error('正式环境不允许array model force')
153
+ }
114
154
  await Promise.all(model.map((m) => app.model[m].sync(config)))
115
155
  return ctx.SUCCESS('ok')
116
156
  }
@@ -251,7 +291,7 @@ exports.showTables = async (ctx) => {
251
291
  if (!target) throw new Error(`检查是否有${_model}/config.js`)
252
292
  const model = target.model ? target.model : _model
253
293
 
254
- function getValueByModelName(target, key, defaultValue, model, _model) {
294
+ const getValueByModelName = (target, key, defaultValue, model, _model) => {
255
295
  return lodash.get(
256
296
  target,
257
297
  key,
@@ -935,3 +975,58 @@ exports.reset = async (ctx) => {
935
975
 
936
976
  ctx.SUCCESS(result.length)
937
977
  }
978
+
979
+ exports.changeIdType = async (ctx) => {
980
+ const { app, appName } = getAppByCtx(ctx)
981
+ const { model } = ctx.request.body
982
+ if (!model) return ctx.ERROR('?model')
983
+ if (!app.model[model]) return ctx.ERROR('check model?')
984
+ const belongs = lodash.get(app.config[model], 'belongs', 'page')
985
+ const idType = lodash.get(
986
+ app.config[model],
987
+ 'idType',
988
+ belongs === 'setting' ? 'TINYINT' : 'MEDIUMINT'
989
+ )
990
+
991
+ const mapper = {
992
+ INTEGER: 'INT',
993
+ TINYINT: 'TINYINT',
994
+ MEDIUMINT: 'MEDIUMINT',
995
+ }
996
+ if (!mapper[idType]) return ctx.ERROR(`not accept ${idType}`)
997
+
998
+ const col = 'id'
999
+ const _result = await app.sequelize.getQueryInterface().describeTable(model)
1000
+ const obj = _result[col]
1001
+ const updateTo = `${mapper[idType]} UNSIGNED`
1002
+
1003
+ const query = `ALTER TABLE \`${model}\` MODIFY COLUMN id ${updateTo} NOT NULL AUTO_INCREMENT`
1004
+
1005
+ const target = lodash.pickBy(app.attributes, (obj) => `${model}_id` in obj)
1006
+
1007
+ console.log(`即将更新${model}的ID类型为${updateTo}`)
1008
+ let error_message = ''
1009
+ let flag = true
1010
+ for (const _model of Object.keys(target)) {
1011
+ const _res = await app.sequelize.getQueryInterface().describeTable(_model)
1012
+ if (updateTo !== _res[`${model}_id`].type) {
1013
+ error_message = `请先处理好${_model}的字段类型${model}_id,当前是${
1014
+ _res[`${model}_id`].type
1015
+ }`
1016
+ console.error(error_message)
1017
+ flag = false
1018
+ }
1019
+ }
1020
+ if (obj.type === updateTo) {
1021
+ return ctx.ERROR('已经是了')
1022
+ }
1023
+
1024
+ if (!flag) {
1025
+ return ctx.ERROR(error_message)
1026
+ }
1027
+ // ctx.SUCCESS(query)
1028
+
1029
+ const result = await app.sequelize.query(query)
1030
+
1031
+ ctx.SUCCESS(result)
1032
+ }
@@ -75,6 +75,8 @@ exports.initData = async ({ includes, excludes, app, ctx }) => {
75
75
  }
76
76
  }
77
77
  if (is_cache && app.cache && app.cache.get(`${model}`)) {
78
+ const omit = data && data.omit ? data.omit : []
79
+ const pick = data && data.pick ? data.pick : []
78
80
  const cacheData = app.cache.get(`${model}`) || []
79
81
  const cacheList = cacheData
80
82
  .map((i) => (i.toJSON ? i.toJSON() : i))
@@ -85,8 +87,6 @@ exports.initData = async ({ includes, excludes, app, ctx }) => {
85
87
  })
86
88
  })
87
89
  .map((c) => {
88
- const omit = data && data.omit ? data.omit : []
89
- const pick = data && data.pick ? data.pick : []
90
90
  return pick.length > 0
91
91
  ? lodash.pick(c, pick)
92
92
  : lodash.omit(c, omit)
@@ -158,159 +158,71 @@ exports.initData = async ({ includes, excludes, app, ctx }) => {
158
158
  })
159
159
  } else if (app.model[model]) {
160
160
  if (app.model[model][fn]) {
161
- if (
162
- data &&
163
- data.cache_level &&
164
- data.cache_level === 2 &&
165
- app.model.cache
166
- ) {
167
- return app.model.cache
168
- .findOne({
169
- where: {
170
- key: JSON.stringify({
171
- order,
172
- limit,
173
- include: myInclude,
174
- ...data,
175
- }),
176
- },
177
- })
178
- .then((res) => {
179
- if (res && res.result) {
180
- console.log(`${model}有cache`)
181
- return Promise.resolve({
182
- [item]: res.result,
183
- })
184
- } else {
185
- return app.model[model][fn]({
186
- order,
187
- limit,
188
- include: myInclude,
189
- ...data,
190
- }).then((result) => {
191
- const list =
192
- data && data.omit && Array.isArray(data.omit)
193
- ? result.map((obj) => {
194
- return lodash.omit(obj.toJSON(), data.omit)
195
- })
196
- : result
197
- if (
198
- data &&
199
- data.cache_level &&
200
- data.cache_level === 2 &&
201
- list.length > 0
202
- ) {
203
- app.model.cache &&
204
- app.model.cache.create({
205
- key: JSON.stringify({
206
- order,
207
- limit,
208
- include: myInclude,
209
- ...data,
210
- }),
211
- result: list,
212
- })
213
- }
214
- return {
215
- [item]: list,
216
- }
217
- })
161
+ if (data && lodash.isObject(data)) {
162
+ if (
163
+ fn === 'findOne' &&
164
+ 'attributes' in data &&
165
+ Array.isArray(data.attributes) &&
166
+ data.attributes.every((attribute) =>
167
+ Array.isArray(attribute)
168
+ ) &&
169
+ data.attributes.some(
170
+ (attribute) =>
171
+ Array.isArray(attribute) &&
172
+ attribute.some((att) => att.startsWith('literal'))
173
+ )
174
+ ) {
175
+ return app.model[model][fn]({
176
+ where: data.where,
177
+ attributes: data.attributes.map((attribute) => {
178
+ if (Array.isArray(attribute)) {
179
+ return attribute.map((att) => {
180
+ if (att.startsWith('literal')) {
181
+ return Sequelize.literal(getLiteral(att))
182
+ }
183
+ return att
184
+ })
185
+ }
186
+ return attribute
187
+ }),
188
+ }).then((res) => {
189
+ return {
190
+ [item]: res,
218
191
  }
219
192
  })
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,
193
+ }
194
+ }
195
+ const formatData =
196
+ fn === 'findAll' &&
197
+ data &&
198
+ lodash.isObject(data) &&
199
+ data.hasOwnProperty('where')
200
+ ? lodash.mapValues(data, (value, key) => {
201
+ if (key === 'where') {
202
+ return lodash.mapValues(data.where, (item) => {
203
+ if (!lodash.isObject(item)) return item
204
+ return formatLiteralObj(item)
205
+ })
251
206
  }
207
+ return value
252
208
  })
253
- }
254
- }
255
- const formatData =
256
- fn === 'findAll' &&
257
- data &&
258
- lodash.isObject(data) &&
259
- data.hasOwnProperty('where')
260
- ? lodash.mapValues(data, (value, key) => {
261
- if (key === 'where') {
262
- return lodash.mapValues(data.where, (item) => {
263
- if (!lodash.isObject(item)) return item
264
- return formatLiteralObj(item)
265
- })
266
- }
267
- return value
209
+ : data
210
+ // console.log('formatData', data, '-->', formatData)
211
+ return app.model[model][fn]({
212
+ order,
213
+ limit,
214
+ include: myInclude,
215
+ ...formatData,
216
+ }).then((result) => {
217
+ const list =
218
+ data && data.omit && Array.isArray(data.omit)
219
+ ? result.map((obj) => {
220
+ return lodash.omit(obj.toJSON(), data.omit)
268
221
  })
269
- : data
270
- // console.log('formatData', data, '-->', formatData)
271
- return app.model[model][fn]({
272
- order,
273
- limit,
274
- include: myInclude,
275
- ...formatData,
276
- }).then((result) => {
277
- const list =
278
- data && data.omit && Array.isArray(data.omit)
279
- ? result.map((obj) => {
280
- return lodash.omit(obj.toJSON(), data.omit)
281
- })
282
- : result
283
- if (
284
- data &&
285
- data.cache_level &&
286
- data.cache_level === 1 &&
287
- list.length > 0
288
- ) {
289
- app.model.cache &&
290
- app.model.cache.update(
291
- {
292
- result: list,
293
- },
294
- {
295
- where: {
296
- key: JSON.stringify({
297
- order,
298
- limit,
299
- include: myInclude,
300
- ...data,
301
- }),
302
- },
303
- }
304
- )
305
- }
306
- return {
307
- [item]: list,
308
- }
309
- })
310
- }
311
- } else {
312
- return Promise.resolve({
313
- [item]: [],
222
+ : result
223
+ return {
224
+ [item]: list,
225
+ }
314
226
  })
315
227
  }
316
228
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "q-koa",
3
- "version": "13.3.0",
3
+ "version": "13.3.2",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {