Mpapp.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <?php
  2. declare(strict_types=1);
  3. namespace app\api\controller;
  4. use app\common\model\Admin;
  5. use app\common\model\MpSubscribe;
  6. use app\common\model\Qrcode;
  7. use app\common\model\Third;
  8. use app\common\model\QrcodeScan;
  9. use think\annotation\route\Get;
  10. use think\annotation\route\Group;
  11. use think\annotation\route\Route;
  12. use app\common\model\User;
  13. #[Group("mpapp")]
  14. class Mpapp extends Api{
  15. protected $noNeedLogin = ['*'];
  16. protected $config=[];
  17. const PAGE=[
  18. //首页
  19. 'index'=>'/pages/index/index',
  20. //绑定用户
  21. 'binduser'=>'/pages/index/index',
  22. //NEXT页
  23. 'next'=>'/pages/index/next',
  24. ];
  25. protected function _initialize()
  26. {
  27. parent::_initialize();
  28. $this->config=[
  29. 'appid'=>site_config("uniapp.mpapp_id"),
  30. 'appsecret'=>site_config("uniapp.mpapp_secret"),
  31. 'token'=>site_config("uniapp.mpapp_token"),
  32. 'encodingaeskey'=>site_config("uniapp.mpapp_aeskey")
  33. ];
  34. }
  35. /**
  36. * 发起授权
  37. */
  38. #[Get('connect')]
  39. public function connect()
  40. {
  41. if($this->auth->id){
  42. return $this->gourl();
  43. }else{
  44. $arr=$this->request->get();
  45. if(count($arr)>0){
  46. $str='';
  47. foreach ($arr as $k=>$v){
  48. $str.=$k.'='.$v.'&';
  49. }
  50. $str=substr($str,0,strlen($str)-1);
  51. $callback=$this->request->domain().'/api/mpapp/callback?'.$str;
  52. }else{
  53. $callback=$this->request->domain().'/api/mpapp/callback';
  54. }
  55. $wechat = new \WeChat\Oauth($this->config);
  56. // 执行操作
  57. $result = $wechat->getOauthRedirect($callback, '', 'snsapi_userinfo');
  58. return redirect($result);
  59. }
  60. }
  61. /**
  62. * 授权回调
  63. */
  64. #[Get('callback')]
  65. public function callback()
  66. {
  67. // 授权成功后的回调
  68. $wechat = new \WeChat\Oauth($this->config);
  69. $result = $wechat->getOauthAccessToken();
  70. $userinfo = $wechat->getUserInfo($result['access_token'],$result['openid']);
  71. $result['nickname']=$userinfo['nickname'];
  72. $result['avatar']=$userinfo['headimgurl'];
  73. //判断是否启用账号绑定
  74. $third=Third::connect('mpapp', $result);
  75. $this->auth->loginByThirdPlatform(Third::PLATFORM('微信公众号'),$third);
  76. return $this->gourl();
  77. }
  78. private function gourl()
  79. {
  80. $arr=$this->request->get();
  81. $action=$arr['action'];
  82. unset($arr['action']);
  83. unset($arr['code']);
  84. unset($arr['state']);
  85. $query='&'.http_build_query($arr);
  86. $url=request()->domain().'/h5/#'.self::PAGE[$action].'?token='.$this->auth->getToken().$query;
  87. return redirect($url);
  88. }
  89. /**
  90. * 创建菜单
  91. */
  92. #[Get('menu')]
  93. public function menu()
  94. {
  95. $this->error('请删除这行代码后重试');
  96. $menu = new \WeChat\Menu($this->config);
  97. $json=array('button'=>[
  98. //跳转到公众号页面
  99. [
  100. "name"=>"首页",
  101. "url"=>$this->request->domain()."/h5/#/pages/index/index",
  102. "type"=>"view",
  103. ],
  104. //跳转到小程序页面
  105. [
  106. "name"=>"列表",
  107. "type"=>"miniprogram",
  108. "appid"=>site_config("uniapp.miniapp_id"),
  109. "pagepath"=>"pages/index/list",
  110. ],
  111. //二级页面
  112. [
  113. "name"=>"我的",
  114. "sub_button"=>[
  115. //先登陆,再跳转到指定页面
  116. [
  117. "name"=>"我的余额",
  118. "url"=>$this->request->domain()."api/mpapp/connect?action=101",
  119. "type"=>"view",
  120. ],
  121. [
  122. "name"=>"其他菜单",
  123. "type"=>"click",
  124. "key"=>"V1001_GOOD",
  125. ],
  126. ]
  127. ]
  128. ]);
  129. // 执行创建菜单
  130. $menu->create($json);
  131. $this->success('创建菜单成功');
  132. }
  133. /**
  134. * 公众号事件接收方法
  135. */
  136. #[Route('POST,GET','event')]
  137. public function event()
  138. {
  139. $api = new \WeChat\Receive($this->config);
  140. $msgtype=$api->getMsgType();
  141. if($msgtype=='text'){
  142. $api->text('尊敬客户您好,感谢您使用【'.site_config("basic.sitename").'】公众号!')->reply();
  143. return;
  144. }
  145. if($msgtype=='event'){
  146. $message = $api->getReceive();
  147. event('write_log','微信消息:'.json_encode($message));
  148. $event = $message['Event'];
  149. $eventkey = isset($message['EventKey'])? $message['EventKey'] : '';
  150. $openid=$message['FromUserName'];
  151. switch ($event) {
  152. //添加关注
  153. case 'subscribe':
  154. $user = new \WeChat\User($this->config);
  155. $userinfo=$user->getUserInfo($openid);
  156. $unionid=isset($userinfo['unionid'])?$userinfo['unionid'] : '';
  157. //记录关注
  158. MpSubscribe::create([
  159. 'openid'=>$openid,
  160. 'unionid'=>$unionid,
  161. ]);
  162. //普通关注
  163. if(is_array($eventkey)){
  164. $api->text('尊敬客户您好,感谢您使用【'.site_config("basic.sitename").'】公众号!')->reply();
  165. return;
  166. }
  167. //扫码关注
  168. if(strpos($eventkey,'qrscene_')===0){
  169. $eventkey=substr($eventkey,8);
  170. $resp=$this->scanQrcode($openid,$unionid,$eventkey);
  171. $api->text($resp)->reply();
  172. return;
  173. }
  174. //取消关注
  175. case 'unsubscribe':
  176. MpSubscribe::where(['openid'=>$openid])->delete();
  177. return;
  178. //扫二维码
  179. case 'SCAN':
  180. $user = new \WeChat\User($this->config);
  181. $userinfo=$user->getUserInfo($openid);
  182. $unionid=isset($userinfo['unionid'])?$userinfo['unionid'] : '';
  183. $resp=$this->scanQrcode($openid,$unionid,$eventkey);
  184. $api->text($resp)->reply();
  185. return;
  186. //跳转链接
  187. case 'VIEW':
  188. }
  189. }
  190. }
  191. /**
  192. * 扫码回调事件
  193. */
  194. private function scanQrcode($openid,$unionid,$qrcode_id)
  195. {
  196. $qrcode=Qrcode::find($qrcode_id);
  197. if(!$qrcode){
  198. return '尊敬客户您好,感谢您使用【'.site_config("basic.sitename").'】公众号!';
  199. }
  200. //记录扫码
  201. $scan=QrcodeScan::where(['openid'=>$openid,'qrcode_id'=>$qrcode->id])->find();
  202. if(!$scan){
  203. //生成的扫码记录表,可以在用户注册时,查询该表从而绑定推荐人
  204. QrcodeScan::create([
  205. 'openid'=>$openid,
  206. 'unionid'=>$unionid,
  207. 'qrcode_id'=>$qrcode->id,
  208. 'foreign_key'=>$qrcode->foreign_key,
  209. 'type'=>$qrcode->type,
  210. ]);
  211. }
  212. //根据业务场景返回不同的消息
  213. switch ($qrcode->type){
  214. case 'backend-login':
  215. $third=Third::where(['platform'=>Third::PLATFORM('微信公众号'),'openid'=>$openid])->find();
  216. if(!$third){
  217. return '您的微信没有绑定管理员,登陆失败!';
  218. }
  219. $admin=Admin::where(['third_id'=>$third->id])->find();
  220. if(!$admin){
  221. return '您的微信没有绑定管理员,登陆失败!';
  222. }
  223. if($admin->status=='hidden'){
  224. return '管理员已经被禁止,登陆失败!';
  225. }
  226. return '登陆成功!';
  227. case 'bind-third-user':
  228. $path=$this->request->domain()."/api/mpapp/connect?action=binduser";
  229. $end="<a href=\"{$path}\">👉👉点击这里授权👈️👈️</a>";
  230. return "您正在使用微信扫码授权获取您的微信头像、昵称\n\n{$end}";
  231. case 'toker':
  232. $user=User::find($qrcode->foreign_key);
  233. return '尊敬客户您好,您的好友'.$user->nickname.'推荐您使用【'.site_config("basic.sitename").'】公众号!';
  234. }
  235. }
  236. }