wechatlogic.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. <?php
  2. /*
  3. * @Author: wang jun
  4. * @Date: 2022-01-18 11:12:23
  5. * @Last Modified by: wang jun
  6. * @Last Modified time: 2022-01-19 10:38:13
  7. * 微信类
  8. */
  9. namespace app\index\logic;
  10. use app\index\logic\wxBizDataCrypt;
  11. use app\index\model\usermodel;
  12. class wechatlogic extends baselogic
  13. {
  14. /**
  15. * 设置请求数据规则
  16. * 20220107
  17. * wj
  18. */
  19. protected function setrules()
  20. {
  21. $list = [
  22. 'getOpenid' => [
  23. ['name' => 'code', 'title' => 'code', 'require' => true, 'type' => 'string'],
  24. ],
  25. 'create_qrcode' => [
  26. ['name' => 'scene', 'title' => 'scene', 'require' => true, 'type' => 'string'],
  27. ['name' => 'page', 'title' => 'page', 'require' => true, 'type' => 'string'],
  28. ],
  29. 'down_qrcode' => [
  30. ['name' => 'scene', 'title' => 'scene', 'require' => true, 'type' => 'string'],
  31. ['name' => 'page', 'title' => 'page', 'require' => true, 'type' => 'string'],
  32. ],
  33. ];
  34. return $list;
  35. }
  36. public function getselfwxconfig()
  37. {
  38. $config = [
  39. 'appid' => 'wx8788dcdf3d075963',
  40. //'appid' => 'wx8240b08d4e0b8954',
  41. 'appSecret' => '0d1928572155d59f0c66c30378e42bfb',
  42. //'appSecret' => 'df07e160bbb1235e7b737cbb7c87a0ed',
  43. ];
  44. return $config;
  45. }
  46. private function curl_get($url, &$httpCode = 0)
  47. {
  48. $ch = curl_init();
  49. curl_setopt($ch, CURLOPT_URL, $url);
  50. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  51. //不做证书校验,部署在linux环境下请改为true
  52. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  53. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
  54. $file_contents = curl_exec($ch);
  55. $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  56. curl_close($ch);
  57. return $file_contents;
  58. }
  59. private function getAccessToken()
  60. {
  61. $config = $this->getselfwxconfig();
  62. $appid = $config['appid'];
  63. $appSecret = $config['appSecret'];
  64. $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appid . "&secret=" . $appSecret;
  65. $result = $this->curl_get($url);
  66. $wxResult = json_decode($result, true);
  67. return $wxResult;
  68. }
  69. //开启curl post请求
  70. private function sendCmd($url, $data)
  71. {
  72. $curl = curl_init(); // 启动一个CURL会话
  73. curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
  74. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检测
  75. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // 从证书中检查SSL加密算法是否存在
  76. curl_setopt($curl, CURLOPT_HTTPHEADER, array('Expect:')); //解决数据包大不能提交
  77. curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
  78. curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
  79. curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
  80. curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包
  81. curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循
  82. curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
  83. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
  84. $tmpInfo = curl_exec($curl); // 执行操作
  85. if (curl_errno($curl)) {
  86. echo 'Errno' . curl_error($curl);
  87. }
  88. curl_close($curl); // 关键CURL会话
  89. return $tmpInfo; // 返回数据
  90. }
  91. /**
  92. * 获取openid
  93. * 20220118
  94. * wj
  95. * code 必填
  96. */
  97. public function getOpenid($arr)
  98. {
  99. $result = $this->checkparam(__FUNCTION__, $arr);
  100. if (1 != $result['status']) {
  101. return $result;
  102. }
  103. $code = $arr['code'];
  104. $config = $this->getselfwxconfig();
  105. $appid = $config['appid'];
  106. $appSecret = $config['appSecret'];
  107. $wxUrl = 'https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code';
  108. $getUrl = sprintf($wxUrl, $appid, $appSecret, $code);
  109. $result = $this->curl_get($getUrl);
  110. $wxResult = json_decode($result, true);
  111. if (empty($wxResult)) {
  112. return backarr(0, "错误");
  113. } else {
  114. $logfail = array_key_exists('errcode', $wxResult);
  115. if ($logfail) {
  116. return backarr(1, 'success', $logfail['errmsg']);
  117. trace(json_encode($wxResult));
  118. } else {
  119. $openid = $wxResult['openid'];
  120. if (!isset($wxResult['unionid'])) {
  121. trace(json_encode($wxResult));
  122. }
  123. $data = ['openid' => $openid];
  124. if (isset($wxResult['unionid'])) {
  125. $unionid = $wxResult['unionid'];
  126. $data['unionid'] = $unionid;
  127. $t_m = new usermodel();
  128. $urec = $t_m->getinfobyopenid($openid);
  129. if ($urec) {
  130. if (!$urec['union_id']) {
  131. $t_m->updateunionidbyopenid($openid, $unionid);
  132. }
  133. }
  134. }
  135. return backarr(1, 'success', $data);
  136. }
  137. }
  138. }
  139. //获得二维码
  140. public function create_qrcode($arr)
  141. {
  142. $result = $this->checkparam(__FUNCTION__, $arr);
  143. if (1 != $result['status']) {
  144. return $result;
  145. }
  146. $sharepage = request()->param();
  147. $qr_path = "./Uploads/";
  148. if (!file_exists($qr_path . 'user/')) {
  149. mkdir($qr_path . 'user/', 0700, true); //判断保存目录是否存在,不存在自动生成文件目录
  150. }
  151. $filename = 'user/' . time() . '.png';
  152. $file = $qr_path . $filename;
  153. $access = $this->getAccessToken();
  154. $access_token = $access['access_token'];
  155. $url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' . $access_token;
  156. $qrcode = array(
  157. 'scene' => $arr['scene'], //二维码所带参数
  158. 'width' => 200,
  159. 'page' => $arr['page'], //二维码跳转路径(要已发布小程序)
  160. 'auto_color' => true,
  161. );
  162. $result = $this->sendCmd($url, json_encode($qrcode)); //请求微信接口
  163. $errcode = json_decode($result, true)['errcode'];
  164. $errmsg = json_decode($result, true)['errmsg'];
  165. if ($errcode) {
  166. trace(json_encode($result));
  167. return backarr(0, $errmsg);
  168. }
  169. $res = file_put_contents($file, $result); //将微信返回的图片数据流写入文件
  170. if ($res === false) {
  171. echo '生成二维码失败';
  172. } else {
  173. $path = getselfurl('default') . "/Uploads/" . $filename;
  174. return backarr(1, 'success', ['path' => $path]);
  175. }
  176. }
  177. //网上代骊,待修改
  178. public function WxDecode()
  179. {
  180. // 接收参数
  181. $data = request()->param();
  182. $config = $this->getselfwxconfig();
  183. $appid = $config['appid'];
  184. $appSecret = $config['appSecret'];
  185. $grant_type = "authorization_code"; //授权(必填)
  186. $code = $data['code']; //有效期5分钟 登录会话
  187. $encryptedData = $data['encryptedData'];
  188. $iv = $data['iv'];
  189. // 拼接url
  190. $url = "https://api.weixin.qq.com/sns/jscode2session?" . "appid=" . $appid . "&secret=" . $appsecret . "&js_code=" . $code . "&grant_type=" . $grant_type;
  191. $res = json_decode($this->curl_get($url), true);
  192. $sessionKey = $res['session_key']; //取出json里对应的值
  193. $pc = new wxBizDataCrypt($appid, $sessionKey);
  194. $errCode = $pc->decryptData($encryptedData, $iv, $data);
  195. //这里是按二手设备做的,以后应该单独变成逻辑,由逻辑层完成,以应对不同的需求
  196. if ($errCode == 0) {
  197. $result['code'] = 200;
  198. $resultData['msg'] = '解密成功';
  199. $resultData['userInfo'] = json_decode($data);
  200. $result['resultData'] = $resultData;
  201. echo json_encode($result);
  202. } else {
  203. return json($errCode);
  204. }
  205. }
  206. //获得二维码
  207. /**
  208. * 保存并下载二维码
  209. * 20220118
  210. * wj
  211. * scene page 必填
  212. */
  213. public function download_qrcode($arr)
  214. {
  215. $result = $this->checkparam(__FUNCTION__, $arr);
  216. if (1 != $result['status']) {
  217. return $result;
  218. }
  219. $qr_path = "./Uploads/";
  220. if (!file_exists($qr_path . 'user/')) {
  221. mkdir($qr_path . 'user/', 0700, true); //判断保存目录是否存在,不存在自动生成文件目录
  222. }
  223. $filename = 'user/' . time() . '.png';
  224. $file = $qr_path . $filename;
  225. $access = $this->getAccessToken(); //json_decode($this->getAccessToken(),true);
  226. $access_token = $access['access_token'];
  227. $url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' . $access_token;
  228. $qrcode = array(
  229. 'scene' => $arr['scene'], //二维码所带参数
  230. 'width' => 200,
  231. 'page' => $arr['page'], //二维码跳转路径(要已发布小程序)
  232. 'auto_color' => true,
  233. );
  234. $result = $this->sendCmd($url, json_encode($qrcode)); //请求微信接口
  235. $errcode = json_decode($result, true)['errcode'];
  236. $errmsg = json_decode($result, true)['errmsg'];
  237. if ($errcode) {
  238. trace(json_encode($result));
  239. return backarr(0, $errmsg);
  240. }
  241. $res = file_put_contents($file, $result); //将微信返回的图片数据流写入文件
  242. $strfile = 'Uploads/' . $filename;
  243. $file1 = fopen($strfile, 'r');
  244. header("Content-Type: application/force-download");
  245. header("Content-Type: application/octet-stream");
  246. header("Content-Type: application/download");
  247. header('Content-Disposition:inline;filename="' . $strfile . '"');
  248. ob_clean();
  249. flush();
  250. echo fread($file1, filesize($file));
  251. fclose($file1);
  252. if ($res === false) {
  253. echo '生成二维码失败';
  254. } else {
  255. $path = getselfurl('default') . "/Uploads/" . $filename;
  256. return backarr(1, 'success', ['path' => $path]);
  257. }
  258. }
  259. }