q-koa 7.7.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.
Files changed (116) hide show
  1. package/core/app.js +1813 -0
  2. package/core/config.js +124 -0
  3. package/core/file/plugins/administrator/config.js +17 -0
  4. package/core/file/plugins/administrator/controller.js +264 -0
  5. package/core/file/plugins/administrator/model.js +53 -0
  6. package/core/file/plugins/administrator/validate.js +41 -0
  7. package/core/file/plugins/alipay/controller.js +68 -0
  8. package/core/file/plugins/alipay/validate.js +9 -0
  9. package/core/file/plugins/cache/service.js +16 -0
  10. package/core/file/plugins/cloudfunction/config.js +4 -0
  11. package/core/file/plugins/cloudfunction/model.js +15 -0
  12. package/core/file/plugins/common/controller.js +398 -0
  13. package/core/file/plugins/common/validate.js +47 -0
  14. package/core/file/plugins/douyin/config.js +3 -0
  15. package/core/file/plugins/douyin/controller.js +521 -0
  16. package/core/file/plugins/douyin/validate.js +40 -0
  17. package/core/file/plugins/douyin_user/config.js +15 -0
  18. package/core/file/plugins/douyin_user/model.js +72 -0
  19. package/core/file/plugins/good_sku/controller.js +80 -0
  20. package/core/file/plugins/h5_user/config.js +19 -0
  21. package/core/file/plugins/h5_user/model.js +71 -0
  22. package/core/file/plugins/lang/config.js +4 -0
  23. package/core/file/plugins/lang/model.js +15 -0
  24. package/core/file/plugins/language/config.js +5 -0
  25. package/core/file/plugins/language/model.js +54 -0
  26. package/core/file/plugins/log/config.js +25 -0
  27. package/core/file/plugins/log/controller.js +31 -0
  28. package/core/file/plugins/log/model.js +51 -0
  29. package/core/file/plugins/model/config.js +12 -0
  30. package/core/file/plugins/model/controller.js +69 -0
  31. package/core/file/plugins/model/model.js +169 -0
  32. package/core/file/plugins/model/service.js +218 -0
  33. package/core/file/plugins/model/validate.js +42 -0
  34. package/core/file/plugins/model_attributes/config.js +12 -0
  35. package/core/file/plugins/model_attributes/model.js +114 -0
  36. package/core/file/plugins/mp_user/config.js +19 -0
  37. package/core/file/plugins/mp_user/model.js +59 -0
  38. package/core/file/plugins/permission/config.js +15 -0
  39. package/core/file/plugins/permission/model.js +91 -0
  40. package/core/file/plugins/role/config.js +27 -0
  41. package/core/file/plugins/role/controller.js +26 -0
  42. package/core/file/plugins/role/model.js +58 -0
  43. package/core/file/plugins/role_permission/config.js +12 -0
  44. package/core/file/plugins/role_permission/controller.js +27 -0
  45. package/core/file/plugins/role_permission/model.js +24 -0
  46. package/core/file/plugins/routes/config.js +17 -0
  47. package/core/file/plugins/routes/controller.js +153 -0
  48. package/core/file/plugins/routes/model.js +70 -0
  49. package/core/file/plugins/routes/service.js +22 -0
  50. package/core/file/plugins/setting/afterExecute.js +14 -0
  51. package/core/file/plugins/setting/config.js +14 -0
  52. package/core/file/plugins/setting/controller.js +50 -0
  53. package/core/file/plugins/setting/model.js +118 -0
  54. package/core/file/plugins/setting/validate.js +42 -0
  55. package/core/file/plugins/system/controller.js +501 -0
  56. package/core/file/plugins/system/service.js +148 -0
  57. package/core/file/plugins/system/validate.js +40 -0
  58. package/core/file/plugins/todolist/config.js +31 -0
  59. package/core/file/plugins/todolist/model.js +69 -0
  60. package/core/file/plugins/toutiao/controller.js +201 -0
  61. package/core/file/plugins/toutiao_user/config.js +15 -0
  62. package/core/file/plugins/toutiao_user/model.js +66 -0
  63. package/core/file/plugins/user/afterExecute.js +38 -0
  64. package/core/file/plugins/user/config.js +9 -0
  65. package/core/file/plugins/user/controller.js +329 -0
  66. package/core/file/plugins/user/model.js +96 -0
  67. package/core/file/plugins/user/test.js +71 -0
  68. package/core/file/plugins/user/validate.js +44 -0
  69. package/core/file/plugins/video/config.js +3 -0
  70. package/core/file/plugins/video/controller.js +15 -0
  71. package/core/file/plugins/video/validate.js +12 -0
  72. package/core/file/plugins/weixin/config.js +3 -0
  73. package/core/file/plugins/weixin/controller.js +994 -0
  74. package/core/file/plugins/weixin/service.js +105 -0
  75. package/core/file/plugins/weixin/validate.js +111 -0
  76. package/core/file/services/aliSms.js +45 -0
  77. package/core/file/services/alipay.js +123 -0
  78. package/core/file/services/amap.js +95 -0
  79. package/core/file/services/card.js +24 -0
  80. package/core/file/services/config.js +38 -0
  81. package/core/file/services/douyin.js +151 -0
  82. package/core/file/services/email.js +45 -0
  83. package/core/file/services/express.js +37 -0
  84. package/core/file/services/geo.js +71 -0
  85. package/core/file/services/qqVideo.js +64 -0
  86. package/core/file/services/toutiao.js +102 -0
  87. package/core/file/services/weixin.js +79 -0
  88. package/core/file/services/weixinArticle.js +53 -0
  89. package/core/file/services/weixinCrypt.js +34 -0
  90. package/core/file/services/weixinMP.js +435 -0
  91. package/core/file/services/weixinPay.js +35 -0
  92. package/core/file/services/xml.js +33 -0
  93. package/core/file/task/shop/index.js +589 -0
  94. package/core/file/task/shop/static/562e45760a44632de6fa7219bab78cce.png +0 -0
  95. package/core/file/task/shop/static/d7aeaeb6bfd68f71a00a83c0f5548363.png +0 -0
  96. package/core/file/utils/index.js +61 -0
  97. package/core/middlewares.js +120 -0
  98. package/core/restc/.npminstall.done +1 -0
  99. package/core/restc/LICENSE +21 -0
  100. package/core/restc/README.md +48 -0
  101. package/core/restc/faas/index.html +1112 -0
  102. package/core/restc/faas/index.txt +31 -0
  103. package/core/restc/faas/install_production.sh +6 -0
  104. package/core/restc/index.d.ts +7 -0
  105. package/core/restc/index.js +9 -0
  106. package/core/restc/lib/express.js +7 -0
  107. package/core/restc/lib/hapi.js +17 -0
  108. package/core/restc/lib/hapiLegacy.js +15 -0
  109. package/core/restc/lib/index.js +46 -0
  110. package/core/restc/lib/koa.js +9 -0
  111. package/core/restc/lib/koa2.js +9 -0
  112. package/core/restc/lib/utils/gateway.js +51 -0
  113. package/core/restc/package.json +41 -0
  114. package/core/validator.js +15 -0
  115. package/index.js +1 -0
  116. package/package.json +65 -0
@@ -0,0 +1,435 @@
1
+ const util = require('util')
2
+ const axios = require('axios')
3
+
4
+ const { lodash } = require('multiple-quick-koa')
5
+ const getAccessTokenUrl =
6
+ 'https://api.weixin.qq.com/cgi-bin/token?grant_type=%s&appid=%s&secret=%s'
7
+ const createQRCodeUrl =
8
+ 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s'
9
+ const sendMessageUrl =
10
+ 'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=%s'
11
+ const handleMessageUrl =
12
+ 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s'
13
+ const uploadFile =
14
+ 'https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s'
15
+ const serviceMarketUrl =
16
+ 'https://api.weixin.qq.com/wxa/servicemarket?access_token=%s&type=%s'
17
+ const createLiveUrl =
18
+ 'https://api.weixin.qq.com/wxaapi/broadcast/room/create?access_token=%s'
19
+ const getLiveUrl =
20
+ 'https://api.weixin.qq.com/wxa/business/getliveinfo?access_token=%s'
21
+ const addSubanchorUrl =
22
+ 'https://api.weixin.qq.com/wxaapi/broadcast/room/addsubanchor?access_token=%s'
23
+
24
+ const addRoleUrl =
25
+ 'https://api.weixin.qq.com/wxaapi/broadcast/addRole?access_token=%s'
26
+
27
+ const getExpressUrl =
28
+ 'https://api.weixin.qq.com/cgi-bin/express/business/delivery/getall?access_token=%s'
29
+ const addOrderUrl =
30
+ 'https://api.weixin.qq.com/cgi-bin/express/business/order/add?access_token=%s'
31
+
32
+ const path = require('path')
33
+ const fs = require('fs')
34
+ const LRU = require('lru-cache')
35
+ const request = require('request')
36
+ const cache = new LRU({
37
+ max: 100,
38
+ maxAge: 1000 * 60 * 60,
39
+ })
40
+ const uuid = require('node-uuid')
41
+
42
+ const uploadPromise = (options) => {
43
+ return new Promise((resolve, reject) => {
44
+ request.post(
45
+ {
46
+ ...options,
47
+ },
48
+ (err, response, body) => {
49
+ if (err || response.statusCode !== 200) {
50
+ reject(err)
51
+ }
52
+ resolve(JSON.parse(body))
53
+ }
54
+ )
55
+ })
56
+ }
57
+
58
+ module.exports = class Singleton {
59
+ constructor(config) {
60
+ this.config = {
61
+ ...config,
62
+ grant_type: 'client_credential',
63
+ }
64
+ /**
65
+ * 单例模式
66
+ */
67
+ if (!Singleton.instance) {
68
+ Singleton.instance = this
69
+ }
70
+ const previous = Singleton.instance.getConfig()
71
+ if (!lodash.isEqual(previous, config)) {
72
+ Singleton.instance = this
73
+ }
74
+ return Singleton.instance
75
+ }
76
+
77
+ init() {
78
+ if (!this.config.appid || !this.config.secrect) {
79
+ throw new Error('没有配置appid或secrect')
80
+ }
81
+ }
82
+
83
+ async getAccessToken() {
84
+ const { appid, secrect, grant_type } = this.config
85
+ if (cache.get(appid)) {
86
+ return cache.get(appid)
87
+ }
88
+ const url = util.format(getAccessTokenUrl, grant_type, appid, secrect)
89
+ const { access_token } = await axios.get(url).then((res) => res.data)
90
+ cache.set(appid, access_token)
91
+ return access_token
92
+ }
93
+
94
+ async getExpress() {
95
+ const access_token = await this.getAccessToken()
96
+ const url = util.format(getExpressUrl, access_token)
97
+ const result = await axios.post(url).then((res) => res.data)
98
+ if (result.errcode) {
99
+ if (result.errcode === 40001) {
100
+ cache.reset()
101
+ return await this.getExpress()
102
+ }
103
+ throw new Error(`${result.errcode};${result.errmsg}`)
104
+ }
105
+ return result
106
+ }
107
+
108
+ async addOrder({
109
+ add_source = 0,
110
+ order_id,
111
+ openid = '',
112
+ delivery_id = '',
113
+ biz_id = '',
114
+ sender,
115
+ receiver,
116
+ cargo,
117
+ shop,
118
+ insured,
119
+ service,
120
+ }) {
121
+ const access_token = await this.getAccessToken()
122
+ const url = util.format(addOrderUrl, access_token)
123
+
124
+ const formatOptions = {
125
+ order_id,
126
+ openid,
127
+ delivery_id,
128
+ biz_id,
129
+ sender,
130
+ receiver,
131
+ cargo,
132
+ shop,
133
+ insured,
134
+ service,
135
+ }
136
+
137
+ const result = await axios.post(url, formatOptions).then((res) => res.data)
138
+ if (result.errcode) {
139
+ if (result.errcode === 40001) {
140
+ cache.reset()
141
+ return await this.addOrder({
142
+ add_source,
143
+ order_id,
144
+ openid,
145
+ delivery_id,
146
+ biz_id,
147
+ sender,
148
+ receiver,
149
+ cargo,
150
+ shop,
151
+ insured,
152
+ service,
153
+ })
154
+ }
155
+ throw new Error(`${result.errcode};${result.errmsg}`)
156
+ }
157
+ return result
158
+ }
159
+
160
+ async addSubanchor({ roomId, username }) {
161
+ const access_token = await this.getAccessToken()
162
+ const url = util.format(addSubanchorUrl, access_token)
163
+
164
+ const formatOptions = {
165
+ roomId,
166
+ username,
167
+ }
168
+
169
+ const result = await axios.post(url, formatOptions).then((res) => res.data)
170
+ if (result.errcode) {
171
+ if (result.errcode === 40001) {
172
+ cache.reset()
173
+ return await this.addSubanchor({
174
+ roomId,
175
+ username,
176
+ })
177
+ }
178
+ throw new Error(`${result.errcode};${result.errmsg}`)
179
+ }
180
+ return result
181
+ }
182
+
183
+ async addRole({ username, role = 2 }) {
184
+ const access_token = await this.getAccessToken()
185
+ const url = util.format(addRoleUrl, access_token)
186
+
187
+ const formatOptions = {
188
+ username,
189
+ role,
190
+ }
191
+ const result = await axios.post(url, formatOptions).then((res) => res.data)
192
+ if (result.errcode) {
193
+ if (result.errcode === 40001) {
194
+ cache.reset()
195
+ return await this.addRole({
196
+ username,
197
+ role,
198
+ })
199
+ }
200
+ throw new Error(`${result.errcode};${result.errmsg}`)
201
+ }
202
+ return result
203
+ }
204
+
205
+ async createLive({
206
+ name,
207
+ createrWechat,
208
+ coverImg,
209
+ startTime,
210
+ endTime,
211
+ shareImg,
212
+ feedsImg,
213
+ subAnchorWechat = '',
214
+ anchorWechat = '',
215
+ anchorName = '',
216
+ closeReplay = 1,
217
+ }) {
218
+ const access_token = await this.getAccessToken()
219
+ const url = util.format(createLiveUrl, access_token)
220
+
221
+ const formatOptions = {
222
+ name, // 房间名字
223
+ coverImg, // 通过 uploadfile 上传,填写 mediaID
224
+ startTime, // 开始时间
225
+ endTime, // 结束时间
226
+ anchorName, // 主播昵称
227
+ anchorWechat, // 主播微信号
228
+ subAnchorWechat, // 主播副号微信号
229
+ createrWechat, // 创建者微信号
230
+ shareImg, // 通过 uploadfile 上传,填写 mediaID
231
+ feedsImg, // 通过 uploadfile 上传,填写 mediaID
232
+ isFeedsPublic: 0, // 是否开启官方收录,1 开启,0 关闭
233
+ type: 0, // 直播类型,1 推流 0 手机直播
234
+ closeLike: 0, // 是否关闭点赞 1:关闭
235
+ closeGoods: 1, // 是否关闭商品货架,1:关闭
236
+ closeComment: 1, // 是否开启评论,1:关闭
237
+ closeReplay, // 是否关闭回放 1 关闭
238
+ closeShare: 1, // 是否关闭分享 1 关闭
239
+ closeKf: 1, // 是否关闭客服,1 关闭
240
+ }
241
+ const result = await axios.post(url, formatOptions).then((res) => res.data)
242
+ if (result.errcode) {
243
+ if (result.errcode === 40001) {
244
+ cache.reset()
245
+ return await this.createLive({
246
+ name,
247
+ createrWechat,
248
+ coverImg,
249
+ startTime,
250
+ endTime,
251
+ shareImg,
252
+ feedsImg,
253
+ subAnchorWechat,
254
+ anchorWechat,
255
+ anchorName,
256
+ })
257
+ }
258
+ throw new Error(`${result.errcode};${result.errmsg}`)
259
+ }
260
+ return result
261
+ }
262
+
263
+ async getLive(start = 0, limit = 10) {
264
+ const access_token = await this.getAccessToken()
265
+ const url = util.format(getLiveUrl, access_token)
266
+
267
+ const formatOptions = {
268
+ start,
269
+ limit,
270
+ }
271
+ const result = await axios.post(url, formatOptions).then((res) => res.data)
272
+ if (result.errcode) {
273
+ if (result.errcode === 40001) {
274
+ cache.reset()
275
+ return await this.getLive({
276
+ start,
277
+ limit,
278
+ })
279
+ }
280
+ throw new Error(`${result.errcode};${result.errmsg}`)
281
+ }
282
+ return result.room_info
283
+ }
284
+
285
+ async createQR(options) {
286
+ if (!this.config.targetPath) throw new Error('没有配置文件夹')
287
+ const access_token = await this.getAccessToken()
288
+ const url = util.format(createQRCodeUrl, access_token)
289
+ const payLoad = {
290
+ ...options,
291
+ scene: options.scene
292
+ ? Object.keys(options.scene)
293
+ .map((item) => `${item}=${options.scene[item]}`)
294
+ .join('&')
295
+ : '',
296
+ }
297
+ const creatuuid = uuid.v1()
298
+
299
+ const bufferResult = await axios
300
+ .post(url, payLoad, {
301
+ responseType: 'arraybuffer',
302
+ })
303
+ .then((res) => {
304
+ if (res.headers['content-type'].includes('json')) {
305
+ return JSON.parse(Buffer.from(res.data).toString('utf8'))
306
+ }
307
+ return res.data
308
+ })
309
+ if (bufferResult.errcode) {
310
+ if (bufferResult.errcode === 40001) {
311
+ cache.reset()
312
+ return await this.createQR(options)
313
+ }
314
+ throw new Error(bufferResult.errmsg)
315
+ }
316
+ await fs.writeFileSync(
317
+ `${this.config.targetPath}/${creatuuid}.png`,
318
+ bufferResult
319
+ )
320
+ return `${creatuuid}.png`
321
+ }
322
+
323
+ async createQRBuffer(options) {
324
+ const access_token = await this.getAccessToken()
325
+ const url = util.format(createQRCodeUrl, access_token)
326
+ const payLoad = {
327
+ ...options,
328
+ scene: options.scene
329
+ ? Object.keys(options.scene)
330
+ .map((item) => `${item}=${options.scene[item]}`)
331
+ .join('&')
332
+ : '',
333
+ }
334
+ const creatuuid = uuid.v1()
335
+
336
+ const bufferResult = await axios
337
+ .post(url, payLoad, {
338
+ responseType: 'arraybuffer',
339
+ })
340
+ .then((res) => {
341
+ if (res.headers['content-type'].includes('json')) {
342
+ return JSON.parse(Buffer.from(res.data).toString('utf8'))
343
+ }
344
+ return res.data
345
+ })
346
+ if (bufferResult.errcode) {
347
+ if (bufferResult.errcode === 40001) {
348
+ cache.reset()
349
+ return await this.createQR(options)
350
+ }
351
+ throw new Error(bufferResult.errmsg)
352
+ }
353
+ return bufferResult
354
+ }
355
+
356
+ async sendMessage(options) {
357
+ const access_token = await this.getAccessToken()
358
+ const url = util.format(sendMessageUrl, access_token)
359
+ const formatOptions = {
360
+ ...options,
361
+ data: lodash.mapValues(options.data, (item) => {
362
+ return {
363
+ value: item,
364
+ }
365
+ }),
366
+ }
367
+ const result = await axios.post(url, formatOptions).then((res) => res.data)
368
+ if (result.errcode) {
369
+ if (result.errcode === 40001) {
370
+ cache.reset()
371
+ return await this.sendMessage(options)
372
+ }
373
+ throw new Error(`${result.errcode};${result.errmsg}`)
374
+ }
375
+ return result
376
+ }
377
+
378
+ async handleMessage(options) {
379
+ const access_token = await this.getAccessToken()
380
+ const url = util.format(handleMessageUrl, access_token)
381
+ const result = await axios.post(url, options).then((res) => res.data)
382
+ if (result.errcode) {
383
+ if (result.errcode === 40001) {
384
+ cache.reset()
385
+ return await this.handleMessage(options)
386
+ }
387
+ throw new Error(`${result.errcode};${result.errmsg}`)
388
+ }
389
+ return result
390
+ }
391
+
392
+ async uploadFile(imgUrl) {
393
+ if (!imgUrl || !imgUrl.includes('//')) throw new Error('检查imgUrl是否链接')
394
+
395
+ const access_token = await this.getAccessToken()
396
+ const url = util.format(uploadFile, access_token, 'image')
397
+ const formData = {
398
+ media: request(imgUrl.startsWith('//') ? `http:${imgUrl}` : imgUrl),
399
+ }
400
+ const uploadResult = await uploadPromise({
401
+ url,
402
+ formData,
403
+ })
404
+ if (uploadResult.errcode) {
405
+ if (uploadResult.errcode === 40001) {
406
+ cache.reset()
407
+ return await this.uploadFile(imgUrl)
408
+ }
409
+ throw new Error(`${uploadResult.errcode};${uploadResult.errmsg}`)
410
+ }
411
+ return uploadResult.media_id
412
+ }
413
+
414
+ async invokeService(payLoad) {
415
+ const access_token = await this.getAccessToken()
416
+ const url = util.format(serviceMarketUrl, access_token)
417
+ const result = await axios
418
+ .post(url, {
419
+ ...payLoad,
420
+ })
421
+ .then((res) => res.data)
422
+ if (result.errcode) {
423
+ if (result.errcode === 40001) {
424
+ cache.reset()
425
+ return await this.invokeService(payLoad)
426
+ }
427
+ throw new Error(`${result.errcode};${result.errmsg}`)
428
+ }
429
+ return result.data
430
+ }
431
+
432
+ getConfig() {
433
+ return this.config
434
+ }
435
+ }
@@ -0,0 +1,35 @@
1
+ const path = require('path')
2
+ const fs = require('fs')
3
+ const {
4
+ WapPay,
5
+ PubPay,
6
+ RequestError,
7
+ CommunicationError,
8
+ utils: { getXMLBody },
9
+ } = require('@sigodenjs/wechatpay')
10
+
11
+ module.exports = class WeixinPay {
12
+ constructor(config) {
13
+ this.pay = new WapPay({
14
+ appId: config.appId,
15
+ key: config.key,
16
+ mchId: config.mchId,
17
+ pfx: null,
18
+ })
19
+ }
20
+
21
+ async run(options) {
22
+ const config = {
23
+ spbill_create_ip: '8.8.8.8',
24
+ ...options,
25
+ }
26
+ return await this.pay.unifiedOrder(config)
27
+ }
28
+
29
+ async getXMLBody(data) {
30
+ return await getXMLBody(data, {
31
+ limit: '1mb',
32
+ encoding: 'utf8',
33
+ })
34
+ }
35
+ }
@@ -0,0 +1,33 @@
1
+
2
+ const { parseString, Builder } = require('xml2js')
3
+
4
+ const xmlToJson = (str) => {
5
+ return new Promise((resolve, reject) => {
6
+ parseString(str, (err, result) => {
7
+ if (err) {
8
+ reject(err)
9
+ } else {
10
+ resolve(result)
11
+ }
12
+ })
13
+ })
14
+ }
15
+ exports.xmlToJson = xmlToJson
16
+
17
+ exports.jsonToXml = (obj) => {
18
+ const builder = new Builder()
19
+ return builder.buildObject(obj)
20
+ }
21
+
22
+ exports.xmlPromise = ctx => new Promise(function (resolve, reject) {
23
+ let buf = ''
24
+ ctx.req.setEncoding('utf8')
25
+ ctx.req.on('data', (chunk) => {
26
+ buf += chunk
27
+ })
28
+ ctx.req.on('end', () => {
29
+ xmlToJson(buf)
30
+ .then(resolve)
31
+ .catch(reject)
32
+ })
33
+ })