q-koa 13.4.0 → 13.4.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
@@ -23,7 +23,23 @@ const jwt = require('jsonwebtoken')
23
23
  const verify = util.promisify(jwt.verify)
24
24
  const fsExtra = require('fs-extra')
25
25
  const { getObject, getAppConfig, formatLiteralObj } = require('./file/utils')
26
-
26
+ const redisVirtual = {
27
+ hSet: () => {
28
+ console.log('redisVirtual hSet')
29
+ },
30
+ hGet: () => {
31
+ console.log('redisVirtual hGet')
32
+ },
33
+ set: () => {
34
+ console.log('redisVirtual set')
35
+ },
36
+ get: () => {
37
+ console.log('redisVirtual get')
38
+ },
39
+ publish: () => {
40
+ console.log('redisVirtual publish')
41
+ },
42
+ }
27
43
  const restc = require('./restc')
28
44
  const APP_DIR = 'app'
29
45
  const PLUGINS_DIR = 'plugins'
@@ -159,6 +175,14 @@ class APP {
159
175
  ) {
160
176
  return ctx.ERROR('error')
161
177
  }
178
+
179
+ if (
180
+ ctx.request.header['user-agent'] &&
181
+ ctx.request.header['user-agent'].includes('Apache-HttpClient')
182
+ ) {
183
+ throw new Error(`error`)
184
+ }
185
+
162
186
  if (this.config.blackList.includes(ip)) {
163
187
  return ctx.ERROR('error')
164
188
  }
@@ -459,6 +483,7 @@ class APP {
459
483
  } else {
460
484
  this.app[appName] = {
461
485
  sequelize: db,
486
+ redisClient: redisVirtual,
462
487
  appConfig: _.defaultsDeep(
463
488
  configExist ? require(path.resolve(__dirname, configPath)) : {},
464
489
  this.config.app,
@@ -483,9 +508,12 @@ class APP {
483
508
  if (initFileConfig) {
484
509
  this.initFile(appName)
485
510
  }
486
-
487
511
  await this.initPlugin(appName)
488
- this.app[appName].event = new EventEmitter()
512
+
513
+ const initEvent = _.get(this.app[appName], 'appConfig.initEvent', false)
514
+ if (initEvent) {
515
+ this.app[appName].event = new EventEmitter()
516
+ }
489
517
 
490
518
  const cacheConfig = _.get(this.app[appName], 'appConfig.cache', {
491
519
  max: 100,
@@ -592,7 +620,7 @@ class APP {
592
620
  const folderResult = await fsPromise.readdir(
593
621
  path.resolve(pluginDir, folder)
594
622
  )
595
- folderResult.forEach((filename) => {
623
+ for (const filename of folderResult) {
596
624
  const extname = path.extname(filename)
597
625
  if (extname === '.js') {
598
626
  const n = path.basename(filename, extname)
@@ -675,7 +703,53 @@ class APP {
675
703
  const indexes = _.cloneDeep(
676
704
  _.get(this.app[appName].config[folder], 'indexList', [])
677
705
  )
706
+ let hookList = _.cloneDeep(
707
+ _.get(this.app[appName].config[folder], 'hookList', [])
708
+ )
709
+ if (
710
+ hookList.some((h) =>
711
+ ['afterDestroy', 'beforeDestroy'].includes(h)
712
+ ) &&
713
+ !hookList.includes('beforeBulkDestroy')
714
+ ) {
715
+ hookList = [...hookList, 'beforeBulkDestroy']
716
+ }
717
+ let reduceHook = {}
718
+ for (let i = 0; i < hookList.length; i++) {
719
+ const hook = hookList[i]
720
+ reduceHook = {
721
+ ...reduceHook,
722
+ [hook]: (target, t) => {
723
+ if (['beforeBulkDestroy'].includes(hook)) {
724
+ target.individualHooks = true
725
+ }
726
+ try {
727
+ this.app[appName].service &&
728
+ this.app[appName].service[folder] &&
729
+ this.app[appName].service[folder][hook] &&
730
+ this.app[appName].service[folder][hook]({
731
+ app: this.app[appName],
732
+ model: folder,
733
+ hook,
734
+ ...(target.toJSON
735
+ ? {
736
+ target: target.toJSON(),
737
+ }
738
+ : {
739
+ target,
740
+ }),
741
+ ...t,
742
+ })
743
+ } catch (e) {
744
+ console.log(e)
745
+ }
678
746
 
747
+ if (['beforeBulkDestroy'].includes(hook)) {
748
+ return target
749
+ }
750
+ },
751
+ }
752
+ }
679
753
  const instance = this.app[appName].sequelize.define(
680
754
  folder,
681
755
  attributes,
@@ -690,6 +764,7 @@ class APP {
690
764
  plural: `${folder}s`,
691
765
  },
692
766
  hooks: {
767
+ ...reduceHook,
693
768
  beforeCreate: (res, t) => {
694
769
  try {
695
770
  if (folder === 'log') {
@@ -807,7 +882,7 @@ class APP {
807
882
  }
808
883
  }
809
884
  }
810
- })
885
+ }
811
886
  }
812
887
  }
813
888
  const start = moment().valueOf()
@@ -836,19 +911,33 @@ class APP {
836
911
  }
837
912
 
838
913
  initModel(appName) {
914
+ const modelList = Object.keys(this.app[appName].model)
915
+
916
+ const include = modelList.reduce((a, b) => {
917
+ return {
918
+ ...a,
919
+ [b]: [],
920
+ }
921
+ }, {})
922
+ this.app[appName] = _.defaultsDeep(
923
+ {
924
+ include,
925
+ },
926
+ this.app[appName]
927
+ )
839
928
  for (let i = 0; i < Object.keys(this.app[appName].model).length; i++) {
840
929
  const model = Object.keys(this.app[appName].model)[i]
841
930
 
842
- if (!this.app[appName].include || !this.app[appName].include[model]) {
843
- this.app[appName] = _.defaultsDeep(
844
- {
845
- include: {
846
- [model]: [],
847
- },
848
- },
849
- this.app[appName]
850
- )
851
- }
931
+ // if (!this.app[appName].include || !this.app[appName].include[model]) {
932
+ // this.app[appName] = _.defaultsDeep(
933
+ // {
934
+ // include: {
935
+ // [model]: [],
936
+ // },
937
+ // },
938
+ // this.app[appName]
939
+ // )
940
+ // }
852
941
  const db = this.app[appName].attributes[model]
853
942
 
854
943
  const list = Object.keys(db)
@@ -1095,7 +1184,7 @@ class APP {
1095
1184
  } = ctx.request.body
1096
1185
  if (['findOne', 'findAll', 'findAndCountAll'].includes(fn)) {
1097
1186
  if (!_.isEmpty(other)) {
1098
- throw new Error('参数不合理,条件需要放在where里')
1187
+ throw new Error('参数不合理')
1099
1188
  }
1100
1189
  }
1101
1190
 
@@ -1374,6 +1463,11 @@ class APP {
1374
1463
  app[appName].cache.get(modelName)
1375
1464
  ? app[appName].cache.get(modelName)
1376
1465
  : await model.findAll({
1466
+ ...(myInclude[j].attributes
1467
+ ? {
1468
+ attributes: myInclude[j].attributes,
1469
+ }
1470
+ : {}),
1377
1471
  where: {
1378
1472
  id: idList,
1379
1473
  ...myInclude[j].where,
@@ -1394,6 +1488,11 @@ class APP {
1394
1488
  const idList = rows.map((r) => r.id).filter((item) => item)
1395
1489
  if (idList.length) {
1396
1490
  const list = await model.findAll({
1491
+ ...(myInclude[j].attributes
1492
+ ? {
1493
+ attributes: myInclude[j].attributes,
1494
+ }
1495
+ : {}),
1397
1496
  where: {
1398
1497
  [controller + '_id']: idList,
1399
1498
  ...myInclude[j].where,
package/core/config.js CHANGED
@@ -66,6 +66,7 @@ module.exports = {
66
66
  'weixin/mp_login',
67
67
  'log/create',
68
68
  'log/upsert',
69
+ 'auto/minute',
69
70
  ].every((item) => {
70
71
  return !ctx.request.url.includes(item)
71
72
  })
@@ -214,8 +214,8 @@ exports.scan = async (ctx) => {
214
214
  })
215
215
  }
216
216
 
217
- app.event.removeAllListeners()
218
- app.event.on('scan', sendMessage)
217
+ app.event && app.event.removeAllListeners()
218
+ app.event && app.event.on('scan', sendMessage)
219
219
  } else {
220
220
  throw new Error('这是一个websocket url')
221
221
  }
@@ -224,8 +224,8 @@ exports.channel = async (ctx) => {
224
224
  })
225
225
  }
226
226
 
227
- app.event.removeAllListeners()
228
- app.event.on(channelId, sendMessage)
227
+ app.event && app.event.removeAllListeners()
228
+ app.event && app.event.on(channelId, sendMessage)
229
229
  } else {
230
230
  throw new Error('这是一个websocket url')
231
231
  }
@@ -442,6 +442,7 @@ exports.verify = async (ctx) => {
442
442
  const expressFn = async ({ app, express_number: _express_number }) => {
443
443
  const appConfig = getConfig(app)
444
444
  const { app_code, express_mobile } = await appConfig.getObject('express')
445
+
445
446
  const express_number = _express_number.replace(/\t/, '').trim()
446
447
 
447
448
  const lastFour = express_mobile
@@ -219,3 +219,10 @@ exports.alias = {
219
219
  return name + model
220
220
  },
221
221
  }
222
+
223
+ exports.hookList = {
224
+ type: Sequelize.JSON,
225
+ comment: 'hookd',
226
+ allowNull: false,
227
+ defaultValue: [],
228
+ }
@@ -111,6 +111,7 @@ exports.loadModel = async ({ app, appName }) => {
111
111
  deleteCheckList: config.deleteCheckList,
112
112
  bulkCreateList: config.bulkCreateList,
113
113
  indexList: config.indexList,
114
+ hookList: config.hookList,
114
115
  list: attributes.map((attr, index) => {
115
116
  const name = attr.match(/exports.(.*)=/)[1].trim()
116
117
  let defaultValue = ''
@@ -3,7 +3,6 @@ const path = require('path')
3
3
  const fsPromise = require('fs/promises')
4
4
  const { VM } = require('vm2')
5
5
  const axios = require('axios')
6
- const cheerio = require('cheerio')
7
6
  const { lodash, getAppByCtx, getConfig, Sequelize, moment } = require('q-koa')
8
7
  const LRU = require('lru-cache')
9
8
  const cache = new LRU({
@@ -231,12 +230,19 @@ exports.customRouter = async (ctx) => {
231
230
  return list
232
231
  }
233
232
 
234
- exports.showTables = async (ctx) => {
233
+ exports.showTables = async (ctx, _data) => {
235
234
  const { app, appName } = getAppByCtx(ctx)
235
+ const { omit = [] } = _data || ctx.request.body
236
236
 
237
+ const mapFn = (item) => {
238
+ if (omit.length === 0) return item
239
+ return lodash.omit(item.toJSON ? item.toJSON() : item, omit)
240
+ }
237
241
  if (app.cache && app.cache.get('showTables')) {
238
- ctx.SUCCESS(app.cache.get('showTables'))
239
- return app.cache.get('showTables')
242
+ const cacheResult = app.cache.get('showTables')
243
+ const payLoad = cacheResult.map(mapFn)
244
+ ctx.SUCCESS(payLoad)
245
+ return payLoad
240
246
  }
241
247
 
242
248
  const pluginDir = path.resolve(
@@ -316,7 +322,13 @@ exports.showTables = async (ctx) => {
316
322
  // 可排序字段
317
323
  order: lodash.get(target, 'order', []),
318
324
  // 默认排序
319
- defaultOrder: lodash.get(target, 'defaultOrder', []),
325
+ defaultOrder: getValueByModelName(
326
+ target,
327
+ 'defaultOrder',
328
+ [],
329
+ model,
330
+ _model
331
+ ),
320
332
  // 下拉筛选
321
333
  select: getValueByModelName(target, 'select', [], model, _model),
322
334
  // 是否可以选择批量删除
@@ -357,19 +369,25 @@ exports.showTables = async (ctx) => {
357
369
  // can be mock boolean
358
370
  mock,
359
371
  // reference model query
360
- referenceSelect: lodash.get(target, 'referenceSelect', []),
372
+ referenceSelect: getValueByModelName(
373
+ target,
374
+ 'referenceSelect',
375
+ [],
376
+ model,
377
+ _model
378
+ ),
361
379
  // 是否可以选择批量删除
362
380
  availableSort: lodash.get(target, 'availableSort', false),
363
381
  // 用于后台管理不要查询太多数据,常用于表多的model
364
382
  autoData: lodash.get(target, 'autoData', null),
365
383
  // 有些model需要前置查询其它model数据
366
- initList: lodash.get(target, 'initList', []),
384
+ initList: getValueByModelName(target, 'initList', [], model, _model),
367
385
  // 有些table需要前置查询数据
368
386
  initTableList: lodash.get(target, 'initTableList', []),
369
387
  // 局部更新列表
370
388
  editInline: lodash.get(target, 'editInline', {}),
371
389
  // 有些model需要前置查询其它model数据
372
- comment: lodash.get(target, 'comment', {}),
390
+ comment: getValueByModelName(target, 'comment', {}, model, _model),
373
391
  // 默认查询,覆盖之前
374
392
  modelQuery: lodash.get(target, 'modelQuery', {}),
375
393
  // 默认更新,覆盖之前
@@ -387,9 +405,10 @@ exports.showTables = async (ctx) => {
387
405
  }
388
406
  })
389
407
 
390
- ctx.SUCCESS(models)
391
- app.cache && app.cache.set('showTables', models)
392
- return models
408
+ const payLoad = models.map(mapFn)
409
+ ctx.SUCCESS(payLoad)
410
+ app.cache && app.cache.set('showTables', models.map(mapFn))
411
+ return payLoad
393
412
  }
394
413
 
395
414
  exports.getTable = async (ctx) => {
@@ -584,7 +603,6 @@ exports.sandbox = async (ctx) => {
584
603
  const vm = new VM({
585
604
  sandbox: {
586
605
  axios,
587
- cheerio,
588
606
  module,
589
607
  setTimeout,
590
608
  sleep: (time) =>
@@ -603,7 +621,6 @@ exports.onlineChat = async (ctx) => {
603
621
  sandbox: {
604
622
  send: (data) => ws.send(JSON.stringify(data)),
605
623
  axios,
606
- cheerio,
607
624
  },
608
625
  })
609
626
  vm.run(code)
@@ -1,5 +1,5 @@
1
1
  const { getConfig, lodash, Sequelize } = require('q-koa')
2
- const { formatLiteralObj } = require('../../utils')
2
+ const { formatLiteralObj, filterFunction } = require('../../utils')
3
3
  const formatPostFunction = (str) => `eval(${str})`
4
4
  const nodeVm = require('vm')
5
5
  const axios = require('axios')
@@ -84,9 +84,7 @@ exports.initData = async ({ includes, excludes, app, ctx }) => {
84
84
  .map((i) => (i.toJSON ? i.toJSON() : i))
85
85
  .filter((c) => {
86
86
  const target = data && data.where ? data.where : {}
87
- return Object.keys(target).every((key) => {
88
- return c[key] === target[key]
89
- })
87
+ return filterFunction(target, c)
90
88
  })
91
89
  .map((c) => {
92
90
  return pick.length > 0
@@ -4,6 +4,7 @@ const {
4
4
  getConfig,
5
5
  moment,
6
6
  ServiceError,
7
+ getUserByCtx,
7
8
  } = require('q-koa')
8
9
 
9
10
  const axios = require('axios')
@@ -93,6 +94,7 @@ exports.mp_getPhone = async (ctx) => {
93
94
  (!exist.mp_user.appid || exist.mp_user.appid === app_id)
94
95
 
95
96
  if (mobileExist) {
97
+ app.service.log.push({ app, message: `系统已存在该手机号${phoneNumber}` })
96
98
  return ctx.ERROR('系统已存在该手机号')
97
99
  }
98
100
 
@@ -1144,6 +1146,50 @@ exports.mp_pay = async (ctx) => {
1144
1146
  })
1145
1147
  }
1146
1148
 
1149
+ exports.b2b_pay = async (ctx) => {
1150
+ const { app, appName } = getAppByCtx(ctx)
1151
+ const appConfig = getConfig(app)
1152
+ const { is_dev } = await appConfig.getObject('base')
1153
+ const { name, _out_trade_no, order_id, price, prefix, code, type, is_admin } =
1154
+ ctx.request.body
1155
+
1156
+ const { app_id, app_secrect } = await appConfig.getObject('weixin_mp')
1157
+ const {
1158
+ mchId: mchid,
1159
+ app_key,
1160
+ key,
1161
+ pay_key: _pay_key,
1162
+ } = await appConfig.getObject('weixin_pay')
1163
+
1164
+ const pay_key = _pay_key || key || appName
1165
+
1166
+ const weixinMp = new WeixinMp({
1167
+ appid: app_id,
1168
+ secrect: app_secrect,
1169
+ })
1170
+ weixinMp.init()
1171
+ const out_trade_no = _out_trade_no
1172
+ ? _out_trade_no
1173
+ : prefix
1174
+ ? `${pay_key}_${prefix}-${order_id}_${type}`
1175
+ : `${pay_key}_${order_id}_${type}`
1176
+
1177
+ const res = await weixinMp.b2bPay({
1178
+ mchid,
1179
+ app_key,
1180
+ code,
1181
+ data: {
1182
+ out_trade_no,
1183
+ description: name,
1184
+ amount: {
1185
+ order_amount: is_admin || is_dev ? 1 : Math.round(price * 100),
1186
+ },
1187
+ },
1188
+ })
1189
+
1190
+ ctx.SUCCESS(res)
1191
+ }
1192
+
1147
1193
  exports.mp_pay_new = async (ctx) => {
1148
1194
  const { app, appName } = getAppByCtx(ctx)
1149
1195
  const {
@@ -13,6 +13,76 @@ const fsPromise = require('fs/promises')
13
13
  const WeixinMp = require('../../services/weixinMP')
14
14
  const OSS = require('ali-oss')
15
15
 
16
+ exports.b2b_refund = async ({
17
+ ctx,
18
+ id,
19
+ prefix = '',
20
+ total_fee,
21
+ refund_fee,
22
+ price,
23
+ pay_type = 'B2B-WEIXIN',
24
+ type = '',
25
+ config = 'weixin_mp',
26
+ pay_config = 'weixin_pay',
27
+ out_trade_no: _out_trade_no,
28
+ out_refund_no: _out_refund_no,
29
+ refund_from = 1,
30
+ ...rest
31
+ }) => {
32
+ if (!ctx) throw new Error('?ctx')
33
+ const { app, appName } = getAppByCtx(ctx)
34
+ const appConfig = getConfig(app)
35
+ const { app_id, app_secrect } = await appConfig.getObject(config)
36
+ const { mchId: mchid, key, app_key } = await appConfig.getObject(pay_config)
37
+
38
+ const weixinMp = new WeixinMp({
39
+ appid: app_id,
40
+ secrect: app_secrect,
41
+ })
42
+ weixinMp.init()
43
+
44
+ const orderModel = prefix ? `${prefix}_order` : 'order'
45
+ const out_trade_no =
46
+ _out_trade_no ||
47
+ (prefix ? `${key}_${prefix}-${id}_${pay_type}` : `${key}_${id}_${pay_type}`)
48
+ const orderDetail = await app.model[orderModel].findOne({
49
+ where: {
50
+ id,
51
+ },
52
+ include: app.model.order_refund_record,
53
+ })
54
+
55
+ if (!orderDetail) throw new Error('不存在该订单')
56
+
57
+ const refundRecords = lodash.get(orderDetail, 'order_refund_records', [])
58
+ const refundNumber = refundRecords.length + 1
59
+ const out_refund_no =
60
+ _out_refund_no || [`${prefix}-${id}`, type, refundNumber].join('_')
61
+
62
+ console.log({
63
+ mchid,
64
+ app_key,
65
+ data: {
66
+ out_trade_no: out_trade_no,
67
+ out_refund_no,
68
+ refund_amount: Math.round((refund_fee || price) * 100),
69
+ refund_from,
70
+ },
71
+ })
72
+ const res = await weixinMp.b2bRefund({
73
+ mchid,
74
+ app_key,
75
+ data: {
76
+ out_trade_no: out_trade_no,
77
+ out_refund_no,
78
+ refund_amount: Math.round((refund_fee || price) * 100),
79
+ refund_from,
80
+ },
81
+ })
82
+
83
+ return res
84
+ }
85
+
16
86
  exports.refund = async ({
17
87
  ctx,
18
88
  id,
@@ -1,6 +1,6 @@
1
1
  const util = require('util')
2
2
  const axios = require('axios')
3
-
3
+ const crypto = require('crypto')
4
4
  const { lodash, ServiceError } = require('q-koa')
5
5
  const getAccessTokenUrl =
6
6
  'https://api.weixin.qq.com/cgi-bin/token?grant_type=%s&appid=%s&secret=%s'
@@ -82,6 +82,14 @@ const createActivityUrl =
82
82
  const setUpdatableMsgUrl =
83
83
  'https://api.weixin.qq.com/cgi-bin/message/wxopen/updatablemsg/send?access_token=%s'
84
84
 
85
+ const b2bRefundUrl =
86
+ 'https://api.weixin.qq.com/retail/B2b/refund?access_token=%s&pay_sig=%s'
87
+
88
+ const b2bCheckRefundUrl =
89
+ 'https://api.weixin.qq.com/retail/B2b/getrefund?access_token=%s&pay_sig=%s'
90
+
91
+ const b2bCheckOrderUrl =
92
+ 'https://api.weixin.qq.com/retail/B2b/getorder?access_token=%s&pay_sig=%s'
85
93
  const fsPromise = require('fs/promises')
86
94
  const LRU = require('lru-cache')
87
95
  const request = require('request')
@@ -90,7 +98,9 @@ const cache = new LRU({
90
98
  maxAge: 1000 * 60 * 60,
91
99
  })
92
100
  const uuid = require('node-uuid')
93
-
101
+ const hmacSha256 = (data, secret) => {
102
+ return crypto.createHmac('sha256', secret).update(data).digest('hex')
103
+ }
94
104
  const uploadPromise = (options) => {
95
105
  return new Promise((resolve, reject) => {
96
106
  request.post(
@@ -998,6 +1008,115 @@ module.exports = class Singleton {
998
1008
  return result
999
1009
  }
1000
1010
 
1011
+ async b2bPay({
1012
+ uri = 'requestCommonPayment',
1013
+ data,
1014
+ app_key,
1015
+ code,
1016
+ env = 0,
1017
+ mchid,
1018
+ }) {
1019
+ const weixinLoginUrl = `https://api.weixin.qq.com/sns/jscode2session?appid=${this.config.appid}&secret=${this.config.secrect}&js_code=${code}&grant_type=authorization_code`
1020
+
1021
+ const weixinResult = await axios.get(weixinLoginUrl).then((res) => res.data)
1022
+
1023
+ const { session_key } = weixinResult
1024
+
1025
+ const signData = {
1026
+ mchid,
1027
+ env,
1028
+ ...data,
1029
+ }
1030
+
1031
+ const signature = hmacSha256(JSON.stringify(signData), session_key)
1032
+ const paySig = hmacSha256(`${uri}&${JSON.stringify(signData)}`, app_key)
1033
+
1034
+ return {
1035
+ signData: JSON.stringify(signData),
1036
+ mode: 'retail_pay_goods',
1037
+ signature,
1038
+ paySig,
1039
+ }
1040
+ }
1041
+
1042
+ async b2bRefund({ mchid, app_key, data }) {
1043
+ const requestUrl = b2bRefundUrl
1044
+
1045
+ const access_token = await this.getAccessToken()
1046
+
1047
+ const uri = requestUrl.split('api.weixin.qq.com')[1].split('?')[0]
1048
+
1049
+ const signData = {
1050
+ mchid,
1051
+ ...data,
1052
+ }
1053
+
1054
+ const pay_sig = hmacSha256(`${uri}&${JSON.stringify(signData)}`, app_key)
1055
+
1056
+ const url = util.format(requestUrl, access_token, pay_sig)
1057
+ const result = await axios.post(url, signData).then((res) => res.data)
1058
+ if (result.errcode) {
1059
+ if (result.errcode === 40001) {
1060
+ cache.reset()
1061
+ return await this.b2bRefund({ mchid, app_key, data })
1062
+ }
1063
+ throw new Error(`${result.errcode};${result.errmsg}`)
1064
+ }
1065
+ return result
1066
+ }
1067
+
1068
+ async b2bCheckRefund({ mchid, app_key, data }) {
1069
+ const requestUrl = b2bCheckRefundUrl
1070
+
1071
+ const access_token = await this.getAccessToken()
1072
+
1073
+ const uri = requestUrl.split('api.weixin.qq.com')[1].split('?')[0]
1074
+
1075
+ const signData = {
1076
+ mchid,
1077
+ ...data,
1078
+ }
1079
+
1080
+ const pay_sig = hmacSha256(`${uri}&${JSON.stringify(signData)}`, app_key)
1081
+
1082
+ const url = util.format(requestUrl, access_token, pay_sig)
1083
+ const result = await axios.post(url, signData).then((res) => res.data)
1084
+ if (result.errcode) {
1085
+ if (result.errcode === 40001) {
1086
+ cache.reset()
1087
+ return await this.b2bCheckRefund({ mchid, app_key, data })
1088
+ }
1089
+ throw new Error(`${result.errcode};${result.errmsg}`)
1090
+ }
1091
+ return result
1092
+ }
1093
+
1094
+ async b2bCheckOrder({ mchid, app_key, data }) {
1095
+ const requestUrl = b2bCheckOrderUrl
1096
+
1097
+ const access_token = await this.getAccessToken()
1098
+
1099
+ const uri = requestUrl.split('api.weixin.qq.com')[1].split('?')[0]
1100
+
1101
+ const signData = {
1102
+ mchid,
1103
+ ...data,
1104
+ }
1105
+
1106
+ const pay_sig = hmacSha256(`${uri}&${JSON.stringify(signData)}`, app_key)
1107
+
1108
+ const url = util.format(requestUrl, access_token, pay_sig)
1109
+ const result = await axios.post(url, signData).then((res) => res.data)
1110
+ if (result.errcode) {
1111
+ if (result.errcode === 40001) {
1112
+ cache.reset()
1113
+ return await this.b2bCheckOrder({ mchid, app_key, data })
1114
+ }
1115
+ throw new Error(`${result.errcode};${result.errmsg}`)
1116
+ }
1117
+ return result
1118
+ }
1119
+
1001
1120
  getConfig() {
1002
1121
  return this.config
1003
1122
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "q-koa",
3
- "version": "13.4.0",
3
+ "version": "13.4.2",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {