feat : wx login

This commit is contained in:
2024-11-25 18:02:40 +08:00
parent 865ff6eb7e
commit 9c175fdb78
8 changed files with 175 additions and 9 deletions

19
app/Constants/ApiCode.php Normal file
View File

@@ -0,0 +1,19 @@
<?php
namespace App\Constants;
use Hyperf\Constants\Annotation\Constants;
#[Constants]
class ApiCode extends ReturnCode
{
/**
* @Message("登录失败")
*/
public const int LOGIN_ERROR = 10001;
/**
* @Message("登录token已失效")
*/
public const int LOGIN_TOKEN_ERROR = 10002;
}

View File

@@ -5,8 +5,8 @@ namespace App\Constants\Common;
class ThirdCode class ThirdCode
{ {
/** /**
* * 第三方登录类型 1=微信登录
*/ */
const WX_LOGIN = 1; const int WX_LOGIN = 1;
} }

View File

@@ -4,17 +4,23 @@ declare(strict_types=1);
namespace App\Controller\Api; namespace App\Controller\Api;
use App\Middleware\Api\JwtAuthMiddleware;
use App\Service\Api\User\BindPhoneByWxService;
use Hyperf\HttpServer\Annotation\Controller; use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\RequestMapping; use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\Validation\Annotation\Scene; use Hyperf\Validation\Annotation\Scene;
#[Controller(prefix: 'api/user')] #[Controller(prefix: 'api/user')]
#[Middlewares([
JwtAuthMiddleware::class,
])]
class UserController class UserController
{ {
#[RequestMapping(path: 'bind/phone',methods: 'post')] #[RequestMapping(path: 'bind_phone/wx_code',methods: 'post')]
#[Scene(scene: 'bind_phone')] #[Scene(scene: 'bind_phone_wx')]
public function bind_phone() public function bind_phone_by_wx_code()
{ {
return (new BindPhoneByWxService)->handle();
} }
} }

View File

@@ -2,7 +2,45 @@
namespace App\Middleware\Api; namespace App\Middleware\Api;
class JwtAuthMiddleware use App\Constants\ApiCode;
{ use App\Lib\ApiReturn;
use App\Lib\Crypto\CryptoFactory;
use Hyperf\Context\Context;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class JwtAuthMiddleware implements MiddlewareInterface
{
public function __construct(
protected HttpResponse $response,
protected ApiReturn $apiReturn,
protected CryptoFactory $cryptoFactory,
){}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
// 获取头部token
$authorization = $request->getHeaderLine('Authorization');
if (empty($authorization)){
return $this->response->json(
$this->apiReturn->error(ApiCode::getMessage(ApiCode::LOGIN_ERROR), ApiCode::LOGIN_ERROR)
);
}
$authorization = str_replace("Bearer ", "", $authorization);
$userJwt = $this->cryptoFactory->cryptoClass('jwt', $authorization)->decrypt();
if (empty($userJwt)) {
return $this->response->json(
$this->apiReturn->error(ApiCode::getMessage(ApiCode::LOGIN_TOKEN_ERROR), ApiCode::LOGIN_TOKEN_ERROR)
);
}
Context::set('user_id',$userJwt['data']->id);
return $handler->handle($request);
}
} }

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Model; namespace App\Model;
use Hyperf\Database\Model\Builder;
use Hyperf\DbConnection\Model\Model; use Hyperf\DbConnection\Model\Model;
/** /**
@@ -47,5 +48,12 @@ class User extends Model
const CREATED_AT = 'create_time'; const CREATED_AT = 'create_time';
const UPDATED_AT = 'update_time'; const UPDATED_AT = 'update_time';
/**
* @param int $id
* @return Builder|\Hyperf\Database\Model\Model|null
*/
public function getInfoById(int $id): \Hyperf\Database\Model\Model|Builder|null
{
return $this->where('id', $id)->first();
}
} }

View File

@@ -0,0 +1,30 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
*/
declare(strict_types=1);
namespace App\Service\Api\User;
use App\Exception\ErrException;
use App\Service\Api\BaseService;
use App\Service\ServiceTrait\Api\GetUserInfoTrait;
use App\Service\ServiceTrait\Api\WxMiniTrait;
class BindPhoneByWxService extends BaseService
{
use GetUserInfoTrait,WxMiniTrait;
public function handle()
{
$this->checkBindPhone($this->userId);
return $this->return->success();
}
}

View File

@@ -0,0 +1,60 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
*/
declare(strict_types=1);
namespace App\Service\ServiceTrait\Api;
use App\Exception\ErrException;
use App\Model\User;
use Hyperf\Context\Context;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Model;
use Hyperf\Di\Annotation\Inject;
trait GetUserInfoTrait
{
/**
* @var User 注入用户模型
*/
#[Inject]
protected User $userModel;
/**
* 单例获取用户信息
* @param $userId
* @return false|Builder|Model|mixed|string
*/
protected function getUserInfo($userId): mixed
{
$key = 'user_id:' . $userId;
if (Context::has($key)) {
return Context::get($key, false);
}
$userInfo = $this->userModel->getInfoById($userId);
if (!$userInfo) {
return false;
}
Context::set($key, $userInfo);
return $userInfo;
}
/**
* @param $userId
* @return void
*/
protected function checkBindPhone($userId): void
{
$userInfo = $this->getUserInfo($userId);
if (!empty($userInfo->phone)) throw new ErrException('该账户已绑定手机号,无需重新绑定。若需更换手机号,请联系客服重置后再绑定');
}
}

View File

@@ -76,4 +76,9 @@ trait WxMiniTrait
throw new ErrException($e->getMessage()); throw new ErrException($e->getMessage());
} }
} }
public function jsCodeGetPhoneNumber(string $code): mixed
{
}
} }