ufutx.dma/app/Services/WechatService.php
2026-03-04 14:42:40 +08:00

1071 lines
39 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Services;
use App\Http\Response\CatchError;
use App\Models\ESTP\User as EstpUser;
use App\Models\User;
use App\Models\Wechat;
use EasyWeChat\Kernel\Support\Str;
use EasyWeChat\MiniApp\Application;
use EasyWeChat\Work\Application as WorkApplication;
use EasyWeChat\OfficialAccount\Application as OfficialApplication;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Facades\UploadService;
use Symfony\Component\Cache\Psr16Cache;
use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Formatter;
use WeChatPay\Util\PemUtil;
class WechatService
{
use CatchError;
protected $app, $official_app, $official_access_token, $mp_access_token;
public function __construct()
{
//小程序
$config = config('wechat.mini_program');
$app = new Application($config);
$this->app = $app;
//公众号
$config = config('wechat.official_account.default');
$official_app = new OfficialApplication($config);
// $app->setCache(new Psr16Cache(app('cache.psr6')));
// $access_token_key = "mp_access_token";
// Log::info("当前access_token: {$app->getAccessToken()->getToken()}");
// if (config('app.env') == 'production') {
// if (Cache::has($access_token_key)) {
// $this->mp_access_token = Cache::get($access_token_key);
// }else {
// $app->getAccessToken()->refresh();
// $this->mp_access_token = $app->getAccessToken()->getToken();
// Cache::put($access_token_key, $this->mp_access_token, now()->addMinutes(90));
// }
// }
// Log::info("缓存access_token: {$this->mp_access_token}");
// $official_app->setCache(new Psr16Cache(app('cache.psr6')));
// $app->setCache(new Psr16Cache(app('cache.psr6')));
// $access_token_key = "official_access_token";
// Log::info("当前access_token: {$official_app->getAccessToken()->getToken()}");
// if (config('app.env') == 'production') {
// if (Cache::has($access_token_key)) {
// $this->official_access_token = Cache::get($access_token_key);
// }else {
// $official_app->getAccessToken()->refresh();
// $this->official_access_token = $official_app->getAccessToken()->getToken();
// Cache::put($access_token_key, $this->official_access_token, now()->addMinutes(90));
// }
// }
// Log::info("缓存access_token: {$this->official_access_token}");
$this->official_app = $official_app;
}
public function instance()
{
//商户号
$merchantId = config('wechat.payment.mch_id');
// 从本地文件中加载「商户API私钥」「商户API私钥」会用来生成请求的签名
$merchantPrivateKeyFilePath = 'file://' . config('wechat.payment.private_key');
$merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
// 「商户API证书」的「证书序列号」
$merchantCertificateSerial = config('wechat.payment.serial');
// 从本地文件中加载「微信支付平台证书」,用来验证微信支付应答的签名
$platformCertificateFilePath = 'file://' . config('wechat.payment.certificate');
$platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
// 从「微信支付平台证书」中获取「证书序列号」
$platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateFilePath);
// 构造一个 APIv3 客户端实例
$instance = Builder::factory([
'mchid' => $merchantId,
'serial' => $merchantCertificateSerial,
'privateKey' => $merchantPrivateKeyInstance,
'certs' => [
$platformCertificateSerial => $platformPublicKeyInstance,
],
]);
return $instance;
}
public function app()
{
return $this->app;
}
/**
* 公众号
* @return \EasyWeChat\OfficialAccount\Application
*/
public function officialApp()
{
return $this->official_app;
}
/**
* 企业微信
* @return WorkApplication
*/
public function workApp($type)
{
$work_config = config('wechat.' . $type);
$work_app = new WorkApplication($work_config);
return $work_app;
}
/**
* 小程序code 换取session 信息
* @param $code
* @param string $grant_type
* @return array
* @throws \Exception
*/
public function codeToSession($code, $grant_type = 'authorization_code')
{
try {
$utils = $this->app->getUtils();
$response = $utils->codeToSession($code);
return $response;
} catch (\Throwable $e) {
throw new \Exception($e->getMessage());
}
}
/**
* 小程序code换取手机号信息
* @param $code
* @return array|string[]
* @throws \Exception
*/
public function phoneNuber($code)
{
try {
if (env('APP_ENV') == 'local')
return ['mobile' => '15872844805'];
$data = ['code' => (string) $code];
$res = $this->app->getClient()->postJson('wxa/business/getuserphonenumber', $data);
if ($res->isFailed())
throw new \Exception($res->getContent());
$r = json_decode($res->toJson());
return ['mobile' => $r->phone_info->phoneNumber];
} catch (\Throwable $e) {
throw new \Exception($e->getMessage());
}
}
/**
* 小程序订阅消息列表
* @return mixed|null
* @throws \Exception
*/
public function templates()
{
try {
$res = $this->app->getClient()->get('wxaapi/newtmpl/gettemplate');
if ($res->isFailed())
throw new \Exception($res->getContent());
return $res['data'] ?? null;
} catch (\Throwable $e) {
throw new \Exception($e->getMessage());
}
}
/**
* 小程序发送订阅消息
* @param $openid
* @param $template_id
* @param $page
* @param array $data
* @return bool|int|mixed
*/
public function subSend($openid, $template_id, $page, $data = [])
{
try {
if (empty($openid))
return false;
$all_data = [
'template_id' => $template_id,
'touser' => $openid,
'page' => $page,
'data' => $data,
'miniprogram_state' => (env('APP_ENV') == 'production') ? 'formal' : 'developer',
'lang' => 'zh_CN',
];
$client = $this->app->getClient();
$response = $client->postJson('cgi-bin/message/subscribe/send', $all_data);
$all_data['type'] = 'mp';
if ($response['errcode']) {
$all_data['err_msg'] = $response['errmsg'];
$all_data['status'] = 0;
} else {
$all_data['err_msg'] = '';
$all_data['status'] = 1;
}
// $this->addTemplateMsgLog($all_data);
return $response['errcode'] ?? 1;
} catch (\Throwable $e) {
$this->getError($e);
return true;
}
}
// public function addTemplateMsgLog($data)
// {
// $where = $data['type'] == 'mp'?['openid'=>$data['touser']]:['official_openid'=>$data['touser']];
// $user_id = Wechat::where($where)->value('user_id');
// $log = new TemplateMsgLog;
// $log->user_id = $user_id;
// $log->openid = $data['touser'];
// $log->type = $data['type'];
// $log->template_id = $data['template_id'];
// $log->status = $data['status'];
// $log->err_msg = $data['err_msg']??'';
// $log->data = json_encode($data);
// $log->save();
// return true;
// }
/**
* 获取小程序二维码
* @param $scene
* @param $page
* @param string $env_version 正式版为 "release",体验版为 "trial",开发版为 "develop"。默认是正式版。
* @param int $width
* @param bool $is_hyaline
* @return string
* @throws \EasyWeChat\Kernel\Exceptions\BadResponseException
* @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
*/
public function getMPQrcode($scene, $page, $env_version = 'release', $width = 430, $is_hyaline = true)
{
$app = $this->app;
$response = $app->getClient()->postJson('/wxa/getwxacodeunlimit', [
'scene' => $scene,
'page' => $page,
'width' => $width,
'is_hyaline' => $is_hyaline,
'env_version' => $env_version,
'check_path' => false
]);
$file_name = uniqid() . time() . 'qrcode.png';
$path = storage_path('qrcode/' . $file_name);
$response->saveAs($path);
$pic = '';
if (file_exists($path)) {
$pic = UploadService::uploadFile($path);
@unlink($path);
}
return $pic;
}
/**
* 小程序支付
* @param $trade_no
* @param $openid
* @param $total
* @param $desc
* @param $callback
* @return array|false
*/
public function mpPay($trade_no, $openid, $total, $desc, $callback, $appId = '', $sub_mchid = '')
{
if (config('wechat.payment.debug')) {
return false;
}
$sub_appid = config('wechat.payment.sub_app_id');
if ($appId) {
$sub_appid = $appId;
}
$resp = $this->instance()
->chain('v3/pay/partner/transactions/jsapi')
->post([
'json' => [
'sp_mchid' => config('wechat.payment.mch_id'),
'sp_appid' => config('wechat.payment.sp_appid'),
'sub_appid' => $sub_appid,
'sub_mchid' => $sub_mchid ?: config('wechat.payment.sub_merchant_id'),
'out_trade_no' => $trade_no,
'description' => $desc,
'notify_url' => $callback,
'amount' => [
'total' => (int) number_format($total * 100, 0, '', ''),
'currency' => 'CNY'
],
'payer' => [
'sub_openid' => $openid,
]
]
]);
$res = json_decode($resp->getBody());
$prepay_id = $res->prepay_id;
$config = $this->paySign($prepay_id, $sub_appid);
$config['prepay_id'] = $prepay_id;
return $config;
}
/**
* 获取jssdk配置
* @param $url
* @return mixed[]
* @throws \EasyWeChat\Kernel\Exceptions\HttpException
* @throws \Psr\SimpleCache\InvalidArgumentException
* @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
*/
// public function getOfficialShareConfig($url){
// $app = $this->officialApp();
// $config = $app->getUtils()->buildJsSdkConfig($url, ['updateAppMessageShareData','updateTimelineShareData','onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone', 'openLocation', 'getLocation', 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage', 'openAddress', 'updateAppMessageShareData', 'updateTimelineShareData', 'wx-open-launch-weapp', 'chooseVideo', 'hideMenuItems','showMenuItems'], ['wx-open-launch-weapp'], false);
// return $config;
// }
public function buildJsSdkConfig($url)
{
// $app = $this->officialApp();
// $api = $app->getClient();
$token_url = config('app.url') . '/go/api/h5/v1/common/accesstoken/get';
$params = ['curr_date' => "#" . date("Y-m-d") . "@-"];
try {
$res = \App\Facades\HttpService::postData($token_url, $params);
$access_token = $res['data'];
} catch (\Exception $e) {
$access_token = '';
}
// $res = $api->get("cgi-bin/ticket/getticket?access_token=$access_token&type=jsapi");
// if ($res->isFailed()) {
//
// }
// $res = json_decode($res->toJson(),true);
$ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" . $access_token . "&type=jsapi";
$res = \App\Facades\HttpService::getData($ticket_url);
Log::info("获取微信ticket cgi-bin/ticket/getticket?access_token=$access_token&type=jsapi");
Log::info($res);
$ticket = $res['ticket'];
$nonce = Str::random();
$timestamp = time();
$signature = sha1("jsapi_ticket=$ticket&noncestr=$nonce&timestamp=$timestamp&url=$url");
$jsApiList = ['updateAppMessageShareData', 'updateTimelineShareData', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone', 'openLocation', 'getLocation', 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage', 'openAddress', 'updateAppMessageShareData', 'updateTimelineShareData', 'wx-open-launch-weapp', 'chooseVideo', 'hideMenuItems', 'showMenuItems'];
$openTagList = ['wx-open-launch-weapp'];
return [
'appId' => config('wechat.official_account.default.app_id'),
'beta' => false,
'debug' => false,
'jsApiList' => $jsApiList,
'nonceStr' => $nonce,
'openTagList' => $openTagList,
'signature' => $signature,
'timestamp' => $timestamp,
'url' => $url,
];
}
/**
* 退款
* @param $trade_no
* @param $refund_trade_no
* @param $total_amount
* @param $refund_amount
* @param array $array
* @return array
*/
public function refund($trade_no, $refund_trade_no, $total_amount, $refund_amount, $callback, $sub_mchid = '')
{
if (config('wechat.payment.debug')) {
return ["status" => true, 'msg' => ''];
}
if (!$sub_mchid) {
$sub_mchid = config('wechat.payment.sub_merchant_id');
}
try {
$resp = $this->instance()
->chain('v3/refund/domestic/refunds')
->post([
'json' => [
'sub_mchid' => $sub_mchid,
'out_trade_no' => $trade_no,
'out_refund_no' => $refund_trade_no,
'notify_url' => $callback,
'amount' => [
'total' => (int) number_format($total_amount * 100, 0, '', ''),
'refund' => (int) number_format($refund_amount * 100, 0, '', ''),
'currency' => 'CNY'
],
]
]);
$res = json_decode($resp->getBody());
Log::info($resp->getBody());
if ($res->status == 'PROCESSING' || $res->status == "SUCCESS") {
return ['status' => true, 'msg' => ''];
}
return ['status' => false, 'msg' => '打款失败'];
} catch (\Exception $e) {
$msg = $e->getMessage();
Log::info($msg);
return ['status' => false, 'msg' => $msg];
}
}
/**
* 退款订单查询
* @param string $refund_trade_no 退款订单号
*/
public function orderRefunded($refund_trade_no, $sub_mch_id = null)
{
if (config('wechat.payment.debug')) {
return ['status' => true, 'message' => ""];
}
try {
if (!$sub_mch_id) {
$sub_mch_id = config('wechat.payment.sub_merchant_id');
}
$resp = $this->instance()
->chain('v3/refund/domestic/refunds/' . $refund_trade_no)
->get([
'query' => [
'sub_mchid' => $sub_mch_id
],
'out_refund_no' => $refund_trade_no,
]);
$res = json_decode($resp->getBody());
if ($res->status == 'SUCCESS') {
return ['status' => true, 'message' => ""];
}
return ['status' => false, 'message' => "退款失败"];
} catch (\Exception $e) {
Log::debug($refund_trade_no . '订单查询退款异常:' . $e->getMessage());
return ['status' => false, 'message' => $e->getMessage()];
}
}
/**
* 小程序-查询订单是否支付
* @param $trade_no
* @return bool
*/
public function mpPaid($trade_no, $sub_mch_id = '')
{
if (config('wechat.payment.debug')) {
return false;
}
if (empty($sub_mch_id)) {
$sub_mch_id = config('wechat.payment.sub_merchant_id');
}
$resp = $this->instance()
->chain('v3/pay/partner/transactions/out-trade-no/' . $trade_no)
->get([
// Query 参数
'query' => [
'sp_mchid' => config('wechat.payment.mch_id'),
'sub_mchid' => $sub_mch_id,
],
// 变量名 => 变量值
'out_trade_no' => $trade_no,
]);
Log::info($resp->getBody());
$res = json_decode($resp->getBody());
if (empty($res))
return true;
if ($res->trade_state == 'NOTPAY' || $res->trade_state == "CLOSED")
return $res->trade_state_desc;
return false;
}
/**
* 小程序-支付签名
* @param $prepay_id
* @return array
*/
public function paySign($prepay_id, $sub_appid)
{
$merchantPrivateKeyFilePath = 'file://' . config('wechat.payment.private_key');
$merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath);
$params = [
// 'appId' => config('wechat.mini_program.app_id'),
'appId' => $sub_appid,
'timeStamp' => (string) Formatter::timestamp(),
'nonceStr' => Formatter::nonce(),
'package' => 'prepay_id=' . $prepay_id,
];
$params += [
'paySign' => Rsa::sign(
Formatter::joinedByLineFeed(...array_values($params)),
$merchantPrivateKeyInstance
),
'signType' => 'RSA'
];
return $params;
}
public function sendSubscribeMessage($params)
{
if (config('app.env') == 'production') {
$app = $this->app;
// $accessToken = $app->getAccessToken();
// $accessToken->getToken();
$response = $app->getClient()->postJson('cgi-bin/message/subscribe/send', $params);
// if ($response['errcode'] && $response['errcode'] != "43101") {
Log::info($params);
//todo 发送失败
// throw new \Exception($response['errmsg']);
// }
}
}
/**
* 公众号-后台服务
* @return \Psr\Http\Message\ResponseInterface
* @throws \EasyWeChat\Kernel\Exceptions\BadRequestException
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
* @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
* @throws \ReflectionException
* @throws \Throwable
*/
public function server()
{
$app = $this->officialApp();
$server = $app->getServer();
$server->with(function ($message, \Closure $next) {
Log::info("api server");
// 你的自定义逻辑
// Log::info($message);
$openid = $message->FromUserName;
//获取微信用户信息
$info = $this->wechatUserByOfficialOpenid($openid);
Log::info($openid . '用户信息', $info);
if ($message->MsgType == 'event') {
if ($message->Event == 'subscribe' || $message->Event == 'unsubscribe') {//关注
//同步健康信息
$this->syncSubscribe($info);
}
}
//同步创业家项目关注信息
// $this->syncEstpSubscribe($info);
return $next($message);
});
return $server->serve();
}
/**
* 同步公众号关注
* @param $info
*/
public function syncSubscribe($info)
{
$subscribe = $info['subscribe'];
if ($subscribe) {
//是否有本地小程序信息信息
$wechat = Wechat::where(['unionid' => $info['unionid'], 'type' => 'mp'])->first();
// if (empty($wechat)) return ;
DB::beginTransaction();
//是否有本地公众号信息信息
$official_wechat = Wechat::where('type', 'official')
->where('openid', $info['openid'])
->first();
if (empty($official_wechat))
return;
// if (!empty($wechat)){
// $official_wechat->user_id = $wechat->user_id;
// }
$official_wechat->unionid = $info['unionid'];
$official_wechat->save();
} else {
$official_wechat = Wechat::where(['openid' => $info['openid'], 'type' => 'official'])->first();
if (empty($official_wechat))
return;
}
//同步关注信息
User::where('id', $official_wechat->user_id)->update(['is_subscribe' => $subscribe]);
DB::commit();
}
/**
* 同步创业家项目关注
* @param $info
*/
public function syncEstpSubscribe($info)
{
$subscribe = $info['subscribe'];
if ($subscribe) {
//关注
$user = EstpUser::query()->where('unionid', $info['unionid'])->first();
if ($user) {
$user['is_subscribe'] = $subscribe;
$user['openid'] = $info['openid'];
$user->save();
}
} else {
//取关
$user = EstpUser::query()->where('openid', $info['openid'])->first();
if ($user) {
$user['is_subscribe'] = $subscribe;
$user['open_recommend'] = $subscribe;
$user->save();
}
}
if ($user) {
Log::info([
'msg' => '已更新创业家' . ['取关', '关注'][$subscribe] . '信息',
'data' => $user->toArray(),
]);
}
}
/**
* 公众号-通过openid获取用户信息
* @param $openid
* @return mixed
* @throws \EasyWeChat\Kernel\Exceptions\BadResponseException
* @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
*/
public function wechatUserByOfficialOpenid($openid)
{
// $app = $this->officialApp();
// $api = $app->getClient();
//处理token过期报错
// $accessToken = $this->official_access_token;
// $accessToken = $app->getAccessToken()->getToken();
$url = config('app.url') . '/go/api/h5/v1/common/accesstoken/get';
$params = ['curr_date' => "#" . date("Y-m-d") . "@-"];
try {
$res = \App\Facades\HttpService::postData($url, $params);
$access_token = $res['data'];
} catch (\Exception $e) {
$access_token = '';
}
$url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=$access_token&openid=$openid";
$res = \App\Facades\HttpService::getData($url);
return $res;
// $response = $api->get('/cgi-bin/user/info', [
// "openid" => $openid,
// "access_token" => $access_token,
// ]);
// if ($response->isFailed()) {
// throw new \Exception("通过openid获取用户微信信息失败, ".$response->getContent());
// }
// $content = $response->toJson();
// return json_decode($content,true);
}
/**
* 公众号-发送模板消息
* @param $param
* @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
*/
public function sendTemplateNotice($param)
{
if (config('app.env') == 'production') {
// $app = $this->officialApp();
// $api = $app->getClient();
// $accessToken = $app->getAccessToken()->getToken();
// $accessToken = $this->official_access_token;
$url = config('app.url') . '/go/api/h5/v1/common/accesstoken/get';
$params = ['curr_date' => "#" . date("Y-m-d") . "@-"];
try {
$res = \App\Facades\HttpService::postData($url, $params);
$access_token = $res['data'];
} catch (\Exception $e) {
$access_token = '';
}
$url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" . $access_token;
$res = \App\Facades\HttpService::postData($url, $param);
// $response = $api->postJson('/cgi-bin/message/template/send?access_token=' . $access_token, $param);
// if ($response->isFailed()) {
// $errMsg = $response->toJson();
// $errMsg = json_decode($errMsg,true);
// if (isset($errMsg['errcode']) && $errMsg['errcode'] == 40001) {
// $app->getAccessToken()->refresh();
// $newResponse = $api->postJson('/cgi-bin/message/template/send', $param);
// Log::error("sendTemplateNotice1".$newResponse->getContent());
// throw new \Exception("发送模板消息失败, ".$response->getContent());
// }
// Log::error("sendTemplateNotice" . $response->getContent());
// }
}
}
/**
* 获取公众号二维码
* @param $param
* @return mixed
* @throws \EasyWeChat\Kernel\Exceptions\BadResponseException
* @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
*/
public function getOfficialQrcode($param)
{
// $app = $this->officialApp();
// $api = $app->getClient();
// $accessToken = $this->official_access_token;
$url = config('app.url') . '/go/api/h5/v1/common/accesstoken/get';
$params = ['curr_date' => "#" . date("Y-m-d") . "@-"];
try {
$res = \App\Facades\HttpService::postData($url, $params);
$access_token = $res['data'];
} catch (\Exception $e) {
$access_token = '';
}
$url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" . $access_token;
$res = \App\Facades\HttpService::postData($url, $param);
return $res;
// $response = $api->postJson('/cgi-bin/qrcode/create?access_token=' . $access_token, $param);
// $content = $response->toJson();
// return json_decode($content,true);
}
/**
* 发送群消息
* @param $touser
* @param $msgtype
* @param $content
* @param string $toparty
* @param string $totag
* @param int $enable_duplicate_check
* @param int $duplicate_check_interval
* @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
*/
public function sendWorkMessage($touser, $msgtype, $content, $toparty = '', $totag = '', $enable_duplicate_check = 0, $duplicate_check_interval = 1800)
{
$api = $this->workApp('work_application')->getClient();
$params = [
"touser" => $touser,
'toparty' => $toparty,
'totag' => $totag,
"msgtype" => $msgtype,
"agentid" => 1000008,
"safe" => 0,
$msgtype => $content,
"enable_duplicate_check" => $enable_duplicate_check,
"duplicate_check_interval" => $duplicate_check_interval
];
$response = $api->postJson('/cgi-bin/message/send', $params);
if ($response->isFailed()) {
// 出错了,处理异常
throw new \Exception($response->getContent());
}
}
/**
* 发送应用消息
* @param $chatid
* @param $msgtype
* @param $content
* @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
*/
public function sendAppChat($chatid, $msgtype, $content)
{
$api = $this->workApp('work_application')->getClient();
// $access_token = $this->workApp()->getAccessToken()->getToken();
// dd($access_token);
$params = [
'chatid' => $chatid,
'msgtype' => $msgtype,
'content' => $content,
'safe' => 0
];
$response = $api->postJson("/cgi-bin/appchat/send", $params);
if ($response->isFailed()) {
// 出错了,处理异常
throw new \Exception($response->getContent());
}
// dd($response->getContent());
}
/**
* 微信公众号授权-获取code
* @param $redirect_uri
* @return string|void
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
*/
public function connectAuth($redirect_uri) //snsapi_userinfo
{
$app = $this->officialApp();
$oauth = $app->getOauth();
$wechat_user = session('wechat_user');
$openid = $wechat_user['id'] ?? null;
if (empty($openid)) {
session(['intend_url' => $redirect_uri]);
// Log::info($redirect_uri);
//生成完整的授权URL
$redirectUrl = $oauth->redirect($redirect_uri);
// Log::info($redirectUrl);
return $redirectUrl;
}
}
/**
* 微信公众号授权-获取维信息
* @param $code
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Session\SessionManager|\Illuminate\Session\Store|mixed|string
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
*/
public function connectAuthByCode($code)
{
// Log::info("wechat code: ". $code);
try {
$app = $this->officialApp();
$oauth = $app->getOauth();
$user = $oauth->userFromCode($code);
session(['wechat_user' => $user->toArray()]);
$targetUrl = session('intend_url') ?: '/';
return $targetUrl;
} catch (\Exception $e) {
// 获取异常错误信息
$errorMessage = $e->getMessage();
// 进行错误处理,例如记录日志或返回给前端
Log::error("connectAuthByCode error: " . $errorMessage);
}
}
public function connectWorkAuthByCode($code, $config = 'work_application')
{
Log::info("wechat code: " . $code);
$app = $this->workApp($config);
Log::info("缓存测试 " . $code);
$user = $app->getOAuth()->detailed()->userFromCode($code);
// $user = $oauth->userFromCode($code);
// Log::info($user->toArray());
//缓存用户信息
Log::info("缓存用户信息");
// Log::info($user->toArray());
session(['work_wechat_user' => $user->toArray()]);
$targetUrl = session('intend_url') ?: '/';
return $targetUrl;
}
public function connectWorkAuth($redirect_uri, $config = 'work_application') //snsapi_userinfo
{
Log::info("connectWorkAuth " . $redirect_uri);
session(['intend_url' => $redirect_uri]);
$app = $this->workApp($config);
$redirect_uri = $app->getOAuth()->redirect($redirect_uri);
return $redirect_uri;
}
/**
* 获取企业微信jsSDK
* @param $url
* @param $type
* @return array|mixed[]
* @throws \EasyWeChat\Kernel\Exceptions\HttpException
* @throws \Psr\SimpleCache\InvalidArgumentException
* @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
*/
public function workJsSdkConfig($url, $type)
{
$config = [];
if ($type == 'work') {
$utils = $this->workApp('work')->getUtils();
$config = $utils->buildJsSdkConfig(
$url,
[],
[],
false,
);
// $config['jsapi_ticket'] = $this->workApp('work')->getTicket()->getTicket();
} elseif ($type == 'app') {
$utils = $this->workApp('work_application')->getUtils();
$config = $utils->buildJsSdkAgentConfig(
config('wechat.work_application.agent_id'),
$url,
[],
[],
false,
);
// $config['jsapi_ticket'] = $this->workApp('work_application')->getTicket()->getAgentTicket(1000003);
}
return $config;
}
public function groupChats($cursor = '', $limit = 15, $status_filter = 0, $userid_list = [])
{
$api = $this->workApp('work')->getClient();
$response = $api->postJson('/cgi-bin/externalcontact/groupchat/list', [
'status_filter' => $status_filter,
'owner_filter' => [
'userid_list' => $userid_list
],
'cursor' => $cursor,
'limit' => $limit
]);
if ($response->isFailed()) {
// 出错了,处理异常
throw new \Exception($response->getContent());
}
return json_decode($response->toJson());
}
public function groupChat($chat_id, $need_name = 0)
{
try {
$api = $this->workApp('work')->getClient();
$response = $api->postJson('/cgi-bin/externalcontact/groupchat/get', [
'chat_id' => $chat_id,
'need_name' => $need_name
]);
// if ($response->isFailed()) {
// // 出错了,处理异常
// throw new \Exception($response->getContent());
// }
$res = json_decode($response->toJson());
return $res;
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
public function workUserInfo($user_id)
{
$api = $this->workApp('work')->getClient();
$response = $api->get('/cgi-bin/user/get', ['userid' => $user_id]);
if ($response->isFailed()) {
// 出错了,处理异常
throw new \Exception($response->getContent());
}
// Log::info($response->toJson());
return json_decode($response->toJson());
}
public function test()
{
$access = $this->official_app->getAccessToken()->getToken();
dd($access);
}
/**
* 获取小程序 url link
*/
public function urlLink($path, $query)
{
$data = [
"path" => $path,
"query" => $query,
];
$res = $this->app->getClient()->post('wxa/generate_urllink', [
'json' => $data
]);
if ($res->isFailed())
throw new \Exception($res->getContent());
$r = json_decode($res->toJson());
return $r->url_link;
}
public function getUrlLink($url_link)
{
$data = [
'url_link' => $url_link,
];
$res = $this->app->getClient()->postJson('wxa/query_urllink', $data);
if ($res->isFailed())
throw new \Exception($res->getContent());
$r = json_decode($res->toJson());
return $r->url_link_info;
}
public function getUserStep($code, $iv, $encryptedData)
{
try {
$app = $this->app;
$utils = $app->getUtils();
$response = $utils->codeToSession($code);
// 获取解密后的用户数据
$userInfo = $utils->decryptSession($response['session_key'], $iv, $encryptedData);
// 用户的微信步数
$stepInfoList = $userInfo['stepInfoList'];
$stepCount = end($stepInfoList); // 获取最近一天的步数
$stepCount['stepInfoList'] = $stepInfoList;
return $stepCount;
} catch (\Throwable $e) {
throw new \Exception($e->getMessage());
}
}
public function getMpUrlLink($url, $query = null)
{
// $access_token = $this->app->getAccessToken()->getToken();
$token_url = config('app.url') . '/go/api/mp/v1/common/accesstoken_mp/get';
$params = ['curr_date' => "#" . date("Y-m-d") . "@-"];
try {
$res = \App\Facades\HttpService::postData($token_url, $params);
$access_token = $res['data'];
} catch (\Exception $e) {
$access_token = '';
}
$res = $this->app->getClient()->post('wxa/generatescheme?access_token=' . $access_token, [
'json' => [
'jump_wxa' => [
'path' => $url,
'query' => $query
],
"is_expire" => true,
"expire_time" => time() + 30 * 24 * 60 * 60
]
]);
if ($res->isFailed())
throw new \Exception($res->getContent());
$r = json_decode($res->toJson());
return $r->openlink;
}
}