231 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			231 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			PHP
		
	
	
|  | <?php | ||
|  | namespace app\controller\api; | ||
|  | 
 | ||
|  | use app\exception\RepositoryException; | ||
|  | use app\model\Account; | ||
|  | use app\repository\AccountRepository; | ||
|  | use app\service\File; | ||
|  | use app\service\Jwt; | ||
|  | use app\service\wx\WechatApplets; | ||
|  | use app\validate\User as UserValidate; | ||
|  | use EasyWeChat\Kernel\Exceptions\InvalidConfigException; | ||
|  | use Exception; | ||
|  | use think\response\Json; | ||
|  | 
 | ||
|  | class User extends Base | ||
|  | { | ||
|  |     protected $noNeedLogin = [ | ||
|  |         'login', | ||
|  |     ]; | ||
|  | 
 | ||
|  |     /** | ||
|  |      * 登录  成功返回token及用户信息 | ||
|  |      * | ||
|  |      * @return Json | ||
|  |      * @throws InvalidConfigException | ||
|  |      */ | ||
|  |     public function login(): Json | ||
|  |     { | ||
|  |         $params = $this->request->param(); | ||
|  | 
 | ||
|  |         $validate = new UserValidate(); | ||
|  |         if (!$validate->scene('wx_applets')->check($params)) { | ||
|  |             return $this->json(4000, $validate->getError()); | ||
|  |         } | ||
|  |         $minApp = WechatApplets::getInstance(); | ||
|  |         $jsCode = $params['code']; | ||
|  |         $wxUser = $minApp->auth->session($jsCode); | ||
|  | 
 | ||
|  |         if (isset($wxUser['errcode']) && $wxUser['errcode'] != 0) { | ||
|  |             return $this->json(4001, $wxUser['errcode'].';'.$wxUser['errmsg'] ?? '登录失败'); | ||
|  |         } | ||
|  |         // $wxUser success has [session_key, openid, unionid]
 | ||
|  |         // 有效期2小时
 | ||
|  |         $wxUser['expire_time'] = time() + 7200; | ||
|  |         $wxUser['session_key'] = $wxUser['session_key'] ?? ''; | ||
|  |         $openID                = $wxUser['openid']; | ||
|  | 
 | ||
|  |         if (empty($openID)) { | ||
|  |             return $this->json(4002, '登录失败'); | ||
|  |         } | ||
|  |         $isActive    = $params['is_active'] ?? 0; | ||
|  |         $isActive    = (is_numeric($isActive) && $isActive > 0) ? AccountRepository::BOOL_TRUE : AccountRepository::BOOL_FALSE; | ||
|  |         $phoneActive = $params['phone_active'] ?? 0; | ||
|  |         $phoneActive = (is_numeric($phoneActive) && $phoneActive > 0) ? AccountRepository::BOOL_TRUE : AccountRepository::BOOL_FALSE; | ||
|  | 
 | ||
|  |         try { | ||
|  |             $repo         = AccountRepository::getInstance(); | ||
|  |             $account      = $repo->findByOpenID($openID); | ||
|  |             $inviteCode   = $params['invite_code'] ?? ''; | ||
|  |             $inviteSource = $params['invite_source'] ?? AccountRepository::INVITE_SOURCE_DEF; | ||
|  |             $channel      = $params['channel'] ?? ''; | ||
|  | 
 | ||
|  |             if (!$account) { | ||
|  |                 // 自动注册
 | ||
|  |                 $inviterAid       = 0; | ||
|  |                 $inviterParentAid = 0; | ||
|  |                 $inviter          = null; | ||
|  | 
 | ||
|  |                 $customerService = 0;// 所属客服
 | ||
|  |                 if (!empty($inviteCode)) { | ||
|  |                     $inviter = $repo->findByInviteCode($inviteCode); | ||
|  |                     if ($inviter) { | ||
|  |                         $inviterAid       = $inviter['id']; | ||
|  |                         $inviterParentAid = $inviter['inviter_account_id']; | ||
|  |                         $channel          = (empty($channel) && $inviter['is_staff'] > 0) ? AccountRepository::CHANNEL_MEMBER : AccountRepository::CHANNEL_CUSTOMER; | ||
|  |                         if ($inviter['is_staff'] > 0) { | ||
|  |                             //若分享人是员工 自动绑定为客服
 | ||
|  |                             $customerService = $inviter['id']; | ||
|  |                         } | ||
|  |                     } | ||
|  |                 } | ||
|  | 
 | ||
|  |                 // 活码进入 绑定客服
 | ||
|  |                 if (isset($params['source_code']) && !empty($params['source_code'])) { | ||
|  |                     if ($sourceUser = Activity::findOne(['code' => $params['source_code']])) { | ||
|  |                         $customerService = $sourceUser['account_id'] ?? 0; | ||
|  |                     } | ||
|  |                 } | ||
|  |                 $inviteSource = in_array($inviteSource, array_keys(AccountRepository::inviteSourceList())) ? $inviteSource : AccountRepository::INVITE_SOURCE_DEF; | ||
|  | 
 | ||
|  |                 $channelList = $repo->channelList(); | ||
|  |                 $channel     = (empty($channel) || !in_array($channel, array_keys($channelList))) ? AccountRepository::CHANNEL_NORMAL : $channel; | ||
|  | 
 | ||
|  |                 $account = $repo->create([ | ||
|  |                     'unionid'            => $wxUser['unionid'] ?? '', | ||
|  |                     'openid'             => $openID, | ||
|  |                     'last_login'         => date('Y-m-d H:i:s'), | ||
|  |                     'login_ip'           => $this->request->ip(), | ||
|  |                     'created_at'         => date('Y-m-d H:i:s'), | ||
|  |                     'created_year'       => date('Y'), | ||
|  |                     'created_month'      => date('n'), | ||
|  |                     'created_day'        => date('j'), | ||
|  |                     'nickname'           => $params['nickname'] ?? '', | ||
|  |                     'headimgurl'         => $params['headimgurl'] ?? '', | ||
|  |                     'country'            => $params['country'] ?? '', | ||
|  |                     'province'           => $params['province'] ?? '', | ||
|  |                     'city'               => $params['city'] ?? '', | ||
|  |                     'county'             => $params['county'] ?? '', | ||
|  |                     'gender'             => $params['gender'] ?? 0, | ||
|  |                     'language'           => $params['language'] ?? 'zh_CN', | ||
|  |                     'mobile'             => $params['mobile'] ?? '', | ||
|  |                     'status'             => AccountRepository::STATUS_NORMAL, | ||
|  |                     'invite_source'      => $inviteSource, | ||
|  |                     'inviter_account_id' => $inviterAid, | ||
|  |                     'inviter_parent_id'  => $inviterParentAid, | ||
|  |                     'channel'            => $channel, | ||
|  |                     'is_staff'           => AccountRepository::BOOL_FALSE, | ||
|  |                     'is_active'          => $isActive, | ||
|  |                     'phone_active'       => $phoneActive, | ||
|  |                     'customer_service'   => $customerService, | ||
|  |                     'source_code'        => $params['source_code'] ?? '', | ||
|  |                     'session_key'        => $wxUser['session_key'] ?? '', | ||
|  |                 ]); | ||
|  | 
 | ||
|  |                 // 存在所属客服 添加绑定记录
 | ||
|  |                 if ($customerService > 0) { | ||
|  |                     CustomerReceive::firstBoundService($account['id'], $customerService); | ||
|  |                 } | ||
|  | 
 | ||
|  |                 $regAccountId  = $account->id ?? 0; | ||
|  |                 $accountActive = $phoneActive > 0; | ||
|  | 
 | ||
|  |                 if ($inviter) { | ||
|  |                     $repo->addShareRegLog($regAccountId, $inviter['id'], AccountRepository::SHARE_GRADE_FIRST, $accountActive); | ||
|  |                     if ($inviterParentAid > 0) { | ||
|  |                         $repo->addShareRegLog($regAccountId, $inviterParentAid, AccountRepository::SHARE_GRADE_SECOND, $accountActive); | ||
|  |                     } | ||
|  | 
 | ||
|  |                     // 邀请人绑定的客服可获得积分, 有效用户才关联
 | ||
|  |                     if ($accountActive) { | ||
|  |                         $boundServiceAid = $repo->getBoundServiceAId($inviter['id']); | ||
|  |                         if ($boundServiceAid > 0) { | ||
|  |                             $repo->addShareRegLog($regAccountId, $boundServiceAid, AccountRepository::SHARE_GRADE_SERVICE, true); | ||
|  |                         } | ||
|  |                     } | ||
|  |                 } | ||
|  | 
 | ||
|  |                 AccountRecord::record($regAccountId, AccountRecord::TYPE_OTHER, AccountRecord::ACTION_REGISTER); | ||
|  | 
 | ||
|  |             } else { | ||
|  |                 $updateData     = [ | ||
|  |                     'last_login'  => date('Y-m-d H:i:s'), | ||
|  |                     'login_ip'    => $this->request->ip(), | ||
|  |                     'session_key' => $wxUser['session_key'] ?? '', | ||
|  |                     'language'    => $params['language'] ?? 'zh_CN', | ||
|  |                 ]; | ||
|  |                 $phoneActiveOld = $account['phone_active']; | ||
|  | 
 | ||
|  |                 // 更新资料
 | ||
|  |                 $modifyStringList = ['headimgurl', 'nickname', 'mobile', 'country', 'province', 'city', 'county']; | ||
|  |                 foreach ($modifyStringList as $modifyKey) { | ||
|  |                     if (isset($account[$modifyKey]) && empty($account[$modifyKey])) { | ||
|  |                         $updateData[$modifyKey] = $params[$modifyKey] ?? ''; | ||
|  |                     } | ||
|  |                 } | ||
|  |                 if (empty($account['gender'])) { | ||
|  |                     $updateData['gender'] = $params['gender'] ?? 0; | ||
|  |                 } | ||
|  |                 if (isset($account['is_active']) && $account['is_active'] == AccountRepository::BOOL_FALSE) { | ||
|  |                     $updateData['is_active'] = $isActive; | ||
|  |                 } | ||
|  |                 if (isset($account['phone_active']) && $account['phone_active'] == AccountRepository::BOOL_FALSE) { | ||
|  |                     $updateData['phone_active'] = $phoneActive; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 $repo->update($updateData, ['id' => $account['id']]); | ||
|  | 
 | ||
|  |                 $account = $repo->findById($account['id']); | ||
|  | 
 | ||
|  |                 // 授权手机号后才能算有效激活用户,并更新相关业务数据
 | ||
|  |                 if ($phoneActiveOld == AccountRepository::BOOL_FALSE && $account['phone_active'] == AccountRepository::BOOL_TRUE) { | ||
|  |                     if ($account['inviter_account_id'] > 0) { | ||
|  |                         $repo->addShareRegLog($account['id'], $account['inviter_account_id'], AccountRepository::SHARE_GRADE_FIRST, true); | ||
|  | 
 | ||
|  |                         // 邀请人绑定的客服可获得积分
 | ||
|  |                         $boundServiceAid = $repo->getBoundServiceAId($account['inviter_account_id']); | ||
|  |                         if ($boundServiceAid > 0) { | ||
|  |                             $repo->addShareRegLog($account['id'], $boundServiceAid, AccountRepository::SHARE_GRADE_SERVICE, true); | ||
|  |                         } | ||
|  |                     } | ||
|  |                     if ($account['inviter_parent_id'] > 0) { | ||
|  |                         $repo->addShareRegLog($account['id'], $account['inviter_parent_id'], AccountRepository::SHARE_GRADE_SECOND, true); | ||
|  |                     } | ||
|  |                 } | ||
|  |             } | ||
|  | 
 | ||
|  |         } catch (RepositoryException | Exception $e) { | ||
|  |             return $this->json(4003, '登录失败!'.$e->getMessage()); | ||
|  |         } | ||
|  | 
 | ||
|  |         $account = $account->toArray(); | ||
|  |         $jwtData = [ | ||
|  |             'user_id'     => $account['id'], | ||
|  |             'open_id'     => $openID, | ||
|  |             'session_key' => $wxUser['session_key'], | ||
|  |             'expire_time' => $wxUser['expire_time'], | ||
|  |         ]; | ||
|  | 
 | ||
|  |         $account['headimgurl'] = File::convertCompleteFileUrl($account['headimgurl']); | ||
|  |         $fields                = [ | ||
|  |             'coding', 'real_name', 'nickname', 'headimgurl', 'gender', 'mobile', | ||
|  |             'province', 'city', 'county', 'country', 'birthday', | ||
|  |             'score', 'status', 'position', 'invite_code', 'channel', | ||
|  |             'is_staff', 'is_active', 'phone_active' | ||
|  |         ]; | ||
|  | 
 | ||
|  |         $accountData          = arrayKeysFilter($account, $fields); | ||
|  |         $account['is_active'] = ($account['is_active'] == Account::COMMON_ON && $account['phone_active'] == Account::COMMON_ON); | ||
|  |         $data                 = [ | ||
|  |             'account_id' => $account['id'], | ||
|  |             'token'      => Jwt::generate($jwtData), | ||
|  |             'expire'     => $wxUser['expire_time'], | ||
|  |             'openid'     => $openID, | ||
|  |         ]; | ||
|  |         $data                 = array_merge($data, $accountData); | ||
|  | 
 | ||
|  |         return $this->json(0, 'success', $data); | ||
|  |     } | ||
|  | 
 | ||
|  | 
 | ||
|  | } |