feat(database): 添加用户角色权限系统及相关监控功能

- 创建用户表(users)包含基本信息和认证字段
- 创建角色表(roles)用于权限控制
- 创建权限表(permissions)定义系统权限
- 创建用户角色关联表(user_roles)建立用户与角色关系
- 创建角色权限关联表(role_permissions)建立角色与权限关系
- 创建迁移记录表(migrations)追踪数据库变更
- 添加AdminController提供管理员面板功能
- 实现系统监控、配置管理、缓存清理等功能
- 添加AOP切面编程支持的各种通知类型
- 实现告警管理AlertManager支持多渠道告警
- 添加文档注解接口规范
This commit is contained in:
Lawson
2026-04-08 17:00:28 +08:00
commit 2782d765fb
270 changed files with 107192 additions and 0 deletions

View File

@@ -0,0 +1,126 @@
<?php
declare(strict_types=1);
namespace Fendx\Core\Container;
use Fendx\Common\Exception\BusinessException;
use ReflectionClass;
use ReflectionException;
final class Container
{
private static ?Container $instance = null;
private array $bindings = [];
private array $instances = [];
private array $singletons = [];
private function __construct()
{
}
public static function getInstance(): self
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function bind(string $abstract, mixed $concrete = null, bool $singleton = false): void
{
if ($concrete === null) {
$concrete = $abstract;
}
$this->bindings[$abstract] = $concrete;
$this->singletons[$abstract] = $singleton;
}
public function singleton(string $abstract, mixed $concrete = null): void
{
$this->bind($abstract, $concrete, true);
}
public function make(string $abstract, array $parameters = []): mixed
{
// 如果已存在实例且为单例
if (isset($this->instances[$abstract])) {
return $this->instances[$abstract];
}
$concrete = $this->bindings[$abstract] ?? $abstract;
// 如果是闭包
if ($concrete instanceof \Closure) {
$object = $concrete($this, $parameters);
} else {
$object = $this->build($concrete, $parameters);
}
// 如果是单例,缓存实例
if (isset($this->singletons[$abstract]) && $this->singletons[$abstract]) {
$this->instances[$abstract] = $object;
}
return $object;
}
private function build(string $concrete, array $parameters): mixed
{
try {
$reflector = new ReflectionClass($concrete);
} catch (ReflectionException $e) {
throw new BusinessException(500, 'CLASS_NOT_FOUND', ['class' => $concrete]);
}
if (!$reflector->isInstantiable()) {
throw new BusinessException(500, 'CLASS_NOT_INSTANTIABLE', ['class' => $concrete]);
}
$constructor = $reflector->getConstructor();
if ($constructor === null) {
return new $concrete();
}
$dependencies = $constructor->getParameters();
$instances = $this->getDependencies($dependencies, $parameters);
return $reflector->newInstanceArgs($instances);
}
private function getDependencies(array $parameters, array $primitives): array
{
$dependencies = [];
foreach ($parameters as $parameter) {
$type = $parameter->getType();
if ($type === null || $type->isBuiltin()) {
$name = $parameter->getName();
$dependencies[] = $primitives[$name] ?? $parameter->getDefaultValue();
} else {
$dependencies[] = $this->make($type->getName());
}
}
return $dependencies;
}
public function has(string $abstract): bool
{
return isset($this->bindings[$abstract]);
}
public function forget(string $abstract): void
{
unset($this->bindings[$abstract], $this->instances[$abstract], $this->singletons[$abstract]);
}
public function flush(): void
{
$this->bindings = [];
$this->instances = [];
$this->singletons = [];
}
}