1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
// +---------------------------------------------------------------------- |
4
|
|
|
// | ThinkLibrary 6.0 for ThinkPhP 6.0 |
5
|
|
|
// +---------------------------------------------------------------------- |
6
|
|
|
// | 版权所有 2017~2020 [ https://www.dtapp.net ] |
7
|
|
|
// +---------------------------------------------------------------------- |
8
|
|
|
// | 官方网站: https://gitee.com/liguangchun/ThinkLibrary |
9
|
|
|
// +---------------------------------------------------------------------- |
10
|
|
|
// | 开源协议 ( https://mit-license.org ) |
11
|
|
|
// +---------------------------------------------------------------------- |
12
|
|
|
// | gitee 仓库地址 :https://gitee.com/liguangchun/ThinkLibrary |
13
|
|
|
// | github 仓库地址 :https://github.com/GC0202/ThinkLibrary |
14
|
|
|
// | gitlab 仓库地址 :https://gitlab.com/liguangchun/thinklibrary |
15
|
|
|
// | weixin 仓库地址 :https://git.weixin.qq.com/liguangchun/ThinkLibrary |
16
|
|
|
// | huaweicloud 仓库地址 :https://codehub-cn-south-1.devcloud.huaweicloud.com/composer00001/ThinkLibrary.git |
17
|
|
|
// | Packagist 地址 :https://packagist.org/packages/liguangchun/think-library |
18
|
|
|
// +---------------------------------------------------------------------- |
19
|
|
|
|
20
|
|
|
namespace DtApp\ThinkLibrary\service\wechat; |
21
|
|
|
|
22
|
|
|
use DtApp\ThinkLibrary\exception\DtaException; |
23
|
|
|
use DtApp\ThinkLibrary\Service; |
24
|
|
|
use DtApp\ThinkLibrary\service\curl\HttpService; |
25
|
|
|
use think\db\exception\DbException; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* 微信小程序 |
29
|
|
|
* Class MiniService |
30
|
|
|
* @package DtApp\ThinkLibrary\service\WeChat |
31
|
|
|
*/ |
32
|
|
|
class MiniService extends Service |
33
|
|
|
{ |
34
|
|
|
/** |
35
|
|
|
* @var |
36
|
|
|
*/ |
37
|
|
|
private $app_id, $app_secret; |
38
|
|
|
/** |
39
|
|
|
* @var string |
40
|
|
|
*/ |
41
|
|
|
private $grant_type = "client_credential"; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* 驱动方式 |
45
|
|
|
* @var string |
46
|
|
|
*/ |
47
|
|
|
private $cache = "file"; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @param string $appId |
51
|
|
|
* @return $this |
52
|
|
|
*/ |
53
|
|
|
public function appId(string $appId) |
54
|
|
|
{ |
55
|
|
|
$this->app_id = $appId; |
56
|
|
|
return $this; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @param string $appSecret |
61
|
|
|
* @return $this |
62
|
|
|
*/ |
63
|
|
|
public function appSecret(string $appSecret) |
64
|
|
|
{ |
65
|
|
|
$this->app_secret = $appSecret; |
66
|
|
|
return $this; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* 驱动方式 |
71
|
|
|
* @param string $cache |
72
|
|
|
* @return $this |
73
|
|
|
*/ |
74
|
|
|
public function cache(string $cache): self |
75
|
|
|
{ |
76
|
|
|
$this->cache = $cache; |
77
|
|
|
return $this; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* 获取配置信息 |
82
|
|
|
* @return $this |
83
|
|
|
*/ |
84
|
|
|
private function getConfig(): self |
85
|
|
|
{ |
86
|
|
|
$this->cache = config('dtapp.wechat.mini.cache'); |
|
|
|
|
87
|
|
|
$this->app_id = config('dtapp.wechat.mini.app_id'); |
88
|
|
|
$this->app_secret = config('dtapp.wechat.mini.app_secret'); |
89
|
|
|
return $this; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* 用户支付完成后,获取该用户的 UnionId,无需用户授权 |
94
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/user-info/auth.getPaidUnionId.html |
95
|
|
|
* @param string $openid |
96
|
|
|
* @return bool|mixed|string |
97
|
|
|
* @throws DbException |
98
|
|
|
* @throws DtaException |
99
|
|
|
*/ |
100
|
|
|
public function getPaidUnionId(string $openid) |
101
|
|
|
{ |
102
|
|
|
$accessToken = $this->getAccessToken(); |
103
|
|
|
$url = "https://api.weixin.qq.com/wxa/getpaidunionid?access_token={$accessToken['access_token']}&openid={$openid}"; |
104
|
|
|
return HttpService::instance() |
105
|
|
|
->url($url) |
106
|
|
|
->toArray(); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* 获取小程序二维码,适用于需要的码数量较少的业务场景。通过该接口生成的小程序码,永久有效,有数量限制 |
111
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.createQRCode.html |
112
|
|
|
* @param array $data |
113
|
|
|
* @return array|bool|mixed|string |
114
|
|
|
* @throws DbException |
115
|
|
|
* @throws DtaException |
116
|
|
|
*/ |
117
|
|
|
public function createWxaQrCode(array $data = []) |
118
|
|
|
{ |
119
|
|
|
$accessToken = $this->getAccessToken(); |
120
|
|
|
$url = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token={$accessToken['access_token']}"; |
121
|
|
|
return HttpService::instance() |
122
|
|
|
->url($url) |
123
|
|
|
->data($data) |
124
|
|
|
->post() |
125
|
|
|
->toArray(false); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* 获取小程序码,适用于需要的码数量较少的业务场景。通过该接口生成的小程序码,永久有效,有数量限制 |
130
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.get.html |
131
|
|
|
* @param array $data |
132
|
|
|
* @return array|bool|mixed|string |
133
|
|
|
* @throws DbException |
134
|
|
|
* @throws DtaException |
135
|
|
|
*/ |
136
|
|
|
public function getWxaCode(array $data = []) |
137
|
|
|
{ |
138
|
|
|
$accessToken = $this->getAccessToken(); |
139
|
|
|
$url = "https://api.weixin.qq.com/wxa/getwxacode?access_token={$accessToken['access_token']}"; |
140
|
|
|
return HttpService::instance() |
141
|
|
|
->url($url) |
142
|
|
|
->data($data) |
143
|
|
|
->post() |
144
|
|
|
->toArray(false); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* 获取小程序码,适用于需要的码数量极多的业务场景。通过该接口生成的小程序码,永久有效,数量暂无限制 |
149
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html |
150
|
|
|
* @param array $data |
151
|
|
|
* @return array|bool|mixed|string |
152
|
|
|
* @throws DbException |
153
|
|
|
* @throws DtaException |
154
|
|
|
*/ |
155
|
|
|
public function getWxaCodeUnLimit(array $data = []) |
156
|
|
|
{ |
157
|
|
|
$accessToken = $this->getAccessToken(); |
158
|
|
|
$url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$accessToken['access_token']}"; |
159
|
|
|
return HttpService::instance() |
160
|
|
|
->url($url) |
161
|
|
|
->data($data) |
162
|
|
|
->post() |
163
|
|
|
->toArray(false); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* 组合模板并添加至帐号下的个人模板库 |
168
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.addTemplate.html |
169
|
|
|
* @param array $data |
170
|
|
|
* @return bool|mixed|string |
171
|
|
|
* @throws DbException |
172
|
|
|
* @throws DtaException |
173
|
|
|
*/ |
174
|
|
|
public function addTemplate(array $data = []) |
175
|
|
|
{ |
176
|
|
|
$accessToken = $this->getAccessToken(); |
177
|
|
|
$url = "https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate?access_token={$accessToken['access_token']}"; |
178
|
|
|
return HttpService::instance() |
179
|
|
|
->url($url) |
180
|
|
|
->data($data) |
181
|
|
|
->toArray(); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* 删除帐号下的个人模板 |
186
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.deleteTemplate.html |
187
|
|
|
* @param string $priTmplId 要删除的模板id |
188
|
|
|
* @return bool|mixed|string |
189
|
|
|
* @throws DbException |
190
|
|
|
* @throws DtaException |
191
|
|
|
*/ |
192
|
|
|
public function deleteTemplate(string $priTmplId) |
193
|
|
|
{ |
194
|
|
|
$accessToken = $this->getAccessToken(); |
195
|
|
|
$url = "https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate?access_token={$accessToken['access_token']}"; |
196
|
|
|
$data = [ |
197
|
|
|
'priTmplId' => $priTmplId |
198
|
|
|
]; |
199
|
|
|
return HttpService::instance() |
200
|
|
|
->url($url) |
201
|
|
|
->data($data) |
202
|
|
|
->toArray(); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* 获取小程序账号的类目 |
207
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getCategory.html |
208
|
|
|
* @return bool|mixed|string |
209
|
|
|
* @throws DbException |
210
|
|
|
* @throws DtaException |
211
|
|
|
*/ |
212
|
|
|
public function getCategory() |
213
|
|
|
{ |
214
|
|
|
$accessToken = $this->getAccessToken(); |
215
|
|
|
$url = "https://api.weixin.qq.com/wxaapi/newtmpl/getcategory?access_token={$accessToken['access_token']}"; |
216
|
|
|
return HttpService::instance() |
217
|
|
|
->url($url) |
218
|
|
|
->toArray(); |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
/** |
222
|
|
|
* 获取模板标题下的关键词列表 |
223
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getPubTemplateKeyWordsById.html |
224
|
|
|
* @param string $tid 模板标题 id |
225
|
|
|
* @return bool|mixed|string |
226
|
|
|
* @throws DbException |
227
|
|
|
* @throws DtaException |
228
|
|
|
*/ |
229
|
|
|
public function getPubTemplateKeyWordsById(string $tid) |
230
|
|
|
{ |
231
|
|
|
$accessToken = $this->getAccessToken(); |
232
|
|
|
$url = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords?access_token={$accessToken['access_token']}"; |
233
|
|
|
$data = [ |
234
|
|
|
'tid' => $tid |
235
|
|
|
]; |
236
|
|
|
return HttpService::instance() |
237
|
|
|
->url($url) |
238
|
|
|
->data($data) |
239
|
|
|
->toArray(); |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
/** |
243
|
|
|
* 获取帐号所属类目下的公共模板标题 |
244
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getPubTemplateTitleList.html |
245
|
|
|
* @param array $data |
246
|
|
|
* @return bool|mixed|string |
247
|
|
|
* @throws DbException |
248
|
|
|
* @throws DtaException |
249
|
|
|
*/ |
250
|
|
|
public function getPubTemplateTitleList(array $data = []) |
251
|
|
|
{ |
252
|
|
|
$accessToken = $this->getAccessToken(); |
253
|
|
|
$url = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatetitles?access_token={$accessToken['access_token']}"; |
254
|
|
|
return HttpService::instance() |
255
|
|
|
->url($url) |
256
|
|
|
->data($data) |
257
|
|
|
->toArray(); |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
/** |
261
|
|
|
* 获取当前帐号下的个人模板列表 |
262
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getTemplateList.html |
263
|
|
|
* @return bool|mixed|string |
264
|
|
|
* @throws DbException |
265
|
|
|
* @throws DtaException |
266
|
|
|
*/ |
267
|
|
|
public function getTemplateList() |
268
|
|
|
{ |
269
|
|
|
$accessToken = $this->getAccessToken(); |
270
|
|
|
$url = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate?access_token={$accessToken['access_token']}"; |
271
|
|
|
return HttpService::instance() |
272
|
|
|
->url($url) |
273
|
|
|
->toArray(); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
/** |
277
|
|
|
* 发送订阅消息 |
278
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html |
279
|
|
|
* @param array $data |
280
|
|
|
* @return bool|mixed|string |
281
|
|
|
* @throws DbException |
282
|
|
|
* @throws DtaException |
283
|
|
|
*/ |
284
|
|
|
public function subscribeMessageSend(array $data = []) |
285
|
|
|
{ |
286
|
|
|
$accessToken = $this->getAccessToken(); |
287
|
|
|
$url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={$accessToken['access_token']}"; |
288
|
|
|
return HttpService::instance() |
289
|
|
|
->url($url) |
290
|
|
|
->data($data) |
291
|
|
|
->post() |
292
|
|
|
->toArray(); |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
/** |
296
|
|
|
* 登录凭证校验 |
297
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html |
298
|
|
|
* @param string $js_code |
299
|
|
|
* @return bool|mixed|string |
300
|
|
|
* @throws DtaException |
301
|
|
|
*/ |
302
|
|
|
public function code2Session(string $js_code) |
303
|
|
|
{ |
304
|
|
|
if (empty($this->app_id) || empty($this->app_secret)) { |
305
|
|
|
$this->getConfig(); |
306
|
|
|
} |
307
|
|
|
if (empty($this->app_id)) { |
308
|
|
|
throw new DtaException('请检查app_id参数'); |
309
|
|
|
} |
310
|
|
|
if (empty($this->app_secret)) { |
311
|
|
|
throw new DtaException('请检查app_secret参数'); |
312
|
|
|
} |
313
|
|
|
$this->grant_type = "authorization_code"; |
314
|
|
|
$url = "https://api.weixin.qq.com/sns/jscode2session?appid={$this->app_id}&secret={$this->app_secret}&js_code={$js_code}&grant_type={$this->grant_type}"; |
315
|
|
|
return HttpService::instance() |
316
|
|
|
->url($url) |
317
|
|
|
->toArray(); |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
/** |
321
|
|
|
* 检验数据的真实性,并且获取解密后的明文. |
322
|
|
|
* @param string $js_code |
323
|
|
|
* @param string $encrypted_data |
324
|
|
|
* @param string $iv |
325
|
|
|
* @return bool|mixed |
326
|
|
|
* @throws DtaException |
327
|
|
|
*/ |
328
|
|
|
public function userInfo(string $js_code, string $encrypted_data, string $iv) |
329
|
|
|
{ |
330
|
|
|
$session = $this->code2Session($js_code); |
331
|
|
|
if (!isset($session['openid'])) { |
332
|
|
|
return false; |
333
|
|
|
} |
334
|
|
|
$result = openssl_decrypt(base64_decode($encrypted_data), "AES-128-CBC", base64_decode($session['session_key']), 1, base64_decode($iv)); |
335
|
|
|
return json_decode($result, true); |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
/** |
339
|
|
|
* 数据签名校验,并且获取解密后的明文. |
340
|
|
|
* @param string $js_code |
341
|
|
|
* @param string $encrypted_data |
342
|
|
|
* @param string $iv |
343
|
|
|
* @return mixed |
344
|
|
|
* @throws DtaException |
345
|
|
|
*/ |
346
|
|
|
public function userPhone(string $js_code, string $encrypted_data, string $iv) |
347
|
|
|
{ |
348
|
|
|
$session = $this->code2Session($js_code); |
349
|
|
|
if (!isset($session['openid'])) { |
350
|
|
|
return false; |
351
|
|
|
} |
352
|
|
|
$result = openssl_decrypt(base64_decode($encrypted_data), "AES-128-CBC", base64_decode($session['session_key']), 1, base64_decode($iv)); |
353
|
|
|
return json_decode($result, true); |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
/** |
357
|
|
|
* 数据签名校验,并且获取解密后的明文. |
358
|
|
|
* @param string $session_key |
359
|
|
|
* @param string $encrypted_data |
360
|
|
|
* @param string $iv |
361
|
|
|
* @return mixed |
362
|
|
|
*/ |
363
|
|
|
public function decode(string $session_key, string $encrypted_data, string $iv) |
364
|
|
|
{ |
365
|
|
|
$result = openssl_decrypt(base64_decode($encrypted_data), "AES-128-CBC", base64_decode($session_key), 1, base64_decode($iv)); |
366
|
|
|
return json_decode($result, true); |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
/** |
370
|
|
|
* 【小程序直播】直播间管理接口 - 创建直播间 |
371
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/framework/liveplayer/studio-api.html#1 |
372
|
|
|
* @param array $data |
373
|
|
|
* @return array|bool|mixed|string |
374
|
|
|
* @throws DbException |
375
|
|
|
* @throws DtaException |
376
|
|
|
*/ |
377
|
|
|
public function broadcastRoomCreate(array $data = []) |
378
|
|
|
{ |
379
|
|
|
$accessToken = $this->getAccessToken(); |
380
|
|
|
$url = "https://api.weixin.qq.com/wxaapi/broadcast/room/create?access_token={$accessToken['access_token']}"; |
381
|
|
|
return HttpService::instance() |
382
|
|
|
->url($url) |
383
|
|
|
->data($data) |
384
|
|
|
->post() |
385
|
|
|
->toArray(); |
386
|
|
|
} |
387
|
|
|
|
388
|
|
|
/** |
389
|
|
|
* 【小程序直播】直播间管理接口 - 获取直播间列表 |
390
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/framework/liveplayer/studio-api.html#2 |
391
|
|
|
* @param array $data |
392
|
|
|
* @return array|bool|mixed|string |
393
|
|
|
* @throws DbException |
394
|
|
|
* @throws DtaException |
395
|
|
|
*/ |
396
|
|
|
public function broadcastGetLiveInfos(array $data = []) |
397
|
|
|
{ |
398
|
|
|
$accessToken = $this->getAccessToken(); |
399
|
|
|
$url = "https://api.weixin.qq.com/wxa/business/getliveinfo?access_token={$accessToken['access_token']}"; |
400
|
|
|
return HttpService::instance() |
401
|
|
|
->url($url) |
402
|
|
|
->data($data) |
403
|
|
|
->post() |
404
|
|
|
->toArray(); |
405
|
|
|
} |
406
|
|
|
|
407
|
|
|
/** |
408
|
|
|
* 【小程序直播】直播间管理接口 - 获取直播间回放 |
409
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/framework/liveplayer/studio-api.html#3 |
410
|
|
|
* @param array $data |
411
|
|
|
* @return array|bool|mixed|string |
412
|
|
|
* @throws DbException |
413
|
|
|
* @throws DtaException |
414
|
|
|
*/ |
415
|
|
|
public function broadcastGetLiveInfo(array $data = []) |
416
|
|
|
{ |
417
|
|
|
$accessToken = $this->getAccessToken(); |
418
|
|
|
$url = "https://api.weixin.qq.com/wxa/business/getliveinfo?access_token={$accessToken['access_token']}"; |
419
|
|
|
return HttpService::instance() |
420
|
|
|
->url($url) |
421
|
|
|
->data($data) |
422
|
|
|
->post() |
423
|
|
|
->toArray(); |
424
|
|
|
} |
425
|
|
|
|
426
|
|
|
/** |
427
|
|
|
* 【小程序直播】直播间管理接口 - 直播间导入商品 |
428
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/framework/liveplayer/studio-api.html#4 |
429
|
|
|
* @param array $data |
430
|
|
|
* @return array|bool|mixed|string |
431
|
|
|
* @throws DbException |
432
|
|
|
* @throws DtaException |
433
|
|
|
*/ |
434
|
|
|
public function broadcastRoomAddGoods(array $data = []) |
435
|
|
|
{ |
436
|
|
|
$accessToken = $this->getAccessToken(); |
437
|
|
|
$url = "https://api.weixin.qq.com/wxaapi/broadcast/room/addgoods?access_token={$accessToken['access_token']}"; |
438
|
|
|
return HttpService::instance() |
439
|
|
|
->url($url) |
440
|
|
|
->data($data) |
441
|
|
|
->post() |
442
|
|
|
->toArray(); |
443
|
|
|
} |
444
|
|
|
|
445
|
|
|
/** |
446
|
|
|
* 【小程序直播】直播商品管理接口 - 商品添加并提审 |
447
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/framework/liveplayer/commodity-api.html#1 |
448
|
|
|
* @param array $data |
449
|
|
|
* @return array|bool|mixed|string |
450
|
|
|
* @throws DbException |
451
|
|
|
* @throws DtaException |
452
|
|
|
*/ |
453
|
|
|
public function broadcastGoodsAdd(array $data = []) |
454
|
|
|
{ |
455
|
|
|
$accessToken = $this->getAccessToken(); |
456
|
|
|
$url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/add?access_token={$accessToken['access_token']}"; |
457
|
|
|
return HttpService::instance() |
458
|
|
|
->url($url) |
459
|
|
|
->data($data) |
460
|
|
|
->post() |
461
|
|
|
->toArray(); |
462
|
|
|
} |
463
|
|
|
|
464
|
|
|
/** |
465
|
|
|
* 【小程序直播】直播商品管理接口 - 撤回审核 |
466
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/framework/liveplayer/commodity-api.html#2 |
467
|
|
|
* @param array $data |
468
|
|
|
* @return array|bool|mixed|string |
469
|
|
|
* @throws DbException |
470
|
|
|
* @throws DtaException |
471
|
|
|
*/ |
472
|
|
|
public function broadcastGoodsResetAudit(array $data = []) |
473
|
|
|
{ |
474
|
|
|
$accessToken = $this->getAccessToken(); |
475
|
|
|
$url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/resetaudit?access_token={$accessToken['access_token']}"; |
476
|
|
|
return HttpService::instance() |
477
|
|
|
->url($url) |
478
|
|
|
->data($data) |
479
|
|
|
->post() |
480
|
|
|
->toArray(); |
481
|
|
|
} |
482
|
|
|
|
483
|
|
|
/** |
484
|
|
|
* 【小程序直播】直播商品管理接口 - 重新提交审核 |
485
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/framework/liveplayer/commodity-api.html#3 |
486
|
|
|
* @param array $data |
487
|
|
|
* @return array|bool|mixed|string |
488
|
|
|
* @throws DbException |
489
|
|
|
* @throws DtaException |
490
|
|
|
*/ |
491
|
|
|
public function broadcastGoodsAudit(array $data = []) |
492
|
|
|
{ |
493
|
|
|
$accessToken = $this->getAccessToken(); |
494
|
|
|
$url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/audit?access_token={$accessToken['access_token']}"; |
495
|
|
|
return HttpService::instance() |
496
|
|
|
->url($url) |
497
|
|
|
->data($data) |
498
|
|
|
->post() |
499
|
|
|
->toArray(); |
500
|
|
|
} |
501
|
|
|
|
502
|
|
|
/** |
503
|
|
|
* 【小程序直播】直播商品管理接口 - 删除商品 |
504
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/framework/liveplayer/commodity-api.html#4 |
505
|
|
|
* @param array $data |
506
|
|
|
* @return array|bool|mixed|string |
507
|
|
|
* @throws DbException |
508
|
|
|
* @throws DtaException |
509
|
|
|
*/ |
510
|
|
|
public function broadcastGoodsDelete(array $data = []) |
511
|
|
|
{ |
512
|
|
|
$accessToken = $this->getAccessToken(); |
513
|
|
|
$url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/delete?access_token={$accessToken['access_token']}"; |
514
|
|
|
return HttpService::instance() |
515
|
|
|
->url($url) |
516
|
|
|
->data($data) |
517
|
|
|
->post() |
518
|
|
|
->toArray(); |
519
|
|
|
} |
520
|
|
|
|
521
|
|
|
/** |
522
|
|
|
* 【小程序直播】直播商品管理接口 - 更新商品 |
523
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/framework/liveplayer/commodity-api.html#5 |
524
|
|
|
* @param array $data |
525
|
|
|
* @return array|bool|mixed|string |
526
|
|
|
* @throws DbException |
527
|
|
|
* @throws DtaException |
528
|
|
|
*/ |
529
|
|
|
public function broadcastGoodsUpdate(array $data = []) |
530
|
|
|
{ |
531
|
|
|
$accessToken = $this->getAccessToken(); |
532
|
|
|
$url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/update?access_token={$accessToken['access_token']}"; |
533
|
|
|
return HttpService::instance() |
534
|
|
|
->url($url) |
535
|
|
|
->data($data) |
536
|
|
|
->post() |
537
|
|
|
->toArray(); |
538
|
|
|
} |
539
|
|
|
|
540
|
|
|
/** |
541
|
|
|
* 【小程序直播】直播商品管理接口 - 获取商品状态 |
542
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/framework/liveplayer/commodity-api.html#6 |
543
|
|
|
* @param array $data |
544
|
|
|
* @return array|bool|mixed|string |
545
|
|
|
* @throws DbException |
546
|
|
|
* @throws DtaException |
547
|
|
|
*/ |
548
|
|
|
public function broadcastGetGoodsWarehouse(array $data = []) |
549
|
|
|
{ |
550
|
|
|
$accessToken = $this->getAccessToken(); |
551
|
|
|
$url = "https://api.weixin.qq.com/wxa/business/getgoodswarehouse?access_token={$accessToken['access_token']}"; |
552
|
|
|
return HttpService::instance() |
553
|
|
|
->url($url) |
554
|
|
|
->data($data) |
555
|
|
|
->post() |
556
|
|
|
->toArray(); |
557
|
|
|
} |
558
|
|
|
|
559
|
|
|
/** |
560
|
|
|
* 【小程序直播】直播商品管理接口 - 获取商品列表 |
561
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/framework/liveplayer/commodity-api.html#7 |
562
|
|
|
* @param array $data |
563
|
|
|
* @return array|bool|mixed|string |
564
|
|
|
* @throws DbException |
565
|
|
|
* @throws DtaException |
566
|
|
|
*/ |
567
|
|
|
public function broadcastGoodsGetAppRoved(array $data = []) |
568
|
|
|
{ |
569
|
|
|
$accessToken = $this->getAccessToken(); |
570
|
|
|
$url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/getapproved?access_token={$accessToken['access_token']}"; |
571
|
|
|
return HttpService::instance() |
572
|
|
|
->url($url) |
573
|
|
|
->data($data) |
574
|
|
|
->post() |
575
|
|
|
->toArray(); |
576
|
|
|
} |
577
|
|
|
|
578
|
|
|
/** |
579
|
|
|
* 数据分析 - 获取用户访问小程序日留存 |
580
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/data-analysis/visit-retain/analysis.getDailyRetain.html |
581
|
|
|
* @param array $data |
582
|
|
|
* @return array|bool|mixed|string |
583
|
|
|
* @throws DbException |
584
|
|
|
* @throws DtaException |
585
|
|
|
*/ |
586
|
|
|
public function analysisGetDailyRetain(array $data = []) |
587
|
|
|
{ |
588
|
|
|
$accessToken = $this->getAccessToken(); |
589
|
|
|
$url = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyretaininfo?access_token={$accessToken['access_token']}"; |
590
|
|
|
return HttpService::instance() |
591
|
|
|
->url($url) |
592
|
|
|
->data($data) |
593
|
|
|
->post() |
594
|
|
|
->toArray(); |
595
|
|
|
} |
596
|
|
|
|
597
|
|
|
/** |
598
|
|
|
* 数据分析 - 获取用户访问小程序月留存 |
599
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/data-analysis/visit-retain/analysis.getMonthlyRetain.html |
600
|
|
|
* @param array $data |
601
|
|
|
* @return array|bool|mixed|string |
602
|
|
|
* @throws DbException |
603
|
|
|
* @throws DtaException |
604
|
|
|
*/ |
605
|
|
|
public function analysisGetMonthlyRetain(array $data = []) |
606
|
|
|
{ |
607
|
|
|
$accessToken = $this->getAccessToken(); |
608
|
|
|
$url = "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyretaininfo?access_token={$accessToken['access_token']}"; |
609
|
|
|
return HttpService::instance() |
610
|
|
|
->url($url) |
611
|
|
|
->data($data) |
612
|
|
|
->post() |
613
|
|
|
->toArray(); |
614
|
|
|
} |
615
|
|
|
|
616
|
|
|
/** |
617
|
|
|
* 数据分析 - 获取用户访问小程序周留存 |
618
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/data-analysis/visit-retain/analysis.getWeeklyRetain.html |
619
|
|
|
* @param array $data |
620
|
|
|
* @return array|bool|mixed|string |
621
|
|
|
* @throws DbException |
622
|
|
|
* @throws DtaException |
623
|
|
|
*/ |
624
|
|
|
public function analysisGetWeeklyRetain(array $data = []) |
625
|
|
|
{ |
626
|
|
|
$accessToken = $this->getAccessToken(); |
627
|
|
|
$url = "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyretaininfo?access_token={$accessToken['access_token']}"; |
628
|
|
|
return HttpService::instance() |
629
|
|
|
->url($url) |
630
|
|
|
->data($data) |
631
|
|
|
->post() |
632
|
|
|
->toArray(); |
633
|
|
|
} |
634
|
|
|
|
635
|
|
|
/** |
636
|
|
|
* 数据分析 - 获取用户访问小程序数据概况 |
637
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/data-analysis/analysis.getDailySummary.html |
638
|
|
|
* @param array $data |
639
|
|
|
* @return array|bool|mixed|string |
640
|
|
|
* @throws DbException |
641
|
|
|
* @throws DtaException |
642
|
|
|
*/ |
643
|
|
|
public function analysisGetDailySummary(array $data = []) |
644
|
|
|
{ |
645
|
|
|
$accessToken = $this->getAccessToken(); |
646
|
|
|
$url = "https://api.weixin.qq.com/datacube/getweanalysisappiddailysummarytrend?access_token={$accessToken['access_token']}"; |
647
|
|
|
return HttpService::instance() |
648
|
|
|
->url($url) |
649
|
|
|
->data($data) |
650
|
|
|
->post() |
651
|
|
|
->toArray(); |
652
|
|
|
} |
653
|
|
|
|
654
|
|
|
/** |
655
|
|
|
* 数据分析 - 获取小程序新增或活跃用户的画像分布数据。时间范围支持昨天、最近7天、最近30天。其中,新增用户数为时间范围内首次访问小程序的去重用户数,活跃用户数为时间范围内访问过小程序的去重用户数 |
656
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/data-analysis/analysis.getUserPortrait.html |
657
|
|
|
* @param array $data |
658
|
|
|
* @return array|bool|mixed|string |
659
|
|
|
* @throws DbException |
660
|
|
|
* @throws DtaException |
661
|
|
|
*/ |
662
|
|
|
public function analysisGetUserPortrait(array $data = []) |
663
|
|
|
{ |
664
|
|
|
$accessToken = $this->getAccessToken(); |
665
|
|
|
$url = "https://api.weixin.qq.com/datacube/getweanalysisappiduserportrait?access_token={$accessToken['access_token']}"; |
666
|
|
|
return HttpService::instance() |
667
|
|
|
->url($url) |
668
|
|
|
->data($data) |
669
|
|
|
->post() |
670
|
|
|
->toArray(); |
671
|
|
|
} |
672
|
|
|
|
673
|
|
|
/** |
674
|
|
|
* 数据分析 - 获取用户访问小程序数据概况 |
675
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/data-analysis/analysis.getVisitDistribution.html |
676
|
|
|
* @param array $data |
677
|
|
|
* @return array|bool|mixed|string |
678
|
|
|
* @throws DbException |
679
|
|
|
* @throws DtaException |
680
|
|
|
*/ |
681
|
|
|
public function analysisGetVisitDistribution(array $data = []) |
682
|
|
|
{ |
683
|
|
|
$accessToken = $this->getAccessToken(); |
684
|
|
|
$url = "https://api.weixin.qq.com/datacube/getweanalysisappidvisitdistribution?access_token={$accessToken['access_token']}"; |
685
|
|
|
return HttpService::instance() |
686
|
|
|
->url($url) |
687
|
|
|
->data($data) |
688
|
|
|
->post() |
689
|
|
|
->toArray(); |
690
|
|
|
} |
691
|
|
|
|
692
|
|
|
/** |
693
|
|
|
* 数据分析 - 访问页面。目前只提供按 page_visit_pv 排序的 top200 |
694
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/data-analysis/analysis.getVisitPage.html |
695
|
|
|
* @param array $data |
696
|
|
|
* @return array|bool|mixed|string |
697
|
|
|
* @throws DbException |
698
|
|
|
* @throws DtaException |
699
|
|
|
*/ |
700
|
|
|
public function analysisGetVisitPage(array $data = []) |
701
|
|
|
{ |
702
|
|
|
$accessToken = $this->getAccessToken(); |
703
|
|
|
$url = "https://api.weixin.qq.com/datacube/getweanalysisappidvisitpage?access_token={$accessToken['access_token']}"; |
704
|
|
|
return HttpService::instance() |
705
|
|
|
->url($url) |
706
|
|
|
->data($data) |
707
|
|
|
->post() |
708
|
|
|
->toArray(); |
709
|
|
|
} |
710
|
|
|
|
711
|
|
|
/** |
712
|
|
|
* 获取小程序全局唯一后台接口调用凭据(access_token) |
713
|
|
|
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html |
714
|
|
|
* @return bool|mixed|string |
715
|
|
|
* @throws DbException |
716
|
|
|
* @throws DtaException |
717
|
|
|
*/ |
718
|
|
|
public function accessToken() |
719
|
|
|
{ |
720
|
|
|
return $this->getAccessToken(); |
721
|
|
|
} |
722
|
|
|
|
723
|
|
|
/** |
724
|
|
|
* 获取access_token信息 |
725
|
|
|
* @return array|bool|mixed|string|string[] |
726
|
|
|
* @throws DbException |
727
|
|
|
* @throws DtaException |
728
|
|
|
*/ |
729
|
|
|
private function getAccessToken() |
730
|
|
|
{ |
731
|
|
|
if (empty($this->cache) || empty($this->app_id) || empty($this->app_secret)) { |
732
|
|
|
$this->getConfig(); |
733
|
|
|
} |
734
|
|
|
if (empty($this->cache)) { |
735
|
|
|
throw new DtaException('请检查cache参数'); |
736
|
|
|
} |
737
|
|
|
if (empty($this->app_id)) { |
738
|
|
|
throw new DtaException('请检查app_id参数'); |
739
|
|
|
} |
740
|
|
|
if (empty($this->app_secret)) { |
741
|
|
|
throw new DtaException('请检查app_secret参数'); |
742
|
|
|
} |
743
|
|
|
$this->grant_type = "client_credential"; |
744
|
|
|
if ($this->cache === "file") { |
745
|
|
|
// 文件名 |
746
|
|
|
$file = "{$this->app->getRootPath()}runtime/{$this->app_id}_access_token.json"; |
747
|
|
|
// 获取数据 |
748
|
|
|
$accessToken = file_exists($file) ? json_decode(file_get_contents($file), true) : []; |
749
|
|
|
if (empty($accessToken) || !is_array($accessToken)) { |
750
|
|
|
$accessToken = [ |
751
|
|
|
'access_token' => '', |
752
|
|
|
'expires_in' => '', |
753
|
|
|
'expires_time' => '', |
754
|
|
|
]; |
755
|
|
|
} |
756
|
|
|
if (empty($accessToken['expires_time'])) { |
757
|
|
|
$accessToken_res = HttpService::instance() |
758
|
|
|
->url("https://api.weixin.qq.com/cgi-bin/token?grant_type={$this->grant_type}&appid={$this->app_id}&secret={$this->app_secret}") |
759
|
|
|
->toArray(); |
760
|
|
|
$accessToken_res['expires_time'] = time() + 6000; |
761
|
|
|
file_put_contents($file, json_encode($accessToken_res, JSON_UNESCAPED_UNICODE)); |
762
|
|
|
$accessToken = $accessToken_res; |
763
|
|
|
} else if (!isset($accessToken['access_token'])) { |
764
|
|
|
$accessToken_res = HttpService::instance() |
765
|
|
|
->url("https://api.weixin.qq.com/cgi-bin/token?grant_type={$this->grant_type}&appid={$this->app_id}&secret={$this->app_secret}") |
766
|
|
|
->toArray(); |
767
|
|
|
$accessToken_res['expires_time'] = time() + 6000; |
768
|
|
|
file_put_contents($file, json_encode($accessToken_res, JSON_UNESCAPED_UNICODE)); |
769
|
|
|
$accessToken = $accessToken_res; |
770
|
|
|
} else if ($accessToken['expires_time'] <= time()) { |
771
|
|
|
$accessToken_res = HttpService::instance() |
772
|
|
|
->url("https://api.weixin.qq.com/cgi-bin/token?grant_type={$this->grant_type}&appid={$this->app_id}&secret={$this->app_secret}") |
773
|
|
|
->toArray(); |
774
|
|
|
$accessToken_res['expires_time'] = time() + 6000; |
775
|
|
|
file_put_contents($file, json_encode($accessToken_res, JSON_UNESCAPED_UNICODE)); |
776
|
|
|
$accessToken = $accessToken_res; |
777
|
|
|
} |
778
|
|
|
return $accessToken; |
779
|
|
|
} |
780
|
|
|
|
781
|
|
|
if ($this->cache === "mysql") { |
782
|
|
|
$access_token = []; |
783
|
|
|
// 文件名 |
784
|
|
|
$file = "{$this->app_id}_access_token"; |
785
|
|
|
// 获取数据 |
786
|
|
|
$cache_mysql_value = dtacache($file); |
787
|
|
|
if (!empty($cache_mysql_value)) { |
788
|
|
|
$access_token['access_token'] = $cache_mysql_value; |
789
|
|
|
} else { |
790
|
|
|
$accessToken_res = HttpService::instance() |
791
|
|
|
->url("https://api.weixin.qq.com/cgi-bin/token?grant_type={$this->grant_type}&appid={$this->app_id}&secret={$this->app_secret}") |
792
|
|
|
->toArray(); |
793
|
|
|
dtacache($file, $accessToken_res['access_token'], 6000); |
794
|
|
|
$access_token['access_token'] = $accessToken_res['access_token']; |
795
|
|
|
} |
796
|
|
|
return $access_token; |
797
|
|
|
} |
798
|
|
|
|
799
|
|
|
throw new DtaException("驱动方式错误"); |
800
|
|
|
} |
801
|
|
|
} |
802
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.