feat : login wx
This commit is contained in:
52
app/Service/Api/BaseService.php
Normal file
52
app/Service/Api/BaseService.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* This service file is part of item.
|
||||
*
|
||||
* @author ctexthuang
|
||||
* @contact ctexthuang@qq.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Api;
|
||||
|
||||
use App\Lib\ApiReturn;
|
||||
use Hyperf\Context\Context;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||
|
||||
abstract class BaseService
|
||||
{
|
||||
/**
|
||||
* 请求对象
|
||||
* @var RequestInterface
|
||||
*/
|
||||
#[Inject]
|
||||
protected RequestInterface $request;
|
||||
|
||||
/**
|
||||
* 通用返回对象
|
||||
* @var ApiReturn $return
|
||||
*/
|
||||
#[Inject]
|
||||
protected ApiReturn $return;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
* @var int $userId
|
||||
*/
|
||||
protected int $userId = 0;
|
||||
|
||||
/**
|
||||
* 主构造函数(获取请求对象)
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->userId = Context::get("user_id",0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 主体函数抽象类
|
||||
*/
|
||||
abstract public function handle();
|
||||
}
|
||||
164
app/Service/Api/Login/LoginBaseService.php
Normal file
164
app/Service/Api/Login/LoginBaseService.php
Normal file
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
/**
|
||||
* This service file is part of item.
|
||||
*
|
||||
* @author ctexthuang
|
||||
* @contact ctexthuang@qq.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Api\Login;
|
||||
|
||||
use App\Cache\Redis\Api\ApiRedisKey;
|
||||
use App\Cache\Redis\RedisCache;
|
||||
use App\Constants\Common\UserCode;
|
||||
use App\Exception\ApiException;
|
||||
use App\Extend\StringUtil;
|
||||
use App\Extend\SystemUtil;
|
||||
use App\Lib\Crypto\CryptoFactory;
|
||||
use App\Model\User;
|
||||
use App\Model\UserThird;
|
||||
use App\Service\Api\BaseService;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
abstract class LoginBaseService extends BaseService
|
||||
{
|
||||
/**
|
||||
* 注入缓存类
|
||||
* @var RedisCache
|
||||
*/
|
||||
#[Inject]
|
||||
protected RedisCache $redis;
|
||||
|
||||
/**
|
||||
* 注入加密工厂
|
||||
* @var CryptoFactory
|
||||
*/
|
||||
#[Inject]
|
||||
protected CryptoFactory $cryptoFactory;
|
||||
|
||||
/**
|
||||
* 注入三方用户
|
||||
* @var UserThird
|
||||
*/
|
||||
#[Inject]
|
||||
protected UserThird $userThirdModel;
|
||||
|
||||
|
||||
/**
|
||||
* 锁定注册
|
||||
* @var string
|
||||
*/
|
||||
protected string $lockKey;
|
||||
|
||||
/**
|
||||
* 登录code login_type = wx_login 必填
|
||||
* @var string
|
||||
*/
|
||||
protected string $jsCode = '';
|
||||
|
||||
/**
|
||||
* 手机号 login_type = mobile_code 必填
|
||||
* @var string
|
||||
*/
|
||||
protected string $mobile = '';
|
||||
|
||||
/**
|
||||
* 获取的用户信息
|
||||
* @var
|
||||
*/
|
||||
protected mixed $userInfo;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $openId = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $unionId = '';
|
||||
|
||||
/**
|
||||
* 登录
|
||||
* @return void
|
||||
*/
|
||||
protected function login(): void
|
||||
{
|
||||
$this->userId = empty($this->userId) ? $this->userInfo->id : $this->userId;
|
||||
|
||||
if (empty($this->userId)) {
|
||||
throw new ApiException('登录失败');
|
||||
}
|
||||
|
||||
//todo 判断注销 判断封号
|
||||
|
||||
//todo 更新登录时间
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回值
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function getReturn():array
|
||||
{
|
||||
$loginReturn = [
|
||||
'id' => $this->userId,
|
||||
'is_bind_mobile' => $this->userInfo->mobile ? UserCode::IS_BIND_PHONE : UserCode::IS_NOT_BIND_PHONE,
|
||||
'nickName' => $this->userInfo->nickName,
|
||||
'is_default_avatar' => $this->userInfo->avatar_id == 0 ? UserCode::IS_DEFAULT_AVATAR : UserCode::IS_NOT_DEFAULT_AVATAR,
|
||||
];
|
||||
|
||||
$loginReturn['token'] = $this->cryptoFactory->cryptoClass('jwt', json_encode($loginReturn))->encrypt();
|
||||
|
||||
|
||||
return $loginReturn;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断是不是没有加锁
|
||||
* @param $type
|
||||
* @return void
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws \RedisException
|
||||
*/
|
||||
protected function checkLock($type): void
|
||||
{
|
||||
$this->lockKey = match ($type){
|
||||
1 => ApiRedisKey::LoginAndRegisterByMobileLock($this->mobile),
|
||||
2 => ApiRedisKey::LoginAndRegisterByCodeLock($this->jsCode)
|
||||
};
|
||||
|
||||
if (0 == ($this->redis->addLock($this->lockKey))){
|
||||
throw new ApiException('请勿重复点击');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加用户
|
||||
* @return void
|
||||
*/
|
||||
protected function addUser(): void
|
||||
{
|
||||
$model = new User();
|
||||
|
||||
//默认头像和默认名称
|
||||
$model->nickname = '用户'.StringUtil::randStr(6);
|
||||
$model->avatar_id = 0;
|
||||
$model->reg_ip = SystemUtil::getClientIp();
|
||||
|
||||
if (!$model->save()) throw new ApiException('数据保存失败-注册失败');
|
||||
|
||||
$this->userId = $model->id;
|
||||
$this->userInfo = $model;
|
||||
}
|
||||
|
||||
abstract protected function register();
|
||||
}
|
||||
36
app/Service/Api/Login/LoginService.php
Normal file
36
app/Service/Api/Login/LoginService.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* This service file is part of item.
|
||||
*
|
||||
* @author ctexthuang
|
||||
* @contact ctexthuang@qq.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Api\Login;
|
||||
|
||||
use App\Exception\AdminException;
|
||||
use App\Service\Api\BaseService;
|
||||
|
||||
class LoginService extends BaseService
|
||||
{
|
||||
protected string $loginType = '';
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$this->loginType = $this->request->input('login_type','');
|
||||
|
||||
$factory = new LoginTypeFactory();
|
||||
$service = match ($this->request->input('login_type',''))
|
||||
{
|
||||
'wx_login' => $factory->wxFastLogin(),
|
||||
'mobile_code' => $factory->mobileCodeLogin(),
|
||||
default => throw new AdminException('登录类型错误'),
|
||||
};
|
||||
|
||||
$loginInfo = $service->handle();
|
||||
|
||||
return $this->return->success('登录成功',$loginInfo);
|
||||
}
|
||||
}
|
||||
32
app/Service/Api/Login/LoginTypeFactory.php
Normal file
32
app/Service/Api/Login/LoginTypeFactory.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* This service file is part of item.
|
||||
*
|
||||
* @author ctexthuang
|
||||
* @contact ctexthuang@qq.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Api\Login;
|
||||
|
||||
class LoginTypeFactory
|
||||
{
|
||||
/**
|
||||
* 验证码登录
|
||||
* @return MobileCodeLoginService
|
||||
*/
|
||||
public function mobileCodeLogin(): MobileCodeLoginService
|
||||
{
|
||||
return new MobileCodeLoginService();
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信快速组件登录
|
||||
* @return WxFastLoginService
|
||||
*/
|
||||
public function wxFastLogin(): WxFastLoginService
|
||||
{
|
||||
return new WxFastLoginService();
|
||||
}
|
||||
}
|
||||
23
app/Service/Api/Login/MobileCodeLoginService.php
Normal file
23
app/Service/Api/Login/MobileCodeLoginService.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* This service file is part of item.
|
||||
*
|
||||
* @author ctexthuang
|
||||
* @contact ctexthuang@qq.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Api\Login;
|
||||
|
||||
class MobileCodeLoginService extends LoginBaseService
|
||||
{
|
||||
|
||||
|
||||
public function handle()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function register() {}
|
||||
}
|
||||
81
app/Service/Api/Login/WxFastLoginService.php
Normal file
81
app/Service/Api/Login/WxFastLoginService.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* This service file is part of item.
|
||||
*
|
||||
* @author ctexthuang
|
||||
* @contact ctexthuang@qq.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Api\Login;
|
||||
|
||||
use App\Exception\ApiException;
|
||||
use App\Model\UserThird;
|
||||
use App\Service\ServiceTrait\Api\WxMiniTrait;
|
||||
use Hyperf\DbConnection\Db;
|
||||
|
||||
class WxFastLoginService extends LoginBaseService
|
||||
{
|
||||
use WxMiniTrait;
|
||||
|
||||
/**
|
||||
* 登录类型 2=微信小程序
|
||||
*/
|
||||
const int LOGIN_TYPE = 2;
|
||||
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$this->jsCode = $this->request->input('js_code');
|
||||
|
||||
if (empty($this->jsCode)) throw new ApiException('登录参数错误');
|
||||
|
||||
$wxInfo = $this->jsCodeGetOpenId($this->jsCode);
|
||||
$this->openId = $wxInfo['openid'];
|
||||
$this->unionId = $wxInfo['unionid'];
|
||||
|
||||
$this->checkLock(self::LOGIN_TYPE);
|
||||
|
||||
$this->register();
|
||||
|
||||
$this->login();
|
||||
|
||||
$this->redis->delLock($this->lockKey);
|
||||
|
||||
return $this->getReturn();
|
||||
}
|
||||
|
||||
protected function register(): void
|
||||
{
|
||||
$thirdInfo = $this->userThirdModel->getThirdInfoByOpenId($this->openId);
|
||||
if (!empty($thirdInfo)) {
|
||||
$this->userId = $thirdInfo->user_id;
|
||||
return;
|
||||
}
|
||||
|
||||
// todo 设备封禁不可注册 注册限制
|
||||
|
||||
Db::transaction(function () {
|
||||
$this->addUser();
|
||||
|
||||
$this->addUserThird();
|
||||
|
||||
//todo 要不要生成邀请码 有没有注册奖励
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function addUserThird(): void
|
||||
{
|
||||
$model = new UserThird();
|
||||
|
||||
$model->user_id = $this->userId;
|
||||
$model->open_id = $this->openId;
|
||||
$model->union_id = $this->unionId;
|
||||
|
||||
if (!$model->save()) throw new ApiException('注册失败-00001');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user