Service.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <?php
  2. namespace addons\third\library;
  3. use addons\third\model\Third;
  4. use app\common\model\User;
  5. use fast\Random;
  6. use think\Db;
  7. use think\Exception;
  8. /**
  9. * 第三方登录服务类
  10. *
  11. */
  12. class Service
  13. {
  14. /**
  15. * 第三方登录
  16. * @param string $platform 平台
  17. * @param array $params 参数
  18. * @param array $extend 会员扩展信息
  19. * @param int $keeptime 有效时长
  20. * @return boolean
  21. */
  22. public static function connect($platform, $params = [], $extend = [], $keeptime = 0)
  23. {
  24. $time = time();
  25. $nickname = $params['nickname'] ?? ($params['userinfo']['nickname'] ?? '');
  26. $avatar = $params['avatar'] ?? ($params['userinfo']['avatar'] ?? '');
  27. $expires_in = $params['expires_in'] ?? 0;
  28. $openid = !empty($params['openid']) ? $params['openid'] : '';
  29. $unionid = !empty($params['unionid']) ? $params['unionid'] : '';
  30. $values = [
  31. 'platform' => $platform,
  32. 'unionid' => $unionid,
  33. 'openid' => $openid,
  34. 'openname' => $nickname,
  35. 'access_token' => $params['access_token'] ?? '',
  36. 'refresh_token' => $params['refresh_token'] ?? '',
  37. 'expires_in' => $expires_in,
  38. 'logintime' => $time,
  39. 'expiretime' => $time + $expires_in,
  40. ];
  41. $values = array_merge($values, $params);
  42. $auth = \app\common\library\Auth::instance();
  43. $auth->keeptime($keeptime);
  44. $third = null;
  45. //存在openid则先判断是否存在对应账号
  46. if ($openid) {
  47. $third = Third::get(['platform' => $platform, 'openid' => $openid], 'user');
  48. }
  49. //存在unionid就需要判断是否需要生成新记录
  50. if (!$third && $unionid) {
  51. $third = Third::get(['platform' => $platform, 'unionid' => $unionid], 'user');
  52. }
  53. if ($third) {
  54. if (!$third->user) {
  55. $third->delete();
  56. $third = null;
  57. } else {
  58. //优化头像存储
  59. $update = [
  60. 'nickname' => !$third->user->nickname || $third->user->nickname == '微信用户' ? ($nickname ?: '') : '',
  61. 'avatar' => !$third->user->avatar ? ($avatar ?: '') : ''
  62. ];
  63. $data = array_filter($update);
  64. if ($data) {
  65. $third->user->save($data);
  66. }
  67. return $auth->direct($third->user_id);
  68. }
  69. }
  70. // 如果已登录则直接绑定
  71. if ($auth->id) {
  72. $values['user_id'] = $auth->id;
  73. Third::create($values, true);
  74. $user = $auth->getUser();
  75. return true;
  76. }
  77. // 先随机一个用户名,随后再变更为u+数字id
  78. $username = Random::alnum(20);
  79. $password = Random::alnum(6);
  80. $domain = request()->host();
  81. if (!empty($extend['mobile'])) {
  82. $username = $extend['mobile'];
  83. $nickname = $extend['nickname'] ?? substr_replace($username, '****', 3, 4);
  84. }
  85. Db::startTrans();
  86. try {
  87. // 默认注册一个会员
  88. $result = $auth->register($username, $password, $username . '@' . $domain, '', $extend);
  89. if (!$result) {
  90. throw new Exception($auth->getError());
  91. }
  92. $user = $auth->getUser();
  93. $username = 'u' . $user->id;
  94. $email = $username . '@' . $domain;
  95. $fields = [];
  96. //判断用户名和邮箱是否已存在
  97. $exist = User::getByUsername($username);
  98. if (!$exist) {
  99. $fields['username'] = $username;
  100. }
  101. $exist = User::getByEmail($email);
  102. if (!$exist) {
  103. $fields['email'] = $email;
  104. }
  105. //如果昵称为空或为微信用户则修改
  106. if (!$user['nickname'] || $user['nickname'] == '微信用户') {
  107. $fields['nickname'] = $nickname = $fields['username'];
  108. }
  109. if ($nickname) {
  110. $fields['nickname'] = xss_clean(strip_tags($nickname));
  111. }
  112. if ($avatar) {
  113. $fields['avatar'] = xss_clean(strip_tags($avatar));
  114. }
  115. // 更新会员资料
  116. $user = User::get($user->id);
  117. $user->save($fields);
  118. if (!$third) {
  119. // 保存第三方信息
  120. $values['user_id'] = $auth->id;
  121. Third::create($values, true);
  122. }
  123. Db::commit();
  124. } catch (\Exception $e) {
  125. Db::rollback();
  126. \think\Log::record($e->getMessage());
  127. $auth->logout();
  128. return false;
  129. }
  130. return $auth->direct($user->id);
  131. }
  132. /**
  133. * 判断是否绑定第三方
  134. * @param string $platform 平台
  135. * @param string $openid Openid
  136. * @param string $apptype 平台类型(web/miniapp/mp)
  137. * @param string $unionid Unionid
  138. * @return bool
  139. */
  140. public static function isBindThird($platform, $openid, $apptype = '', $unionid = '')
  141. {
  142. $conddtions = [
  143. 'platform' => $platform,
  144. 'openid' => $openid
  145. ];
  146. if ($apptype) {
  147. $conddtions['apptype'] = $apptype;
  148. }
  149. $third = Third::get($conddtions, 'user');
  150. //第三方存在
  151. if ($third) {
  152. //用户失效
  153. if (!$third->user) {
  154. $third->delete();
  155. return false;
  156. }
  157. return true;
  158. }
  159. if ($unionid) {
  160. $third = Third::get(['platform' => $platform, 'unionid' => $unionid], 'user');
  161. if ($third) {
  162. //
  163. if (!$third->user) {
  164. $third->delete();
  165. return false;
  166. }
  167. return true;
  168. }
  169. }
  170. return false;
  171. }
  172. /**
  173. * 判断是否在微信内
  174. * @return bool
  175. */
  176. public static function isWechat()
  177. {
  178. return strpos(request()->server('HTTP_USER_AGENT'), 'MicroMessenger') !== false;
  179. }
  180. /**
  181. * 获取平台类型
  182. * @return string
  183. */
  184. public static function getApptype()
  185. {
  186. //如果是公众号则为mp,网页为web,小程序为miniapp,单独判断
  187. return self::isWechat() ? 'mp' : 'web';
  188. }
  189. }