mirror of
https://devops.lemonos.cn/lawson/FendxPHP.git
synced 2026-06-15 23:12:49 +08:00
feat(database): 添加用户角色权限系统及相关监控功能
- 创建用户表(users)包含基本信息和认证字段 - 创建角色表(roles)用于权限控制 - 创建权限表(permissions)定义系统权限 - 创建用户角色关联表(user_roles)建立用户与角色关系 - 创建角色权限关联表(role_permissions)建立角色与权限关系 - 创建迁移记录表(migrations)追踪数据库变更 - 添加AdminController提供管理员面板功能 - 实现系统监控、配置管理、缓存清理等功能 - 添加AOP切面编程支持的各种通知类型 - 实现告警管理AlertManager支持多渠道告警 - 添加文档注解接口规范
This commit is contained in:
152
fendx-framework/fendx-web/src/Scanner/RouteScanner.php
Normal file
152
fendx-framework/fendx-web/src/Scanner/RouteScanner.php
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fendx\Web\Scanner;
|
||||
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use ReflectionException;
|
||||
use Fendx\Core\Annotation\Controller;
|
||||
use Fendx\Web\Annotation\GetRoute;
|
||||
use Fendx\Web\Annotation\PostRoute;
|
||||
use Fendx\Web\Route\Router;
|
||||
|
||||
final class RouteScanner
|
||||
{
|
||||
private Router $router;
|
||||
private array $controllers = [];
|
||||
|
||||
public function __construct(Router $router)
|
||||
{
|
||||
$this->router = $router;
|
||||
}
|
||||
|
||||
public function scan(string $scanPath): void
|
||||
{
|
||||
$this->scanControllers($scanPath);
|
||||
$this->registerRoutes();
|
||||
}
|
||||
|
||||
private function scanControllers(string $path): void
|
||||
{
|
||||
if (!is_dir($path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$files = glob($path . '/**/*.php');
|
||||
|
||||
foreach ($files as $file) {
|
||||
$this->scanControllerFile($file);
|
||||
}
|
||||
}
|
||||
|
||||
private function scanControllerFile(string $file): void
|
||||
{
|
||||
$className = $this->getClassNameFromFile($file);
|
||||
|
||||
if ($className === null || class_exists($className) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$reflection = new ReflectionClass($className);
|
||||
|
||||
// 检查是否有Controller注解
|
||||
$controllerAttributes = $reflection->getAttributes(Controller::class);
|
||||
if (empty($controllerAttributes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$controllerAttribute = $controllerAttributes[0]->newInstance();
|
||||
$prefix = $controllerAttribute->prefix;
|
||||
|
||||
// 扫描方法上的路由注解
|
||||
$this->scanControllerMethods($className, $reflection, $prefix);
|
||||
|
||||
} catch (ReflectionException $e) {
|
||||
error_log("Failed to scan controller $className: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function scanControllerMethods(string $className, ReflectionClass $reflection, string $prefix): void
|
||||
{
|
||||
$methods = $reflection->getMethods(ReflectionMethod::IS_PUBLIC);
|
||||
|
||||
foreach ($methods as $method) {
|
||||
if ($method->getName() === '__construct') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->scanMethodRoutes($className, $method, $prefix);
|
||||
}
|
||||
}
|
||||
|
||||
private function scanMethodRoutes(string $className, ReflectionMethod $method, string $prefix): void
|
||||
{
|
||||
// 扫描GetRoute注解
|
||||
$getRouteAttributes = $method->getAttributes(GetRoute::class);
|
||||
foreach ($getRouteAttributes as $attribute) {
|
||||
$routeAttribute = $attribute->newInstance();
|
||||
$path = $prefix . $routeAttribute->path;
|
||||
$this->controllers[] = [
|
||||
'method' => 'GET',
|
||||
'path' => $path,
|
||||
'controller' => $className,
|
||||
'action' => $method->getName()
|
||||
];
|
||||
}
|
||||
|
||||
// 扫描PostRoute注解
|
||||
$postRouteAttributes = $method->getAttributes(PostRoute::class);
|
||||
foreach ($postRouteAttributes as $attribute) {
|
||||
$routeAttribute = $attribute->newInstance();
|
||||
$path = $prefix . $routeAttribute->path;
|
||||
$this->controllers[] = [
|
||||
'method' => 'POST',
|
||||
'path' => $path,
|
||||
'controller' => $className,
|
||||
'action' => $method->getName()
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
private function registerRoutes(): void
|
||||
{
|
||||
foreach ($this->controllers as $route) {
|
||||
$handler = [$route['controller'], $route['action']];
|
||||
|
||||
switch ($route['method']) {
|
||||
case 'GET':
|
||||
$this->router->get($route['path'], $handler);
|
||||
break;
|
||||
case 'POST':
|
||||
$this->router->post($route['path'], $handler);
|
||||
break;
|
||||
case 'PUT':
|
||||
$this->router->put($route['path'], $handler);
|
||||
break;
|
||||
case 'DELETE':
|
||||
$this->router->delete($route['path'], $handler);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getClassNameFromFile(string $file): ?string
|
||||
{
|
||||
$content = file_get_contents($file);
|
||||
|
||||
if (preg_match('/namespace\s+([^;]+);/', $content, $matches)) {
|
||||
$namespace = trim($matches[1]);
|
||||
$className = basename($file, '.php');
|
||||
return $namespace . '\\' . $className;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRoutes(): array
|
||||
{
|
||||
return $this->controllers;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user