|
|
@@ -0,0 +1,169 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Service;
|
|
|
+
|
|
|
+use Illuminate\Support\Facades\Http;
|
|
|
+use Illuminate\Support\Facades\Cache;
|
|
|
+use Illuminate\Support\Facades\Log;
|
|
|
+
|
|
|
+class qyWechatService
|
|
|
+{
|
|
|
+ public $corpId = "ww0e2580a34523500b";
|
|
|
+ public $agentId = "1000046";
|
|
|
+ protected $secret = "8YFLG89PjXQ20CTF2DDq1Pwng8vvSHrC37C_6lgV6mY";
|
|
|
+
|
|
|
+ public function __construct()
|
|
|
+ {
|
|
|
+// $this->corpId = config('services.wechat.corp_id');
|
|
|
+// $this->agentId = config('services.wechat.agent_id');
|
|
|
+// $this->secret = config('services.wechat.secret');
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Step 1: 获取 AccessToken
|
|
|
+ */
|
|
|
+ public function getAccessToken()
|
|
|
+ {
|
|
|
+ // 1. 先从缓存拿
|
|
|
+ $wechat_access_token = "wechat_access_token" . $this->corpId . $this->agentId;
|
|
|
+ $cacheToken = Cache::get($wechat_access_token);
|
|
|
+ if ($cacheToken) return [true, $cacheToken];
|
|
|
+
|
|
|
+ // 2. 缓存没有则请求接口
|
|
|
+ $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=".$this->corpId."&corpsecret=".$this->secret;
|
|
|
+ list($status, $res) = $this->get_helper($url);
|
|
|
+ if (!$status) return [false, $res];
|
|
|
+
|
|
|
+ if (isset($res['access_token'])) {
|
|
|
+ Cache::put($wechat_access_token, $res['access_token'], 7000);
|
|
|
+ return [true, $res['access_token']];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [false, $res['errmsg'] ?? '获取AccessToken失败'];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取 企业级 Ticket (用于 wx.config)
|
|
|
+ */
|
|
|
+ public function getJsApiTicket()
|
|
|
+ {
|
|
|
+ $cacheTicketKey = "wechat_jsapi_ticket" . $this->corpId . $this->agentId;
|
|
|
+ $cacheTicket = Cache::get($cacheTicketKey);
|
|
|
+ if ($cacheTicket) return [true, $cacheTicket];
|
|
|
+
|
|
|
+ list($status, $token) = $this->getAccessToken();
|
|
|
+ if (!$status) return [false, $token];
|
|
|
+
|
|
|
+ $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=" . $token;
|
|
|
+ list($status, $res) = $this->get_helper($url);
|
|
|
+
|
|
|
+ if (!$status) return [false, $res];
|
|
|
+
|
|
|
+ if (isset($res['ticket'])) {
|
|
|
+ Cache::put($cacheTicketKey, $res['ticket'], 7000);
|
|
|
+ return [true, $res['ticket']];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [false, $res['errmsg'] ?? '获取JsApiTicket失败'];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取 应用级 Ticket (用于 wx.agentConfig)
|
|
|
+ */
|
|
|
+ public function getAgentTicket()
|
|
|
+ {
|
|
|
+ $cacheTicketKey = "wechat_agent_ticket" . $this->corpId . $this->agentId;
|
|
|
+ $cacheTicket = Cache::get($cacheTicketKey);
|
|
|
+ if ($cacheTicket) return [true, $cacheTicket];
|
|
|
+
|
|
|
+ list($status, $token) = $this->getAccessToken();
|
|
|
+ if (!$status) return [false, $token];
|
|
|
+
|
|
|
+ // 注意这里 type=agent_config
|
|
|
+ $url = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token={$token}&type=agent_config";
|
|
|
+ list($status, $res) = $this->get_helper($url);
|
|
|
+
|
|
|
+ if (!$status) return [false, $res];
|
|
|
+
|
|
|
+ if (isset($res['ticket'])) {
|
|
|
+ Cache::put($cacheTicketKey, $res['ticket'], 7000);
|
|
|
+ return [true, $res['ticket']];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [false, $res['errmsg'] ?? '获取AgentTicket失败'];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成签名通用方法
|
|
|
+ */
|
|
|
+ public function makeSignature($ticket, $nonceStr, $timestamp, $url)
|
|
|
+ {
|
|
|
+ $string = "jsapi_ticket={$ticket}&noncestr={$nonceStr}×tamp={$timestamp}&url={$url}";
|
|
|
+ return sha1($string);
|
|
|
+ }
|
|
|
+
|
|
|
+ public function post_helper($url, $data, $header = [], $timeout = 20, $title = ""){
|
|
|
+ Log::channel('apiLog')->info($title . 'POST', ["api" => $url , "param" => json_decode($data,true) ,"header" => $header]);
|
|
|
+
|
|
|
+ $ch = curl_init();
|
|
|
+ curl_setopt($ch, CURLOPT_URL, $url);
|
|
|
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
|
+ curl_setopt($ch, CURLOPT_ENCODING, '');
|
|
|
+ curl_setopt($ch, CURLOPT_POST, 1);
|
|
|
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
|
|
|
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
|
|
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
|
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
|
|
+
|
|
|
+ if(!is_null($data)) curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
|
|
+ $r = curl_exec($ch);
|
|
|
+
|
|
|
+ if ($r === false) {
|
|
|
+ // 获取错误号
|
|
|
+ $errorNumber = curl_errno($ch);
|
|
|
+ // 获取错误信息
|
|
|
+ $errorMessage = curl_error($ch);
|
|
|
+ $message = "cURL Error #{$errorNumber}: {$errorMessage}";
|
|
|
+
|
|
|
+ Log::channel('apiLog')->info($title . 'POST结果', ["message" => $message ]);
|
|
|
+ return [false, $message];
|
|
|
+ }
|
|
|
+ curl_close($ch);
|
|
|
+
|
|
|
+ Log::channel('apiLog')->info($title . 'POST结果', ["message" => json_decode($r, true) ]);
|
|
|
+ return [true, json_decode($r, true)];
|
|
|
+ }
|
|
|
+
|
|
|
+ public function get_helper($url,$header=[],$timeout = 20){
|
|
|
+ $ch = curl_init();
|
|
|
+ curl_setopt_array($ch, array(
|
|
|
+ CURLOPT_URL => $url,
|
|
|
+ CURLOPT_RETURNTRANSFER => true,
|
|
|
+ CURLOPT_ENCODING => '',
|
|
|
+ CURLOPT_MAXREDIRS => 10,
|
|
|
+ CURLOPT_TIMEOUT => $timeout,
|
|
|
+ CURLOPT_FOLLOWLOCATION => true,
|
|
|
+ CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
|
+ CURLOPT_CUSTOMREQUEST => 'GET',
|
|
|
+ CURLOPT_SSL_VERIFYPEER => false,
|
|
|
+ CURLOPT_HTTPHEADER => $header,
|
|
|
+ ));
|
|
|
+ $r = curl_exec($ch);
|
|
|
+
|
|
|
+ if ($r === false) {
|
|
|
+ // 获取错误号
|
|
|
+ $errorNumber = curl_errno($ch);
|
|
|
+ // 获取错误信息
|
|
|
+ $errorMessage = curl_error($ch);
|
|
|
+
|
|
|
+ $message = "cURL Error #{$errorNumber}: {$errorMessage}";
|
|
|
+ Log::channel('apiLog')->info('企业微信GET结果', ["message" => $message]);
|
|
|
+ return [false, $message];
|
|
|
+ }
|
|
|
+
|
|
|
+ curl_close($ch);
|
|
|
+ Log::channel('apiLog')->info('企业微信GET结果', ["message" => json_decode($r, true)]);
|
|
|
+
|
|
|
+ return [true, json_decode($r, true)];
|
|
|
+ }
|
|
|
+}
|