q-koa 12.9.3 → 12.9.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
@@ -22,7 +22,7 @@ const jwt = require('jsonwebtoken')
22
22
  const verify = util.promisify(jwt.verify)
23
23
  const fsExtra = require('fs-extra')
24
24
  const { getObject, getAppConfig } = require('./file/utils')
25
-
25
+ const { push } = require('./file/plugins/log/service')
26
26
  const restc = require('./restc')
27
27
  const APP_DIR = 'app'
28
28
  const PLUGINS_DIR = 'plugins'
@@ -472,6 +472,10 @@ class APP {
472
472
  await this.initModel(appName)
473
473
  // const models = Object.keys(this.app[appName].model).join(' / ')
474
474
  } catch (e) {
475
+ push({
476
+ appName,
477
+ message: `${appName}数据库连接失败`,
478
+ })
475
479
  console.log(`${appName}数据库连接失败`)
476
480
  console.log(e)
477
481
  throw new Error(e.message)
@@ -588,24 +592,20 @@ class APP {
588
592
  'page'
589
593
  )
590
594
 
591
- const _id =
592
- belongs === 'setting'
593
- ? {
594
- id: {
595
- type: Sequelize.TINYINT.UNSIGNED,
596
- allowNull: false,
597
- primaryKey: true,
598
- autoIncrement: true,
599
- },
600
- }
601
- : {
602
- id: {
603
- type: Sequelize.MEDIUMINT.UNSIGNED,
604
- allowNull: false,
605
- primaryKey: true,
606
- autoIncrement: true,
607
- },
608
- }
595
+ const idType = _.get(
596
+ this.app[appName].config[folder],
597
+ 'idType',
598
+ belongs === 'setting' ? 'TINYINT' : 'MEDIUMINT'
599
+ )
600
+
601
+ const _id = {
602
+ id: {
603
+ type: Sequelize[idType].UNSIGNED,
604
+ allowNull: false,
605
+ primaryKey: true,
606
+ autoIncrement: true,
607
+ },
608
+ }
609
609
 
610
610
  const attributes = _.defaultsDeep(_.cloneDeep(_attributes), {
611
611
  ..._id,
@@ -793,7 +793,7 @@ class APP {
793
793
  }
794
794
 
795
795
  if (is_dev) {
796
- console.log(moment().valueOf() - start)
796
+ console.log('挂载service bind', moment().valueOf() - start)
797
797
  }
798
798
  }
799
799
 
@@ -959,24 +959,24 @@ class APP {
959
959
  ]
960
960
  for (let i = 0; i < hooksList.length; i++) {
961
961
  if (_.get(app, `${appName}.${hooksList[i]}.${controller}.${fn}`)) {
962
- if (hooksList[i] === 'controller') {
963
- process.once('unhandledRejection', (reason, promise) => {
964
- if (
965
- this.app &&
966
- this.app[appName] &&
967
- this.app[appName].model &&
968
- this.app[appName].model.log
969
- ) {
970
- this.app[appName].model.log.create({
971
- url: ctx.request.href,
972
- body: ctx.request.body,
973
- message: 'promise unhandledRejection',
974
- content: reason.stack,
975
- header: ctx.request.header,
976
- })
977
- }
978
- })
979
- }
962
+ // if (hooksList[i] === 'controller') {
963
+ // process.once('unhandledRejection', (reason, promise) => {
964
+ // if (
965
+ // this.app &&
966
+ // this.app[appName] &&
967
+ // this.app[appName].model &&
968
+ // this.app[appName].model.log
969
+ // ) {
970
+ // this.app[appName].model.log.create({
971
+ // url: ctx.request.href,
972
+ // body: ctx.request.body,
973
+ // message: 'promise unhandledRejection',
974
+ // content: reason.stack,
975
+ // header: ctx.request.header,
976
+ // })
977
+ // }
978
+ // })
979
+ // }
980
980
  await app[appName][hooksList[i]][controller][fn](ctx)
981
981
  }
982
982
  }
@@ -1,4 +1,5 @@
1
- const { lodash, getConfig } = require('q-koa')
1
+ const { getConfig } = require('q-koa')
2
+ const lodash = require('lodash')
2
3
  const axios = require('axios')
3
4
 
4
5
  const is_dev = process.env.NODE_ENV !== 'production'
@@ -38,10 +39,17 @@ exports.push = async ({ app, appName = '通知', url, message }) => {
38
39
  return
39
40
  }
40
41
  if (log_push_url) {
41
- const appConfig = getConfig(app)
42
- const { site_name, logo_image, logo_img } = await appConfig.getObject(
43
- 'base'
44
- )
42
+ let site_name = appName
43
+ let logo_image = ''
44
+ let logo_img = ''
45
+ if (app) {
46
+ const appConfig = getConfig(app)
47
+ const res = await appConfig.getObject('base')
48
+
49
+ site_name = res.site_name
50
+ logo_image = res.logo_image
51
+ logo_img = res.logo_img
52
+ }
45
53
 
46
54
  const queryObject = {
47
55
  ...(is_dev ? {} : { url: encodeURIComponent(url) }),
@@ -4,7 +4,12 @@ module.exports = {
4
4
  multiple: false,
5
5
  availableSort: false,
6
6
  order: ['created_at'],
7
- select: [{ key: 'user_id' }, { key: 'nick_name' }, { key: 'openid' }],
7
+ select: [
8
+ { key: 'user_id' },
9
+ { key: 'nick_name' },
10
+ { key: 'appid' },
11
+ { key: 'openid' },
12
+ ],
8
13
  excludes: [],
9
14
  limit: 20,
10
15
  defaultOrder: [{ sort: 'descending', type: 'id' }],
@@ -682,6 +682,7 @@ exports.mockPay = async (ctx) => {
682
682
  throw new Error(`没配置${model}支付回调notify`)
683
683
  }
684
684
  await app.service[model].notify({
685
+ ctx,
685
686
  app,
686
687
  order_id,
687
688
  order: model,
@@ -925,9 +925,12 @@ exports.app_pay = async (ctx) => {
925
925
  // }
926
926
  const appConfig = getConfig(app)
927
927
 
928
- const { mchId, key, partner_key, appId: appid } = await appConfig.getObject(
929
- pay_config
930
- )
928
+ const {
929
+ mchId,
930
+ key,
931
+ partner_key,
932
+ appId: appid,
933
+ } = await appConfig.getObject(pay_config)
931
934
 
932
935
  if (!appid) throw new Error(`appId不能存在`)
933
936
 
@@ -1960,3 +1963,89 @@ exports.getCommentInfo = async (ctx, _data) => {
1960
1963
  ctx.SUCCESS(result)
1961
1964
  return result
1962
1965
  }
1966
+
1967
+ exports.createActivity = async (ctx, _data) => {
1968
+ const { app, appName } = getAppByCtx(ctx)
1969
+ const { config = 'weixin_mp' } = _data || ctx.request.body
1970
+ const appConfig = getConfig(app)
1971
+ const {
1972
+ app_id,
1973
+ app_secrect,
1974
+ template_type = 'start',
1975
+ limit_number = 5,
1976
+ room_limit = 100,
1977
+ activityId = '',
1978
+ } = await appConfig.getObject(config)
1979
+
1980
+ const weixinMp = new WeixinMp({
1981
+ appid: app_id,
1982
+ secrect: app_secrect,
1983
+ })
1984
+ weixinMp.init()
1985
+
1986
+ const template = {
1987
+ start: '21B034D08C5615B9889CE362BB957B1EE69A584B',
1988
+ present: '666F374D69D16C932E45D7E7D9F10CEF6177F5F5',
1989
+ }
1990
+
1991
+ if (!activityId) {
1992
+ const { activity_id: activityId } = await weixinMp.createActivity()
1993
+ }
1994
+
1995
+ const payLoad = {
1996
+ withShareTicket: true,
1997
+ isUpdatableMessage: true,
1998
+ activityId,
1999
+ templateInfo: {
2000
+ parameterList: [
2001
+ {
2002
+ name: 'member_count',
2003
+ value: limit_number + '',
2004
+ },
2005
+ {
2006
+ name: 'room_limit',
2007
+ value: room_limit + '',
2008
+ },
2009
+ ],
2010
+ templateld: template[template_type],
2011
+ },
2012
+ }
2013
+ ctx.SUCCESS(payLoad)
2014
+ return payLoad
2015
+ }
2016
+
2017
+ exports.setUpdatableMsg = async (ctx, _data) => {
2018
+ const { app, appName } = getAppByCtx(ctx)
2019
+
2020
+ const {
2021
+ config = 'weixin_mp',
2022
+ activity_id,
2023
+ target_state = 0,
2024
+ room_limit,
2025
+ member_count,
2026
+ path,
2027
+ version_type,
2028
+ } = _data || ctx.request.body
2029
+
2030
+ if (!activity_id) throw new ServiceError('?activity_id')
2031
+
2032
+ const appConfig = getConfig(app)
2033
+ const { app_id, app_secrect } = await appConfig.getObject(config)
2034
+ const weixinMp = new WeixinMp({
2035
+ appid: app_id,
2036
+ secrect: app_secrect,
2037
+ })
2038
+ weixinMp.init()
2039
+
2040
+ const result = await weixinMp.setUpdatableMsg({
2041
+ activity_id,
2042
+ target_state,
2043
+ room_limit,
2044
+ member_count,
2045
+ path,
2046
+ version_type,
2047
+ })
2048
+
2049
+ ctx.SUCCESS(result)
2050
+ return result
2051
+ }
@@ -373,14 +373,8 @@ exports.qr_code = async ({
373
373
 
374
374
  return qr_image
375
375
  } else {
376
- const {
377
- accessKeyId,
378
- accessKeySecret,
379
- bucket,
380
- region,
381
- cdn_host,
382
- oss_host,
383
- } = await appConfig.getObject('oss')
376
+ const { accessKeyId, accessKeySecret, bucket, region, cdn_host, oss_host } =
377
+ await appConfig.getObject('oss')
384
378
  if (!(accessKeyId && accessKeySecret && bucket && region)) {
385
379
  throw new Error('没有配置oss设置')
386
380
  }
@@ -1,7 +1,7 @@
1
1
  const util = require('util')
2
2
  const axios = require('axios')
3
3
 
4
- const { lodash } = require('q-koa')
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'
7
7
  const getPhoneNumberUrl =
@@ -72,6 +72,11 @@ const getUserPortraitUrl =
72
72
 
73
73
  const getCommentInfoUrl =
74
74
  'https://api.weixin.qq.com/wxaapi/comment/commentinfo/get?commentId=%s&access_token=%s'
75
+ const createActivityUrl =
76
+ 'https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create?access_token=%s'
77
+
78
+ const setUpdatableMsgUrl =
79
+ 'https://api.weixin.qq.com/cgi-bin/message/wxopen/updatablemsg/send?access_token=%s'
75
80
 
76
81
  const fsPromise = require('fs/promises')
77
82
  const LRU = require('lru-cache')
@@ -864,6 +869,88 @@ module.exports = class Singleton {
864
869
  return result
865
870
  }
866
871
 
872
+ async createActivity() {
873
+ const access_token = await this.getAccessToken()
874
+ const url = util.format(createActivityUrl, access_token)
875
+
876
+ const result = await axios.get(url).then((res) => res.data)
877
+ if (result.errcode) {
878
+ if (result.errcode === 40001) {
879
+ cache.reset()
880
+ return await this.createActivity()
881
+ }
882
+ throw new Error(`${result.errcode};${result.errmsg}`)
883
+ }
884
+ return result
885
+ }
886
+
887
+ async setUpdatableMsg(target) {
888
+ let {
889
+ activity_id,
890
+ target_state,
891
+ member_count,
892
+ room_limit,
893
+ version_type,
894
+ path,
895
+ } = target
896
+
897
+ if (target_state === 1) {
898
+ version_type = version_type || 'release'
899
+ path = path || 'pages/index/index'
900
+ room_limit = null
901
+ member_count = null
902
+ } else {
903
+ version_type = ''
904
+ path = ''
905
+ }
906
+ const access_token = await this.getAccessToken()
907
+ const url = util.format(setUpdatableMsgUrl, access_token)
908
+ const postData = {
909
+ activity_id,
910
+ target_state,
911
+ template_info: {
912
+ parameter_list: [
913
+ member_count
914
+ ? {
915
+ name: 'member_count',
916
+ value: member_count + '',
917
+ }
918
+ : null,
919
+ room_limit
920
+ ? {
921
+ name: 'room_limit',
922
+ value: room_limit + '',
923
+ }
924
+ : null,
925
+ path
926
+ ? {
927
+ name: 'path',
928
+ value: path + '',
929
+ }
930
+ : null,
931
+ version_type
932
+ ? {
933
+ name: 'version_type',
934
+ value: version_type + '',
935
+ }
936
+ : null,
937
+ ].filter(Boolean),
938
+ },
939
+ }
940
+ if (!postData.template_info.parameter_list.length) {
941
+ throw new ServiceError('?parameter_list length 0')
942
+ }
943
+ const result = await axios.post(url, postData).then((res) => res.data)
944
+ if (result.errcode) {
945
+ if (result.errcode === 40001) {
946
+ cache.reset()
947
+ return await this.setUpdatableMsg(target)
948
+ }
949
+ throw new Error(`${result.errcode};${result.errmsg}`)
950
+ }
951
+ return result
952
+ }
953
+
867
954
  getConfig() {
868
955
  return this.config
869
956
  }
@@ -63,24 +63,26 @@ exports.miResponse = (methods) =>
63
63
  methods,
64
64
  })
65
65
 
66
- exports.miCors = (arr = [], ip = '192.168.0.1') => async (ctx, next) => {
67
- ctx.set('Access-Control-Allow-Origin', `${ctx.header.origin || '*'}`)
68
- ctx.set('Access-Control-Allow-Credentials', true)
69
- // ctx.set('Access-Control-Allow-Headers', '*');
70
- ctx.set(
71
- 'Access-Control-Allow-Headers',
72
- ` Origin, X-Requested-With, Content-Type, client-type, Accept, ${arr
73
- .map((item) => `${item}-token`)
74
- .join(', ')}`
75
- )
76
- ctx.set('server-ip', ip)
77
- ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS')
78
- if (ctx.method === 'OPTIONS') {
79
- ctx.body = 200
80
- } else {
81
- await next()
66
+ exports.miCors =
67
+ (arr = [], ip = '192.168.0.1') =>
68
+ async (ctx, next) => {
69
+ ctx.set('Access-Control-Allow-Origin', `${ctx.header.origin || '*'}`)
70
+ ctx.set('Access-Control-Allow-Credentials', true)
71
+ // ctx.set('Access-Control-Allow-Headers', '*');
72
+ ctx.set(
73
+ 'Access-Control-Allow-Headers',
74
+ ` Origin, X-Requested-With, Content-Type, client-type, Accept, ${arr
75
+ .map((item) => `${item}-token`)
76
+ .join(', ')}`
77
+ )
78
+ ctx.set('server-ip', ip)
79
+ ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS')
80
+ if (ctx.method === 'OPTIONS') {
81
+ ctx.body = 200
82
+ } else {
83
+ await next()
84
+ }
82
85
  }
83
- }
84
86
 
85
87
  exports.miXmlBody = (config) =>
86
88
  xmlParser({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "q-koa",
3
- "version": "12.9.3",
3
+ "version": "12.9.5",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {