Wechat.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <?php
  2. namespace addons\shopro\service\third\wechat;
  3. use app\common\library\Auth;
  4. use addons\shopro\service\user\UserAuth;
  5. use app\admin\model\shopro\ThirdOauth;
  6. use app\admin\model\shopro\user\User as UserModel;
  7. class Wechat
  8. {
  9. // 平台
  10. protected $platform;
  11. // 转发服务
  12. protected $service;
  13. public function __construct($platform, $payload = [])
  14. {
  15. $this->platform = $platform;
  16. $this->service = $this->setPlatformService($payload);
  17. }
  18. public function getApp()
  19. {
  20. return $this->service->wechat;
  21. }
  22. /**
  23. * 微信登陆
  24. *
  25. * @return array
  26. */
  27. public function login()
  28. {
  29. $wechatUser = $this->service->login();
  30. $oauthInfo = $this->createOrUpdateOauthInfo($wechatUser);
  31. $this->registerOrBindUser($oauthInfo, 0, ['mobile' => $wechatUser['mobile'] ?? '']);
  32. $oauthInfo->save();
  33. $auth = Auth::instance();
  34. $ret = $auth->direct($oauthInfo->user_id);
  35. if ($ret) {
  36. $oauthInfo->login_num += 1;
  37. set_token_in_header($auth->getToken());
  38. return true;
  39. } else {
  40. $oauthInfo->user_id = 0;
  41. $oauthInfo->save();
  42. return false;
  43. }
  44. }
  45. /**
  46. * 微信绑定
  47. *
  48. * @return array
  49. */
  50. public function bind(Object $user)
  51. {
  52. $wechatUser = $this->service->bind();
  53. $oauthInfo = $this->createOrUpdateOauthInfo($wechatUser);
  54. if ($this->registerOrBindUser($oauthInfo, $user->id)) {
  55. return true;
  56. }
  57. return false;
  58. }
  59. /**
  60. * 微信解绑
  61. *
  62. * @return array
  63. */
  64. public function unbind()
  65. {
  66. $user = auth_user();
  67. if (!$user->verification->mobile) {
  68. error_stop('请先绑定手机号后再进行操作');
  69. }
  70. $oauthInfo = ThirdOauth::where([
  71. 'user_id' => $user->id,
  72. 'platform' => $this->platform,
  73. 'provider' => 'wechat'
  74. ])->find();
  75. if ($oauthInfo) {
  76. $oauthInfo->delete();
  77. return true;
  78. }
  79. return false;
  80. }
  81. /**
  82. * 创建/更新用户认证信息
  83. *
  84. * @return think\Model
  85. */
  86. private function createOrUpdateOauthInfo($wechatUser, $extend = [])
  87. {
  88. $oauthInfo = ThirdOauth::getByOpenid($wechatUser['openid']);
  89. if (!$oauthInfo) { // 创建新的third_oauth条目
  90. $wechatUser['user_id'] = 0;
  91. if (!empty($wechatUser['unionid'])) { // unionid账号合并策略
  92. $unionOauthInfo = ThirdOauth::getByUnionid($wechatUser['unionid']);
  93. if ($unionOauthInfo) {
  94. $wechatUser['user_id'] = $unionOauthInfo->user_id;
  95. }
  96. }
  97. $wechatUser['provider'] = 'wechat';
  98. $wechatUser['platform'] = $this->platform;
  99. $wechatUser = array_merge($wechatUser, $extend);
  100. $thirdOauth = new ThirdOauth($wechatUser);
  101. $thirdOauth->allowField(true)->save();
  102. $oauthInfo = ThirdOauth::getByOpenid($wechatUser['openid']);
  103. }else {
  104. $oauthInfo->allowField(true)->save($wechatUser);
  105. }
  106. return $oauthInfo;
  107. }
  108. /**
  109. * 注册/绑定用户
  110. *
  111. * @return think\Model
  112. */
  113. private function registerOrBindUser($oauthInfo, $user_id = 0, $extend = [])
  114. {
  115. // 检查用户存在
  116. if ($oauthInfo->user_id) {
  117. $user = UserModel::get($oauthInfo->user_id);
  118. if ($user && $user_id > 0) {
  119. error_stop('该微信账号已绑定其他用户');
  120. }
  121. // 用户被删除,则重置第三方信息所绑定的用户id
  122. if (!$user) {
  123. $oauthInfo->user_id = 0;
  124. }
  125. }
  126. // 绑定用户
  127. if ($oauthInfo->user_id === 0 && $user_id > 0) {
  128. $user = UserModel::get($user_id);
  129. if ($user) {
  130. $oauthInfo->user_id = $user_id;
  131. return $oauthInfo->save();
  132. } else {
  133. error_stop('该用户暂不可绑定微信账号');
  134. }
  135. return false;
  136. }
  137. // 注册新用户
  138. if ($oauthInfo->user_id === 0 && $user_id === 0) {
  139. $auth = (new UserAuth())->register([
  140. 'nickname' => $oauthInfo->nickname ?? '',
  141. 'avatar' => $oauthInfo->avatar ?? '',
  142. 'mobile' => $extend['mobile'] ?? ''
  143. ]);
  144. $user = $auth->getUser();
  145. $oauthInfo->user_id = $user->id;
  146. return $oauthInfo->save();
  147. }
  148. }
  149. /**
  150. * 设置平台服务类
  151. *
  152. * @return class
  153. */
  154. private function setPlatformService($payload)
  155. {
  156. switch ($this->platform) {
  157. case 'officialAccount':
  158. $service = new OfficialAccount($payload);
  159. break;
  160. case 'miniProgram':
  161. $service = new MiniProgram($payload);
  162. break;
  163. case 'openPlatform':
  164. $service = new OpenPlatform($payload);
  165. break;
  166. }
  167. if (!isset($service)) error_stop('平台参数有误');
  168. return $service;
  169. }
  170. /**
  171. * 方法转发到驱动提供者
  172. *
  173. * @param string $funcname
  174. * @param array $arguments
  175. * @return void
  176. */
  177. public function __call($funcname, $arguments)
  178. {
  179. return $this->service->{$funcname}(...$arguments);
  180. }
  181. }