Compare commits

..

6 Commits

Author SHA1 Message Date
5890122a37 fix : readme update 2025-09-18 17:26:45 +08:00
b405585bc7 fix : readme update 2025-09-17 17:18:39 +08:00
5d2f32b22b fix : readme update 2025-09-17 17:18:18 +08:00
082c15d697 fix : first finish 2025-09-17 16:17:55 +08:00
21331655f9 fix : common request 2025-09-16 18:07:10 +08:00
be0d0913b6 fix : update path And request 2025-09-16 15:14:47 +08:00
52 changed files with 848 additions and 203 deletions

View File

@@ -1,22 +1,25 @@
APP_NAME=sfyy
APP_NAME=ctext
APP_ENV=dev
APP_DEBUG=false
APP_URL=http://127.0.0.1:9501
JWT_SECRET=azOVxsOWt3r0ozZNz8Ss429ht0T8z6OpeIJAIwNp6X0xqrbEY2epfIWyxtC1qSNM8eD6/LQ/SahcQi2ByXa/2A==
JWT_ADMIN_SECRET=azOVxsOWt3r0ozZNz8Ss429ht0T8z6OpeIJAIwNp6X0xqrbEY2epfIWyxtC1qSNM8eD6/LQ/SahcQi2ByXa/2Aaa
# [ide]
DEVTOOL_IDE=phpstorm
DB_DRIVER=mysql
DB_HOST=s2.gnip.vip
DB_PORT=20191
DB_DATABASE=mineadmin
DB_USERNAME=hhl
DB_PASSWORD=hhltest
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=xxx
DB_USERNAME=username
DB_PASSWORD=password
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
DB_PREFIX=
REDIS_HOST=s2.gnip.vip
REDIS_AUTH=hhltest
REDIS_PORT=4379
REDIS_HOST=127.0.0.1
REDIS_AUTH=
REDIS_PORT=6379
REDIS_DB=0

223
README.md
View File

@@ -1,6 +1,6 @@
## 仓库
- [sfyy_server](https://codeup.aliyun.com/67039465d8d1ada68263f984/hhl/rewrite/hyperf_service.git) - git远程仓库地址
- [hyperf_rbac_framework_server_ctexthuang](https://gitee.com/ctexthuang/hyperf_rbac_framework_server_ctexthuang.git) - git远程仓库地址
## 特性
@@ -27,9 +27,7 @@
- 获取代码
```bash
git clone https://codeup.aliyun.com/67039465d8d1ada68263f984/hhl/rewrite/hyperf_service.git
mkdir uploads
git clone https://gitee.com/ctexthuang/hyperf_rbac_framework_server_ctexthuang.git
```
- vendor
@@ -50,22 +48,32 @@ php bin/hyperf.php start
- command 函数
```bash
#框架自有
php bin/hyperf.php gen:controller LoginController
php bin/hyperf.php gen:model UserModel
php bin/hyperf.php gen:request LoginRequest
php bin/hyperf.php gen:command TestCommand
php bin/hyperf.php gen:job TestJob
php bin/hyperf.php gen:listener TestListener
php bin/hyperf.php gen:middleware AuthMiddleware
php bin/hyperf.php gen:amqp-consumer DemoConsumer
php bin/hyperf.php gen:amqp-producer DemoProducer
php bin/hyperf.php gen:constant ErrorCode --type enum
#框架自有 php bin/hyperf.php + 以下
gen:amqp-consumer Create a new amqp consumer class
gen:amqp-producer Create a new amqp producer class
gen:aspect Create a new aspect class
gen:class Create a new class
gen:command Create a new command class
gen:constant Create a new constant class
gen:controller Create a new controller class
gen:job Create a new job class
gen:kafka-consumer Create a new kafka consumer class
gen:listener Create a new listener class
gen:middleware Create a new middleware class
gen:migration Generate a new migration file
gen:model Create new model classes.
gen:nats-consumer Create a new nats consumer class
gen:nsq-consumer Create a new nsq consumer class
gen:process Create a new process class
gen:repository Create a new repository class
gen:request Create a new form request class
gen:resource create a new resource
gen:seeder Create a new seeder class
gen:service Create a new service class
#新增命令
php bin/hyperf.php gen:service LoginService
php bin/hyperf.php gen:cron OssTask
php bin/hyperf.php gen:event TestEvent
php bin/hyperf.php gen:repository OssRepository
```
## Git 贡献提交规范
@@ -86,9 +94,6 @@ php bin/hyperf.php gen:event TestEvent
- `wip` 开发中
- `types` 类型
## cache
不允许使用序列化,为跨语言做准备
## 日志(合理安排)
| 分组名称 | 用途 | 日志级别 | 保留天数 | 备注 |
|---------|---------|------------|------|----------|
@@ -98,4 +103,180 @@ php bin/hyperf.php gen:event TestEvent
| request | 请求访问日志 | INFO | 15 | 记录所有请求 |
| cron | 定时任务日志 | INFO | 30 | 定时任务执行记录 |
| payment | 支付相关日志 | INFO | 90 | 重要财务数据 |
| audit | 审计日志 | INFO | 365 | 重要操作记录 |
| audit | 审计日志 | INFO | 365 | 重要操作记录 |\
```php
//注入这个类
use App\Lib\Log\Logger;
$this->logger->cache()->error(...),
```
## 缓存
```php
//注入这个类
use App\Cache\Redis\RedisCache
$this->redis->with($poolName)->exists($key)
//$poolName 配置在 config/autoload/redis.php 在 default下面追加即可 看官网
//lua调用涉及多文件请看示例
$this->redis->with($poolName ?? 'default')->lua(RateLimit::class)->check($argument);
//lua()里面是App\Cache\Redis\Lua\*文件 后面跟的方法是 该文件的方法
//我做了返回类型补全 可以直接IDE跳转查看参数
```
## tips
1.AdminService类必须继承BaseAdminService
```php
//例子 app/Service/Admin/AdminUser/UserService
class UserService extends \App\Service\Admin\BaseAdminService {
}
//由于在 app/Controller/Admin/AdminUserController 中 service 是 注解注入的 所以 BaseAdminService只会实例化一次单例
class AdminUserController extends AbstractController
{
/**
* @var UserService
*/
#[Inject]
protected UserService $service;
/**
* @return array
*/
#[RequestMapping(path: "getInfo", methods: "GET")]
public function getInfo(): array
{
return $this->service->handle();
}
}
//所以在service中获取上下文的数据必须重置获取而不能存入BaseService属性中拿取
//假设在 Api目录中写 BaseApiService请务必注意
class UserService extends \App\Service\Admin\BaseAdminService {
/**
* @param string $name
* @return \current_admin_id|mixed
*/
public function __get(string $name)
{
if ($name === 'adminId') return Context::get('current_admin_id',0);
if (!property_exists($this, $name)) throw new ErrException('属性未定义');
return $this->$name;
}
}
class UserService extends BaseAdminService{
public function handle()
{
return $this->adminId;
}
}
// 或者在controller中实例化去调用
class AdminUserController extends AbstractController
{
/**
* @return array
*/
#[RequestMapping(path: "getInfo", methods: "GET")]
public function getInfo(): array
{
return (new UserService)->handle();
}
}
```
2.controller必须增加ResponseFormat注解
```php
//示例 : app/Controller/Admin/AdminUserController
#[Controller(prefix: "admin/adminUser")]
#[ResponseFormat('admin')]
#[Middleware(middleware: AdminTokenMiddleware::class, priority: 100)]
#[Middleware(middleware: PermissionMiddleware::class, priority: 99)]
class AdminUserController extends \App\Controller\AbstractController{
}
//因为在涉及到公有抛出 ErrException或者 验证器抛出 的时候 会根据不同的注解 返回不同的 Return
class BaseErrExceptionHandler extends ExceptionHandler{
public function handle()
{
// 从注解获取响应格式(优先于路径解析)
$format = $this->request->getAttribute('response_format') ?? $this->repairResponseFormatByPath();
// 动态选择策略
$returnClass = match ($format) {
'admin', 'common' => AdminReturn::class,
'api' => ApiReturn::class,
default => null,
};
}
}
// 通过切面存入
class ResponseFormatAspect extends AbstractAspect
{
// 获取注解定义的格式
$annotation = $proceedingJoinPoint->getAnnotationMetadata()->class[ResponseFormat::class]
?? $proceedingJoinPoint->getAnnotationMetadata()->method[ResponseFormat::class] ?? null;
if ($annotation) {
// 将注解格式存入请求属性(覆盖中间件的默认值)
$request = $proceedingJoinPoint->arguments['request'] ?? null;
if ($request instanceof Request) {
$request->withAttribute('response_format', $annotation->format);
}
}
}
```
3.token的使用要分模块
```php
//示例 app/Service/Admin/Login/LoginService
use App\Service\BaseTokenService $tokenService
class LoginService extends \App\Service\Admin\BaseAdminService{
public function handle()
{
$jwtHandle = $this->tokenService->setJwt('admin')->getJwt();
return $this->adminReturn->success('success',[
'access_token' => $jwtHandle->builderAccessToken((string) $adminInfo->id)->toString(),
'refresh_token' => $jwtHandle->builderRefreshToken((string) $adminInfo->id)->toString(),
'expire_at' => (int) $jwtHandle->getConfig('ttl', 0),
]);
}
}
//setJwt函数里面类似$poolName 设置在 config/autoload/jwt.php 未设置属性可复用 default 设置
```
4.引入 Repository层架构 解放 model层压力 model 只管理数据模型和关联
```php
//详细请看app/Common/Repository 文件下的文件 示例 app/Service/Admin/Login/LoginService
class LoginService extends \App\Service\Admin\BaseAdminService{
/**
* 需要提前注入
* @var AdminUserRepository
*/
#[Inject]
protected AdminUserRepository $userRepository;
public function handle()
{
$adminInfo = $this->userRepository->findByUserName((string)$this->request->input('username'));
}
}
```
5.公用类都在 app/Common 下面 包括 `Interface``Macros``Repository``Trait`
6.后台权限注解 #[Permission] 和 #[PermissionMiddleware]

View File

@@ -4,18 +4,18 @@ declare(strict_types=1);
namespace App\Aspect;
use App\Common\Repository\AdminUserRepository;
use App\Common\Trait\ClientIpTrait;
use App\Common\Trait\ClientOsTrait;
use App\Lib\Log\Logger;
use App\Model\AdminUserLoginLog;
use App\Repository\AdminUserRepository;
use App\Service\Admin\Login\LoginService;
use App\Trait\ClientIpTrait;
use App\Trait\ClientOsTrait;
use Hyperf\Coroutine\Coroutine;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use Hyperf\Di\Exception\Exception;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use Throwable;
#[Aspect]
@@ -50,7 +50,7 @@ class AdminLoginLogAspect extends AbstractAspect
*/
public function __construct(
protected readonly Logger $logger,
protected readonly RequestInterface $request,
protected RequestInterface $request,
protected readonly AdminUserRepository $adminUserRepository,
protected readonly AdminUserLoginLog $adminUserLoginLogModel,
) {}
@@ -61,7 +61,7 @@ class AdminLoginLogAspect extends AbstractAspect
* @throws Exception
* @throws Throwable
*/
public function process(ProceedingJoinPoint $proceedingJoinPoint)
public function process(ProceedingJoinPoint $proceedingJoinPoint): mixed
{
// 写日志
@@ -87,23 +87,24 @@ class AdminLoginLogAspect extends AbstractAspect
*/
private function writeLoginLog(): void
{
Coroutine::create(function () {
$userInfo = $this->adminUserRepository->findByUserName($this->request->input('username'));
$context = [
'username' => $this->request->input('username',''),
'password' => $this->request->input('password',''),
'user_info' => $userInfo?->toArray() ?? [],
'ip' => $this->getClientIp(),
'os' => $this->getClientOs(),
'browser' => $this->request->header('User-Agent') ?: 'unknown',
];
$userInfo = $this->adminUserRepository->findByUserName($this->request->input('username'));
$context = [
'username' => $this->request->input('username',''),
'password' => $this->request->input('password',''),
'user_info' => $userInfo?->toArray() ?? [],
'ip' => $this->getClientIp(),
'os' => $this->getClientOs(),
'browser' => $this->request->header('User-Agent') ?: 'unknown',
];
Coroutine::create(function () use ($userInfo, $context) {
$this->logger->request()->info('admin_login_log', $context);
$this->adminUserLoginLogModel->save([
$this->adminUserLoginLogModel->create([
'admin_user_id' => $userInfo?->id ?? 0,
'username' => $userInfo?->username ?? '',
'ip' => $context['ip'],
'ip' => current($context['ip']) ?: '0.0.0.0',
'os' => $context['os'],
'browser' => $context['browser'] ?? '',
'status' => $this->loginSuccess ? 1 : 2,

View File

@@ -4,20 +4,19 @@ declare(strict_types=1);
namespace App\Aspect;
use App\Common\Trait\AdminUserTrait;
use App\Common\Trait\ClientIpTrait;
use App\Lib\Log\Logger;
use App\Lib\Return\AdminReturn;
use App\Model\AdminUser;
use App\Model\AdminUserOperationLog;
use App\Service\Admin\Login\LoginService;
use App\Trait\AdminUserTrait;
use App\Trait\ClientIpTrait;
use Hyperf\Context\Context;
use Hyperf\Coroutine\Coroutine;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\HttpServer\Contract\RequestInterface;
use Psr\Container\ContainerInterface;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use Hyperf\Di\Exception\Exception;
use Hyperf\HttpServer\Contract\RequestInterface;
#[Aspect]
class AdminReturnLogAspect extends AbstractAspect
@@ -50,13 +49,18 @@ class AdminReturnLogAspect extends AbstractAspect
*/
public function __construct(
protected readonly Logger $logger,
protected readonly RequestInterface $request,
protected RequestInterface $request,
protected readonly AdminUserOperationLog $adminUserOperationLogModel,
) {
$this->adminId = Context::get('current_admin_id',0);
if ($this->adminId > 0) $this->adminUserInfo = $this->getAdminUserInfo($this->adminId);
}
/**
* @param ProceedingJoinPoint $proceedingJoinPoint
* @return mixed
* @throws Exception
*/
public function process(ProceedingJoinPoint $proceedingJoinPoint)
{
// 直接从方法参数获取请求数据
@@ -65,11 +69,14 @@ class AdminReturnLogAspect extends AbstractAspect
// 执行原方法并获取返回值
$responseData = $proceedingJoinPoint->process();
// 没登录不记录日志
if ($this->adminId <= 0) return $responseData;
// 写日志
$this->writeOperationLog($requestData, $responseData);
// 返回
return $requestData;
return $responseData;
}
/**
@@ -79,25 +86,25 @@ class AdminReturnLogAspect extends AbstractAspect
*/
private function writeOperationLog(array $requestData = [], array $responseData = []): void
{
Coroutine::create(function () use ($requestData, $responseData) {
$context = [
'user_id' => $this->adminId,
'method' => $this->request->getMethod(),
'router' => $this->request->getUri(),
'ip' => $this->getClientIp(),
'request_data' => $requestData,
'response_data' => $responseData,
];
$context = [
'user_id' => $this->adminId,
'method' => $this->request->getMethod(),
'router' => $this->request->getUri(),
'ip' => $this->getClientIp(),
'request_data' => $requestData,
'response_data' => $responseData,
];
Coroutine::create(function () use ($requestData, $responseData, $context) {
$this->logger->request()->info('admin_request_log', $context);
$this->adminUserOperationLogModel->save([
$this->adminUserOperationLogModel->create([
'admin_user_id' => $this->adminId,
'username' => $this->adminUserInfo?->username ?? '',
'method' => $context['method'],
'router' => $context['router'],
'service_name' => $context['service_name'] ?? '',
'ip' => $context['ip'],
'ip' => current($context['ip']) ?: '0.0.0.0',
]);
});
}

View File

@@ -163,7 +163,7 @@ abstract class BaseScript
];
$logStrategy = match(true) {
!$success => $this->logger->cache()->error(...),
!$success => $this->logger->error()->error(...),
$this->debugMode => $this->logger->cache()->debug(...),
default => fn() => null // 不记录
};

View File

@@ -2,6 +2,7 @@
namespace App\Cache\Redis;
use App\Cache\Redis\Lua\RateLimit;
use App\Lib\Log\Logger;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Redis\RedisFactory;
@@ -9,6 +10,7 @@ use Hyperf\Redis\RedisProxy;
/**
* @mixin RedisProxy
* @template T
*/
class RedisCache
{
@@ -53,10 +55,11 @@ class RedisCache
}
/**
* @param string $scriptClass
* @return mixed
* @template TReturn
* @param class-string<TReturn> $scriptClass
* @return TReturn
*/
public function lua(string $scriptClass): mixed
public function lua(string $scriptClass)
{
$poolName = $this->poolName ?? 'default';
$key = $poolName . ':' . $scriptClass;

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Interface;
namespace App\Common\Interface;
use Lcobucci\JWT\UnencryptedToken;

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Interface;
namespace App\Common\Interface;
use Lcobucci\JWT\UnencryptedToken;

View File

@@ -8,7 +8,7 @@
declare(strict_types=1);
namespace App\Repository;
namespace App\Common\Repository;
use App\Constants\Model\AdminUser\AdminMenuStatusCode;
use App\Model\AdminMenu;

View File

@@ -0,0 +1,38 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
*/
declare(strict_types=1);
namespace App\Common\Repository;
use App\Model\AdminRole;
use Hyperf\Collection\Arr;
use Hyperf\Database\Model\Builder;
final class AdminRoleRepository extends BaseRepository
{
public function __construct(protected readonly AdminRole $model) {}
/**
* @param Builder $query
* @param array $params
* @return Builder
*/
public function handleSearch(Builder $query, array $params): Builder
{
return $query->when(Arr::get($params, 'name'), static function (Builder $query, $name) {
$query->where('name', 'like', '%' . $name . '%');
})->when(Arr::get($params, 'code'), static function (Builder $query, $code) {
$query->whereIn('code', Arr::wrap($code));
})->when(Arr::has($params, 'status'), static function (Builder $query) use ($params) {
$query->where('status', $params['status']);
})->when(Arr::get($params, 'created_at'), static function (Builder $query, $createdAt) {
$query->whereBetween('created_at', $createdAt);
});
}
}

View File

@@ -8,7 +8,7 @@
declare(strict_types=1);
namespace App\Repository;
namespace App\Common\Repository;
use App\Model\AdminUserLoginLog;
use Hyperf\Collection\Arr;

View File

@@ -8,7 +8,7 @@
declare(strict_types=1);
namespace App\Repository;
namespace App\Common\Repository;
use App\Model\AdminUserOperationLog;

View File

@@ -8,13 +8,11 @@
declare(strict_types=1);
namespace App\Repository;
namespace App\Common\Repository;
use App\Model\AdminUser;
use Hyperf\Collection\Arr;
use Hyperf\Database\Concerns\BuildsQueries;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Model;
/**
* Class AdminUserRepository

View File

@@ -1,9 +1,9 @@
<?php
namespace App\Repository;
namespace App\Common\Repository;
use App\Repository\Traits\BootTrait;
use App\Repository\Traits\RepositoryOrderByTrait;
use App\Common\Repository\Traits\BootTrait;
use App\Common\Repository\Traits\RepositoryOrderByTrait;
use Hyperf\Collection\Collection;
use Hyperf\Contract\LengthAwarePaginatorInterface;
use Hyperf\Database\Model\Builder;
@@ -13,7 +13,7 @@ use Hyperf\Paginator\AbstractPaginator;
/**
* @template T of Model
* @property T $model
* @property Model $model
*/
abstract class BaseRepository
{
@@ -67,7 +67,7 @@ abstract class BaseRepository
}
/**
* @return T
* @return Model
*/
public function create(array $data): mixed
{
@@ -81,7 +81,7 @@ abstract class BaseRepository
}
/**
* @return null|T
* @return null|Model
*/
public function saveById(mixed $id, array $data): mixed
{
@@ -105,7 +105,7 @@ abstract class BaseRepository
}
/**
* @return null|T
* @return null|Model
*/
public function findById(mixed $id): mixed
{
@@ -118,7 +118,7 @@ abstract class BaseRepository
}
/**
* @return null|T
* @return null|Model
*/
public function findByFilter(array $params): mixed
{
@@ -142,7 +142,7 @@ abstract class BaseRepository
}
/**
* @return T
* @return Model
*/
public function getModel(): Model
{

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Repository\Traits;
namespace App\Common\Repository\Traits;
use function Hyperf\Support\class_basename;
use function Hyperf\Support\class_uses_recursive;

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Repository\Traits;
namespace App\Common\Repository\Traits;
use Hyperf\Database\Model\Builder;

View File

@@ -1,11 +1,12 @@
<?php
namespace App\Trait;
namespace App\Common\Trait;
use App\Cache\Redis\Lua\RateLimit;
use App\Cache\Redis\RedisCache;
use App\Cache\Redis\RedisKey;
use App\Common\Repository\AdminUserRepository;
use App\Model\AdminUser;
use App\Repository\AdminUserRepository;
use Hyperf\Context\Context;
use Hyperf\Database\Model\Model;
use Hyperf\Di\Annotation\Inject;
@@ -25,6 +26,7 @@ trait AdminUserTrait
protected AdminUserRepository $adminUserRepository;
/**
* 单例加缓存模型(仅仅用户信息) tips: 只可读取显示的数据(不影响大致问题),不可操作类敏感数据 比如 inc 账户余额 之类的 会导致脏读
* @param int $adminId
* @return AdminUser|Model|mixed|string|null
*/

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Trait;
namespace App\Common\Trait;
use App\Constants\Common\ClientIpRequestConstant;
use App\Exception\ErrException;
@@ -15,7 +15,7 @@ trait ClientIpTrait
* @var RequestInterface
*/
#[Inject]
protected readonly RequestInterface $request;
protected RequestInterface $request;
/**
* @var string[]

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Trait;
namespace App\Common\Trait;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
@@ -11,7 +11,7 @@ trait ClientOsTrait
* @var RequestInterface
*/
#[Inject]
protected readonly RequestInterface $request;
protected RequestInterface $request;
/**
* @return string

View File

@@ -0,0 +1,47 @@
<?php
namespace App\Common\Trait;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
trait HttpMethodTrait
{
/**
* @var RequestInterface
*/
#[Inject]
protected readonly RequestInterface $request;
/**
* @return bool
*/
public function isCreate(): bool
{
return $this->request->isMethod('POST');
}
/**
* @return bool
*/
public function isUpdate(): bool
{
return $this->request->isMethod('PATCH') || $this->request->isMethod('PUT');
}
/**
* @return bool
*/
public function isDelete(): bool
{
return $this->request->isMethod('DELETE');
}
/**
* @return bool
*/
public function isSearch(): bool
{
return $this->request->isMethod('GET');
}
}

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Trait;
namespace App\Common\Trait;
trait ParserRouterTrait
{

View File

@@ -9,11 +9,13 @@ use App\Annotation\ResponseFormat;
use App\Controller\AbstractController;
use App\Middleware\Admin\AdminTokenMiddleware;
use App\Middleware\Admin\PermissionMiddleware;
use App\Request\Admin\AdminMenuRequest;
use App\Service\Admin\AdminUser\MenuService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\Validation\Annotation\Scene;
#[Controller(prefix: "admin/menu")]
@@ -39,22 +41,26 @@ class AdminMenuController extends AbstractController
}
/**
* @param AdminMenuRequest $request
* @return array
*/
#[RequestMapping(path: "", methods: "POST")]
#[Permission(code: 'permission:menu:create')]
public function createMenu(): array
#[Scene(scene: "create")]
public function createMenu(AdminMenuRequest $request): array
{
return $this->service->create();
}
/**
* @param int $id
* @param AdminMenuRequest $request
* @return array
*/
#[RequestMapping(path: "{id}", methods: "PUT")]
#[Permission(code: 'permission:menu:save')]
public function updateMenu(int $id): array
#[Scene(scene: "update")]
public function updateMenu(int $id, AdminMenuRequest $request): array
{
return $this->service->update($id);
}

View File

@@ -9,11 +9,13 @@ use App\Annotation\ResponseFormat;
use App\Controller\AbstractController;
use App\Middleware\Admin\AdminTokenMiddleware;
use App\Middleware\Admin\PermissionMiddleware;
use App\Request\Admin\AdminRoleRequest;
use App\Service\Admin\AdminUser\RoleService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\Validation\Annotation\Scene;
#[Controller(prefix: "admin/role")]
@@ -39,22 +41,26 @@ class AdminRoleController extends AbstractController
}
/**
* @param AdminRoleRequest $request
* @return array
*/
#[RequestMapping(path: "", methods: "POST")]
#[Permission(code: 'permission:role:save')]
public function createRole(): array
#[Scene(scene: "create")]
public function createRole(AdminRoleRequest $request): array
{
return $this->service->create();
}
/**
* @param int $id
* @param AdminRoleRequest $request
* @return array
*/
#[RequestMapping(path: "{id}", methods: "PUT")]
#[Permission(code: 'permission:role:update')]
public function updateRole(int $id): array
#[Scene(scene: "create")]
public function updateRole(int $id, AdminRoleRequest $request): array
{
return $this->service->update($id);
}
@@ -82,11 +88,13 @@ class AdminRoleController extends AbstractController
/**
* @param int $id
* @param AdminRoleRequest $request
* @return array
*/
#[RequestMapping(path: "{id}/permission", methods: "PUT")]
#[Permission(code: 'permission:role:setMenu')]
public function batchGrantPermissionByRole(int $id): array
#[Scene(scene: "batch_grant_permission")]
public function batchGrantPermissionByRole(int $id,AdminRoleRequest $request): array
{
return $this->service->setRole($id);
}

View File

@@ -9,11 +9,13 @@ use App\Annotation\ResponseFormat;
use App\Controller\AbstractController;
use App\Middleware\Admin\AdminTokenMiddleware;
use App\Middleware\Admin\PermissionMiddleware;
use App\Request\Admin\AdminUserRequest;
use App\Service\Admin\AdminUser\UserService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\Validation\Annotation\Scene;
#[Controller(prefix: "admin/adminUser")]
@@ -57,11 +59,13 @@ class AdminUserController extends AbstractController
}
/**
* @param AdminUserRequest $request
* @return array
*/
#[RequestMapping(path: "", methods: "PUT")]
#[Permission(code: 'permission:user:update')]
public function updateInfo(): array
#[Scene(scene: "update")]
public function updateInfo(AdminUserRequest $request): array
{
return $this->service->updateInfo();
}
@@ -77,11 +81,13 @@ class AdminUserController extends AbstractController
}
/**
* @param AdminUserRequest $request
* @return array
*/
#[RequestMapping(path: "", methods: "POST")]
#[Permission(code: 'permission:user:save')]
public function createAdminUser(): array
#[Scene(scene: "create")]
public function createAdminUser(AdminUserRequest $request): array
{
return $this->service->createUser();
}
@@ -98,7 +104,8 @@ class AdminUserController extends AbstractController
#[RequestMapping(path: "{userId}", methods: "PUT")]
#[Permission(code: 'permission:user:update')]
public function saveInfo(int $userId): array
#[Scene(scene: "update")]
public function saveInfo(int $userId,AdminUserRequest $request): array
{
return $this->service->saveUser($userId);
}
@@ -116,11 +123,13 @@ class AdminUserController extends AbstractController
/**
* @param int $userId
* @param AdminUserRequest $request
* @return array
*/
#[RequestMapping(path: "{userId}/roles", methods: "PUT")]
#[Permission(code: 'permission:user:setRole')]
public function batchGrantRolesForAdminUser(int $userId): array
#[Scene(scene: "batch_grant_role")]
public function batchGrantRolesForAdminUser(int $userId,AdminUserRequest $request): array
{
return $this->service->batchGrantRoleForUser($userId);
}

View File

@@ -8,11 +8,13 @@ use App\Annotation\Permission;
use App\Annotation\ResponseFormat;
use App\Controller\AbstractController;
use App\Middleware\Admin\AdminTokenMiddleware;
use App\Request\Admin\PermissionRequest;
use App\Service\Admin\AdminUser\PermissionService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\Validation\Annotation\Scene;
#[Controller(prefix: "admin/permission")]
#[ResponseFormat('admin')]
@@ -44,10 +46,12 @@ class PermissionController extends AbstractController
}
/**
* @param PermissionRequest $request
* @return array
*/
#[RequestMapping(path: "update", methods: "POST")]
public function update(): array
#[Scene(scene: "update")]
public function update(PermissionRequest $request): array
{
return $this->service->update();
}

View File

@@ -2,9 +2,7 @@
namespace App\Lib\Jwt;
use App\Constants\ResultCode;
use App\Exception\ErrException;
use App\Interface\JwtInterface;
use App\Common\Interface\JwtInterface;
use Carbon\Carbon;
use Hyperf\Cache\CacheManager;
use Hyperf\Cache\Driver\DriverInterface;
@@ -18,7 +16,6 @@ use Lcobucci\JWT\UnencryptedToken;
use Lcobucci\JWT\Validation\Constraint;
use Lcobucci\JWT\Validation\Constraint\SignedWith;
use Lcobucci\JWT\Validation\Constraint\StrictValidAt;
use Lcobucci\JWT\Validation\RequiredConstraintsViolated;
use Psr\SimpleCache\InvalidArgumentException;
abstract class AbstractJwt implements JwtInterface

View File

@@ -2,6 +2,6 @@
namespace App\Lib\Jwt;
use App\Interface\JwtInterface;
use App\Common\Interface\JwtInterface;
final class Jwt extends AbstractJwt implements JwtInterface {}

View File

@@ -2,7 +2,7 @@
namespace App\Lib\Jwt;
use App\Interface\JwtInterface;
use App\Common\Interface\JwtInterface;
use Hyperf\Collection\Arr;
use Hyperf\Contract\ConfigInterface;
use function Hyperf\Support\make;

View File

@@ -4,10 +4,11 @@ declare(strict_types=1);
namespace App\Middleware\Admin;
use App\Common\Interface\JwtInterface;
use App\Constants\ResultCode;
use App\Exception\ErrException;
use App\Interface\JwtInterface;
use App\Middleware\Token\AbstractTokenMiddleware;
use Hyperf\Context\Context;
use Lcobucci\JWT\Token\RegisteredClaims;
use Lcobucci\JWT\UnencryptedToken;
use function Hyperf\Support\env;
@@ -29,4 +30,13 @@ final class AdminTokenMiddleware extends AbstractTokenMiddleware
if ($audience !== env('APP_NAME') .'_admin') throw new ErrException('token错误',ResultCode::JWT_ERROR);
}
/**
* @param UnencryptedToken $token
* @return void
*/
public function setContext(UnencryptedToken $token): void
{
Context::set('current_admin_id',(int)$token->claims()?->get(RegisteredClaims::ID) ?? 0);
}
}

View File

@@ -5,21 +5,21 @@ declare(strict_types=1);
namespace App\Middleware\Admin;
use App\Annotation\Permission;
use App\Common\Trait\AdminUserTrait;
use App\Common\Trait\ParserRouterTrait;
use App\Constants\AdminCode;
use App\Constants\Model\AdminUser\AdminUserStatusCode;
use App\Exception\ErrException;
use App\Lib\Jwt\RequestScopedTokenTrait;
use App\Model\AdminUser;
use App\Trait\AdminUserTrait;
use App\Trait\ParserRouterTrait;
use Hyperf\Collection\Arr;
use Hyperf\Di\Annotation\AnnotationCollector;
use Hyperf\HttpServer\Router\Dispatched;
use Lcobucci\JWT\Token\RegisteredClaims;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class PermissionMiddleware implements MiddlewareInterface
@@ -45,7 +45,7 @@ class PermissionMiddleware implements MiddlewareInterface
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$adminId = $this->getToken()?->claims()?->get(RegisteredClaims::ID) ?? 0;
$adminId = (int) $this->getToken()?->claims()?->get(RegisteredClaims::ID) ?? 0;
if ($adminId <= 0) throw new ErrException('账户不存在');
$this->adminUserInfo = $this->getAdminUserInfo($adminId);
@@ -74,6 +74,7 @@ class PermissionMiddleware implements MiddlewareInterface
/**
* @var Permission[] $permissions
*/
$permissions = [];
$classAnnotation && $permissions[] = $classAnnotation;
$methodPermission = Arr::get($annotations, Permission::class);
$methodPermission && $permissions[] = $methodPermission;

View File

@@ -4,9 +4,9 @@ declare(strict_types=1);
namespace App\Middleware\Admin;
use App\Common\Interface\JwtInterface;
use App\Constants\ResultCode;
use App\Exception\ErrException;
use App\Interface\JwtInterface;
use App\Middleware\Token\AbstractTokenMiddleware;
use Lcobucci\JWT\Token\RegisteredClaims;
use Lcobucci\JWT\UnencryptedToken;
@@ -68,4 +68,13 @@ class RefreshAdminTokenMiddleware extends AbstractTokenMiddleware
if ($audience !== env('APP_NAME') .'_admin') throw new ErrException('token错误',ResultCode::JWT_ERROR);
}
/**
* @param UnencryptedToken $token
* @return void
*/
public function setContext(UnencryptedToken $token): void
{
return;
}
}

View File

@@ -4,10 +4,10 @@ declare(strict_types=1);
namespace App\Middleware\Token;
use App\Common\Interface\CheckTokenInterface;
use App\Common\Interface\JwtInterface;
use App\Constants\ResultCode;
use App\Exception\ErrException;
use App\Interface\CheckTokenInterface;
use App\Interface\JwtInterface;
use App\Lib\Jwt\JwtFactory;
use Hyperf\Collection\Arr;
use Hyperf\Stringable\Str;
@@ -35,6 +35,8 @@ abstract class AbstractTokenMiddleware
$this->checkToken->checkJwt($token);
$this->checkIssuer($token);
$this->setContext($token);
return $handler->handle(
value(
static function (ServerRequestPlusInterface $request, UnencryptedToken $token) {
@@ -54,6 +56,12 @@ abstract class AbstractTokenMiddleware
abstract public function getJwt(): JwtInterface;
/**
* @param UnencryptedToken $token
* @return void
*/
abstract public function setContext(UnencryptedToken $token): void;
/**
* @param ServerRequestInterface $request
* @return Token

View File

@@ -85,8 +85,8 @@ class AdminMenu extends Model
return $this->belongsToMany(
AdminRole::class,
'admin_role_belongs_menu',
'menu_id',
'role_id'
'admin_menu_id',
'admin_role_id'
);
}

View File

@@ -65,9 +65,9 @@ class AdminRole extends Model
{
return $this->belongsToMany(
AdminMenu::class,
'role_belongs_menu',
'role_id',
'menu_id'
'admin_role_belongs_menu',
'admin_role_id',
'admin_menu_id'
);
}
@@ -79,8 +79,8 @@ class AdminRole extends Model
return $this->belongsToMany(
AdminUser::class,
'admin_user_belongs_role',
'role_id',
'user_id'
'admin_role_id',
'admin_user_id'
);
}

View File

@@ -34,7 +34,7 @@ class AdminUserLoginLog extends Model
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['id', 'username', 'ip', 'os', 'browser', 'status', 'message', 'login_time', 'remark'];
protected array $fillable = ['id','admin_user_id', 'username', 'ip', 'os', 'browser', 'status', 'message', 'login_time', 'remark'];
/**
* The attributes that should be cast to native types.

View File

@@ -28,7 +28,7 @@ class AdminUserOperationLog extends Model
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['id', 'username', 'method', 'router', 'service_name', 'ip', 'ip_location', 'created_at', 'updated_at', 'remark'];
protected array $fillable = ['id', 'admin_user_id','username', 'method', 'router', 'service_name', 'ip', 'ip_location', 'created_at', 'updated_at', 'remark'];
/**
* The attributes that should be cast to native types.

View File

@@ -1,18 +0,0 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
*/
declare(strict_types=1);
namespace App\Repository;
use App\Model\AdminRole;
final class AdminRoleRepository extends BaseRepository
{
public function __construct(protected readonly AdminRole $model) {}
}

View File

@@ -0,0 +1,114 @@
<?php
declare(strict_types=1);
namespace App\Request\Admin;
use Hyperf\Validation\Request\FormRequest;
class AdminMenuRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'parent_id' => 'sometimes|integer',
'name' => 'required|string|max:255',
'path' => 'sometimes|string|max:255',
'component' => 'sometimes|string|max:255',
'redirect' => 'sometimes|string|max:255',
'status' => 'sometimes|integer',
'sort' => 'sometimes|integer',
'remark' => 'sometimes|string|max:255',
'meta.title' => 'required|string|max:255',
'meta.i18n' => 'sometimes|string|max:255',
'meta.badge' => 'sometimes|string|max:255',
'meta.link' => 'sometimes|string|max:255',
'meta.icon' => 'sometimes|string|max:255',
'meta.affix' => 'sometimes|boolean',
'meta.hidden' => 'sometimes|boolean',
'meta.type' => 'sometimes|string|max:255',
'meta.cache' => 'sometimes|boolean',
'meta.breadcrumbEnable' => 'sometimes|boolean',
'meta.copyright' => 'sometimes|boolean',
'meta.componentPath' => 'sometimes|string|max:64',
'meta.componentSuffix' => 'sometimes|string|max:4',
'meta.activeName' => 'sometimes|string|max:255',
'btnPermission' => 'sometimes|array',
];
}
/**
* @return array
*/
public function messages(): array
{
return parent::messages();
}
/**
* @var array|array[]
*/
protected array $scenes = [
'update' => [
'parent_id',
'name',
'path',
'component',
'redirect',
'status',
'sort',
'remark',
'meta.title',
'meta.i18n',
'meta.badge',
'meta.link',
'meta.icon',
'meta.affix',
'meta.hidden',
'meta.type',
'meta.cache',
'meta.breadcrumbEnable',
'meta.copyright',
'meta.componentPath',
'meta.componentSuffix',
'meta.activeName',
'btnPermission',
],
'create' => [
'parent_id',
'name',
'path',
'component',
'redirect',
'status',
'sort',
'remark',
'meta.title',
'meta.i18n',
'meta.badge',
'meta.link',
'meta.icon',
'meta.affix',
'meta.hidden',
'meta.type',
'meta.cache',
'meta.breadcrumbEnable',
'meta.copyright',
'meta.componentPath',
'meta.componentSuffix',
'meta.activeName',
'btnPermission',
],
];
}

View File

@@ -0,0 +1,79 @@
<?php
declare(strict_types=1);
namespace App\Request\Admin;
use App\Common\Trait\HttpMethodTrait;
use Hyperf\Validation\Request\FormRequest;
class AdminRoleRequest extends FormRequest
{
use HttpMethodTrait;
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
$rules = [
'name' => 'required|string|max:60',
'code' => [
'required',
'string',
'max:60',
'regex:/^[a-zA-Z0-9_]+$/',
],
'status' => 'sometimes|integer|in:1,2',
'sort' => 'required|integer',
'remark' => 'nullable|string|max:255',
'permissions' => 'sometimes|array',
'permissions.*' => 'string|exists:admin_menu,name',
];
if ($this->isCreate()) {
$rules['code'][] = 'unique:admin_role,code';
}
if ($this->isUpdate()) {
$rules['code'][] = 'unique:admin_role,code,' . $this->route('id');
}
return $rules;
}
/**
* @return array
*/
public function messages(): array
{
return parent::messages();
}
protected array $scenes = [
'update' => [
'code',
'name',
'status',
'sort',
'remark',
],
'create' => [
'code',
'name',
'status',
'sort',
'remark',
],
'batch_grant_permission' => [
'permissions',
'permissions.*',
]
];
}

View File

@@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
namespace App\Request\Admin;
use Hyperf\Validation\Request\FormRequest;
class AdminUserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'username' => 'required|string|max:20',
'user_type' => 'required|integer',
'nickname' => ['required', 'string', 'max:60', 'regex:/^[^\s]+$/'],
'phone' => 'sometimes|string|max:12',
'email' => 'sometimes|string|max:60|email:rfc,dns',
'avatar' => 'sometimes|string|max:255|url',
'signed' => 'sometimes|string|max:255',
'status' => 'sometimes|integer',
'backend_setting' => 'sometimes|array|max:255',
'remark' => 'sometimes|string|max:255',
'password' => 'sometimes|string|min:6|max:20',
'role_codes' => 'required|array',
'role_codes.*' => 'string|exists:admin_role,code',
];
}
/**
* @return array
*/
public function messages(): array
{
return parent::messages();
}
protected array $scenes = [
'update' => [
'username',
'user_type',
'nickname',
'phone',
'email',
'avatar',
'signed',
'status',
'backend_setting',
'remark',
'password',
],
'create' => [
'username',
'user_type',
'nickname',
'phone',
'email',
'avatar',
'signed',
'status',
'backend_setting',
'remark',
'password',
],
'batch_grant_role' => [
'role_codes',
'role_codes.*',
]
];
}

View File

@@ -22,7 +22,20 @@ class LoginRequest extends FormRequest
public function rules(): array
{
return [
'username' => 'required|string|exists:admin_user,username',
'password' => 'required|string'
];
}
/**
* @return array
*/
public function messages(): array
{
return parent::messages();
}
protected array $scenes = [
'login' => ['username', 'password'],
];
}

View File

@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
namespace App\Request\Admin;
use Hyperf\Validation\Request\FormRequest;
class PermissionRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'nickname' => 'sometimes|string|max:255',
'new_password' => 'sometimes|confirmed|string|min:8',
'new_password_confirmation' => 'sometimes|string|min:8',
'old_password' => ['sometimes', 'string'],
'avatar' => 'sometimes|string|max:255',
'signed' => 'sometimes|string|max:255',
'backend_setting' => 'sometimes|array',
];
}
/**
* @return array
*/
public function messages(): array
{
return parent::messages();
}
/**
* @var array|array[]
*/
protected array $scenes = [
'update' => [
'nickname',
'new_password',
'new_password_confirmation',
'old_password',
'avatar',
'signed',
'backend_setting',
],
];
}

View File

@@ -10,9 +10,9 @@ declare(strict_types=1);
namespace App\Service\Admin\AdminUser;
use App\Common\Repository\AdminMenuRepository;
use App\Exception\ErrException;
use App\Model\AdminMenu;
use App\Repository\AdminMenuRepository;
use App\Service\Admin\BaseAdminService;
use Hyperf\Di\Annotation\Inject;
@@ -40,9 +40,10 @@ class MenuService extends BaseAdminService
*/
public function create(): array
{
$data = array($this->getRequestData(),[
$data = array_merge($this->getRequestData(),[
'created_by' => $this->adminId
]);
if (empty($data['parent_id'])) $data['parent_id'] = 0;
/**
* @var AdminMenu $model
*/
@@ -75,7 +76,7 @@ class MenuService extends BaseAdminService
*/
public function update(int $id): array
{
$data = array($this->getRequestData(),[
$data = array_merge($this->getRequestData(),[
'updated_by' => $this->adminId
]);

View File

@@ -10,15 +10,16 @@ declare(strict_types=1);
namespace App\Service\Admin\AdminUser;
use App\Common\Repository\AdminMenuRepository;
use App\Common\Repository\AdminRoleRepository;
use App\Common\Trait\AdminUserTrait;
use App\Constants\Model\AdminUser\AdminMenuStatusCode;
use App\Constants\Model\AdminUser\AdminRoleStatusCode;
use App\Constants\ResultCode;
use App\Exception\ErrException;
use App\Repository\AdminMenuRepository;
use App\Repository\AdminRoleRepository;
use App\Service\Admin\BaseAdminService;
use App\Trait\AdminUserTrait;
use Hyperf\Collection\Arr;
use Hyperf\Di\Annotation\Inject;
class PermissionService extends BaseAdminService
{
@@ -27,11 +28,13 @@ class PermissionService extends BaseAdminService
/**
* @var AdminRoleRepository
*/
#[Inject]
protected AdminRoleRepository $adminRoleRepository;
/**
* @var AdminMenuRepository
*/
#[Inject]
protected AdminMenuRepository $adminMenuRepository;
/**

View File

@@ -10,10 +10,10 @@ declare(strict_types=1);
namespace App\Service\Admin\AdminUser;
use App\Common\Repository\AdminMenuRepository;
use App\Common\Repository\AdminRoleRepository;
use App\Exception\ErrException;
use App\Model\AdminMenu;
use App\Repository\AdminMenuRepository;
use App\Repository\AdminRoleRepository;
use App\Service\Admin\BaseAdminService;
use Hyperf\Collection\Arr;
use Hyperf\Di\Annotation\Inject;
@@ -96,6 +96,7 @@ class RoleService extends BaseAdminService
public function getRole(int $id): array
{
return $this->adminReturn->success(
'success',
$this->adminRoleRepository
->findById($id)
->adminMenus()

View File

@@ -12,17 +12,15 @@ namespace App\Service\Admin\AdminUser;
use App\Cache\Redis\Lua\RateLimit;
use App\Cache\Redis\RedisCache;
use App\Common\Repository\AdminRoleRepository;
use App\Common\Repository\AdminUserRepository;
use App\Common\Trait\AdminUserTrait;
use App\Exception\ErrException;
use App\Lib\Jwt\RequestScopedTokenTrait;
use App\Model\AdminRole;
use App\Repository\AdminRoleRepository;
use App\Repository\AdminUserRepository;
use App\Service\Admin\BaseAdminService;
use App\Service\BaseTokenService;
use App\Trait\AdminUserTrait;
use Hyperf\Collection\Arr;
use Hyperf\Di\Annotation\Inject;
use Lcobucci\JWT\Token\RegisteredClaims;
class UserService extends BaseAdminService
{
@@ -46,21 +44,15 @@ class UserService extends BaseAdminService
#[Inject]
protected AdminRoleRepository $adminRoleRepository;
#[Inject]
protected RedisCache $redisCache;
/**
* @return array
*/
public function handle(): array
{
$this->redisCache->with()->set('123',1);
$this->redisCache->with()->lua(RateLimit::class)->check('user:123', 10, 60);
return $this->adminReturn->success(
'success',
Arr::only(
$this->getAdminUserInfo($this->adminId) ?: [],
$this->getAdminUserInfo($this->adminId)?->toArray() ?: [],
['username', 'nickname', 'avatar', 'signed', 'backend_setting', 'phone', 'email']
)
);
@@ -190,7 +182,7 @@ class UserService extends BaseAdminService
'code' => $this->request->input('role_codes')
])->map(static function(AdminRole $adminRole) {
return $adminRole->id;
})->all()
})
);
return $this->adminReturn->success();

View File

@@ -10,12 +10,12 @@ declare(strict_types=1);
namespace App\Service\Admin;
use App\Exception\ErrException;
use App\Lib\Jwt\RequestScopedTokenTrait;
use App\Lib\Return\AdminReturn;
use Hyperf\Context\Context;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use Lcobucci\JWT\Token\RegisteredClaims;
abstract class BaseAdminService
{
@@ -36,20 +36,27 @@ abstract class BaseAdminService
protected AdminReturn $adminReturn;
/**
* 管理员 id
* @var int
* @param string $name
* @return \current_admin_id|mixed
*/
protected int $adminId = 0;
/**
* 主构造函数
*/
public function __construct()
public function __get(string $name)
{
$this->adminId = (int) $this->getToken()?->claims()?->get(RegisteredClaims::ID) ?? 0;
if ($this->adminId > 0) Context::set('current_admin_id', $this->adminId);
if ($name === 'adminId') return Context::get('current_admin_id',0);
if (!property_exists($this, $name)) throw new ErrException('属性未定义');
return $this->$name;
}
// /**
// * 主构造函数
// */
// public function __construct()
// {
// $this->adminId = Context::get('current_admin_id',0);
// var_dump('BaseAdminService获取到的'.$this->adminId);
// }
/**
* 主函数抽象类
*/

View File

@@ -10,8 +10,8 @@ declare(strict_types=1);
namespace App\Service\Admin\Log;
use App\Common\Repository\AdminUserLoginLogRepository;
use App\Exception\ErrException;
use App\Repository\AdminUserLoginLogRepository;
use App\Service\Admin\BaseAdminService;
use Hyperf\Di\Annotation\Inject;

View File

@@ -10,8 +10,8 @@ declare(strict_types=1);
namespace App\Service\Admin\Log;
use App\Common\Repository\AdminUserOperationLogRepository;
use App\Exception\ErrException;
use App\Repository\AdminUserOperationLogRepository;
use App\Service\Admin\BaseAdminService;
use Hyperf\Di\Annotation\Inject;

View File

@@ -10,9 +10,9 @@ declare(strict_types=1);
namespace App\Service\Admin\Login;
use App\Common\Repository\AdminUserRepository;
use App\Constants\Model\AdminUser\AdminUserStatusCode;
use App\Exception\ErrException;
use App\Repository\AdminUserRepository;
use App\Service\Admin\BaseAdminService;
use App\Service\BaseTokenService;
use Hyperf\Di\Annotation\Inject;
@@ -46,7 +46,6 @@ class LoginService extends BaseAdminService
}
if ($adminInfo->status == AdminUserStatusCode::DISABLE) throw new ErrException('用户已禁用');
$jwtHandle = $this->tokenService->setJwt('admin')->getJwt();
return $this->adminReturn->success('success',[

View File

@@ -10,13 +10,13 @@ declare(strict_types=1);
namespace App\Service;
use App\Common\Interface\CheckTokenInterface;
use App\Common\Interface\JwtInterface;
use App\Exception\ErrException;
use App\Interface\CheckTokenInterface;
use App\Lib\Jwt\JwtFactory;
use Hyperf\Di\Annotation\Inject;
use Lcobucci\JWT\Token\RegisteredClaims;
use Lcobucci\JWT\UnencryptedToken;
use App\Interface\JwtInterface;
use function Hyperf\Support\value;
final class BaseTokenService implements CheckTokenInterface
@@ -55,20 +55,4 @@ final class BaseTokenService implements CheckTokenInterface
$this->jwt = $jwt;
return $this;
}
/**
* @param UnencryptedToken $token
* @return \Closure
*/
public function refreshToken(UnencryptedToken $token): \Closure
{
return value(static function (JwtInterface $jwt) use ($token) {
$jwt->addBlackList($token);
return [
'access_token' => $jwt->builderAccessToken($token->claims()->get(RegisteredClaims::ID))->toString(),
'refresh_token' => $jwt->builderRefreshToken($token->claims()->get(RegisteredClaims::ID))->toString(),
'expire_at' => (int) $jwt->getConfig('ttl', 0),
];
}, $this->getJwt());
}
}

View File

@@ -11,5 +11,5 @@ declare(strict_types=1);
*/
return [
Hyperf\Database\Schema\Blueprint::class => App\Common\Macros\BlueprintMacros::class,
App\Interface\CheckTokenInterface::class => App\Service\BaseTokenService::class,
App\Common\Interface\CheckTokenInterface::class => App\Service\BaseTokenService::class,
];