WxaQrCodeService.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Administrator
  5. * Date: 2020/7/29
  6. * Time: 9:44
  7. */
  8. namespace app\common\services\wechat;
  9. use app\common\exceptions\ShopException;
  10. use app\common\services\Utils;
  11. use GuzzleHttp\Client;
  12. class WxaQrCodeService
  13. {
  14. protected $get_token_url = 'https://api.weixin.qq.com/cgi-bin/token?'; //获取token的url
  15. protected $wxaUrl = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=';//获取小程序码url
  16. private $patch; //小程序码保存路径
  17. private $fileName; //小程序码文件名称
  18. private $new = false; //是否重新生成
  19. protected $parameters;
  20. /**
  21. * @param $new bool 生成新的
  22. * @param $storage_path string 图片存储相对路径
  23. */
  24. public function __construct($storage_path, $new = false)
  25. {
  26. $this->patch = $storage_path;
  27. $this->new = $new;
  28. }
  29. /**
  30. * @param mixed $parameters
  31. */
  32. public function setParameter($key, $value)
  33. {
  34. $this->parameters[$key] = $value;
  35. }
  36. /**
  37. * @return mixed
  38. */
  39. public function getParameter($key)
  40. {
  41. return isset($this->parameters[$key])?$this->parameters[$key]:'';
  42. }
  43. public function getAllParameters()
  44. {
  45. return $this->parameters;
  46. }
  47. /**
  48. * @return bool|mixed|\Psr\Http\Message\ResponseInterface|string
  49. * @throws ShopException
  50. * @throws \GuzzleHttp\Exception\GuzzleException
  51. */
  52. public function getQrCode()
  53. {
  54. if (!$this->getParameter('page')) {
  55. throw new ShopException('小程序页面路径不能为空');
  56. }
  57. $filePathName = $this->getQrFileFullPath();
  58. if (file_exists($filePathName) && $this->new === false) {
  59. return $this->getPathUrl();
  60. }
  61. return $this->getWxaCode();
  62. }
  63. /**
  64. * 生成小程序码
  65. * @param $order_id
  66. * @return bool|mixed|\Psr\Http\Message\ResponseInterface
  67. * @throws ShopException
  68. * @throws \GuzzleHttp\Exception\GuzzleException
  69. */
  70. public function getWxaCode()
  71. {
  72. $token = $this->getToken();
  73. $url = $this->wxaUrl.$token;
  74. // $json_data = [
  75. // "scene" => 'order_id=232&orderType=verifier',
  76. // "page" => 'packageA/member/orderdetail/orderdetail'
  77. // ];
  78. $client = new Client;
  79. $res = $client->request('POST', $url, ['json'=>$this->getAllParameters()]);
  80. $data = json_decode($res->getBody()->getContents(), JSON_FORCE_OBJECT);
  81. //$path_file = $this->getPosterPath().'ceshi.png';
  82. //file_put_contents($path_file, $data);
  83. if (isset($data['errcode'])) {
  84. \Log::debug('-----小程序码生成失败------', $data);
  85. throw new ShopException('小程序码生成失败:'.$data['errMsg']);
  86. }
  87. $qr_binary_content = $res->getBody(); //图片二进制内容
  88. return $this->saveWxaQrCode($qr_binary_content);
  89. }
  90. /**
  91. * 发送获取token请求,获取token(有效期2小时)
  92. * @return mixed
  93. * @throws ShopException
  94. * @throws \GuzzleHttp\Exception\GuzzleException
  95. */
  96. protected function getToken()
  97. {
  98. $set = \Setting::get('plugin.min_app');
  99. $paramMap = [
  100. 'grant_type' => 'client_credential',
  101. 'appid' => $set['key'],
  102. 'secret' => $set['secret'],
  103. ];
  104. //获取token的url参数拼接
  105. $strQuery="";
  106. foreach ($paramMap as $k=>$v){
  107. $strQuery .= strlen($strQuery) == 0 ? "" : "&";
  108. $strQuery.=$k."=".urlencode($v);
  109. }
  110. $getTokenUrl = $this->get_token_url. $strQuery; //获取token的url
  111. $client = new Client();
  112. $res = $client->request('GET', $getTokenUrl);
  113. $data = json_decode($res->getBody()->getContents(), JSON_FORCE_OBJECT);
  114. if (isset($data['errcode'])) {
  115. \Log::debug('----小程序码获取token失败---', $data);
  116. throw new ShopException('小程序码获取token失败:'.$data['errmsg']);
  117. }
  118. return $data['access_token'];
  119. }
  120. /**
  121. * 保存小程序码
  122. * @param $qr_binary_content
  123. * @return string
  124. */
  125. private function saveWxaQrCode($qr_binary_content)
  126. {
  127. $filePathName = $this->getQrFileFullPath();
  128. unlink(storage_path($filePathName));//存在删除
  129. file_put_contents($filePathName, $qr_binary_content); //保存
  130. return $this->getPathUrl();
  131. }
  132. /**
  133. * 设置小程序图片唯一标识
  134. * @param $name
  135. */
  136. public function setFileId($code)
  137. {
  138. $this->fileName = md5($code).'.png';
  139. }
  140. /**
  141. * 获取小程序码文件名
  142. * @return string
  143. */
  144. protected function getFileName()
  145. {
  146. if (!isset($this->fileName)) {
  147. $file_name = md5(json_encode($this->getAllParameters()));
  148. $this->fileName = $file_name.'.png';
  149. }
  150. return $this->fileName;
  151. }
  152. /**
  153. * 文件储存全路径
  154. * @return string
  155. */
  156. private function getQrFileFullPath()
  157. {
  158. return $this->getStoragePath() .DIRECTORY_SEPARATOR. $this->getFileName();
  159. }
  160. /**
  161. * 储存路径
  162. * @return string
  163. */
  164. public function getStoragePath()
  165. {
  166. $path = storage_path($this->patch);
  167. if (!is_dir($path)) {
  168. Utils::mkdirs($path);
  169. }
  170. return $path;
  171. }
  172. public function getPathUrl()
  173. {
  174. return request()->getSchemeAndHttpHost() . config('app.webPath') . \Storage::url($this->patch .DIRECTORY_SEPARATOR.$this->getFileName());
  175. }
  176. }