diff --git a/app/api/controller/Login.php b/app/api/controller/Login.php index 1c0f1b5..9cad3a8 100755 --- a/app/api/controller/Login.php +++ b/app/api/controller/Login.php @@ -33,7 +33,7 @@ class Login extends Base /** * 处理用户的UID * - * @param User $user 用户对象 + * @param User|array $user 用户对象或数组 */ private function processUid($user) { @@ -179,470 +179,7 @@ class Login extends Base return $uid; } - /** - * 微信授权,登录接口 微信登录 - */ - public function login() - { - // 初始化日志收集变量 - $logMessages = []; - try { - $code = request()->param("code", ''); - if (empty($code)) { - $logMessages[] = '用户未获取到code:' . $code; - Log::error(end($logMessages)); - return $this->renderError('请求参数错误'); - } - - $logMessages[] = '用户开始登录: ' . $code; - $click_id = request()->header('clickid'); - $wxPlatform = \app\common\server\platform\PlatformFactory::create(); - $openInfo = $wxPlatform->getOpenid($code); - if ($openInfo['status'] == 0) { - return $this->renderError($openInfo['msg']); - } - $openid = $openInfo['data']['openid']; - $wx_unionid = null; - if (isset($openInfo['data']['unionid'])) { - $wx_unionid = $openInfo['data']['unionid']; - } - // 添加Redis防抖锁 - $redis = (new RedisHelper())->getRedis(); - $lockKey = 'login:debounce:' . $openid; - if (!$redis->set($lockKey, 1, ['nx', 'ex' => 3])) { - $logMessages[] = '用户登录请求过于频繁: ' . $openid; - Log::warning(end($logMessages)); - return $this->renderError('请勿频繁登录,请稍后再试'); - } - - $user = null; - if ($wx_unionid != null && $wx_unionid != '') { - $user = User::getInfo(['unionid' => $wx_unionid]); - } - if ($user == null) { - $user = User::getInfo(['openid' => $openid]); - } - - // return $this->renderSuccess("登录成功", $user); - if ($user) { - if ($user['click_id'] != $click_id) { - $res[] = User::where(['id' => $user['id']])->update(['click_id' => $click_id]); - } - //设置unionId - if ($wx_unionid && !empty($wx_unionid)) { - $unionid = $user['unionid']; - if ($unionid == null || empty($unionid)) { - $user['unionid'] = $wx_unionid; - // User::update($user); - $user->save(); - } - } - - // 检查并生成uid - $this->processUid($user); - - #token时间戳 - $time = time(); - #token字符串 - $token_num = getRandStr(10); - #加密token - $account_token = user_md5($user['id'] . $token_num . $time); - #更新账号信息 - $last_login_ip1 = $this->getRealIp(); - $result = $this->ip_location($last_login_ip1); - $ip_province = ''; - $ip_city = ''; - $ip_adcode = ''; - if ($result) { - $ip_province = $result['province']; - $ip_city = $result['city']; - $ip_adcode = $result['adcode']; - - } else { - - } - - // 检查UserAccount是否存在 - $userAccount = UserAccount::where(['user_id' => $user['id']])->find(); - if ($userAccount) { - // 存在则更新 - $res[] = UserAccount::where(['user_id' => $user['id']])->update([ - 'account_token' => $account_token, - 'token_num' => $token_num, - 'token_time' => $time, - 'last_login_time' => $time, - 'last_login_ip' => ip2long($last_login_ip1), - 'last_login_ip1' => $last_login_ip1, - 'ip_adcode' => $ip_adcode, - 'ip_province' => $ip_province, - 'ip_city' => $ip_city, - ]); - } else { - // 不存在则新增 - $res[] = UserAccount::insert([ - 'user_id' => $user['id'], - 'account_token' => $account_token, - 'token_num' => $token_num, - 'token_time' => $time, - 'last_login_time' => $time, - 'last_login_ip' => ip2long($last_login_ip1), - 'last_login_ip1' => $last_login_ip1, - 'ip_adcode' => $ip_adcode, - 'ip_province' => $ip_province, - 'ip_city' => $ip_city, - ]); - } - - // 记录用户登录日志(每天只记录一次) - UserLoginLog::recordLogin( - $user['id'], - 'wechat', - $last_login_ip1, - ''//$ip_province . $ip_city - ); - - $logMessages[] = '用户登录成功: ' . $code . ' 用户ID: ' . $user['id'] . '用户手机号' . $user['mobile']; - // 输出收集的所有日志 - Log::info(implode("==》", $logMessages)); - - return $this->renderSuccess("登录成功", $account_token); - - } else { - $nickname = request()->param('nickname', ''); - $headimg = request()->param('headimg', ''); - // if (!$nickname) { - // return $this->renderError('请求参数错误!'); - // } - - $pid = 0; - $pid_pid = request()->param('pid', 0); - - $randx = rand(1000, 9999); - $nickname = "微信用户" . $randx; - $logMessages[] = $nickname; - $randx = rand(10000, 99999); - $identicon = new \Identicon\Identicon(); - $imageData = $identicon->getImageData($openid . $nickname); - $uploadResult = $this->uploader->uploadFile($imageData, "storage/users/icon/default/" . $randx . ".png"); - $headimg = $uploadResult['full_url']; - if ($pid_pid) { - $logMessages[] = "尝试获取推荐人ID: " . $pid_pid; - $pid_info = User::where('id', '=', $pid_pid)->value("id"); - if ($pid_info) { - $logMessages[] = "获取推荐人ID成功: " . $pid_info; - $pid = $pid_info; - } - } - Db::startTrans(); - - $res[] = $user_id = User::insertGetId([ - 'openid' => $openid, - 'nickname' => $nickname, - 'headimg' => $headimg, - 'pid' => $pid, - 'addtime' => time(), - 'click_id' => $click_id, - 'unionid' => $wx_unionid, - 'uid' => '', - ]); - - // 生成用户uid - $uid = $this->generateUid($user_id); - if ($uid) { - User::where('id', $user_id)->update(['uid' => $uid]); - } - // $isTest = \app\common\helper\ConfigHelper::getSystemTestKey("enable_test"); - // if ($isTest == "1") { - // $userCount = ProfitMoney::where('user_id', $user_id) - // ->where('type', 8) - // ->where('content', '=', '内测免费送') - // ->count(); - // if ($userCount == 0) { - // // 使用Redis锁防止重复获取 - // $redis = (new RedisHelper())->getRedis(); - // $lockKey = 'user:beta_reward:' . $user_id; - // if ($redis->set($lockKey, 1, ['nx', 'ex' => 60])) { - // $res[] = User::changeMoney($user_id, 50000, 8, '内测免费送'); - // $logMessages[] = '赠送钻石: 50000'; - // // 释放锁 - // $redis->del($lockKey); - // } - // } - // } - $time = time(); - #token字符串 - $token_num = getRandStr(10); - #加密token - $account_token = user_md5($user_id . $token_num . $time); - #更新账号信息 - $last_login_ip1 = $this->getRealIp(); - $result = $this->ip_location($last_login_ip1); - $ip_province = ''; - $ip_city = ''; - $ip_adcode = ''; - if ($result) { - $ip_province = $result['province']; - $ip_city = $result['city']; - $ip_adcode = $result['adcode']; - } else { - - - } - $res[] = UserAccount::insert([ - 'user_id' => $user_id, - 'account_token' => $account_token, - 'token_num' => $token_num, - 'token_time' => $time, - 'last_login_time' => $time, - 'last_login_ip' => ip2long($last_login_ip1), - 'last_login_ip1' => $last_login_ip1, - 'ip_adcode' => $ip_adcode, - 'ip_province' => $ip_province, - 'ip_city' => $ip_city, - ]); - #记录登录日志 - - #推荐成功之后获取一张抽奖券 - #配置 - $rule = getConfig('base'); - $draw_people_num = $rule['draw_people_num']; - if (!empty($pid)) { - $num = 0; - $num = ProfitDraw::where(['type' => 5, 'user_id' => $pid, 'share_uid' => $user_id])->count(); - if (bccomp("$num", "$draw_people_num") < 0) { - #可以获得一张抽奖券 - // $res[] = User::changeDraw($pid, 1, 5, '获得一张抽奖券', $user_id); - } - - } - if (resCheck($res)) { - // 新用户注册也要记录登录日志 - UserLoginLog::recordLogin( - $user_id, - 'wechat:v1.0.0', - $last_login_ip1, - ''//$ip_province . $ip_city - ); - - $logMessages[] = '==》用户注册成功: ' . $code . ' 用户ID: ' . $user_id; - // 输出收集的所有日志 - Log::info(implode("==>", $logMessages)); - - Db::commit(); - return $this->renderSuccess("登录成功", $account_token); - } else { - Db::rollback(); - - $logMessages[] = '==》用户注册失败: ' . $code . ' 用户ID: ' . $user_id; - // 输出收集的所有日志 - Log::info(implode("==>", $logMessages)); - - return $this->renderError("登录失败"); - } - } - } catch (\Exception $e) { - Log::error('登录失败->错误信息' . $e->getMessage()); - Log::error('登录失败->错误行数' . $e->getLine()); - return $this->renderError("登录失败"); - } - } - - - /** - * 微信授权-公众号登录 - */ - public function h5login() - { - - try { - $code = request()->param("code", ''); - if (empty($code)) { - return $this->renderError('请求参数错误'); - } - $click_id = request()->header('clickid'); - $wxServer = new \app\common\server\WechatOfficialAccount($this->app); - $user_base = $wxServer->getAccessToken($code); - // $user_base_info = $wxServer->getUserInfo($user_base); - $retrieved_openid = $user_base['openid']; - - $openid = $retrieved_openid; - - // 添加Redis防抖锁 - $redis = (new RedisHelper())->getRedis(); - $lockKey = 'login:h5:debounce:' . $openid; - if (!$redis->set($lockKey, 1, ['nx', 'ex' => 3])) { - Log::warning('用户公众号登录请求过于频繁: ' . $openid); - return $this->renderError('请勿频繁登录,请稍后再试'); - } - - $user = null; - if ($user_base['unionid'] != null && $user_base['unionid'] != '') { - - $unionid = $user_base['unionid']; - $user = User::getInfo(['unionid' => $unionid]); - if ($user != null) { - // $user - if ($user['gzh_openid'] == null || $user['gzh_openid'] != $retrieved_openid) { - $user['gzh_openid'] = $retrieved_openid; - $user->save(); - } - - } - } - if ($user == null) { - $user = User::getInfo(['openid' => $openid]); - } - // return $this->renderSuccess("登录成功", $user); - if ($user) { - if ($user['click_id'] != $click_id) { - $res[] = User::where(['id' => $user['id']])->update(['click_id' => $click_id]); - } - #token时间戳 - $time = time(); - #token字符串 - $token_num = getRandStr(10); - #加密token - $account_token = user_md5($user['id'] . $token_num . $time); - #更新账号信息 - $last_login_ip1 = $this->getRealIp(); - $result = $this->ip_location($last_login_ip1); - $ip_province = ''; - $ip_city = ''; - $ip_adcode = ''; - if ($result) { - - $ip_province = $result['province']; - $ip_city = $result['city']; - $ip_adcode = $result['adcode']; - - } else { - - - } - $res[] = UserAccount::where(['user_id' => $user['id']])->update([ - 'account_token' => $account_token, - 'token_num' => $token_num, - 'token_time' => $time, - 'last_login_time' => $time, - 'last_login_ip' => ip2long($last_login_ip1), - 'last_login_ip1' => $last_login_ip1, - 'ip_adcode' => $ip_adcode, - 'ip_province' => $ip_province, - 'ip_city' => $ip_city, - ]); - - // 记录用户登录日志(每天只记录一次) - UserLoginLog::recordLogin( - $user['id'], - 'wechat_h5', - $last_login_ip1, - $ip_province . $ip_city - ); - - return $this->renderSuccess("登录成功", $account_token); - - } else { - $userinfo = $wxServer->getUserInfo($user_base); - $nickname = $userinfo['nickname']; - $headimg = $userinfo['headimgurl']; - if (!$nickname || !$headimg) { - return $this->renderError('请求参数错误!'); - } - $pid = 0; - $pid_pid = request()->param('pid', 0); - if ($pid_pid > 0) { - log::info("获取推荐人id" . $pid_pid); - } - - - if ($pid_pid) { - $pid_info = User::where('id', '=', $pid_pid)->value("id"); - if ($pid_info) { - log::info("获取推荐人id" . $pid_info); - $pid = $pid_info; - } - } - - Db::startTrans(); - - $res[] = $user_id = User::insertGetId([ - 'openid' => $openid, - 'nickname' => $nickname, - 'headimg' => $headimg, - 'pid' => $pid, - 'addtime' => time(), - 'click_id' => $click_id, - 'uid' => '', - ]); - $time = time(); - #token字符串 - $token_num = getRandStr(10); - #加密token - $account_token = user_md5($user_id . $token_num . $time); - #更新账号信息 - $last_login_ip1 = $this->getRealIp(); - $result = $this->ip_location($last_login_ip1); - $ip_province = ''; - $ip_city = ''; - $ip_adcode = ''; - if ($result) { - $ip_province = $result['province']; - $ip_city = $result['city']; - $ip_adcode = $result['adcode']; - } else { - - - } - $res[] = UserAccount::insert([ - 'user_id' => $user_id, - 'account_token' => $account_token, - 'token_num' => $token_num, - 'token_time' => $time, - 'last_login_time' => $time, - 'last_login_ip' => ip2long($last_login_ip1), - 'last_login_ip1' => $last_login_ip1, - 'ip_adcode' => $ip_adcode, - 'ip_province' => $ip_province, - 'ip_city' => $ip_city, - ]); - #记录登录日志 - - #推荐成功之后获取一张抽奖券 - #配置 - $rule = getConfig('base'); - $draw_people_num = $rule['draw_people_num']; - if (!empty($pid)) { - $num = 0; - $num = ProfitDraw::where(['type' => 5, 'user_id' => $pid, 'share_uid' => $user_id])->count(); - if (bccomp("$num", "$draw_people_num") < 0) { - #可以获得一张抽奖券 - $res[] = User::changeDraw($pid, 1, 5, '获得一张抽奖券', $user_id); - } - - } - if (resCheck($res)) { - // 新用户注册也要记录登录日志 - UserLoginLog::recordLogin( - $user_id, - 'wechat_h5', - $last_login_ip1, - $ip_province . $ip_city - ); - - Db::commit(); - return $this->renderSuccess("登录成功", $account_token); - } else { - Db::rollback(); - return $this->renderError("登录失败"); - } - } - } catch (\Exception $e) { - Log::error('错误信息' . $e->getMessage()); - Log::error('错误行数' . $e->getLine()); - return $this->renderError('非法请求'); - } - } public function ip_location($last_login_ip) { @@ -667,6 +204,214 @@ class Login extends Base } + /** + * 创建默认头像 + * + * @param string $seed 用于生成头像的种子字符串 + * @param string $prefix 头像前缀(如"微信用户") + * @return array [nickname, headimg] + */ + private function createDefaultAvatar($seed, $prefix = '') + { + // 生成随机昵称 + $randx = rand(1000, 9999); + $nickname = ($prefix ?: "用户") . $randx; + + // 使用Identicon生成默认头像 + $randx = rand(10000, 99999); + $identicon = new \Identicon\Identicon(); + $imageData = $identicon->getImageData($seed . $nickname); + $uploadResult = $this->uploader->uploadFile($imageData, "storage/users/icon/default/" . $randx . ".png"); + $headimg = $uploadResult['full_url']; + + return ['nickname' => $nickname, 'headimg' => $headimg]; + } + + /** + * 创建或更新用户账号信息 + * + * @param int $user_id 用户ID + * @param string $platform 登录平台 + * @return array [account_token, token_data] + */ + private function createAccount($user_id, $platform = 'unknown') + { + // 获取IP和地理位置信息 + $last_login_ip = $this->getRealIp(); + $result = $this->ip_location($last_login_ip); + $ip_province = ''; + $ip_city = ''; + $ip_adcode = ''; + if ($result) { + $ip_province = $result['province']; + $ip_city = $result['city']; + $ip_adcode = $result['adcode']; + } + + // 生成token + $time = time(); + $token_num = getRandStr(10); + $account_token = user_md5($user_id . $token_num . $time); + + // 准备账号数据 + $account_data = [ + 'account_token' => $account_token, + 'token_num' => $token_num, + 'token_time' => $time, + 'last_login_time' => $time, + 'last_login_ip' => ip2long($last_login_ip), + 'last_login_ip1' => $last_login_ip, + 'ip_adcode' => $ip_adcode, + 'ip_province' => $ip_province, + 'ip_city' => $ip_city, + ]; + + // 检查账号是否存在 + $userAccount = UserAccount::where(['user_id' => $user_id])->find(); + $res = []; + + if ($userAccount) { + // 更新账号信息 + $res[] = UserAccount::where(['user_id' => $user_id])->update($account_data); + } else { + // 创建新账号 + $account_data['user_id'] = $user_id; + $res[] = UserAccount::insert($account_data); + } + + // 记录登录日志 + UserLoginLog::recordLogin( + $user_id, + $platform, + $last_login_ip, + $ip_province && $ip_city ? $ip_province . $ip_city : '' + ); + + return ['account_token' => $account_token, 'token_data' => $account_data, 'res' => $res]; + } + + /** + * 处理用户登录或注册的通用逻辑 + * + * @param mixed $user 已有用户数据 + * @param array $userData 新用户数据 (如果需要注册) + * @param array $options 其他选项 + * @return array|bool 登录结果 + */ + private function handleLogin($user, $userData = [], $options = []) + { + $res = []; + $logMessages = $options['logMessages'] ?? []; + $click_id = $options['click_id'] ?? ''; + $platform = $options['platform'] ?? $this->getPlatform(); + $register_platform = $options['register_platform'] ?? $platform; + + // 用户已存在,进行登录 + if ($user) { + if (!empty($click_id) && $user['click_id'] != $click_id) { + $res[] = User::where(['id' => $user['id']])->update(['click_id' => $click_id]); + } + + // 处理特殊字段更新 + if (!empty($options['update_fields'])) { + foreach ($options['update_fields'] as $field => $value) { + if ($user[$field] == null || empty($user[$field])) { + $user[$field] = $value; + $user->save(); + } + } + } + + // 检查并生成uid + $this->processUid($user); + + // 创建账号Token + $accountResult = $this->createAccount($user['id'], $platform); + $res = array_merge($res, $accountResult['res']); + $account_token = $accountResult['account_token']; + + if (!empty($logMessages)) { + $logMessages[] = '用户登录成功: 用户ID: ' . $user['id']; + Log::info(implode("==》", $logMessages)); + } + + return ['success' => true, 'token' => $account_token, 'user_id' => $user['id'], 'res' => $res]; + } + // 用户不存在,需要注册 + else if (!empty($userData)) { + // 开始事务 + Db::startTrans(); + + // 处理推荐人 + $pid = 0; + if (!empty($options['pid']) && is_numeric($options['pid'])) { + $pid_info = User::where('id', '=', $options['pid'])->value("id"); + if ($pid_info) { + if (!empty($logMessages)) { + $logMessages[] = "获取推荐人ID成功: " . $pid_info; + } + $pid = $pid_info; + } + } + + // 准备用户数据 + $userData['pid'] = $pid; + $userData['addtime'] = time(); + $userData['click_id'] = $click_id; + $userData['uid'] = ''; + + // 插入用户数据 + $res[] = $user_id = User::insertGetId($userData); + + // 生成用户uid + $uid = $this->generateUid($user_id); + if ($uid) { + User::where('id', $user_id)->update(['uid' => $uid]); + } + + // 创建账号 + $accountResult = $this->createAccount($user_id, $register_platform); + $res = array_merge($res, $accountResult['res']); + $account_token = $accountResult['account_token']; + + // 处理推荐人奖励(抽奖券) + if (!empty($pid)) { + $rule = getConfig('base'); + $draw_people_num = $rule['draw_people_num'] ?? 0; + if ($draw_people_num > 0) { + $num = ProfitDraw::where(['type' => 5, 'user_id' => $pid, 'share_uid' => $user_id])->count(); + if (bccomp("$num", "$draw_people_num") < 0) { + if (!empty($options['give_draw'])) { + $res[] = User::changeDraw($pid, 1, 5, '获得一张抽奖券', $user_id); + } + } + } + } + + // 处理事务 + if (resCheck($res)) { + if (!empty($logMessages)) { + $logMessages[] = '==》用户注册成功: 用户ID: ' . $user_id; + Log::info(implode("==>", $logMessages)); + } + + Db::commit(); + return ['success' => true, 'token' => $account_token, 'user_id' => $user_id, 'res' => $res]; + } else { + Db::rollback(); + + if (!empty($logMessages)) { + $logMessages[] = '==》用户注册失败: 用户ID: ' . $user_id; + Log::info(implode("==>", $logMessages)); + } + + return ['success' => false, 'msg' => '登录失败']; + } + } else { + return ['success' => false, 'msg' => '用户不存在且未提供注册数据']; + } + } + /** * 绑定手机号 */ @@ -757,6 +502,88 @@ class Login extends Base } + public function bindMobile() + { + + $mobile = request()->param("mobile", ''); + $code = request()->param("code", ''); + if (empty($code)) { + return $this->renderError('请输入验证码'); + } + if (empty($mobile)) { + return $this->renderError('请输入手机号'); + } + $redis = (new RedisHelper())->getRedis(); + $redisKey = "VerificationCode:{$mobile}"; + $redisCode = $redis->get($redisKey); + $is_test = EnvHelper::getIsTest(); + if (!$is_test) { + if (empty($redisCode) || $redisCode != $code) { + $logMessages[] = '验证码错误: ' . $code . ',正确验证码: ' . $redisCode . '==>' . $mobile; + Log::error(end($logMessages)); + return $this->renderError('验证码错误'); + } + } + + $user = $this->getUser(); + $user_id = $user['id']; + if (empty($user_id)) { + return $this->renderError('用户不存在'); + } + Db::startTrans(); + $res = []; + + $data = []; + //查找用户是否存在 + $user_mobile = User::where(['mobile' => $mobile])->find(); + if ($user_mobile) { + //现在用户数据 + $old_user_account = UserAccount::where(['user_id' => $user_id])->find(); + $nickName = $user_mobile['nickname']; + $headimg = $user_mobile['headimg']; + $position = strpos($nickName, "用户"); // 返回6 + if ($position !== false) { + $nickName = $user['nickname']; + $headimg = $user['headimg']; + $user_mobile->nickname = $nickName; + $user_mobile->headimg = $headimg; + } + $user_mobile->unionid = $user['unionid']; + $user_mobile->save(); + + $time = time(); + #token字符串 + $token_num = getRandStr(10); + #加密token + $account_token = user_md5($user_mobile['id'] . $token_num . $time); + #修改token + $res[] = UserAccount::where(['user_id' => $user_mobile['id']])->update([ + 'account_token' => $account_token, + 'token_num' => $token_num, + 'token_time' => $time, + 'last_login_time' => $old_user_account['last_login_time'], + 'last_login_ip' => $old_user_account['last_login_ip'], + ]); + #修改 + $res[] = User::where(['id' => $user['id']])->delete(); + $res[] = UserAccount::where(['user_id' => $user_id])->delete(); + $data['token'] = $account_token; + + } else { + $res[] = User::where(['id' => $user['id']])->update([ + 'mobile' => $mobile, + 'update_time' => time(), + ]); + } + if (resCheck($res)) { + Db::commit(); + return $this->renderSuccess("绑定成功", $data); + } else { + Db::rollback(); + return $this->renderSuccess("绑定成功"); + } + } + /** * * @@ -770,8 +597,6 @@ class Login extends Base return $this->renderSuccess('', $data); } - - /** * 记录用户登录 * 小程序每次打开时调用此方法记录登录信息 @@ -859,6 +684,182 @@ class Login extends Base } } + /** + * 微信授权,登录接口 微信登录 + */ + public function wxMplogin() + { + // 初始化日志收集变量 + $logMessages = []; + + try { + $code = request()->param("code", ''); + if (empty($code)) { + $logMessages[] = '用户未获取到code:' . $code; + Log::error(end($logMessages)); + return $this->renderError('请求参数错误'); + } + + $logMessages[] = '用户开始登录: ' . $code; + $click_id = request()->header('clickid'); + $wxPlatform = \app\common\server\platform\PlatformFactory::create(); + $openInfo = $wxPlatform->getOpenid($code); + if ($openInfo['status'] == 0) { + return $this->renderError($openInfo['msg']); + } + + $openid = $openInfo['data']['openid']; + $wx_unionid = isset($openInfo['data']['unionid']) ? $openInfo['data']['unionid'] : null; + + // 添加Redis防抖锁 + $redis = (new RedisHelper())->getRedis(); + $lockKey = 'login:debounce:' . $openid; + if (!$redis->set($lockKey, 1, ['nx', 'ex' => 3])) { + $logMessages[] = '用户登录请求过于频繁: ' . $openid; + Log::warning(end($logMessages)); + return $this->renderError('请勿频繁登录,请稍后再试'); + } + + // 查找用户 + $user = null; + if ($wx_unionid) { + $user = User::getInfo(['unionid' => $wx_unionid]); + } + if ($user == null) { + $user = User::getInfo(['openid' => $openid]); + } + + // 如果用户不存在,准备注册数据 + $userData = null; + if (!$user) { + // 生成默认头像和昵称 + $avatar = $this->createDefaultAvatar($openid, "微信用户"); + + $userData = [ + 'openid' => $openid, + 'nickname' => $avatar['nickname'], + 'headimg' => $avatar['headimg'], + 'unionid' => $wx_unionid, + ]; + } + + // 处理登录 + $loginResult = $this->handleLogin( + $user, + $userData, + [ + 'logMessages' => $logMessages, + 'click_id' => $click_id, + 'platform' => 'wechat', + 'register_platform' => 'wechat:v1.0.0', + 'pid' => request()->param('pid', 0), + 'update_fields' => [ + 'unionid' => $wx_unionid + ] + ] + ); + + if ($loginResult['success']) { + return $this->renderSuccess("登录成功", $loginResult['token']); + } else { + return $this->renderError($loginResult['msg'] ?? "登录失败"); + } + + } catch (\Exception $e) { + Log::error('登录失败->错误信息' . $e->getMessage()); + Log::error('登录失败->错误行数' . $e->getLine()); + return $this->renderError("登录失败"); + } + } + + /** + * 微信授权-公众号登录 + */ + public function h5login() + { + try { + $code = request()->param("code", ''); + if (empty($code)) { + return $this->renderError('请求参数错误'); + } + + $click_id = request()->header('clickid'); + $wxServer = new \app\common\server\WechatOfficialAccount($this->app); + $user_base = $wxServer->getAccessToken($code); + $openid = $user_base['openid']; + $unionid = $user_base['unionid'] ?? null; + + // 添加Redis防抖锁 + $redis = (new RedisHelper())->getRedis(); + $lockKey = 'login:h5:debounce:' . $openid; + if (!$redis->set($lockKey, 1, ['nx', 'ex' => 3])) { + Log::warning('用户公众号登录请求过于频繁: ' . $openid); + return $this->renderError('请勿频繁登录,请稍后再试'); + } + + // 查找用户 + $user = null; + if ($unionid) { + $user = User::getInfo(['unionid' => $unionid]); + if ($user) { + // 更新公众号openid + if ($user['gzh_openid'] == null || $user['gzh_openid'] != $openid) { + $user['gzh_openid'] = $openid; + $user->save(); + } + } + } + if ($user == null) { + $user = User::getInfo(['openid' => $openid]); + } + + // 如果用户不存在,获取用户信息并准备注册 + $userData = null; + if (!$user) { + $userinfo = $wxServer->getUserInfo($user_base); + $nickname = $userinfo['nickname'] ?? ''; + $headimg = $userinfo['headimgurl'] ?? ''; + + if (!$nickname || !$headimg) { + return $this->renderError('请求参数错误!'); + } + + $userData = [ + 'openid' => $openid, + 'nickname' => $nickname, + 'headimg' => $headimg, + 'unionid' => $unionid, + ]; + } + + // 处理登录 + $loginResult = $this->handleLogin( + $user, + $userData, + [ + 'click_id' => $click_id, + 'platform' => 'wechat_h5', + 'pid' => request()->param('pid', 0), + 'give_draw' => true, + 'update_fields' => [ + 'gzh_openid' => $openid + ] + ] + ); + + if ($loginResult['success']) { + return $this->renderSuccess("登录成功", $loginResult['token']); + } else { + return $this->renderError($loginResult['msg'] ?? "登录失败"); + } + + } catch (\Exception $e) { + Log::error('错误信息' . $e->getMessage()); + Log::error('错误行数' . $e->getLine()); + return $this->renderError('非法请求'); + } + } + /** * 手机号登录接口 */ @@ -899,7 +900,6 @@ class Login extends Base } } - // 验证通过后删除Redis中的验证码 $redis->del($redisKey); @@ -911,213 +911,43 @@ class Login extends Base return $this->renderError('请勿频繁登录,请稍后再试'); } - // 检查用户是否已存在 + // 查找用户 $user = User::getInfo(['mobile' => $mobile]); - // 如果用户已存在 - if ($user) { - if ($user['click_id'] != $click_id) { - $res[] = User::where(['id' => $user['id']])->update(['click_id' => $click_id]); - } + // 如果用户不存在,准备注册数据 + $userData = null; + if (!$user) { + // 生成默认头像和昵称 + $avatar = $this->createDefaultAvatar($mobile, "友达用户"); - // 检查并生成uid - $this->processUid($user); - - // token时间戳 - $time = time(); - // token字符串 - $token_num = getRandStr(10); - // 加密token - $account_token = user_md5($user['id'] . $token_num . $time); - // 更新账号信息 - $last_login_ip1 = $this->getRealIp(); - $result = $this->ip_location($last_login_ip1); - $ip_province = ''; - $ip_city = ''; - $ip_adcode = ''; - if ($result) { - $ip_province = $result['province']; - $ip_city = $result['city']; - $ip_adcode = $result['adcode']; - } - - // 检查UserAccount是否存在 - $userAccount = UserAccount::where(['user_id' => $user['id']])->find(); - if ($userAccount) { - // 存在则更新 - $res[] = UserAccount::where(['user_id' => $user['id']])->update([ - 'account_token' => $account_token, - 'token_num' => $token_num, - 'token_time' => $time, - 'last_login_time' => $time, - 'last_login_ip' => ip2long($last_login_ip1), - 'last_login_ip1' => $last_login_ip1, - 'ip_adcode' => $ip_adcode, - 'ip_province' => $ip_province, - 'ip_city' => $ip_city, - ]); - } else { - // 不存在则新增 - $res[] = UserAccount::insert([ - 'user_id' => $user['id'], - 'account_token' => $account_token, - 'token_num' => $token_num, - 'token_time' => $time, - 'last_login_time' => $time, - 'last_login_ip' => ip2long($last_login_ip1), - 'last_login_ip1' => $last_login_ip1, - 'ip_adcode' => $ip_adcode, - 'ip_province' => $ip_province, - 'ip_city' => $ip_city, - ]); - } - - // 记录用户登录日志(每天只记录一次) - UserLoginLog::recordLogin( - $user['id'], - 'mobile', - $last_login_ip1, - '' - ); - - $logMessages[] = '用户手机号登录成功: ' . $mobile . ' 用户ID: ' . $user['id']; - // 输出收集的所有日志 - Log::info(implode("==》", $logMessages)); - - return $this->renderSuccess("登录成功", $account_token); - } else { - // 用户不存在,创建新用户 - $pid = 0; - if ($pid_pid) { - $logMessages[] = "尝试获取推荐人ID: " . $pid_pid; - $pid_info = User::where('id', '=', $pid_pid)->value("id"); - if ($pid_info) { - $logMessages[] = "获取推荐人ID成功: " . $pid_info; - $pid = $pid_info; - } - } - - // 开始事务 - Db::startTrans(); - - // 生成随机昵称和头像 - $randx = rand(1000, 9999); - $nickname = "手机用户" . $randx; - $logMessages[] = $nickname; - - // 使用Identicon生成默认头像 - $randx = rand(10000, 99999); - $identicon = new \Identicon\Identicon(); - $imageData = $identicon->getImageData($mobile . $nickname); - $uploadResult = $this->uploader->uploadFile($imageData, "storage/users/icon/default/" . $randx . ".png"); - $headimg = $uploadResult['full_url']; - - // 插入用户记录 - $res[] = $user_id = User::insertGetId([ - 'openid' => '', // 手机号注册无openid + $userData = [ + 'openid' => '', // 手机号注册无openid 'mobile' => $mobile, - 'nickname' => $nickname, - 'headimg' => $headimg, - 'pid' => $pid, - 'addtime' => time(), - 'click_id' => $click_id, - 'uid' => '', - ]); - - // 生成用户uid - $uid = $this->generateUid($user_id); - if ($uid) { - User::where('id', $user_id)->update(['uid' => $uid]); - } - - // 如果是测试环境,给新用户赠送钻石 - // $isTest = \app\common\helper\ConfigHelper::getSystemTestKey("enable_test"); - // if ($isTest == "1") { - // $userCount = ProfitMoney::where('user_id', $user_id) - // ->where('type', 8) - // ->where('content', '=', '内测免费送') - // ->count(); - // if ($userCount == 0) { - // // 使用Redis锁防止重复获取 - // $redis = (new RedisHelper())->getRedis(); - // $lockKey = 'user:beta_reward:' . $user_id; - // if ($redis->set($lockKey, 1, ['nx', 'ex' => 60])) { - // $res[] = User::changeMoney($user_id, 50000, 8, '内测免费送'); - // $logMessages[] = '赠送钻石: 50000'; - // // 释放锁 - // $redis->del($lockKey); - // } - // } - // } - - // 生成账号token - $time = time(); - $token_num = getRandStr(10); - $account_token = user_md5($user_id . $token_num . $time); - - // 获取IP和地理位置信息 - $last_login_ip1 = $this->getRealIp(); - $result = $this->ip_location($last_login_ip1); - $ip_province = ''; - $ip_city = ''; - $ip_adcode = ''; - if ($result) { - $ip_province = $result['province']; - $ip_city = $result['city']; - $ip_adcode = $result['adcode']; - } - - // 插入用户账号信息 - $res[] = UserAccount::insert([ - 'user_id' => $user_id, - 'account_token' => $account_token, - 'token_num' => $token_num, - 'token_time' => $time, - 'last_login_time' => $time, - 'last_login_ip' => ip2long($last_login_ip1), - 'last_login_ip1' => $last_login_ip1, - 'ip_adcode' => $ip_adcode, - 'ip_province' => $ip_province, - 'ip_city' => $ip_city, - ]); - - // 推荐成功后获取抽奖券 - $rule = getConfig('base'); - $draw_people_num = $rule['draw_people_num']; - if (!empty($pid)) { - $num = 0; - $num = ProfitDraw::where(['type' => 5, 'user_id' => $pid, 'share_uid' => $user_id])->count(); - if (bccomp("$num", "$draw_people_num") < 0) { - // 可以获得一张抽奖券 - $res[] = User::changeDraw($pid, 1, 5, '获得一张抽奖券', $user_id); - } - } - - if (resCheck($res)) { - // 新用户注册也要记录登录日志 - UserLoginLog::recordLogin( - $user_id, - 'mobile:v1.0.0', - $last_login_ip1, - '' - ); - - $logMessages[] = '==》用户手机号注册成功: ' . $mobile . ' 用户ID: ' . $user_id; - // 输出收集的所有日志 - Log::info(implode("==>", $logMessages)); - - Db::commit(); - return $this->renderSuccess("登录成功", $account_token); - } else { - Db::rollback(); - - $logMessages[] = '==》用户手机号注册失败: ' . $mobile . ' 用户ID: ' . $user_id; - // 输出收集的所有日志 - Log::info(implode("==>", $logMessages)); - - return $this->renderError("登录失败"); - } + 'nickname' => $avatar['nickname'], + 'headimg' => $avatar['headimg'], + ]; } + + // 处理登录 + $loginResult = $this->handleLogin( + $user, + $userData, + [ + 'logMessages' => $logMessages, + 'click_id' => $click_id, + 'platform' => $this->getPlatform(), + 'register_platform' => 'mobile:v1.0.0', + 'pid' => $pid_pid, + 'give_draw' => true + ] + ); + + if ($loginResult['success']) { + return $this->renderSuccess("登录成功", $loginResult['token']); + } else { + return $this->renderError($loginResult['msg'] ?? "登录失败"); + } + } catch (\Exception $e) { Log::error('手机号登录失败->错误信息' . $e->getMessage()); Log::error('手机号登录失败->错误行数' . $e->getLine()); @@ -1125,4 +955,55 @@ class Login extends Base } } + /** + * 微信App登录接口 + */ + public function wxAppLogin() + { + $unionId = request()->param('unionId', ''); + $nickname = request()->param('nickname', ''); + $headimg = request()->param('headimg', ''); + $pid_pid = request()->param('pid', 0); + + if (empty($unionId)) { + return $this->renderError("参数错误"); + } + + // 查找用户 + $user = User::where('unionid', $unionId)->find(); + // 如果用户不存在,准备注册数据 + $userData = null; + if (!$user) { + // 如果提供了昵称,使用提供的昵称,否则生成默认昵称 + if (!$nickname) { + $avatar = $this->createDefaultAvatar($unionId, "友达用户"); + $nickname = $avatar['nickname']; + $headimg = $avatar['headimg']; + } + $userData = [ + 'openid' => '', + 'mobile' => '', + 'nickname' => $nickname, + 'headimg' => $headimg, + 'unionid' => $unionId, + ]; + } + + // 处理登录 + $loginResult = $this->handleLogin( + $user, + $userData, + [ + 'platform' => $this->getPlatform(), + 'pid' => $pid_pid, + 'give_draw' => true + ] + ); + + if ($loginResult['success']) { + return $this->renderSuccess("登录成功", $loginResult['token']); + } else { + return $this->renderError($loginResult['msg'] ?? "登录失败"); + } + } } \ No newline at end of file diff --git a/app/api/route/app.php b/app/api/route/app.php index 3893f89..0d8a4e5 100755 --- a/app/api/route/app.php +++ b/app/api/route/app.php @@ -15,9 +15,11 @@ use think\facade\Route; #============================ #Login.php登录 #============================ -Route::any('login', 'Login/login'); +Route::any('login', 'Login/wxMplogin'); Route::any('mobileLogin', 'Login/mobileLogin'); Route::any('login_bind_mobile', 'Login/login_bind_mobile'); +Route::any('wx_app_login', 'Login/wxAppLogin'); +Route::any('bindMobile', 'Login/bindMobile'); #Index.php首页 #============================ @@ -267,7 +269,7 @@ Route::any('get_order_statistics', 'FFOrdersController/getOrderStatistics'); #============================APP使用的路由 ============================# -Route::any('V5Vx6qHOM5Ks9HqH', 'Login/login'); +Route::any('V5Vx6qHOM5Ks9HqH', 'Login/wxMplogin'); Route::any('jaqXJ27mqJMfwT7X', 'Login/mobileLogin'); Route::any('UaMT0s7a6Tcp68ES', 'Login/login_bind_mobile'); Route::any('uzkXfi3aqrPxOwVx', 'Index/index'); diff --git a/app/common/server/platform/AppPlatform.php b/app/common/server/platform/AppPlatform.php index 40681f7..96d9fa6 100644 --- a/app/common/server/platform/AppPlatform.php +++ b/app/common/server/platform/AppPlatform.php @@ -36,18 +36,20 @@ class AppPlatform extends BasePlatform $config = [ 'isWebPay' => false, 'buildVersion' => '106', - 'version' => '1.0.1', + 'version' => '1.0.2', 'userAgreement' => "https://zfunbox.cn?_p=cb20xad0e35094521ae46a1d1fb0ddd1&time=" . time() ]; $is_env_test = EnvHelper::getIsTest(); if ($is_env_test) { $config['userAgreement'] = "https://testweb.zfunbox.cn?_p=cb20xad0e35094521ae46a1d1fb0ddd1&time=" . time(); } + $config['userAgreement'] = " https://192.168.1.21:3001?_p=cb20xad0e35094521ae46a1d1fb0ddd1&time=" . time(); $configVersion = (int) preg_replace('/[^0-9]/', '', $config['version']); if ($versionNumber >= $configVersion) { $config['buildVersion'] = '105'; // $config['isCheck'] = true; $config['userAgreement'] = "https://zfunbox.cn/pages/guize/guize?type=4"; + } return $config; }