WechatLoginTrait.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <?php
  2. namespace App\Traits;
  3. use App\Jobs\SendEmail;
  4. use App\Jobs\UserLog;
  5. use App\Services\LoginService;
  6. use App\Services\Eav\EavSetService;
  7. use App\Services\Eav\MaterialService;
  8. use Illuminate\Http\Response;
  9. use Illuminate\Support\Facades\Cache;
  10. use Illuminate\Support\Facades\Log;
  11. use Illuminate\Support\Facades\Request;
  12. use Illuminate\Support\Facades\Validator;
  13. /**
  14. * pc 微信公众号 登录及绑定
  15. *
  16. * Trait WechatLoginTrait
  17. * @package App\Traits
  18. */
  19. trait WechatLoginTrait
  20. {
  21. /**
  22. * 是否开启登录日志记录
  23. *
  24. * @var bool
  25. */
  26. private $is_open_login_log = false;
  27. /**
  28. * 微信公众号登录,如果已经绑定了,则直接登录,没有绑定则需要绑定手机号
  29. */
  30. public function bind()
  31. {
  32. $code = Request::input('code');
  33. if (empty($code)) {
  34. return redirect(toRoute('/sso/index/login'));
  35. }
  36. // 有可能会返回多次,为了防止这种情况,添加缓存进行解决
  37. $wechat_cache_key = 'wechat_cache_key:' . $code;
  38. if ($url = Cache::get($wechat_cache_key)) {
  39. Log::info($wechat_cache_key . '已经存在!');
  40. die();
  41. } else {
  42. Cache::put($wechat_cache_key, true, 10);
  43. }
  44. $app = $this->getPcApp();
  45. $user = $app->oauth->userFromCode($code);
  46. $weInfo = $user->toArray();
  47. $wx_unionid = $weInfo['raw']['unionid'] ?? '';
  48. $wx_h5_openid = $weInfo['raw']['openid'];
  49. $key2 = 'wechat:userInfo:' . $code;
  50. Cache::put($key2, $weInfo, 600);
  51. //根据openid判断该用户是否已经存在,如果存在则登录跳转
  52. $flag = false;
  53. $materialService = new MaterialService(new EavSetService('user'));
  54. $memberInfo = $materialService->elasticClientService()->queryOne(['wx_h5_openid' => $wx_h5_openid]);
  55. if ($memberInfo) {
  56. $flag = true;
  57. } else {
  58. if ($wx_unionid) {
  59. $memberInfo = $materialService->elasticClientService()->queryOne(['wx_unionid' => $wx_unionid]);
  60. if ($memberInfo) {
  61. $flag = true;
  62. }
  63. }
  64. }
  65. if ($flag) {
  66. //更新微信的头像和昵称信息
  67. $materialService->update($memberInfo['id'], ['wx_unionid' => $wx_unionid, 'wx_h5_openid' => $wx_h5_openid, 'wx_info' => json_encode($weInfo)]);
  68. $loginToken = $this->setLoginStatus($memberInfo);
  69. $loginKey = md5(microtime() . mt_rand());
  70. Cache::put($loginKey, $loginToken, 120);
  71. $url = toRoute('/store/tologin?is_login=1&key=' . $loginKey);
  72. } else {
  73. $loginKey = $code;
  74. $url = toRoute('/store/tologin?is_login=2&key=' . $loginKey);
  75. }
  76. Cache::forget($wechat_cache_key);
  77. return redirect($url);
  78. }
  79. /**
  80. * 微信公账号登录,客户绑定手机号
  81. */
  82. public function bindIn()
  83. {
  84. $requestData = Request::all();
  85. $rule = [
  86. 'key' => 'required',
  87. 'mobile' => 'required',
  88. 'sms_code' => 'required',
  89. ];
  90. $msg = [
  91. 'key.required' => '参数错误!',
  92. 'mobile.required' => '请填写手机号!',
  93. 'sms_code.required' => '请填写6位短信验证码!',
  94. 'sms_code.size' => '短信验证码必须是6个字符!',
  95. ];
  96. $validator = Validator::make($requestData, $rule, $msg);
  97. if ($validator->fails()) {
  98. $errorMessage = $validator->errors()->all();
  99. return response()->json(['result' => false, 'code' => 2001, 'msg' => $errorMessage[0] ?? '']);
  100. }
  101. //判断验证短信验证码是否正确
  102. $result_bool = $this->smsService->checkSmsCode($requestData['mobile'], $requestData['sms_code'], 'bind');
  103. if (!$result_bool) {
  104. return $this->responseMessage(2002, '短信验证码错误,请确认后再试!');
  105. }
  106. //获取微信的信息
  107. $key2 = 'wechat:userInfo:' . $requestData['key'];
  108. $weInfo = Cache::get($key2);
  109. if (empty($weInfo)) {
  110. return $this->responseMessage(2003, '微信登录失败,请重试!');
  111. }
  112. $wx_unionid = $weInfo['raw']['unionid'] ?? '';
  113. $wx_h5_openid = $weInfo['raw']['openid'];
  114. //检测手机号是否已经存在
  115. $loginToken = '';
  116. $materialService = new MaterialService(new EavSetService($this->userSetAlias));
  117. $userInfo = $materialService->elasticClientService()->queryOne(['mobile' => $requestData['mobile']]);
  118. if ($userInfo) {
  119. //更新到数据库
  120. $is_success = $materialService->update($userInfo['id'], ['wx_unionid' => $wx_unionid, 'wx_h5_openid' => $wx_h5_openid, 'wx_info' => json_encode($weInfo)]);
  121. if ($is_success) {
  122. //设置登录状态
  123. $loginService = new LoginService($this->siteAliasName);
  124. $loginToken = $loginService->setLoginCookie($userInfo);
  125. //给管理员发送邮件通知
  126. $this->dispatch(new SendEmail('597196313@qq.com', '老用户【' . $requestData['mobile'] . '】【' . $weInfo['nickname'] . '】,通过微信绑定成功!!'));
  127. }
  128. } else {
  129. //保存到数据库
  130. $data = [
  131. 'mobile' => $requestData['mobile'],
  132. 'username' => $weInfo['nickname'],
  133. 'wx_unionid' => $wx_unionid,
  134. 'wx_h5_openid' => $wx_h5_openid,
  135. 'gender' => $weInfo['raw']['sex'] ?? 0,
  136. 'wx_info' => json_encode($weInfo),
  137. 'password' => '', //生成随机密码
  138. 'avatar' => $weInfo['avatar'],
  139. 'role_id' => 1,
  140. 'status' => 1, // 状态 1正常 2黑名单
  141. 'setmeal_type' => 1, // 7天 体验版
  142. 'end_use_time' => time() + 3600 * 24 * 7
  143. ];
  144. $is_success = $materialService->addProduct($data, true);
  145. if ($is_success) {
  146. //设置登录状态
  147. $userInfo = $materialService->elasticClientService()->docGet($is_success);
  148. $loginService = new LoginService($this->siteAliasName);
  149. $loginToken = $loginService->setLoginCookie($userInfo);
  150. //给管理员发送邮件通知
  151. $this->dispatch(new SendEmail('597196313@qq.com', '新商家【' . $data['mobile'] . '】【' . $weInfo['nickname'] . '】,通过微信绑定,注册成功!!请尽快和该用户取得联系。提供服务!'));
  152. }
  153. }
  154. // 登录日志
  155. if ($loginToken) {
  156. return $this->responseMessage(1001, '绑定成功', $loginToken);
  157. } else {
  158. return $this->responseMessage(2001, '绑定失败,请稍后再试!');
  159. }
  160. }
  161. }