bourse stock
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

890 lines
38 KiB

<?php
namespace app\home\service;
use app\home\controller\User;
use app\home\validate\LoginValidate;
use app\model\AdminModel;
use app\model\CountryModel;
use app\model\CustomerRelationalModel;
use app\model\UserChatLinkModel;
use app\model\UserModel;
use app\utility\Jwt;
use app\utility\SendSms;
use app\utility\UnqId;
use Psr\SimpleCache\InvalidArgumentException;
use think\exception\ValidateException;
use think\facade\Cache;
use think\facade\Log;
use think\facade\Queue;
use think\queue\Job;
use GeoIp2\Database\Reader;
class LoginService extends BaseHomeService
{
/**
* 发送邮件
* @param $param
* @return array
* @throws InvalidArgumentException
*/
public function sendEmail($param): array
{
try {
// 防止重复操作 单个ip 3秒钟内只能请求一次
$ip = $this->getClientRealIp();
// 参数校验
validate(LoginValidate::class)->scene('sendEmail')->check($param);
$param['email'] = trim($param['email']);
// 邮箱类型校验 去除国内邮箱
if ($this->checkForbidEmail($param['email'])) {
return $this->toData('100300', 'The email is not supported.', []);
}
// 每天获取code 次数限制
$sendCodeKey = 'USER:SEND_CODE_NUM:' . $ip;
if ($this->checkGetNoTradeCodeNum($sendCodeKey)) {
return $this->toData('100300', 'The maximum number of attempts for today has been exceeded. Please try again tomorrow.', []);
}
// 获取发送的邮件内容
$content = $this->getEmailContent();
$content['email'] = $param['email'];
// 将发送邮件任务添加到异步队列
$queuename = 'app\home\job\SendEmail';
Queue::push($queuename, $content, 'sendEmail');
// 邮件code存到缓存(未登录操作共用)
$key = 'DB:USER:UNLOGIN:EMAIL_CODE:' . $param['email'];
$this->insertCodeToCache($key, $content['code'], 300);
// 记录已经发送的code次数
$this->updateHadGetCodeNumCache($sendCodeKey);
// 返回结果
return $this->toData('0', 'Email sent successfully. Please check your inbox.', []);
} catch (ValidateException $validateException) {
// 参数校验失败 异常类
$message = $validateException->getError();
return $this->toData('100400', $message);
} catch (\Exception $exception) {
// 异常情况
return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]);
}
}
/**
* @desc 邮箱注册用户
* @param $param
* @return array
* @throws InvalidArgumentException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function registerEmail($param): array
{
try {
// 获取客户端ip
$ip = $this->getClientRealIp();
$param['invite_code'] = $param['invite_code'] ?? '';
$param['agent_code'] = $param['agent_code'] ?? '';
// 邮件注册参数校验
validate(LoginValidate::class)->scene('emailRegister')->check($param);
// 判断注册数量 ip每天可注册数量
$ipCanRegisterNumPerIpPerDay = 'USER:REGISTER:' . $ip;
if ($this->checkRegisterLimit($ipCanRegisterNumPerIpPerDay)) {
return $this->toData('100300', 'The maximum number of attempts for today has been exceeded. Please try again tomorrow.', []);
}
// 验证验证码
$emailKey = 'DB:USER:UNLOGIN:EMAIL_CODE:' . $param['email'];
if (!$this->checkCode($emailKey, $param['email_code'])) {
//注册验证码
$reg_key = "USER:REG:CODE";
if (!$this->checkCode($reg_key, $param['email_code'])) {
return $this->toData('100300', 'The verification code is incorrect.', []);
} else {
$code = random_int(1000, 9999);
$this->insertCodeToCache($reg_key, $code, 300);
}
}
$email = $param['email'];
$inviteCode = trim($param['invite_code']);
$agentCode = trim($param['agent_code']);
// 邮箱是否已经存在
$emailExists = UserModel::checkEmailExists($email);
if ($emailExists) {
return $this->toData('100300', 'The email has already been registered.', []);
}
// 判断邀请人是否存在
$agentId = 0;
$parentUserId = 0;
if (!empty($inviteCode)) {
$agentId = AdminModel::getIdByInviteCode($inviteCode);
if ($agentId <= 0) {
$parentUserId = $this->getParentIdByInviteCode($inviteCode);
if ($parentUserId <= 0) {
return $this->toData('100400', 'The invitation code is invalid.', []);
}
}
}
// 判断代理人是否存在
if (!empty($agentCode) || $agentId > 0) {
if ($agentId == 0) {
$agentId = AdminModel::getIdByInviteCode($agentCode);
if ($agentId <= 0) {
return $this->toData('100400', 'The invitation code is invalid.', []);
}
}
} else {
// 是否必须填写有效的邀请码
$inviteCodeIsRequired = env("REG_USER.INVITE_CODE_REQUIRED");
if ($parentUserId <= 0 && $inviteCodeIsRequired >= 1) {
return $this->toData('100400', 'The invitation code is invalid.', []);
}
}
// 入库
$userNo = $this->getUniqUserNo();
$salt = env('ENCRYPT.SALT');
$password = (new UnqId())->encryptPassword($param['password'], $salt);
$userInviteCode = $this->getUniqInviteCode();
Log::info("邮箱注册 - agentId=".$agentId);
// 需要开启事务
\think\facade\Db::transaction(function () use ($email, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, $agentId) {
// 生成用户数据
$userId = UserModel::emailRegister($email, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, 1, $agentId);
// 生成钱包地址
(new UserService())->doRegInitUserInfo($userId, $parentUserId);
// 注册聊天账号
$chatData = [
'Username' => $userNo,
'Password' => '123456',
];
$chatUrl = env('CHAT_SERVER.BASE_URL') . '/api/user/register';
$chatRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatUrl, $chatData);
if (!isset($chatRes['data']['uuid'])) {
return $this->toData('100400', 'Failed to register a chat account.', []);
}
// 绑定注册账号与聊天账号
UserChatLinkModel::create([
'user_id' => $userId,
'user_type' => 1,
'chat_uuid' => $chatRes['data']['uuid'],
'chat_name' => $chatRes['data']['username']
]);
Log::info("邮箱注册 - 用户注册chat账号 - user_id=".$userId. " chat_uiud=".$chatRes['data']['uuid']);
// 如果有代理,绑定到代理下一个客服(轮询客服绑定)
if ($agentId > 0 ) {
$customerIds = AdminModel::getCustomerIdsByAgentId($agentId); // 获取代理下的所有客服ID
Log::info("邮箱注册 - 代理下客服ids=".json_encode($customerIds));
if (empty($customerIds)) {
return $this->toData('100400', 'There is no customer service account under the current agent', []);
}
$counterKey = 'counter_bind_customer:'.$agentId;
$counterIndex = Cache::store('redis')->get($counterKey); //客服绑定计数器索引
if (empty($counterIndex)) {
$counterIndex = 0;
Cache::store('redis')->set($counterKey, $counterIndex);
$tagCustomerId = $customerIds[0];
} else {
Cache::store('redis')->inc($counterKey); //更新计数器索引
$tagIndex = $counterIndex % count($customerIds);
$tagCustomerId = $customerIds[$tagIndex];
}
Log::info("邮箱注册 - 要绑定的客服id=".$tagCustomerId);
if ($tagCustomerId > 0) {
CustomerRelationalModel::create([
'user_id' => $userId,
'customer_id' => $tagCustomerId,
'agent_id' => $agentId,
]);
}
// 将注册账号的chat_id与绑定客服的chat_id加为好友
Log::info("邮箱注册 - 获取去客服聊天账号信息, $tagCustomerId=".$tagCustomerId);
$customerChatInfo = UserChatLinkModel::where(['user_id'=>$tagCustomerId, 'user_type'=>2])->find(); //查询客服的聊天账号uuid
if (empty($customerChatInfo)) {
return $this->toData('100400', 'The customer uuid is error.', []);
}
$chatFriendsData = [
'UserUuid' => $chatRes['data']['uuid'],
'CustomerUuid' => $customerChatInfo->chat_uuid,
];
Log::info("邮箱注册 - 请求聊天夫加好友=".$tagCustomerId);
$chatFriendsUrl = env('CHAT_SERVER.BASE_URL') . '/api/eachOtherFriends';
$chatFriendsRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatFriendsUrl, $chatFriendsData);
Log::info("邮箱注册 - chat服务加好友结果:".json_encode($chatFriendsRes));
}
});
// 删除缓存
$this->delCache($emailKey);
// 累加已经注册的个数
$this->updateHadRegisterNumCache($ipCanRegisterNumPerIpPerDay);
return $this->toData('0', 'Registration Successful.', []);
} catch (ValidateException $validateException) {
// 参数校验失败 异常类
$message = $validateException->getError();
return $this->toData('100400', $message);
} catch (\Exception $exception) {
trace('【注册错误】提交数据:'.json_encode($param), 'error');
trace('【注册错误】'.$exception->getMessage(), 'error');
return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
}
}
/**
* @desc 登陆业务处理接口
* @param array $param
* @return array
*/
public function loginEmail(array $param): array
{
try {
// 参数校验 邮箱 密码
validate(LoginValidate::class)->scene('emailLogin')->check($param);
$param['email'] = trim($param['email']);
// 查找邮箱
$userId = UserModel::getUserIdByEmail($param['email']);
if ($userId <= 0) {
return $this->toData('100300', 'The user does not exist.', []);
}
// 查找用户信息
$user = UserModel::getFieldsByUserId('invite_code,user_id,user_no,nick_name,is_real,login_password,salt', $userId);
if (empty($user)) {
return $this->toData('100300', 'Incorrect account or password.', []);
}
// 校验密码
$checkPasswordBool = (new UnqId())->checkPassword($param['password'], $user['login_password'], $user['salt']);
if (!$checkPasswordBool) {
return $this->toData('100300', 'Incorrect account or password.', []);
}
// 生成token
$token = (new Jwt())->getToken($userId, env('ENCRYPT.SALT'));
if (empty($token)) {
return $this->toData('100300', 'The system is busy.', []);
}
// 用户登陆之后需要进行的操作 异步完成
Queue::push('app\home\job\LoginDone', ['userId' => $userId,
'fields' => [
'last_login_time' => date('Y-m-d H:i:s'),
'ip' => $this->getClientRealIp(),
'device' => $param['device'],
]
], 'loginDone');
// 将token存致缓存 覆盖新的缓存 实现单设备登陆
$this->setUserTokenCache($token, $userId);
// 用户登记关系
(new UserService())->getUserLevel($userId);
// 返回结果以及用户信息
return $this->toData('0', 'Request successful.', [
'userId' => $userId,
'userNo' => $user['user_no'],
'nickName' => $user['nick_name'],
'inviteCode' => $user['invite_code'],
'isReal' => $user['is_real'],
'logo' => env('USER.DEFAULT_HEAD_IMG_PATH'),
'token' => $token,
]);
} catch (ValidateException $validateException) {
// 参数校验失败 异常类
$message = $validateException->getError();
return $this->toData('100400', $message);
} catch (InvalidArgumentException $invalidArgumentException) {
return $this->toData('100400', 'The system is busy. Please try again later.', []);
} catch (\Exception $exception) {
return $this->toData('100500', 'The system is busy.', []);
}
}
/**
* @desc未登陆获取短信验证码
* @param array $param
* @return array
* @throws InvalidArgumentException
*/
public function sendSms(array $param): array
{
try {
// 防止重复操作 单个ip 3秒钟内只能请求一次
$ip = $this->getClientRealIp();
// 参数校验
validate(LoginValidate::class)->scene('sendSms')->check($param);
$param['nation'] = trim($param['nation']);
$param['phone'] = trim($param['phone']);
// 去除国内手机号
if ($this->checkForbidNation($param['nation'])) {
return $this->toData('100300', 'Unsupported country or region.', []);
}
// 判断国家码是否有效
$nationExists = CountryModel::checkCodeExists($param['nation']);
if (!$nationExists) {
return $this->toData('100300', 'Unsupported country or region.', []);
}
// 发送次数校验 - 号码
$phoneSendCodeKey = 'USER:PHONE_SEND_CODE_NUM:' . $param['nation'].':'.$param['phone'];
if ($this->checkGetNoTradeCodeNumPhone($phoneSendCodeKey)) {
return $this->toData('100300', 'No worries. Please feel free to reach out again tomorrow.', []);
}
// 发送次数校验 - ip
$ipSendCodeKey = 'USER:IP_SEND_CODE_NUM:' . $ip;
if ($this->checkGetNoTradeCodeNum($ipSendCodeKey)) {
return $this->toData('100300', 'No worries. Please feel free to reach out again tomorrow.', []);
}
// 获取发送内容
$content = $this->getSmsContent();
$mobile = $param['nation'] . $param['phone'];
$content['mobile'] = $mobile;
// 异步发送
$queuename = 'app\home\job\SendSms';
Queue::push($queuename, $content, 'sendSms');
// 短信code存到缓存(未登录操作共用)
$key = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile;
$this->insertCodeToCache($key, $content['code'], 300);
// 累加已经获取的次数
$this->updateHadGetCodeNumCache($phoneSendCodeKey);
$this->updateHadGetCodeNumCache($ipSendCodeKey);
// 返回结果
return $this->toData('0', 'The message has been sent. Please check your inbox.', []);
} catch (ValidateException $validateException) {
// 参数校验失败 异常类
$message = $validateException->getError();
return $this->toData('100400', $message);
} catch (\Exception $exception) {
trace('【注册错误】提交数据:'.json_encode($param), 'error');
trace('【注册错误】'.$exception->getMessage(), 'error');
return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]);
}
}
/**
* @desc 短信注册
* @param array $param
* @return array
* @throws InvalidArgumentException
*/
public function registerSms(array $param): array
{
try {
// 防止重复操作
$ip = $this->getClientRealIp();
$param['invite_code'] = $param['invite_code'] ?? '';
$param['agent_code'] = $param['agent_code'] ?? '';
// 短信注册参数校验
validate(LoginValidate::class)->scene('smsRegister')->check($param);
// 判断注册数量 ip每天可注册数量
$ipCanRegisterNumPerIpPerDay = 'USER:REGISTER:' . $ip;
$this->checkRegisterLimit($ipCanRegisterNumPerIpPerDay);
// 校验验证码
$mobile = $param['nation'] . $param['phone'];
$smsKey = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile;
if (!$this->checkCode($smsKey, $param['sms_code'])) {
$reg_key = "USER:REG:CODE";
//注册验证码
if (!$this->checkCode($reg_key, $param['sms_code'])) {
return $this->toData('100300', 'The verification code is incorrect.', []);
}
// else {
// $code = random_int(1000, 9999);
// $this->insertCodeToCache($reg_key, $code, 300);
// }
}
// 手机号是否已经存在
$phoneExists = UserModel::checkPhoneExists($param['phone']);
if ($phoneExists) {
return $this->toData('100300', 'The phone number has already been registered.', []);
}
// 邀请人
$inviteCode = trim($param['invite_code']);
$agentCode = trim($param['agent_code']);
$parentUserId = 0;
$agentId = 0;
if (!empty($inviteCode)) {
$agentId = AdminModel::getIdByInviteCode($inviteCode);
if ($agentId <= 0) {
$parentUserId = $this->getParentIdByInviteCode($inviteCode);
if ($parentUserId <= 0) {
return $this->toData('100400', 'The invitation code is invalid.', []);
}
}
}
// 判断代理人是否存在
if (!empty($agentCode) || $agentId > 0) {
if ($agentId == 0) {
$agentId = AdminModel::getIdByInviteCode($agentCode);
if ($agentId <= 0) {
return $this->toData('100400', 'The invitation code is invalid.', []);
}
}
} else {
// 是否必须填写有效的邀请码
$inviteCodeIsRequired = env("REG_USER.INVITE_CODE_REQUIRED");
if ($parentUserId <= 0 && $inviteCodeIsRequired >= 1) {
return $this->toData('100400', 'The invitation code is invalid.', []);
}
}
// 入库
$userNo = $this->getUniqUserNo();
$salt = env('ENCRYPT.SALT');
$password = (new UnqId())->encryptPassword($param['password'], $salt);
$userInviteCode = $this->getUniqInviteCode();
// 需要开启事务
\think\facade\Db::transaction(function () use ($param, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, $agentId) {
// 生成用户数据
$userId = UserModel::phoneRegister($param['nation'], $param['phone'], $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, 1, $agentId);
// 生成钱包地址
(new UserService())->doRegInitUserInfo($userId, $parentUserId);
// 注册聊天账号
$chatData = [
'Username' => $userNo,
'Password' => '123456',
];
$chatUrl = env('CHAT_SERVER.BASE_URL') . '/api/user/register';
$chatRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatUrl, $chatData);
if (!isset($chatRes['data']['uuid'])) {
return $this->toData('100400', 'Failed to register a chat account.', []);
}
// 绑定注册账号与聊天账号
UserChatLinkModel::create([
'user_id' => $userId,
'user_type' => 1,
'chat_uuid' => $chatRes['data']['uuid'],
'chat_name' => $chatRes['data']['username']
]);
// 如果有代理,绑定到代理下一个客服(轮询客服绑定)
if ($agentId > 0 ) {
$customerIds = AdminModel::getCustomerIdsByAgentId($agentId); // 获取代理下的所有客服ID
if (empty($customerIds)) {
return $this->toData('100400', 'There is no customer service account under the current agent', []);
}
$counterKey = 'counter_bind_customer:'.$agentId;
$counterIndex = Cache::store('redis')->get($counterKey); //客服绑定计数器索引
if (empty($counterIndex)) {
$counterIndex = 0;
Cache::store('redis')->set($counterKey, $counterIndex);
$tagCustomerId = $customerIds[0];
} else {
Cache::store('redis')->inc($counterKey); //更新计数器索引
$tagIndex = $counterIndex % count($customerIds);
$tagCustomerId = $customerIds[$tagIndex];
}
if ($tagCustomerId > 0) {
CustomerRelationalModel::create([
'user_id' => $userId,
'customer_id' => $tagCustomerId,
'agent_id' => $agentId,
]);
}
// 将注册账号的chat_id与绑定客服的chat_id加为好友
$customerChatInfo = UserChatLinkModel::where('user_id', $tagCustomerId)->find(); //查询客服的聊天账号uuid
if (empty($customerChatInfo)) {
return $this->toData('100400', 'The customer uuid is error.', []);
}
$chatFriendsData = [
'UserUuid' => $chatRes['data']['uuid'],
'CustomerUuid' => $customerChatInfo->chat_uuid,
];
$chatFriendsUrl = env('CHAT_SERVER.BASE_URL') . '/api/eachOtherFriends';
$chatFriendsRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatFriendsUrl, $chatFriendsData);
Log::info("手机号注册 - chat服务加好友结果:".json_encode($chatFriendsRes));
}
});
// 删除缓存
$this->delCache($smsKey);
// 更新注册个数
$this->updateHadRegisterNumCache($ipCanRegisterNumPerIpPerDay);
return $this->toData('0', 'Registration Successful.', []);
} catch (ValidateException $validateException) {
// 参数校验失败 异常类
$message = $validateException->getError();
return $this->toData('100400', $message);
} catch (\Exception $exception) {
return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
}
}
/**
* @desc 短信验证码登陆
* @param array $param
* @return array
* @throws InvalidArgumentException
*/
public function loginSms(array $param): array
{
try {
// 邮件注册参数校验
validate(LoginValidate::class)->scene('smsLogin')->check($param);
$param['nation'] = trim($param['nation']);
$param['phone'] = trim($param['phone']);
// 验证短信验证码
$mobile = $param['nation'] . $param['phone'];
$smsKey = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile;
if (!$this->checkCode($smsKey, $param['sms_code'])) {
return $this->toData('100300', 'The verification code is incorrect.', []);
};
// 查找手机号
$userId = UserModel::getUserIdByNationAndPhone($param['nation'], $param['phone']);
if ($userId <= 0) {
return $this->toData('100300', 'The user does not exist.', []);
}
// 查找用户信息
$user = UserModel::getFieldsByUserId('invite_code,user_id,user_no,nick_name,is_real,login_password,salt', $userId);
if (empty($user)) {
return $this->toData('100300', 'Incorrect account or password.', []);
}
// 生成token
$token = (new Jwt())->getToken($userId, env('ENCRYPT.SALT'));
if (empty($token)) {
return $this->toData('100300', 'The system is busy. Please try again later.', []);
}
// 用户登陆之后需要进行的操作 异步完成
Queue::push('app\home\job\LoginDone', ['userId' => $userId,
'fields' => [
'last_login_time' => date('Y-m-d H:i:s'),
'ip' => $this->getClientRealIp(),
'device' => $param['device'],
]
], 'loginDone');
// 将token存致缓存 覆盖新的缓存 实现单设备登陆
$this->setUserTokenCache($token, $userId);
// 用户登记关系
(new UserService())->getUserLevel($userId);
// 返回结果以及用户信息
return $this->toData('0', 'Request successful.', [
'userId' => $userId,
'userNo' => $user['user_no'],
'nickName' => $user['nick_name'],
'isReal' => $user['is_real'],
'inviteCode' => $user['invite_code'],
'logo' => env('USER.DEFAULT_HEAD_IMG_PATH'),
'token' => $token,
]);
} catch (ValidateException $validateException) {
// 参数校验失败 异常类
$message = $validateException->getError();
return $this->toData('100400', $message);
} catch (\Exception $exception) {
return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
}
}
/**
* @desc 忘记密码 根据邮箱设置密码
* @param array $param
* @return array
* @throws InvalidArgumentException
*/
public function resetPasswordByEmail(array $param): array
{
try {
// 邮件注册参数校验
validate(LoginValidate::class)->scene('emailForget')->check($param);
// 验证码
$emailKey = 'DB:USER:UNLOGIN:EMAIL_CODE:' . $param['email'];
if (!$this->checkCode($emailKey, $param['email_code'])) {
return $this->toData('100300', 'The verification code is incorrect', []);
}
// 查找邮箱
$userId = UserModel::getUserIdByEmail($param['email']);
if ($userId <= 0) {
return $this->toData('100300', 'The user does not exist.', []);
}
// 修改密码
$salt = env('ENCRYPT.SALT');
$password = (new UnqId())->encryptPassword($param['password'], $salt);
UserModel::updatePassword($password, $salt, $userId);
// 删除缓存
$this->delCache($emailKey);
return $this->toData('0', 'Modification successful.', []);
} catch (ValidateException $validateException) {
// 参数校验失败 异常类
$message = $validateException->getError();
return $this->toData('100400', $message);
} catch (\Exception $exception) {
return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
}
}
/**
* @desc 忘记密码 根据短信设置密码
* @param array $param
* @return array
* @throws InvalidArgumentException
*/
public function resetPasswordBySms(array $param): array
{
try {
// 邮件注册参数校验
validate(LoginValidate::class)->scene('smsForget')->check($param);
// 判断验证码
$mobile = $param['nation'] . $param['phone'];
$smsKey = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile;
if (!$this->checkCode($smsKey, $param['sms_code'])) {
return $this->toData('100300', 'The verification code is incorrect', []);
}
// 查找用户
$userId = UserModel::getUserIdByNationAndPhone($param['nation'], $param['phone']);
if ($userId <= 0) {
return $this->toData('100300', 'The user does not exist.', []);
}
// 修改密码
$salt = env('ENCRYPT.SALT');
$password = (new UnqId())->encryptPassword($param['password'], $salt);
UserModel::updatePassword($password, $salt, $userId);
// 删除缓存
$this->delCache($smsKey);
return $this->toData('0', 'Modification successful.', []);
} catch (ValidateException $validateException) {
// 参数校验失败 异常类
$message = $validateException->getError();
return $this->toData('100400', $message);
} catch (\Exception $exception) {
return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
}
}
/**
* @desc 手机号 密码登陆
* @param $param
* @return array
*/
public function phoneLogin($param): array
{
try {
// 参数校验
validate(LoginValidate::class)->scene('smsPasswordLogin')->check($param);
// 获取用户
$userId = UserModel::getUserIdByNationAndPhone($param['nation'], $param['phone']);
if ($userId <= 0) {
return $this->toData('100300', 'Incorrect account or password.1', []);
}
$info = UserModel::getFieldsByUserId('invite_code,is_real,nick_name,user_no,user_id,login_password,salt', $userId);
if (empty($info)) {
return $this->toData('100300', 'Incorrect account or password.2', []);
}
// 校验密码
$checkPasswordBool = (new UnqId())->checkPassword($param['password'], $info['login_password'], $info['salt']);
if (!$checkPasswordBool) {
return $this->toData('100300', 'Incorrect account or password.3', []);
}
// 生成token
$token = (new Jwt())->getToken($userId, env('ENCRYPT.SALT'));
if (empty($token)) {
return $this->toData('100400', 'The system is busy. Please try again later.', []);
}
// 用户登陆之后需要进行的操作 异步完成
Queue::push('app\home\job\LoginDone', ['userId' => $userId,
'fields' => [
'last_login_time' => date('Y-m-d H:i:s'),
'ip' => $this->getClientRealIp(),
'device' => $param['device'],
]
], 'loginDone');
// 将token存致缓存 覆盖新的缓存 实现单设备登陆
$this->setUserTokenCache($token, $userId);
// 用户登记关系
(new UserService())->getUserLevel($userId);
// 返回结果以及用户信息
return $this->toData('0', 'Request successful.', [
'userId' => $userId,
'userNo' => $info['user_no'],
'nickName' => $info['nick_name'],
'isReal' => $info['is_real'],
'inviteCode' => $info['invite_code'],
'logo' => env('USER.DEFAULT_HEAD_IMG_PATH'),
'token' => $token,
]);
} catch (ValidateException $validateException) {
// 参数校验失败 异常类
$message = $validateException->getError();
return $this->toData('100400', $message);
} catch (\Exception $exception) {
return $this->toData('100500', 'The system is busy. Please try again later.', []);
}
}
public function autoLogin($param): array
{
try {
$login_token=$param['login_token'];
$tokenUserKey = 'AUTO:TOKEN:'.$login_token;
$userId = Cache::store('redis')->get($tokenUserKey);
if(empty($userId) || $userId <= 0){
return $this->toData('100300', 'Incorrect token', []);
}
$info = UserModel::getFieldsByUserId('invite_code,is_real,nick_name,user_no,user_id,login_password,salt', $userId);
if (empty($info)) {
return $this->toData('100300', 'Incorrect account or password.2', []);
}
// 生成token
$token = (new Jwt())->getToken($userId, env('ENCRYPT.SALT'));
if (empty($token)) {
return $this->toData('100400', 'The system is busy. Please try again later.', []);
}
// 将token存致缓存 覆盖新的缓存 实现单设备登陆
$this->setUserTokenCache($token, $userId);
// 用户登记关系
(new UserService())->getUserLevel($userId);
// 返回结果以及用户信息
return $this->toData('0', 'Request successful.', [
'userId' => $userId,
'userNo' => $info['user_no'],
'nickName' => $info['nick_name'],
'isReal' => $info['is_real'],
'inviteCode' => $info['invite_code'],
'logo' => env('USER.DEFAULT_HEAD_IMG_PATH'),
'token' => $token,
]);
} catch (ValidateException $validateException) {
// 参数校验失败 异常类
$message = $validateException->getError();
return $this->toData('100400', $message);
} catch (\Exception $exception) {
return $this->toData('100500', 'The system is busy. Please try again later.', []);
}
}
public function testLogin($param): array
{
try {
$login_token=$param['login_token'];
$tokenUserKey = 'AUTO:TOKEN:'.$login_token;
$userId = Cache::store('redis')->get($tokenUserKey);
if(empty($userId) || $userId <= 0){
return $this->toData('100300', 'Incorrect token', []);
}
$info = UserModel::getFieldsByUserId('invite_code,is_real,nick_name,user_no,user_id,login_password,salt', $userId);
if (empty($info)) {
return $this->toData('100300', 'Incorrect account or password.2', []);
}
// 生成token
$token = (new Jwt())->getToken($userId, env('ENCRYPT.SALT'));
if (empty($token)) {
return $this->toData('100400', 'The system is busy. Please try again later.', []);
}
// 将token存致缓存 覆盖新的缓存 实现单设备登陆
$this->setUserTokenCache($token, $userId);
// 用户登记关系
(new UserService())->getUserLevel($userId);
// 返回结果以及用户信息
return $this->toData('0', 'Request successful.', [
'userId' => $userId,
'userNo' => $info['user_no'],
'nickName' => $info['nick_name'],
'isReal' => $info['is_real'],
'inviteCode' => $info['invite_code'],
'logo' => env('USER.DEFAULT_HEAD_IMG_PATH'),
'token' => $token,
]);
} catch (ValidateException $validateException) {
// 参数校验失败 异常类
$message = $validateException->getError();
return $this->toData('100400', $message);
} catch (\Exception $exception) {
return $this->toData('100500', 'The system is busy. Please try again later.', []);
}
}
public function getIP(): array
{
$ip=$this->getClientRealIp();
$countryDb = base_path().'GeoLite2-Country.mmdb';
$cityDb = base_path().'GeoLite2-City.mmdb';
$countryReader = new Reader($countryDb);
$cityReader = new Reader($cityDb);
try{
$countryNames = $countryReader->country($ip)->country->names;
$cityNames = $cityReader->city($ip)->city->names;
return $this->toData('0', 'Request successful.', [
'country' => $countryNames['zh-CN'],
'city' => $cityNames['zh-CN'],
'ip'=>$ip
]);
}catch (\Exception $exception){
return $this->toData('0', 'Request successful.', [
'country' => '未知',
'city' =>'未知',
'ip'=>$ip
]);
}
}
}