2023-10-24 17:29:10 +08:00

415 lines
14 KiB
PHP

<?php
namespace Extend\Wechat;
use App\Constants\HttpEnumCode;
use App\Exception\BusinessException;
use App\Factory\CacheFactory;
use App\Factory\ProdRedisFactory;
use EasyWeChat\Kernel\Exceptions\BadResponseException;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\HttpClient\AccessTokenAwareClient;
use EasyWeChat\MiniApp\Application;
use Hyperf\Cache\Cache;
use Hyperf\Redis\Redis;
//use Hyperf\Utils\ApplicationContext;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\SimpleCache\CacheInterface;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Hyperf\Context\ApplicationContext;
use Hyperf\Guzzle\CoroutineHandler;
/**
* 微信类
*/
class Wechat
{
protected Application $app;
protected array $config;// 系统配置
/**
* @param string|int $user_type
*/
public function __construct(string|int $user_type)
{
if ($user_type == 1){
$this->config = config("we_chat.applets.patient");
}elseif ($user_type == 2){
$this->config = config("we_chat.applets.doctor");
}elseif ($user_type == 3){
$this->config = config("we_chat.applets.pharmacist");
}
if (empty($this->config)){
throw new BusinessException("系统配置错误", HttpEnumCode::SERVER_ERROR);
}
}
/**
* 获取wechat类
* @param string $appId
* @param string $appSecret
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function createApp(string $appId, string $appSecret): void
{
$config = array(
"app_id" => $appId,
"secret" => $appSecret,
"use_stable_access_token" => true,
"http" => [
'throw' => false, // 状态码非 200、300 时是否抛出异常,默认为开启
'timeout' => 5.0,
// 'base_uri' => 'https://api.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用,根据不同的模块配置不同的 uri
'retry' => true, // 使用默认重试配置
]
);
try {
// 获取WeChat客户端
$this->app = new Application($config);
// 替换缓存
$this->app->setCache(ApplicationContext::getContainer()->get(CacheInterface::class));
} catch (InvalidArgumentException $e) {
throw new BusinessException('实例化EasyWeChat类失败:' . $e->getMessage(), HttpEnumCode::SERVER_ERROR);
}
}
/**
* 获取wechat客户端
* @param string $appId
* @param string $appSecret
* @return AccessTokenAwareClient
*/
public function createClient(string $appId, string $appSecret): AccessTokenAwareClient
{
try {
// 获取WeChat客户端
$this->createApp($appId, $appSecret);
return $this->app->getClient();
} catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) {
throw new BusinessException('实例化EasyWeChat类失败:' . $e->getMessage(), HttpEnumCode::SERVER_ERROR);
}
}
/**
* 根据 jsCode 获取用户 session 信息
* @param string $code code
* @return array
* @throws ClientExceptionInterface
* @throws ContainerExceptionInterface
* @throws DecodingExceptionInterface
* @throws NotFoundExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
public function codeToSession(string $code): array
{
try {
$this->createApp($this->config['app_id'],$this->config['secret']);
$utils = $this->app->getUtils();
return $utils->codeToSession($code);
} catch (\Exception $e) {
throw new BusinessException($e->getMessage(), HttpEnumCode::SERVER_ERROR);
}
}
/**
* 解密微信会话信息
* @param string $sessionKey 会话密钥
* @param string $iv 加密算法的初始向量
* @param string $encryptedData 用户信息的加密数据
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function decryptSession(string $sessionKey, string $iv, string $encryptedData): array
{
try {
$this->createApp($this->config['app_id'],$this->config['secret']);
$utils = $this->app->getUtils();
return $utils->decryptSession($sessionKey, $iv, $encryptedData);
} catch (\Exception $e) {
throw new BusinessException($e->getMessage(), HttpEnumCode::SERVER_ERROR);
}
}
/**
* 获取 access_token
* @return string
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getAccessToken(): string
{
try {
$this->createApp($this->config['app_id'],$this->config['secret']);
$accessToken = $this->app->getAccessToken();
return $accessToken->getToken();
} catch (\Exception $e) {
throw new BusinessException($e->getMessage(), HttpEnumCode::SERVER_ERROR);
}
}
/**
* 获取手机号
* @param string $code
* @return array
* @throws ClientExceptionInterface
* @throws DecodingExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface|BadResponseException
*/
public function getPhone(string $code): array
{
try {
$this->createApp($this->config['app_id'],$this->config['secret']);
$client = $this->createClient($this->config['app_id'],$this->config['secret']);
$options = [
"code" => $code,
];
$response = $client->postJson('wxa/business/getuserphonenumber', $options);
if ($response->isFailed()) {
// 出错了,处理异常
$result = $response->toArray();
if(empty($result)){
// 返回值为空
return [];
}
dump($result);
if (isset($result['errcode'])){
if ($result['errcode'] == "40029"){
// code过期
return [];
// throw new BusinessException( HttpEnumCode::getMessage(HttpEnumCode::GET_WX_ERROR),HttpEnumCode::GET_WX_ERROR);
}
}
return [];
}
return $response->toArray(false);
} catch (\Exception $e) {
throw new BusinessException($e->getMessage(), HttpEnumCode::SERVER_ERROR);
}
}
/**
* 获取分享二维码
* @throws NotFoundExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ContainerExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
*/
public function getUnlimitedQRCode(array $options): array|string
{
try {
$this->createApp($this->config['app_id'], $this->config['secret']);
$client = $this->createClient($this->config['app_id'], $this->config['secret']);
$response = $client->postJson('wxa/getwxacodeunlimit', $options);
if ($response->isFailed()) {
// 出错了,处理异常
$result = $response->toArray();
dump($result);
if(empty($result)){
// 返回值为空
return [];
}
if (isset($result['errcode'])){
throw new BusinessException();
}
return [];
}
return $response->getContent(true);
} catch (\Exception $e) {
throw new BusinessException($e->getMessage(), HttpEnumCode::SERVER_ERROR);
}
}
/**
* 获取当前账号下订阅消息个人模版列表
* @return array|string
* @throws ClientExceptionInterface
* @throws ContainerExceptionInterface
* @throws DecodingExceptionInterface
* @throws NotFoundExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
public function getTemplate(): array|string
{
try {
$this->createApp($this->config['app_id'], $this->config['secret']);
$client = $this->createClient($this->config['app_id'], $this->config['secret']);
$options = [];
$response = $client->get('wxaapi/newtmpl/gettemplate', $options);
if ($response->isFailed()) {
// 出错了,处理异常
$result = $response->toArray();
if(empty($result)){
// 返回值为空
return [];
}
if (isset($result['errcode'])){
throw new BusinessException();
}
return [];
}
return $response->getContent(false);
} catch (\Exception $e) {
throw new BusinessException($e->getMessage(), HttpEnumCode::SERVER_ERROR);
}
}
/**
* 发送订阅消息
* @throws NotFoundExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ContainerExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
*/
public function sendSubscribeMessage(array $options): array|string
{
try {
$this->createApp($this->config['app_id'], $this->config['secret']);
$client = $this->createClient($this->config['app_id'], $this->config['secret']);
$response = $client->postJson('cgi-bin/message/subscribe/send', $options);
if ($response->isFailed()) {
// 出错了,处理异常
$result = $response->toArray();
if(empty($result)){
// 返回值为空
throw new BusinessException("返回值为空");
}
if (isset($result['errcode'])){
if ($result['errcode'] == 43101){
// 用户拒绝接收消息
return $result;
}
throw new BusinessException($result['errmsg']);
}
throw new BusinessException();
}
return $response->toArray();
} catch (\Exception $e) {
throw new BusinessException($e->getMessage(), HttpEnumCode::SERVER_ERROR);
}
}
/**
* 生成UrlLink
* @throws NotFoundExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ContainerExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
*/
public function createUrlLink(array $options): array|string
{
try {
$this->createApp($this->config['app_id'], $this->config['secret']);
$client = $this->createClient($this->config['app_id'], $this->config['secret']);
$response = $client->postJson('wxa/generate_urllink', $options);
if ($response->isFailed()) {
// 出错了,处理异常
$result = $response->toArray();
if(empty($result)){
// 返回值为空
throw new BusinessException("返回值为空");
}
if (isset($result['errcode'])){
throw new BusinessException($result['errmsg']);
}
throw new BusinessException();
}
return $response->toArray();
} catch (\Exception $e) {
throw new BusinessException($e->getMessage(), HttpEnumCode::SERVER_ERROR);
}
}
/**
* 获取UrlLink
* @throws NotFoundExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ContainerExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
*/
public function getUrlLink(array $options): array|string
{
try {
$this->createApp($this->config['app_id'], $this->config['secret']);
$client = $this->createClient($this->config['app_id'], $this->config['secret']);
$response = $client->postJson('wxa/query_urllink', $options);
if ($response->isFailed()) {
// 出错了,处理异常
$result = $response->toArray();
if(empty($result)){
// 返回值为空
throw new BusinessException("返回值为空");
}
if (isset($result['errcode'])){
throw new BusinessException($result['errmsg']);
}
throw new BusinessException();
}
return $response->toArray();
} catch (\Exception $e) {
throw new BusinessException($e->getMessage(), HttpEnumCode::SERVER_ERROR);
}
}
}