q-koa 13.2.9 → 13.3.1

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
@@ -286,10 +286,11 @@ class APP {
286
286
  typeof this.config.includes[0] === 'string'
287
287
  ? this.config.includes[0]
288
288
  : this.config.includes[0].app
289
- if (!this.app[appName])
289
+ if (!this.app[appName]) {
290
290
  throw new Error(
291
291
  `没有生成应用${this.config.includes[0]},请检查config includes`
292
292
  )
293
+ }
293
294
  this.server = this.app.listen(this.port, () => {
294
295
  console.log(
295
296
  `${moment().format(
@@ -518,9 +519,8 @@ class APP {
518
519
  this.app[appName].service.log.push({
519
520
  app: this.app[appName],
520
521
  appName,
521
- message: e.message,
522
+ message: e.stack,
522
523
  })
523
- console.log(e.message)
524
524
  }
525
525
  }
526
526
 
@@ -851,8 +851,8 @@ class APP {
851
851
 
852
852
  list.forEach((model1) => {
853
853
  if (this.app[appName].attributes[model][`${model1}_id`].belongsTo) {
854
- const myModel = this.app[appName].attributes[model][`${model1}_id`]
855
- .belongsTo
854
+ const myModel =
855
+ this.app[appName].attributes[model][`${model1}_id`].belongsTo
856
856
  this.app[appName].model[model].belongsTo(
857
857
  this.app[appName].model[myModel],
858
858
  {
@@ -976,7 +976,13 @@ class APP {
976
976
  if (ctx.app[appName].redisClient) {
977
977
  ctx.app[appName].redisClient.publish('cache clear', `${controller}`)
978
978
  } else {
979
- ctx.app[appName].cache.set(`${controller}`, null)
979
+ // ctx.app[appName].cache.set(`${controller}`, null)
980
+ ctx.app[appName].service.cache &&
981
+ ctx.app[appName].service.cache.init({
982
+ app: ctx.app[appName],
983
+ appName,
984
+ model: controller,
985
+ })
980
986
  }
981
987
  }
982
988
  }
@@ -1103,8 +1109,9 @@ class APP {
1103
1109
  const strInclude = postInclude(app[appName])
1104
1110
  // const postInclude = include.toFunction();
1105
1111
 
1106
- if (!Array.isArray(strInclude))
1107
- throw new Error(`可能include不是一个数组`)
1112
+ if (!Array.isArray(strInclude)) {
1113
+ throw new Error('可能include不是一个数组')
1114
+ }
1108
1115
 
1109
1116
  myInclude =
1110
1117
  app[appName] &&
@@ -1654,9 +1661,8 @@ class APP {
1654
1661
  app[appName].attributes[modelName] &&
1655
1662
  app[appName].attributes[modelName][controller + '_id']
1656
1663
  ) {
1657
- const { required, include, where, ...rest } = myInclude[
1658
- j
1659
- ]
1664
+ const { required, include, where, ...rest } =
1665
+ myInclude[j]
1660
1666
  const list = await model.findAll({
1661
1667
  where: {
1662
1668
  [controller + '_id']: target.id,
@@ -1959,7 +1965,13 @@ class APP {
1959
1965
  `${controller}`
1960
1966
  )
1961
1967
  } else {
1962
- ctx.app[appName].cache.set(`${controller}`, null)
1968
+ // ctx.app[appName].cache.set(`${controller}`, null)
1969
+ ctx.app[appName].service.cache &&
1970
+ ctx.app[appName].service.cache.init({
1971
+ app: ctx.app[appName],
1972
+ appName,
1973
+ model: controller,
1974
+ })
1963
1975
  }
1964
1976
  }
1965
1977
  }
@@ -1974,8 +1986,6 @@ class APP {
1974
1986
  (ctx.request[`${appName}-user`] &&
1975
1987
  ((ctx.request[`${appName}-user`].name &&
1976
1988
  ctx.request[`${appName}-user`].name === 'admin') ||
1977
- (ctx.request[`${appName}-user`].mobile &&
1978
- ctx.request[`${appName}-user`].mobile === '18978909244') ||
1979
1989
  ctx.request[`${appName}-user`].is_admin ||
1980
1990
  ctx.request[`${appName}-user`].is_dev))
1981
1991
  ? ['updated_at']
@@ -2018,7 +2028,13 @@ class APP {
2018
2028
  `${controller}`
2019
2029
  )
2020
2030
  } else {
2021
- ctx.app[appName].cache.set(`${controller}`, null)
2031
+ // ctx.app[appName].cache.set(`${controller}`, null)
2032
+ ctx.app[appName].service.cache &&
2033
+ ctx.app[appName].service.cache.init({
2034
+ app: ctx.app[appName],
2035
+ appName,
2036
+ model: controller,
2037
+ })
2022
2038
  }
2023
2039
  }
2024
2040
  }
@@ -2050,7 +2066,13 @@ class APP {
2050
2066
  `${controller}`
2051
2067
  )
2052
2068
  } else {
2053
- ctx.app[appName].cache.set(`${controller}`, null)
2069
+ // ctx.app[appName].cache.set(`${controller}`, null)
2070
+ ctx.app[appName].service.cache &&
2071
+ ctx.app[appName].service.cache.init({
2072
+ app: ctx.app[appName],
2073
+ appName,
2074
+ model: controller,
2075
+ })
2054
2076
  }
2055
2077
  }
2056
2078
  }
@@ -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({
@@ -8,5 +8,5 @@ module.exports = {
8
8
  defaultOrder: [],
9
9
  comment: {},
10
10
  reference: [],
11
-
12
- };
11
+ indexList: [{ fields: ['model_id'] }],
12
+ }
@@ -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
  }
@@ -149,7 +189,7 @@ exports.initModel = async (ctx) => {
149
189
  )
150
190
  .then((res) => res.data)
151
191
  if (code === 200) {
152
- const findList = Object.keys(productionModel).filter((key) => {
192
+ const findList = Object.keys(productionModel || {}).filter((key) => {
153
193
  return (
154
194
  !['id', 'created_at', 'createdid', 'updated_at'].includes(key) &&
155
195
  !Object.keys(app.attributes[model]).includes(key)
@@ -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 flag = true
1009
+ for (const _model of Object.keys(target)) {
1010
+ const _res = await app.sequelize.getQueryInterface().describeTable(_model)
1011
+ if (updateTo !== _res[`${model}_id`].type) {
1012
+ console.error(
1013
+ `请先处理好${_model}的字段类型${model}_id,当前是${
1014
+ _res[`${model}_id`].type
1015
+ }`
1016
+ )
1017
+ flag = false
1018
+ }
1019
+ }
1020
+ if (obj.type === updateTo) {
1021
+ return ctx.ERROR('已经是了')
1022
+ }
1023
+
1024
+ if (!flag) {
1025
+ return ctx.ERROR('更新失败')
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 {
@@ -279,7 +279,7 @@ const $in = {
279
279
  }
280
280
  const $between = {
281
281
  check: (param) =>
282
- Array.isArray(param) && param.every((p) => typeof param === 'string'),
282
+ Array.isArray(param) && param.every((p) => typeof p === 'string'),
283
283
  result: (param, key) => {
284
284
  if (param[key].every((i) => getLiteral(i))) {
285
285
  return {
@@ -322,7 +322,7 @@ exports.formatLiteralObj = (target) => {
322
322
  return target
323
323
  }
324
324
 
325
- exports.filterFunction = (target, data) => {
325
+ const filterFunction = (target, data) => {
326
326
  if (!target) {
327
327
  return false
328
328
  }
@@ -333,6 +333,16 @@ exports.filterFunction = (target, data) => {
333
333
  if (typeof target[key] === 'boolean') {
334
334
  return Boolean(data[key]) === target[key]
335
335
  }
336
+ if ('$and' in target) {
337
+ return target.$and.every((item) => {
338
+ return filterFunction(item, data)
339
+ })
340
+ }
341
+ if ('$or' in target) {
342
+ return target.$or.some((item) => {
343
+ return filterFunction(item, data)
344
+ })
345
+ }
336
346
  if (Array.isArray(target[key])) {
337
347
  return target[key].includes(data[key])
338
348
  }
@@ -386,3 +396,5 @@ exports.filterFunction = (target, data) => {
386
396
  return data[key] === target[key]
387
397
  })
388
398
  }
399
+
400
+ exports.filterFunction = filterFunction
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "q-koa",
3
- "version": "13.2.9",
3
+ "version": "13.3.1",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {