q-koa 13.4.3 → 13.4.5

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
@@ -222,6 +222,7 @@ class APP {
222
222
  this.app[appName].sign = async (user) => {
223
223
  const result = await jwt.sign(user, secret, {
224
224
  expiresIn,
225
+ algorithm: 'HS256',
225
226
  })
226
227
  return result
227
228
  }
@@ -248,7 +249,9 @@ class APP {
248
249
  }
249
250
 
250
251
  try {
251
- const { user } = await verify(token, secret)
252
+ const { user } = await verify(token, secret, {
253
+ algorithms: ['HS256'],
254
+ })
252
255
  if (user) {
253
256
  if (this.config.log.request) {
254
257
  console.log('user id ---> ', appName, '--->', user.id, user.name)
@@ -893,15 +896,11 @@ class APP {
893
896
  const modelService = cloneTarget[b]
894
897
  const newB = Object.keys(modelService).reduce((_a, _b) => {
895
898
  const bindFn = modelService[_b].bind(this.app[appName])
896
- return {
897
- ..._a,
898
- [_b]: bindFn,
899
- }
899
+ _a[_b] = bindFn
900
+ return _a
900
901
  }, {})
901
- return {
902
- ...a,
903
- [b]: newB,
904
- }
902
+ a[b] = newB
903
+ return a
905
904
  }, {})
906
905
  }
907
906
 
@@ -914,10 +913,8 @@ class APP {
914
913
  const modelList = Object.keys(this.app[appName].model)
915
914
 
916
915
  const include = modelList.reduce((a, b) => {
917
- return {
918
- ...a,
919
- [b]: [],
920
- }
916
+ a[b] = []
917
+ return a
921
918
  }, {})
922
919
  this.app[appName] = _.defaultsDeep(
923
920
  {
@@ -1308,10 +1305,18 @@ class APP {
1308
1305
  typeof where.id === 'string' &&
1309
1306
  where.id.includes('/')
1310
1307
  ) {
1308
+ const arr = where.id.split('?')
1309
+
1310
+ let obj = {}
1311
+ if (arr[1] && arr[1].includes('id=')) {
1312
+ obj = {
1313
+ id: JSON.parse(arr[1].split('=')[1]),
1314
+ }
1315
+ }
1311
1316
  const _result = await _.get(
1312
1317
  app[appName].controller,
1313
- where.id.replace('/', '.')
1314
- )(ctx)
1318
+ arr[0].replace('/', '.')
1319
+ )(ctx, obj)
1315
1320
  where.id = _result
1316
1321
  }
1317
1322
 
@@ -431,12 +431,17 @@ exports.syncModel = async (ctx) => {
431
431
  ctx.SUCCESS('ok')
432
432
  }
433
433
 
434
- exports.verify = async (ctx) => {
434
+ exports.verify = async (ctx, _data) => {
435
435
  const { app, appName } = getAppByCtx(ctx)
436
- const { code } = ctx.request.body
436
+ const { code } = _data || ctx.request.body
437
+ if (!code) {
438
+ ctx.SUCCESS(null)
439
+ return null
440
+ }
437
441
  const verify = util.promisify(jwt.verify)
438
442
  const result = await verify(code, 'token')
439
443
  ctx.SUCCESS(result)
444
+ return result
440
445
  }
441
446
 
442
447
  const expressFn = async ({ app, express_number: _express_number, mobile }) => {
@@ -33,11 +33,12 @@ exports.clearWeixin = async (ctx) => {
33
33
  exports.push = async (ctx) => {
34
34
  const { app, appName } = getAppByCtx(ctx)
35
35
 
36
- const { message = '测试通知' } = ctx.request.body
36
+ const { message = '测试通知', url } = ctx.request.body
37
37
 
38
38
  await app.service.log.push({
39
39
  app,
40
40
  message,
41
+ url,
41
42
  })
42
43
 
43
44
  ctx.SUCCESS('ok')
@@ -4,7 +4,11 @@ module.exports = {
4
4
  multiple: false,
5
5
  availableSort: false,
6
6
  order: [],
7
- select: [],
7
+ select: [
8
+ {
9
+ key: 'controller',
10
+ },
11
+ ],
8
12
  excludes: [],
9
13
  limit: 20,
10
14
  defaultOrder: [],
@@ -12,4 +16,4 @@ module.exports = {
12
16
  sortOrder: 1,
13
17
  reference: [],
14
18
  excludeAuth: [],
15
- };
19
+ }
@@ -78,13 +78,13 @@ exports.countAndMaxId = async (ctx, _data) => {
78
78
  ctx.SUCCESS(null)
79
79
  return null
80
80
  }
81
- const count = await app.model[model].count()
82
- const current = await app.model[model].findOne({
83
- attributes: ['id', 'created_at'],
84
- order: [['id', 'DESC']],
85
- })
86
81
 
87
- const current_max_id = current ? current.id : 0
82
+ const result = await app.sequelize.query(
83
+ `select * from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = '${app.sequelize.config.database}' and TABLE_NAME = '${model}'`
84
+ )
85
+ const count = result[0][0].TABLE_ROWS
86
+
87
+ const current_max_id = result[0][0].AUTO_INCREMENT
88
88
 
89
89
  const lastMonth = await app.model[model].findOne({
90
90
  attributes: ['id'],
@@ -933,6 +933,40 @@ exports.checkIndex = async (ctx) => {
933
933
  }
934
934
  }
935
935
 
936
+ exports.checkAttribute = async (ctx) => {
937
+ const { app, appName } = getAppByCtx(ctx)
938
+ const { model } = ctx.request.body
939
+
940
+ if (!model) return ctx.ERROR('model不能为空')
941
+
942
+ const result = await app.sequelize.getQueryInterface().describeTable(model)
943
+
944
+ const attributeList = Object.keys(result).filter(
945
+ (item) => !['id', 'created_at', 'createdid', 'updated_at'].includes(item)
946
+ )
947
+
948
+ const currentAttributeList = Object.keys(app.attributes[model]).filter(
949
+ (item) => {
950
+ return app.attributes[model][item].type !== Sequelize.VIRTUAL
951
+ }
952
+ )
953
+
954
+ let flag = true
955
+ if (attributeList.length !== currentAttributeList.length) {
956
+ flag = false
957
+ }
958
+
959
+ const current = attributeList.filter(
960
+ (item) => !currentAttributeList.includes(item)
961
+ )
962
+
963
+ ctx.SUCCESS({
964
+ isSame: flag,
965
+ current,
966
+ remote: [],
967
+ })
968
+ }
969
+
936
970
  exports.dropIndex = async (ctx) => {
937
971
  const { app, appName } = getAppByCtx(ctx)
938
972
  const { model, key } = ctx.request.body
@@ -342,14 +342,18 @@ exports.checkLogin = async (ctx) => {
342
342
  const mp_user_include = config.includes('mp')
343
343
  ? {
344
344
  model: app.model.mp_user,
345
+ attributes: ['openid', 'unionid'],
345
346
  where: {
346
347
  appid,
347
348
  },
348
349
  }
349
350
  : {
350
351
  model: app.model.mp_user,
352
+ attributes: ['openid', 'unionid'],
351
353
  }
354
+
352
355
  let result
356
+
353
357
  const includeDefault = [
354
358
  {
355
359
  model: app.model.github_user,
@@ -364,6 +368,7 @@ exports.checkLogin = async (ctx) => {
364
368
 
365
369
  if (app.appConfig.loginData) {
366
370
  const application = await getAppConfig({ app, config })
371
+
367
372
  const loginData = lodash.mergeWith(
368
373
  lodash.cloneDeep(app.appConfig.loginData),
369
374
  lodash.get(application, 'loginData', {}),
@@ -390,6 +395,7 @@ exports.checkLogin = async (ctx) => {
390
395
  ])
391
396
  ),
392
397
  }
398
+
393
399
  result = await app.model.user.findOne({
394
400
  where: {
395
401
  id: ctx.request[`${appName}-user`].id,
@@ -94,8 +94,17 @@ exports.mp_getPhone = async (ctx) => {
94
94
  (!exist.mp_user.appid || exist.mp_user.appid === app_id)
95
95
 
96
96
  if (mobileExist) {
97
- app.service.log.push({ app, message: `系统已存在该手机号${phoneNumber}` })
98
- return ctx.ERROR('系统已存在该手机号')
97
+ const formatMobile = (mobile) => {
98
+ if (!mobile) return ''
99
+ return mobile.slice(0, 3) + '*****' + mobile.slice(8, mobile.length)
100
+ }
101
+
102
+ const user_id = getUserByCtx(ctx)
103
+ app.service.log.push({
104
+ app,
105
+ message: `系统已存在该手机号${phoneNumber};${user_id}`,
106
+ })
107
+ return ctx.ERROR(`系统已存在该手机号`)
99
108
  }
100
109
 
101
110
  const userResult = await app.model.mp_user.findOne({
@@ -1043,6 +1052,7 @@ exports.mp_pay = async (ctx) => {
1043
1052
  config = 'weixin_mp',
1044
1053
  pay_config = 'weixin_pay',
1045
1054
  profit_sharing = 'N',
1055
+ mch_id = '',
1046
1056
  } = ctx.request.body
1047
1057
  if (price === 0) throw new Error('价格不能为0')
1048
1058
 
@@ -1066,7 +1076,7 @@ exports.mp_pay = async (ctx) => {
1066
1076
  key,
1067
1077
  pay_key: _pay_key,
1068
1078
  partner_key,
1069
- } = await appConfig.getObject(pay_config)
1079
+ } = await appConfig.getObject(mch_id || pay_config)
1070
1080
 
1071
1081
  const pay_key = _pay_key || key || appName
1072
1082
  const { is_dev, site_host } = await appConfig.getObject('base')
@@ -1078,7 +1088,7 @@ exports.mp_pay = async (ctx) => {
1078
1088
 
1079
1089
  const wxpay = WXPay({
1080
1090
  appid: app_id,
1081
- mch_id: mchId,
1091
+ mch_id: mchId || mch_id,
1082
1092
  partner_key, // 微信商户平台API密钥
1083
1093
  })
1084
1094
 
@@ -1675,6 +1685,7 @@ exports.checkPayOnly = async (ctx, _data) => {
1675
1685
  })
1676
1686
 
1677
1687
  ctx.SUCCESS({ prefix, out_trade_no, ...payResult })
1688
+ return { prefix, out_trade_no, ...payResult }
1678
1689
  }
1679
1690
 
1680
1691
  exports.checkRefund = async (ctx, _data) => {
@@ -866,6 +866,60 @@ exports.removereceiver = async ({
866
866
  return res
867
867
  }
868
868
 
869
+ const handleBillData = (result) => {
870
+ const arr = result.split('\r\n')
871
+ const list = arr.slice(1, arr.length - 3)
872
+ return {
873
+ header: arr[0],
874
+ list,
875
+ result: list.map((item) => {
876
+ const array = item.split(',')
877
+ const orderdate = array[20].substring(1).slice(2, 10)
878
+ const orderPrefix = array[6].substring(1).split('_')[1]
879
+ let order_id = 0
880
+ let prefix = ''
881
+ if (orderPrefix.includes('-')) {
882
+ order_id = Number(orderPrefix.split('-')[1])
883
+ prefix = orderPrefix.split('-')[0]
884
+ } else {
885
+ order_id = Number(orderPrefix)
886
+ }
887
+ let order_date
888
+ if (prefix) {
889
+ order_date = moment(array[0].substring(1)).format('YYYY-MM-DD') + ''
890
+ } else {
891
+ order_date = moment(
892
+ `${orderdate.slice(0, 4)}-${orderdate.slice(4, 6)}-${orderdate.slice(
893
+ 6,
894
+ 8
895
+ )}`
896
+ ).format('YYYY-MM-DD')
897
+ }
898
+ return {
899
+ created_at: array[0].substring(1),
900
+ transactionid: array[5].substring(1),
901
+ [`${[prefix, 'order_id'].filter(Boolean).join('_')}`]: order_id,
902
+ openid: array[7].substring(1),
903
+ price: Number(array[12].substring(1)),
904
+ refund_price: Number(array[16].substring(1)),
905
+ remark: array[20].substring(1),
906
+ rate_price: Number(array[22].substring(1)),
907
+ type: array[9].substring(1),
908
+ order_date,
909
+ }
910
+ }),
911
+ totalHeader: arr[arr.length - 3],
912
+ total: arr[arr.length - 2],
913
+ totalResult: {
914
+ number: Number(arr[arr.length - 2].split(',')[0].substring(1)),
915
+ total_price: Number(arr[arr.length - 2].split(',')[1].substring(1)),
916
+ refund_price: Number(arr[arr.length - 2].split(',')[2].substring(1)),
917
+ rate_price: Number(arr[arr.length - 2].split(',')[4].substring(1)),
918
+ price: Number(arr[arr.length - 2].split(',')[5].substring(1)),
919
+ },
920
+ }
921
+ }
922
+
869
923
  exports.downloadBill = async ({ ctx, pay_config = 'weixin_pay', ...rest }) => {
870
924
  if (!ctx) throw new Error('?ctx')
871
925
  const { app, appName } = getAppByCtx(ctx)
@@ -887,58 +941,17 @@ exports.downloadBill = async ({ ctx, pay_config = 'weixin_pay', ...rest }) => {
887
941
 
888
942
  try {
889
943
  const result = await payObj.downloadBill(rest)
944
+ return handleBillData(result)
945
+ } catch {
946
+ return []
947
+ }
948
+ }
890
949
 
891
- const arr = result.split('\r\n')
892
- const list = arr.slice(1, arr.length - 3)
893
- return {
894
- header: arr[0],
895
- list,
896
- result: list.map((item) => {
897
- const array = item.split(',')
898
- const orderdate = array[20].substring(1).slice(2, 10)
899
- const orderPrefix = array[6].substring(1).split('_')[1]
900
- let order_id = 0
901
- let prefix = ''
902
- if (orderPrefix.includes('-')) {
903
- order_id = Number(orderPrefix.split('-')[1])
904
- prefix = orderPrefix.split('-')[0]
905
- } else {
906
- order_id = Number(orderPrefix)
907
- }
908
- let order_date
909
- if (prefix) {
910
- order_date = moment(array[0].substring(1)).format('YYYY-MM-DD') + ''
911
- } else {
912
- order_date = moment(
913
- `${orderdate.slice(0, 4)}-${orderdate.slice(
914
- 4,
915
- 6
916
- )}-${orderdate.slice(6, 8)}`
917
- ).format('YYYY-MM-DD')
918
- }
919
- return {
920
- created_at: array[0].substring(1),
921
- transactionid: array[5].substring(1),
922
- [`${[prefix, 'order_id'].filter(Boolean).join('_')}`]: order_id,
923
- openid: array[7].substring(1),
924
- price: Number(array[12].substring(1)),
925
- refund_price: Number(array[16].substring(1)),
926
- remark: array[20].substring(1),
927
- rate_price: Number(array[22].substring(1)),
928
- type: array[9].substring(1),
929
- order_date,
930
- }
931
- }),
932
- totalHeader: arr[arr.length - 3],
933
- total: arr[arr.length - 2],
934
- totalResult: {
935
- number: Number(arr[arr.length - 2].split(',')[0].substring(1)),
936
- total_price: Number(arr[arr.length - 2].split(',')[1].substring(1)),
937
- refund_price: Number(arr[arr.length - 2].split(',')[2].substring(1)),
938
- rate_price: Number(arr[arr.length - 2].split(',')[4].substring(1)),
939
- price: Number(arr[arr.length - 2].split(',')[5].substring(1)),
940
- },
941
- }
950
+ exports.uploadBill = async ({ ctx, content }) => {
951
+ if (!ctx) throw new Error('?ctx')
952
+ if (!content) return []
953
+ try {
954
+ return handleBillData(content)
942
955
  } catch {
943
956
  return []
944
957
  }
@@ -123,6 +123,20 @@ const uploadPromise = (options) => {
123
123
  })
124
124
  }
125
125
 
126
+ const https = require('https')
127
+
128
+ // 1. 全局 HTTPS 连接池(微信专用)
129
+ const wxHttpsAgent = new https.Agent({
130
+ keepAlive: true, // 开启长连接
131
+ keepAliveMsecs: 60000, // 空闲连接保留 60 秒
132
+ maxSockets: 30, // 最大并发连接(适配微信QPS,不超限)
133
+ maxFreeSockets: 10, // 保留空闲连接数
134
+ timeout: 8000, // 底层套接字超时
135
+ rejectUnauthorized: true,
136
+ })
137
+
138
+ axios.defaults.httpsAgent = wxHttpsAgent
139
+
126
140
  module.exports = class Singleton {
127
141
  constructor(config) {
128
142
  this.config = {
@@ -1,6 +1,17 @@
1
1
  const util = require('util')
2
2
  const axios = require('axios')
3
+ const https = require('https')
4
+ // 1. 全局 HTTPS 连接池(微信专用)
5
+ const wxHttpsAgent = new https.Agent({
6
+ keepAlive: true, // 开启长连接
7
+ keepAliveMsecs: 60000, // 空闲连接保留 60 秒
8
+ maxSockets: 30, // 最大并发连接(适配微信QPS,不超限)
9
+ maxFreeSockets: 10, // 保留空闲连接数
10
+ timeout: 8000, // 底层套接字超时
11
+ rejectUnauthorized: true,
12
+ })
3
13
 
14
+ axios.defaults.httpsAgent = wxHttpsAgent
4
15
  const { lodash } = require('q-koa')
5
16
  const getAccessTokenUrl =
6
17
  'https://api.weixin.qq.com/cgi-bin/token?grant_type=%s&appid=%s&secret=%s'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "q-koa",
3
- "version": "13.4.3",
3
+ "version": "13.4.5",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {