luck-draw/app/service/wx/WechatApplets.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'] ?? '');
}
}