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,223 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use Fendx\Core\Annotation\Controller;
use Fendx\Core\Annotation\Inject;
use Fendx\Web\Annotation\GetRoute;
use Fendx\Web\Annotation\PostRoute;
use Fendx\Web\Annotation\PutRoute;
use Fendx\Web\Annotation\DeleteRoute;
use Fendx\Web\Request\Request;
use Fendx\Web\Response\Response;
use Fendx\Web\Validator\Validator;
use App\Service\UserService;
#[Controller('/api/users')]
class UserController
{
#[Inject]
private UserService $userService;
#[GetRoute('/')]
public function index(Request $request): array
{
$page = (int)($request->get('page', 1));
$pageSize = min((int)($request->get('pageSize', 10)), 100);
$result = $this->userService->getUsersPaginated($page, $pageSize);
return Response::paginated(
$result['users'],
$result['total'],
$result['page'],
$result['pageSize']
);
}
#[GetRoute('/{id}')]
public function show(int $id): array
{
$user = $this->userService->getUser($id);
if (!$user) {
return Response::notFound('User not found');
}
return Response::success($user->toArray());
}
#[PostRoute('')]
public function store(Request $request): array
{
$data = [
'username' => $request->post('username'),
'email' => $request->post('email'),
'password' => $request->post('password'),
'status' => (int)($request->post('status', 1))
];
try {
$user = $this->userService->createUser($data);
return Response::success($user->toArray(), 'User created successfully');
} catch (\Exception $e) {
return Response::error($e->getCode(), $e->getMessage());
}
}
#[PutRoute('/{id}')]
public function update(int $id, Request $request): array
{
$data = $request->all();
unset($data['id']); // 防止修改ID
try {
$success = $this->userService->updateUser($id, $data);
if (!$success) {
return Response::notFound('User not found');
}
$user = $this->userService->getUser($id);
return Response::success($user->toArray(), 'User updated successfully');
} catch (\Exception $e) {
return Response::error($e->getCode(), $e->getMessage());
}
}
#[DeleteRoute('/{id}')]
public function destroy(int $id): array
{
try {
$success = $this->userService->deleteUser($id);
if (!$success) {
return Response::notFound('User not found');
}
return Response::success(null, 'User deleted successfully');
} catch (\Exception $e) {
return Response::error($e->getCode(), $e->getMessage());
}
}
#[GetRoute('/search')]
public function search(Request $request): array
{
$keyword = $request->get('keyword', '');
$page = (int)($request->get('page', 1));
$pageSize = min((int)($request->get('pageSize', 10)), 100);
if (empty($keyword)) {
return Response::error(400, 'Keyword is required');
}
$result = $this->userService->searchUsers($keyword, $page, $pageSize);
return Response::paginated(
$result['users'],
$result['total'],
$result['page'],
$result['pageSize']
);
}
#[GetRoute('/active')]
public function active(): array
{
$users = $this->userService->getActiveUsers();
return Response::success($users);
}
#[GetRoute('/stats')]
public function stats(): array
{
$stats = [
'total_users' => $this->userService->getUsersCount(),
'active_users' => $this->userService->getActiveUsersCount(),
'inactive_users' => $this->userService->getUsersCount() - $this->userService->getActiveUsersCount()
];
return Response::success($stats);
}
#[PutRoute('/{id}/status')]
public function toggleStatus(int $id): array
{
try {
$success = $this->userService->toggleUserStatus($id);
if (!$success) {
return Response::notFound('User not found');
}
return Response::success(null, 'User status updated successfully');
} catch (\Exception $e) {
return Response::error($e->getCode(), $e->getMessage());
}
}
#[PutRoute('/{id}/password')]
public function changePassword(int $id, Request $request): array
{
$data = [
'old_password' => $request->post('old_password'),
'new_password' => $request->post('new_password')
];
$validator = Validator::make($data, [
'old_password' => 'required',
'new_password' => 'required|min:6'
]);
if (!$validator->validate()) {
return Response::validationError('Validation failed', $validator->errors());
}
try {
$success = $this->userService->changePassword($id, $data['old_password'], $data['new_password']);
if (!$success) {
return Response::notFound('User not found');
}
return Response::success(null, 'Password changed successfully');
} catch (\Exception $e) {
return Response::error($e->getCode(), $e->getMessage());
}
}
#[GetRoute('/{id}/exists')]
public function exists(int $id): array
{
$user = $this->userService->getUser($id);
return Response::success(['exists' => $user !== null]);
}
#[PostRoute('/check-email')]
public function checkEmail(Request $request): array
{
$email = $request->post('email');
if (empty($email)) {
return Response::error(400, 'Email is required');
}
$user = $this->userService->getUserByEmail($email);
return Response::success(['exists' => $user !== null]);
}
#[PostRoute('/check-username')]
public function checkUsername(Request $request): array
{
$username = $request->post('username');
if (empty($username)) {
return Response::error(400, 'Username is required');
}
$user = $this->userService->getUserByUsername($username);
return Response::success(['exists' => $user !== null]);
}
}