q-koa 13.1.8 → 13.2.0
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 +14 -1
- package/core/config.js +0 -1
- package/core/file/plugins/system/controller.js +3 -1
- package/core/file/plugins/system/service.js +8 -1
- package/core/file/plugins/weixin/service.js +12 -1
- package/core/file/services/weixinMP.js +25 -0
- package/core/file/utils/index.js +72 -1
- package/package.json +1 -1
package/core/app.js
CHANGED
|
@@ -288,6 +288,18 @@ class APP {
|
|
|
288
288
|
)} server is running at http://localhost:${this.port}`
|
|
289
289
|
)
|
|
290
290
|
if (is_dev) {
|
|
291
|
+
const db_name = _.get(this.app[appName], 'sequelize.config.database')
|
|
292
|
+
this.app[appName].model.setting.update(
|
|
293
|
+
{
|
|
294
|
+
value: db_name,
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
where: {
|
|
298
|
+
code: 'db_name',
|
|
299
|
+
},
|
|
300
|
+
}
|
|
301
|
+
)
|
|
302
|
+
|
|
291
303
|
console.log(
|
|
292
304
|
`first app is http://localhost:3001/${appName}/setting/findOne`
|
|
293
305
|
)
|
|
@@ -1231,12 +1243,12 @@ class APP {
|
|
|
1231
1243
|
return {
|
|
1232
1244
|
...item,
|
|
1233
1245
|
where: {
|
|
1234
|
-
...item.where,
|
|
1235
1246
|
...(includeWhere[item.model.getName()]
|
|
1236
1247
|
? {
|
|
1237
1248
|
...includeWhere[item.model.getName()],
|
|
1238
1249
|
}
|
|
1239
1250
|
: {}),
|
|
1251
|
+
...item.where,
|
|
1240
1252
|
},
|
|
1241
1253
|
}
|
|
1242
1254
|
})
|
|
@@ -2040,6 +2052,7 @@ APP.Validator = Validator
|
|
|
2040
2052
|
APP.ServiceError = ServiceError
|
|
2041
2053
|
APP.TransactionError = TransactionError
|
|
2042
2054
|
APP.moment = moment
|
|
2055
|
+
APP.utils = require('./file/utils')
|
|
2043
2056
|
APP.is_dev = is_dev
|
|
2044
2057
|
|
|
2045
2058
|
global.moment = moment
|
package/core/config.js
CHANGED
|
@@ -309,7 +309,9 @@ exports.getTable = async (ctx) => {
|
|
|
309
309
|
return ctx.SUCCESS(app.cache.get(`${_model}-table`))
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
-
const model = app.config[_model].model || _model
|
|
312
|
+
const model = (app.config[_model] && app.config[_model].model) || _model
|
|
313
|
+
|
|
314
|
+
if (!app.config[model]) return ctx.SUCCESS(null)
|
|
313
315
|
|
|
314
316
|
const _result = await app.sequelize.getQueryInterface().describeTable(model)
|
|
315
317
|
|
|
@@ -34,6 +34,7 @@ exports.initData = async ({ includes, excludes, app, ctx }) => {
|
|
|
34
34
|
excludeInclude,
|
|
35
35
|
autoInclude = true,
|
|
36
36
|
is_cache = false,
|
|
37
|
+
defaultValue,
|
|
37
38
|
} = route
|
|
38
39
|
|
|
39
40
|
if (url.includes('http')) {
|
|
@@ -135,8 +136,14 @@ exports.initData = async ({ includes, excludes, app, ctx }) => {
|
|
|
135
136
|
|
|
136
137
|
if (app.controller[model] && app.controller[model][fn]) {
|
|
137
138
|
return app.controller[model][fn](ctx, data).then((result) => {
|
|
138
|
-
if (
|
|
139
|
+
if (
|
|
140
|
+
result === undefined &&
|
|
141
|
+
process.env.NODE_ENV !== 'production'
|
|
142
|
+
) {
|
|
139
143
|
console.error(`需要在控制器${fn}中返回`)
|
|
144
|
+
return {
|
|
145
|
+
[item]: defaultValue || result,
|
|
146
|
+
}
|
|
140
147
|
}
|
|
141
148
|
return {
|
|
142
149
|
[item]: result,
|
|
@@ -4,6 +4,7 @@ const {
|
|
|
4
4
|
getConfig,
|
|
5
5
|
lodash,
|
|
6
6
|
moment,
|
|
7
|
+
sleep,
|
|
7
8
|
} = require('q-koa')
|
|
8
9
|
const { Pay } = require('@sigodenjs/wechatpay')
|
|
9
10
|
const WXPay = require('weixin-pay-fork')
|
|
@@ -480,13 +481,23 @@ exports.handleUserMessage = async ({ app, result }) => {
|
|
|
480
481
|
secrect: app_secrect,
|
|
481
482
|
})
|
|
482
483
|
weixinMp.init()
|
|
484
|
+
const touser = result.FromUserName
|
|
485
|
+
await weixinMp.handleTyping({
|
|
486
|
+
touser,
|
|
487
|
+
is_typing: true,
|
|
488
|
+
})
|
|
489
|
+
await sleep(3)
|
|
483
490
|
await weixinMp.handleMessage({
|
|
484
|
-
touser
|
|
491
|
+
touser,
|
|
485
492
|
msgtype: 'text',
|
|
486
493
|
text: {
|
|
487
494
|
content: `你说${result.Content},是吗?`,
|
|
488
495
|
},
|
|
489
496
|
})
|
|
497
|
+
await weixinMp.handleTyping({
|
|
498
|
+
touser,
|
|
499
|
+
is_typing: false,
|
|
500
|
+
})
|
|
490
501
|
}
|
|
491
502
|
}
|
|
492
503
|
|
|
@@ -20,6 +20,8 @@ const sendMessageUrl =
|
|
|
20
20
|
'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=%s'
|
|
21
21
|
const handleMessageUrl =
|
|
22
22
|
'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s'
|
|
23
|
+
const handleTypingUrl =
|
|
24
|
+
'https://api.weixin.qq.com/cgi-bin/message/custom/typing?access_token=%s'
|
|
23
25
|
const uploadFile =
|
|
24
26
|
'https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s'
|
|
25
27
|
const serviceMarketUrl =
|
|
@@ -391,6 +393,11 @@ module.exports = class Singleton {
|
|
|
391
393
|
cache.reset()
|
|
392
394
|
return await this.queryUrlLink(url_link)
|
|
393
395
|
}
|
|
396
|
+
if (result.errcode === 85403) {
|
|
397
|
+
return {
|
|
398
|
+
expire_time: 0,
|
|
399
|
+
}
|
|
400
|
+
}
|
|
394
401
|
throw new Error(`${result.errcode};${result.errmsg}`)
|
|
395
402
|
}
|
|
396
403
|
return result.url_link_info
|
|
@@ -558,6 +565,24 @@ module.exports = class Singleton {
|
|
|
558
565
|
return result
|
|
559
566
|
}
|
|
560
567
|
|
|
568
|
+
async handleTyping({ touser, is_typing = true }) {
|
|
569
|
+
const options = {
|
|
570
|
+
touser,
|
|
571
|
+
command: is_typing ? 'Typing' : 'CancelTyping',
|
|
572
|
+
}
|
|
573
|
+
const access_token = await this.getAccessToken()
|
|
574
|
+
const url = util.format(handleTypingUrl, access_token)
|
|
575
|
+
const result = await axios.post(url, options).then((res) => res.data)
|
|
576
|
+
if (result.errcode) {
|
|
577
|
+
if (result.errcode === 40001) {
|
|
578
|
+
cache.reset()
|
|
579
|
+
return await this.handleTyping(options)
|
|
580
|
+
}
|
|
581
|
+
throw new Error(`${result.errcode};${result.errmsg}`)
|
|
582
|
+
}
|
|
583
|
+
return result
|
|
584
|
+
}
|
|
585
|
+
|
|
561
586
|
async uploadFile(imgUrl) {
|
|
562
587
|
if (!imgUrl || !imgUrl.includes('//')) throw new Error('检查imgUrl是否链接')
|
|
563
588
|
|
package/core/file/utils/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const { lodash } = require('q-koa')
|
|
2
2
|
const Sequelize = require('sequelize')
|
|
3
3
|
const md5 = require('md5')
|
|
4
|
+
const moment = require('moment')
|
|
4
5
|
|
|
5
6
|
const findConfig = (type) => (item) =>
|
|
6
7
|
item.key === type ||
|
|
@@ -207,6 +208,11 @@ exports.signResult = (params, salt) => {
|
|
|
207
208
|
return md5(signStr)
|
|
208
209
|
}
|
|
209
210
|
|
|
211
|
+
function isDateTime(str) {
|
|
212
|
+
const dateRegex = /^[\u4e00-\u9fa5]{4}-[\u4e00-\u9fa5]{2}-[\u4e00-\u9fa5]{2}$/
|
|
213
|
+
return dateRegex.test(str)
|
|
214
|
+
}
|
|
215
|
+
|
|
210
216
|
const $lt = {
|
|
211
217
|
check: (param) => typeof param === 'string',
|
|
212
218
|
result: (param, key) => {
|
|
@@ -225,7 +231,7 @@ const $in = {
|
|
|
225
231
|
}
|
|
226
232
|
const $between = {
|
|
227
233
|
check: (param) =>
|
|
228
|
-
Array.isArray(param) && param.every((p) =>
|
|
234
|
+
Array.isArray(param) && param.every((p) => typeof param === 'string'),
|
|
229
235
|
result: (param, key) => {
|
|
230
236
|
return {
|
|
231
237
|
[key]: param[key].map(Sequelize.literal),
|
|
@@ -257,3 +263,68 @@ exports.formatLiteralObj = (target) => {
|
|
|
257
263
|
}
|
|
258
264
|
return target
|
|
259
265
|
}
|
|
266
|
+
|
|
267
|
+
exports.filterFunction = (target, data) => {
|
|
268
|
+
if (!target) {
|
|
269
|
+
console.error(`target为null`)
|
|
270
|
+
return false
|
|
271
|
+
}
|
|
272
|
+
return Object.keys(target).every((key) => {
|
|
273
|
+
if (key.includes('.')) {
|
|
274
|
+
return lodash.get(data, key) === target[key]
|
|
275
|
+
}
|
|
276
|
+
if (typeof target[key] === 'boolean') {
|
|
277
|
+
return Boolean(data[key]) === target[key]
|
|
278
|
+
}
|
|
279
|
+
if (Array.isArray(target[key])) {
|
|
280
|
+
return target[key].includes(data[key])
|
|
281
|
+
}
|
|
282
|
+
if (lodash.isObject(target[key])) {
|
|
283
|
+
if (Object.prototype.hasOwnProperty.call(target[key], '$gt')) {
|
|
284
|
+
if (key.endsWith('time') || key.endsWith('_at')) {
|
|
285
|
+
return moment(data[key]).diff(moment(target[key].$gt), 'seconds') > 0
|
|
286
|
+
}
|
|
287
|
+
return data[key] > target[key].$gt
|
|
288
|
+
} else if (Object.prototype.hasOwnProperty.call(target[key], '$gte')) {
|
|
289
|
+
if (key.endsWith('time') || key.endsWith('_at')) {
|
|
290
|
+
return moment(data[key]).diff(moment(target[key].$gt), 'seconds') >= 0
|
|
291
|
+
}
|
|
292
|
+
return data[key] >= target[key].$gte
|
|
293
|
+
} else if (Object.prototype.hasOwnProperty.call(target[key], '$lt')) {
|
|
294
|
+
if (key.endsWith('time') || key.endsWith('_at')) {
|
|
295
|
+
return moment(target[key].$gt).diff(moment(data[key]), 'seconds') < 0
|
|
296
|
+
}
|
|
297
|
+
return data[key] < target[key].$lt
|
|
298
|
+
} else if (Object.prototype.hasOwnProperty.call(target[key], '$lte')) {
|
|
299
|
+
if (key.endsWith('time') || key.endsWith('_at')) {
|
|
300
|
+
return moment(target[key].$gt).diff(moment(data[key]), 'seconds') <= 0
|
|
301
|
+
}
|
|
302
|
+
return data[key] <= target[key].$lte
|
|
303
|
+
} else if (Object.prototype.hasOwnProperty.call(target[key], '$notIn')) {
|
|
304
|
+
return !target[key].$notIn.includes(data[key])
|
|
305
|
+
} else if (Object.prototype.hasOwnProperty.call(target[key], '$in')) {
|
|
306
|
+
return target[key].$in.includes(data[key])
|
|
307
|
+
} else if (
|
|
308
|
+
Object.prototype.hasOwnProperty.call(target[key], '$between')
|
|
309
|
+
) {
|
|
310
|
+
if (
|
|
311
|
+
!Array.isArray(target[key].$between) ||
|
|
312
|
+
target[key].$between.length !== 2
|
|
313
|
+
) {
|
|
314
|
+
throw new Error(`$between example : [2,5]`)
|
|
315
|
+
}
|
|
316
|
+
const min = target[key].$between[0]
|
|
317
|
+
const max = target[key].$between[1]
|
|
318
|
+
return data[key] >= min && data[key] <= max
|
|
319
|
+
} else if (Object.prototype.hasOwnProperty.call(target[key], '$ne')) {
|
|
320
|
+
return data[key] !== target[key].$ne
|
|
321
|
+
} else if (Object.prototype.hasOwnProperty.call(target[key], '$neq')) {
|
|
322
|
+
return data[key] !== target[key].$neq
|
|
323
|
+
} else if (Object.prototype.hasOwnProperty.call(target[key], '$eq')) {
|
|
324
|
+
return data[key] === target[key].$eq
|
|
325
|
+
}
|
|
326
|
+
return data[key] === target[key]
|
|
327
|
+
}
|
|
328
|
+
return data[key] === target[key]
|
|
329
|
+
})
|
|
330
|
+
}
|