qyWechatService.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <?php
  2. namespace App\Service;
  3. use Illuminate\Support\Facades\Http;
  4. use Illuminate\Support\Facades\Cache;
  5. use Illuminate\Support\Facades\Log;
  6. class qyWechatService
  7. {
  8. public $corpId = "ww0e2580a34523500b";
  9. public $agentId = "1000046";
  10. protected $secret = "8YFLG89PjXQ20CTF2DDq1Pwng8vvSHrC37C_6lgV6mY";
  11. public function __construct()
  12. {
  13. // $this->corpId = config('services.wechat.corp_id');
  14. // $this->agentId = config('services.wechat.agent_id');
  15. // $this->secret = config('services.wechat.secret');
  16. }
  17. /**
  18. * Step 1: 获取 AccessToken
  19. */
  20. public function getAccessToken()
  21. {
  22. // 1. 先从缓存拿
  23. $wechat_access_token = "wechat_access_token" . $this->corpId . $this->agentId;
  24. $cacheToken = Cache::get($wechat_access_token);
  25. if ($cacheToken) return [true, $cacheToken];
  26. // 2. 缓存没有则请求接口
  27. $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=".$this->corpId."&corpsecret=".$this->secret;
  28. list($status, $res) = $this->get_helper($url);
  29. if (!$status) return [false, $res];
  30. if (isset($res['access_token'])) {
  31. Cache::put($wechat_access_token, $res['access_token'], 7000);
  32. return [true, $res['access_token']];
  33. }
  34. return [false, $res['errmsg'] ?? '获取AccessToken失败'];
  35. }
  36. /**
  37. * 获取 企业级 Ticket (用于 wx.config)
  38. */
  39. public function getJsApiTicket()
  40. {
  41. $cacheTicketKey = "wechat_jsapi_ticket" . $this->corpId . $this->agentId;
  42. $cacheTicket = Cache::get($cacheTicketKey);
  43. if ($cacheTicket) return [true, $cacheTicket];
  44. list($status, $token) = $this->getAccessToken();
  45. if (!$status) return [false, $token];
  46. $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=" . $token;
  47. list($status, $res) = $this->get_helper($url);
  48. if (!$status) return [false, $res];
  49. if (isset($res['ticket'])) {
  50. Cache::put($cacheTicketKey, $res['ticket'], 7000);
  51. return [true, $res['ticket']];
  52. }
  53. return [false, $res['errmsg'] ?? '获取JsApiTicket失败'];
  54. }
  55. /**
  56. * 获取 应用级 Ticket (用于 wx.agentConfig)
  57. */
  58. public function getAgentTicket()
  59. {
  60. $cacheTicketKey = "wechat_agent_ticket" . $this->corpId . $this->agentId;
  61. $cacheTicket = Cache::get($cacheTicketKey);
  62. if ($cacheTicket) return [true, $cacheTicket];
  63. list($status, $token) = $this->getAccessToken();
  64. if (!$status) return [false, $token];
  65. // 注意这里 type=agent_config
  66. $url = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token={$token}&type=agent_config";
  67. list($status, $res) = $this->get_helper($url);
  68. if (!$status) return [false, $res];
  69. if (isset($res['ticket'])) {
  70. Cache::put($cacheTicketKey, $res['ticket'], 7000);
  71. return [true, $res['ticket']];
  72. }
  73. return [false, $res['errmsg'] ?? '获取AgentTicket失败'];
  74. }
  75. /**
  76. * 生成签名通用方法
  77. */
  78. public function makeSignature($ticket, $nonceStr, $timestamp, $url)
  79. {
  80. $string = "jsapi_ticket={$ticket}&noncestr={$nonceStr}&timestamp={$timestamp}&url={$url}";
  81. return sha1($string);
  82. }
  83. public function post_helper($url, $data, $header = [], $timeout = 20, $title = ""){
  84. Log::channel('apiLog')->info($title . 'POST', ["api" => $url , "param" => json_decode($data,true) ,"header" => $header]);
  85. $ch = curl_init();
  86. curl_setopt($ch, CURLOPT_URL, $url);
  87. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  88. curl_setopt($ch, CURLOPT_ENCODING, '');
  89. curl_setopt($ch, CURLOPT_POST, 1);
  90. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  91. curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
  92. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  93. curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
  94. if(!is_null($data)) curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  95. $r = curl_exec($ch);
  96. if ($r === false) {
  97. // 获取错误号
  98. $errorNumber = curl_errno($ch);
  99. // 获取错误信息
  100. $errorMessage = curl_error($ch);
  101. $message = "cURL Error #{$errorNumber}: {$errorMessage}";
  102. Log::channel('apiLog')->info($title . 'POST结果', ["message" => $message ]);
  103. return [false, $message];
  104. }
  105. curl_close($ch);
  106. Log::channel('apiLog')->info($title . 'POST结果', ["message" => json_decode($r, true) ]);
  107. return [true, json_decode($r, true)];
  108. }
  109. public function get_helper($url,$header=[],$timeout = 20){
  110. $ch = curl_init();
  111. curl_setopt_array($ch, array(
  112. CURLOPT_URL => $url,
  113. CURLOPT_RETURNTRANSFER => true,
  114. CURLOPT_ENCODING => '',
  115. CURLOPT_MAXREDIRS => 10,
  116. CURLOPT_TIMEOUT => $timeout,
  117. CURLOPT_FOLLOWLOCATION => true,
  118. CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  119. CURLOPT_CUSTOMREQUEST => 'GET',
  120. CURLOPT_SSL_VERIFYPEER => false,
  121. CURLOPT_HTTPHEADER => $header,
  122. ));
  123. $r = curl_exec($ch);
  124. if ($r === false) {
  125. // 获取错误号
  126. $errorNumber = curl_errno($ch);
  127. // 获取错误信息
  128. $errorMessage = curl_error($ch);
  129. $message = "cURL Error #{$errorNumber}: {$errorMessage}";
  130. Log::channel('apiLog')->info('企业微信GET结果', ["message" => $message]);
  131. return [false, $message];
  132. }
  133. curl_close($ch);
  134. Log::channel('apiLog')->info('企业微信GET结果', ["message" => json_decode($r, true)]);
  135. return [true, json_decode($r, true)];
  136. }
  137. }