112 lines
3.5 KiB
PHP
112 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace app\service\wx;
|
|
|
|
use EasyWeChat\Factory;
|
|
use EasyWeChat\Kernel\Exceptions\HttpException;
|
|
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
|
|
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
|
|
use EasyWeChat\Kernel\Exceptions\RuntimeException;
|
|
use EasyWeChat\MiniProgram\Application;
|
|
use Exception;
|
|
use GuzzleHttp\Client;
|
|
use GuzzleHttp\Exception\GuzzleException;
|
|
use think\facade\Config;
|
|
use think\facade\Log;
|
|
|
|
/**
|
|
* 微信小程序
|
|
* Class WechatApplets
|
|
* @package app\service\wx
|
|
*/
|
|
class WechatApplets
|
|
{
|
|
private static $app = null;
|
|
|
|
/**
|
|
* TODO 正式上线时需要替换模板配置信息和相关小程序配置信息
|
|
*/
|
|
// 订阅消息模板:预约通知
|
|
public const SUBSCRIBE_TPL_APPOINTMENT = 'uvGd7RqaegheGU-uVxR-uM3y2MadZeMOHdQaNiiWm8U';
|
|
|
|
private function __construct()
|
|
{
|
|
}
|
|
|
|
private function __clone()
|
|
{
|
|
}
|
|
|
|
//微信小程序实例 单例模式
|
|
public static function getInstance(): ?Application
|
|
{
|
|
if (self::$app == null) {
|
|
Config::load('extra/wechat', 'wechat');
|
|
$conf = config('wechat');
|
|
$config = [
|
|
// 必要配置
|
|
'app_id' => $conf['applets_appId'],
|
|
'secret' => $conf['applets_appSecret'],
|
|
// 返回数据类型 array | xml
|
|
'response_type' => 'array',
|
|
];
|
|
self::$app = Factory::miniProgram($config);
|
|
}
|
|
return self::$app;
|
|
}
|
|
|
|
/**
|
|
* 生成微信小程序链接
|
|
*
|
|
* @param string $path
|
|
* @param string $sourceCode
|
|
* @param bool $tokenRefresh 是否强制刷新access_token 默认false 非特殊条件请勿设为true
|
|
* @return string
|
|
* @throws GuzzleException
|
|
* @throws HttpException
|
|
* @throws InvalidArgumentException
|
|
* @throws InvalidConfigException
|
|
* @throws RuntimeException
|
|
* @throws \Psr\SimpleCache\InvalidArgumentException
|
|
*/
|
|
public static function generateActivityUrl(string $path, string $sourceCode, bool $tokenRefresh = false): string
|
|
{
|
|
$accessToken = self::getInstance()->access_token;
|
|
|
|
$client = new Client();
|
|
|
|
$url = 'https://api.weixin.qq.com/wxa/generate_urllink?access_token=';
|
|
|
|
$params = [];
|
|
$query = '';
|
|
$params['path'] = 'pages/tabbar/pagehome/pagehome';//首页路径
|
|
if (!empty($path)) {
|
|
$pathArr = explode('?', $path);
|
|
$query = isset($pathArr[1]) ? $pathArr[1].'&' : '';
|
|
$params['path'] = $pathArr[0];
|
|
}
|
|
|
|
$params['query'] = $query.'channel=activity&source_code='.$sourceCode;
|
|
$jsonStr = !empty($params) ? json_encode($params, JSON_UNESCAPED_UNICODE) : '';
|
|
|
|
Log::info('【小程序链接生成请求参数】'.$jsonStr);
|
|
|
|
$response = $client->request('POST', $url.($accessToken->getToken($tokenRefresh)['access_token'] ?? ''), [
|
|
'body' => $jsonStr
|
|
]);
|
|
|
|
$res = json_decode($response->getBody(), true);
|
|
Log::info('【小程序链接生成响应】'.json_encode($res, JSON_UNESCAPED_UNICODE));
|
|
if ($res['errcode'] == 0) {
|
|
return $res['url_link'] ?? '';
|
|
}
|
|
|
|
if ($res['errcode'] == 40001 && $tokenRefresh == false) {
|
|
// 可能是token过期 刷新一次
|
|
// tokenRefresh 防止无限循环
|
|
return self::generateActivityUrl($path, $sourceCode, true);
|
|
}
|
|
|
|
throw new Exception('链接生成失败 '.$res['errmsg'] ?? '');
|
|
}
|
|
} |