q-koa 12.8.5 → 12.9.1
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.
|
@@ -534,6 +534,7 @@ exports.funds_order_pay = async ({ app, result }) => {
|
|
|
534
534
|
|
|
535
535
|
if (app.service[model] && app.service[model].notify) {
|
|
536
536
|
await app.service[model].notify({
|
|
537
|
+
ctx,
|
|
537
538
|
app,
|
|
538
539
|
order_id,
|
|
539
540
|
order: model,
|
|
@@ -590,6 +591,7 @@ exports.funds_order_refund = async ({ app, result }) => {
|
|
|
590
591
|
throw new Error('还没退成功')
|
|
591
592
|
if (app.service[model] && app.service[model].refund_notify) {
|
|
592
593
|
await app.service[model].refund_notify({
|
|
594
|
+
ctx,
|
|
593
595
|
app,
|
|
594
596
|
order_id,
|
|
595
597
|
order: model,
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
const util = require('util')
|
|
2
|
+
const axios = require('axios')
|
|
3
|
+
|
|
4
|
+
const { lodash } = require('q-koa')
|
|
5
|
+
const getAccessTokenUrl =
|
|
6
|
+
'https://api.weixin.qq.com/cgi-bin/token?grant_type=%s&appid=%s&secret=%s'
|
|
7
|
+
|
|
8
|
+
const getOpenListUrl =
|
|
9
|
+
'https://api.weixin.qq.com/cgi-bin/user/get?access_token=%s'
|
|
10
|
+
|
|
11
|
+
const getUserInfoUrl =
|
|
12
|
+
'https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN'
|
|
13
|
+
|
|
14
|
+
const getUserInfoListUrl =
|
|
15
|
+
'https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=%s'
|
|
16
|
+
|
|
17
|
+
const sendMessageUrl =
|
|
18
|
+
'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s'
|
|
19
|
+
|
|
20
|
+
const getTemplateUrl =
|
|
21
|
+
'https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=%s'
|
|
22
|
+
|
|
23
|
+
const LRU = require('lru-cache')
|
|
24
|
+
const cache = new LRU({
|
|
25
|
+
max: 100,
|
|
26
|
+
maxAge: 1000 * 60 * 60,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
module.exports = class Singleton {
|
|
30
|
+
constructor(config) {
|
|
31
|
+
this.config = {
|
|
32
|
+
...config,
|
|
33
|
+
grant_type: 'client_credential',
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 单例模式
|
|
37
|
+
*/
|
|
38
|
+
if (!Singleton.instance) {
|
|
39
|
+
Singleton.instance = this
|
|
40
|
+
}
|
|
41
|
+
const previous = Singleton.instance.getConfig()
|
|
42
|
+
if (!lodash.isEqual(previous, config)) {
|
|
43
|
+
Singleton.instance = this
|
|
44
|
+
}
|
|
45
|
+
return Singleton.instance
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
init() {
|
|
49
|
+
if (!this.config.appid || !this.config.secrect) {
|
|
50
|
+
throw new Error('没有配置appid或secrect')
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async getAccessToken() {
|
|
55
|
+
const { appid, secrect, grant_type } = this.config
|
|
56
|
+
if (cache.get(appid)) {
|
|
57
|
+
return cache.get(appid)
|
|
58
|
+
}
|
|
59
|
+
const url = util.format(getAccessTokenUrl, grant_type, appid, secrect)
|
|
60
|
+
|
|
61
|
+
const result = await axios.get(url).then((res) => res.data)
|
|
62
|
+
const { errcode, errmsg, access_token } = result
|
|
63
|
+
|
|
64
|
+
if (errcode) {
|
|
65
|
+
throw new Error(errmsg)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
cache.set(appid, access_token)
|
|
69
|
+
return access_token
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async getOpenList() {
|
|
73
|
+
const access_token = await this.getAccessToken()
|
|
74
|
+
const url = util.format(getOpenListUrl, access_token)
|
|
75
|
+
const result = await axios.post(url).then((res) => res.data)
|
|
76
|
+
if (result.errcode) {
|
|
77
|
+
if (result.errcode === 40001) {
|
|
78
|
+
cache.reset()
|
|
79
|
+
return await this.getOpenList()
|
|
80
|
+
}
|
|
81
|
+
throw new Error(`${result.errcode};${result.errmsg}`)
|
|
82
|
+
}
|
|
83
|
+
return result
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async getUserInfo(openid) {
|
|
87
|
+
const access_token = await this.getAccessToken()
|
|
88
|
+
const url = util.format(getUserInfoUrl, access_token, openid)
|
|
89
|
+
const result = await axios.post(url).then((res) => res.data)
|
|
90
|
+
if (result.errcode) {
|
|
91
|
+
if (result.errcode === 40001) {
|
|
92
|
+
cache.reset()
|
|
93
|
+
return await this.getUserInfo(openid)
|
|
94
|
+
}
|
|
95
|
+
throw new Error(`${result.errcode};${result.errmsg}`)
|
|
96
|
+
}
|
|
97
|
+
return result
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async getUserInfoList(list = []) {
|
|
101
|
+
const user_list = list.map((openid) => {
|
|
102
|
+
return {
|
|
103
|
+
openid,
|
|
104
|
+
lang: 'zh_CN',
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
const access_token = await this.getAccessToken()
|
|
108
|
+
const url = util.format(getUserInfoListUrl, access_token)
|
|
109
|
+
const result = await axios
|
|
110
|
+
.post(url, {
|
|
111
|
+
user_list,
|
|
112
|
+
})
|
|
113
|
+
.then((res) => res.data)
|
|
114
|
+
if (result.errcode) {
|
|
115
|
+
if (result.errcode === 40001) {
|
|
116
|
+
cache.reset()
|
|
117
|
+
return await this.getUserInfoList(list)
|
|
118
|
+
}
|
|
119
|
+
throw new Error(`${result.errcode};${result.errmsg}`)
|
|
120
|
+
}
|
|
121
|
+
return result.user_info_list
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async sendMessage(options) {
|
|
125
|
+
const access_token = await this.getAccessToken()
|
|
126
|
+
const url = util.format(sendMessageUrl, access_token)
|
|
127
|
+
const formatOptions = {
|
|
128
|
+
...options,
|
|
129
|
+
data: lodash.mapValues(options.data, (item) => {
|
|
130
|
+
return {
|
|
131
|
+
value: item,
|
|
132
|
+
}
|
|
133
|
+
}),
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const result = await axios.post(url, formatOptions).then((res) => res.data)
|
|
137
|
+
if (result.errcode) {
|
|
138
|
+
if (result.errcode === 40001) {
|
|
139
|
+
cache.reset()
|
|
140
|
+
return await this.sendMessage(options)
|
|
141
|
+
}
|
|
142
|
+
throw new Error(`${result.errcode};${result.errmsg}`)
|
|
143
|
+
}
|
|
144
|
+
return result
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async getTemplate() {
|
|
148
|
+
const access_token = await this.getAccessToken()
|
|
149
|
+
const url = util.format(getTemplateUrl, access_token)
|
|
150
|
+
const result = await axios.post(url).then((res) => res.data)
|
|
151
|
+
if (result.errcode) {
|
|
152
|
+
if (result.errcode === 40001) {
|
|
153
|
+
cache.reset()
|
|
154
|
+
return await this.getTemplate()
|
|
155
|
+
}
|
|
156
|
+
throw new Error(`${result.errcode};${result.errmsg}`)
|
|
157
|
+
}
|
|
158
|
+
return result
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
getConfig() {
|
|
162
|
+
return this.config
|
|
163
|
+
}
|
|
164
|
+
}
|