feat : admin aspect

This commit is contained in:
2025-09-15 14:45:29 +08:00
parent 8665b27294
commit 8046676669
11 changed files with 430 additions and 16 deletions

View File

@@ -0,0 +1,107 @@
<?php
declare(strict_types=1);
namespace App\Middleware\Admin;
use App\Annotation\Permission;
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\RequestHandlerInterface;
class PermissionMiddleware implements MiddlewareInterface
{
use RequestScopedTokenTrait;
use AdminUserTrait;
use ParserRouterTrait;
/**
* @var AdminUser
*/
protected AdminUser $adminUserInfo;
/**
* @param ContainerInterface $container
*/
public function __construct(protected ContainerInterface $container) {}
/**
* @param ServerRequestInterface $request
* @param RequestHandlerInterface $handler
* @return ResponseInterface
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$adminId = $this->getToken()?->claims()?->get(RegisteredClaims::ID) ?? 0;
if ($adminId <= 0) throw new ErrException('账户不存在');
$this->adminUserInfo = $this->getAdminUserInfo($adminId);
if ($this->adminUserInfo->status == AdminUserStatusCode::DISABLE) throw new ErrException('账号已禁用',AdminCode::DISABLED);
// 超级管理员提前下场 不用判断权限
if ($this->adminUserInfo->isSuperAdmin()) return $handler->handle($request);
$this->check($request->getAttribute(Dispatched::class));
return $handler->handle($request);
}
/**
* @param Dispatched $dispatched
* @return bool
*/
private function check(Dispatched $dispatched): bool
{
$parseResult = $this->parse($dispatched->handler->callback);
if (! $parseResult) return true;
[$controller, $method] = $parseResult;
$annotations = AnnotationCollector::getClassMethodAnnotation($controller, $method);
$classAnnotation = AnnotationCollector::getClassAnnotation($controller, Permission::class);
/**
* @var Permission[] $permissions
*/
$classAnnotation && $permissions[] = $classAnnotation;
$methodPermission = Arr::get($annotations, Permission::class);
$methodPermission && $permissions[] = $methodPermission;
foreach ($permissions as $permission) {
$this->handlePermission($permission);
}
return true;
}
/**
* @param Permission $permission
* @return void
*/
private function handlePermission(Permission $permission): void
{
$operation = $permission->getOperation();
$codes = $permission->getCode();
foreach ($codes as $code) {
$isMenu = $this->adminUserInfo->hasPermission($code);
if ($operation === Permission::OPERATION_AND && !$isMenu) throw new ErrException('暂无权限',AdminCode::FORBIDDEN);
if ($operation === Permission::OPERATION_OR && $isMenu) return;
}
if ($operation === Permission::OPERATION_OR) throw new ErrException('暂无权限',AdminCode::FORBIDDEN);
}
}