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:
436
fendx-framework/fendx-cli/src/Generator/ControllerGenerator.php
Normal file
436
fendx-framework/fendx-cli/src/Generator/ControllerGenerator.php
Normal file
@@ -0,0 +1,436 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fendx\CLI\Generator;
|
||||
|
||||
class ControllerGenerator extends CodeGenerator
|
||||
{
|
||||
protected function loadTemplates(): void
|
||||
{
|
||||
$this->templates = [
|
||||
'controller' => $this->getControllerTemplate(),
|
||||
'method' => $this->getMethodTemplate(),
|
||||
'api_controller' => $this->getApiControllerTemplate(),
|
||||
'resource_controller' => $this->getResourceControllerTemplate()
|
||||
];
|
||||
}
|
||||
|
||||
public function generate(string $name, array $options = []): bool
|
||||
{
|
||||
if (!$this->validateName($name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$className = $this->getClassName($name) . 'Controller';
|
||||
$type = $options['type'] ?? 'basic';
|
||||
$resource = $options['resource'] ?? null;
|
||||
$api = $options['api'] ?? false;
|
||||
$methods = $options['methods'] ?? [];
|
||||
|
||||
$subNamespace = 'Controller';
|
||||
if ($api) {
|
||||
$subNamespace .= '\\Api';
|
||||
}
|
||||
|
||||
$path = $this->getNamespacePath($subNamespace);
|
||||
$namespace = $this->getFullNamespace($subNamespace);
|
||||
|
||||
if (!$this->createDirectory($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$content = $this->generateController($className, $namespace, $type, $resource, $methods, $options);
|
||||
$filePath = $path . '/' . $className . '.php';
|
||||
|
||||
if (!$this->createFile($filePath, $content)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->showMessage('success', "Controller '{$className}' generated successfully!");
|
||||
|
||||
// 生成路由提示
|
||||
$this->showRouteHint($className, $resource, $api);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function generateController(string $className, string $namespace, string $type, ?string $resource, array $methods, array $options): string
|
||||
{
|
||||
switch ($type) {
|
||||
case 'api':
|
||||
return $this->generateApiController($className, $namespace, $resource, $methods, $options);
|
||||
case 'resource':
|
||||
return $this->generateResourceController($className, $namespace, $resource, $options);
|
||||
default:
|
||||
return $this->generateBasicController($className, $namespace, $methods, $options);
|
||||
}
|
||||
}
|
||||
|
||||
private function generateBasicController(string $className, string $namespace, array $methods, array $options): string
|
||||
{
|
||||
$useStatements = [];
|
||||
$classMethods = '';
|
||||
|
||||
if (empty($methods)) {
|
||||
$methods = ['index'];
|
||||
}
|
||||
|
||||
foreach ($methods as $method) {
|
||||
$classMethods .= $this->generateMethod($method, $options);
|
||||
|
||||
if (in_array($method, ['request', 'response'])) {
|
||||
$useStatements[] = 'use Fendx\\Web\\Request\\Request;';
|
||||
$useStatements[] = 'use Fendx\\Web\\Response\\Response;';
|
||||
}
|
||||
}
|
||||
|
||||
$useStatements = array_unique($useStatements);
|
||||
$useBlock = empty($useStatements) ? '' : implode("\n", $useStatements) . "\n\n";
|
||||
|
||||
return $this->renderTemplate('controller', [
|
||||
'namespace' => $namespace,
|
||||
'use_block' => $useBlock,
|
||||
'class_name' => $className,
|
||||
'methods' => $classMethods
|
||||
]);
|
||||
}
|
||||
|
||||
private function generateApiController(string $className, string $namespace, ?string $resource, array $methods, array $options): string
|
||||
{
|
||||
$useStatements = [
|
||||
'use Fendx\\Core\\Annotation\\Controller;',
|
||||
'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;'
|
||||
];
|
||||
|
||||
$classMethods = '';
|
||||
$resourceName = $resource ?: strtolower(str_replace('Controller', '', $className));
|
||||
|
||||
if (empty($methods)) {
|
||||
$methods = ['index', 'show', 'store', 'update', 'destroy'];
|
||||
}
|
||||
|
||||
foreach ($methods as $method) {
|
||||
$classMethods .= $this->generateApiMethod($method, $resourceName, $options);
|
||||
}
|
||||
|
||||
return $this->renderTemplate('api_controller', [
|
||||
'namespace' => $namespace,
|
||||
'use_block' => implode("\n", $useStatements) . "\n\n",
|
||||
'class_name' => $className,
|
||||
'resource_name' => $resourceName,
|
||||
'methods' => $classMethods
|
||||
]);
|
||||
}
|
||||
|
||||
private function generateResourceController(string $className, string $namespace, ?string $resource, array $options): string
|
||||
{
|
||||
$useStatements = [
|
||||
'use Fendx\\Core\\Annotation\\Controller;',
|
||||
'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;'
|
||||
];
|
||||
|
||||
$resourceName = $resource ?: strtolower(str_replace('Controller', '', $className));
|
||||
$modelClass = $this->getClassName($resourceName);
|
||||
$modelNamespace = $this->getFullNamespace('Model');
|
||||
|
||||
$classMethods = $this->generateResourceMethods($resourceName, $modelClass, $modelNamespace, $options);
|
||||
|
||||
return $this->renderTemplate('resource_controller', [
|
||||
'namespace' => $namespace,
|
||||
'use_block' => implode("\n", $useStatements) . "\n\n",
|
||||
'class_name' => $className,
|
||||
'resource_name' => $resourceName,
|
||||
'model_class' => $modelClass,
|
||||
'model_namespace' => $modelNamespace,
|
||||
'methods' => $classMethods
|
||||
]);
|
||||
}
|
||||
|
||||
private function generateMethod(string $method, array $options): string
|
||||
{
|
||||
$methodName = $method;
|
||||
$parameters = '';
|
||||
$body = '';
|
||||
$docBlock = '';
|
||||
|
||||
switch ($method) {
|
||||
case 'index':
|
||||
$docBlock = $this->generateDocBlock([], 'array');
|
||||
$body = ' // TODO: Implement index method' . "\n" . ' return [];';
|
||||
break;
|
||||
|
||||
case 'show':
|
||||
$docBlock = $this->generateDocBlock(['id' => 'int'], 'array');
|
||||
$parameters = 'int $id';
|
||||
$body = ' // TODO: Implement show method' . "\n" . ' return [];';
|
||||
break;
|
||||
|
||||
case 'create':
|
||||
$docBlock = $this->generateDocBlock([], 'array');
|
||||
$body = ' // TODO: Implement create method' . "\n" . ' return [];';
|
||||
break;
|
||||
|
||||
case 'store':
|
||||
$docBlock = $this->generateDocBlock(['request' => 'Request'], 'array');
|
||||
$parameters = 'Request $request';
|
||||
$useStatements[] = 'use Fendx\\Web\\Request\\Request;';
|
||||
$body = ' // TODO: Implement store method' . "\n" . ' return [];';
|
||||
break;
|
||||
|
||||
case 'edit':
|
||||
$docBlock = $this->generateDocBlock(['id' => 'int'], 'array');
|
||||
$parameters = 'int $id';
|
||||
$body = ' // TODO: Implement edit method' . "\n" . ' return [];';
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$docBlock = $this->generateDocBlock(['id' => 'int', 'request' => 'Request'], 'array');
|
||||
$parameters = 'int $id, Request $request';
|
||||
$useStatements[] = 'use Fendx\\Web\\Request\\Request;';
|
||||
$body = ' // TODO: Implement update method' . "\n" . ' return [];';
|
||||
break;
|
||||
|
||||
case 'destroy':
|
||||
$docBlock = $this->generateDocBlock(['id' => 'int'], 'bool');
|
||||
$parameters = 'int $id';
|
||||
$body = ' // TODO: Implement destroy method' . "\n" . ' return true;';
|
||||
break;
|
||||
|
||||
default:
|
||||
$docBlock = $this->generateDocBlock([], 'mixed');
|
||||
$body = ' // TODO: Implement ' . $method . ' method' . "\n" . ' return null;';
|
||||
}
|
||||
|
||||
return $this->renderTemplate('method', [
|
||||
'doc_block' => $docBlock,
|
||||
'method_name' => $methodName,
|
||||
'parameters' => $parameters,
|
||||
'body' => $body
|
||||
]);
|
||||
}
|
||||
|
||||
private function generateApiMethod(string $method, string $resourceName, array $options): string
|
||||
{
|
||||
$methodName = $method;
|
||||
$route = '';
|
||||
$parameters = '';
|
||||
$body = '';
|
||||
$httpMethod = '';
|
||||
|
||||
switch ($method) {
|
||||
case 'index':
|
||||
$route = "/{$resourceName}";
|
||||
$httpMethod = 'GetRoute';
|
||||
$docBlock = $this->generateDocBlock([], 'array');
|
||||
$body = ' $data = []; // TODO: Fetch data from database' . "\n" . ' return Response::success($data);';
|
||||
break;
|
||||
|
||||
case 'show':
|
||||
$route = "/{$resourceName}/{id}";
|
||||
$httpMethod = 'GetRoute';
|
||||
$parameters = 'int $id';
|
||||
$docBlock = $this->generateDocBlock(['id' => 'int'], 'array');
|
||||
$body = ' $data = []; // TODO: Fetch item by id' . "\n" . ' return Response::success($data);';
|
||||
break;
|
||||
|
||||
case 'store':
|
||||
$route = "/{$resourceName}";
|
||||
$httpMethod = 'PostRoute';
|
||||
$parameters = 'Request $request';
|
||||
$docBlock = $this->generateDocBlock(['request' => 'Request'], 'array');
|
||||
$body = ' $data = $request->all();' . "\n" . ' // TODO: Store data to database' . "\n" . ' return Response::success($data, \'Resource created successfully\');';
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$route = "/{$resourceName}/{id}";
|
||||
$httpMethod = 'PutRoute';
|
||||
$parameters = 'int $id, Request $request';
|
||||
$docBlock = $this->generateDocBlock(['id' => 'int', 'request' => 'Request'], 'array');
|
||||
$body = ' $data = $request->all();' . "\n" . ' // TODO: Update item by id' . "\n" . ' return Response::success($data, \'Resource updated successfully\');';
|
||||
break;
|
||||
|
||||
case 'destroy':
|
||||
$route = "/{$resourceName}/{id}";
|
||||
$httpMethod = 'DeleteRoute';
|
||||
$parameters = 'int $id';
|
||||
$docBlock = $this->generateDocBlock(['id' => 'int'], 'array');
|
||||
$body = ' // TODO: Delete item by id' . "\n" . ' return Response::success(null, \'Resource deleted successfully\');';
|
||||
break;
|
||||
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
|
||||
return <<<PHP
|
||||
#[{$httpMethod}('{$route}')]
|
||||
public function {$methodName}({$parameters}): array
|
||||
{
|
||||
{$body}
|
||||
}
|
||||
|
||||
PHP;
|
||||
}
|
||||
|
||||
private function generateResourceMethods(string $resourceName, string $modelClass, string $modelNamespace, array $options): string
|
||||
{
|
||||
$methods = '';
|
||||
|
||||
// Index method
|
||||
$methods .= <<<PHP
|
||||
#[GetRoute('/{$resourceName}')]
|
||||
public function index(): array
|
||||
{
|
||||
\$items = {$modelClass}::all();
|
||||
return Response::success(\$items);
|
||||
}
|
||||
|
||||
PHP;
|
||||
|
||||
// Show method
|
||||
$methods .= <<<PHP
|
||||
#[GetRoute('/{$resourceName}/{id}')]
|
||||
public function show(int \$id): array
|
||||
{
|
||||
\$item = {$modelClass}::find(\$id);
|
||||
if (!\$item) {
|
||||
return Response::error(404, '{$modelClass} not found');
|
||||
}
|
||||
return Response::success(\$item);
|
||||
}
|
||||
|
||||
PHP;
|
||||
|
||||
// Store method
|
||||
$methods .= <<<PHP
|
||||
#[PostRoute('/{$resourceName}')]
|
||||
public function store(Request \$request): array
|
||||
{
|
||||
\$data = \$request->all();
|
||||
\$item = {$modelClass}::create(\$data);
|
||||
return Response::success(\$item, '{$modelClass} created successfully');
|
||||
}
|
||||
|
||||
PHP;
|
||||
|
||||
// Update method
|
||||
$methods .= <<<PHP
|
||||
#[PutRoute('/{$resourceName}/{id}')]
|
||||
public function update(int \$id, Request \$request): array
|
||||
{
|
||||
\$item = {$modelClass}::find(\$id);
|
||||
if (!\$item) {
|
||||
return Response::error(404, '{$modelClass} not found');
|
||||
}
|
||||
|
||||
\$data = \$request->all();
|
||||
\$item->update(\$data);
|
||||
return Response::success(\$item, '{$modelClass} updated successfully');
|
||||
}
|
||||
|
||||
PHP;
|
||||
|
||||
// Destroy method
|
||||
$methods .= <<<PHP
|
||||
#[DeleteRoute('/{$resourceName}/{id}')]
|
||||
public function destroy(int \$id): array
|
||||
{
|
||||
\$item = {$modelClass}::find(\$id);
|
||||
if (!\$item) {
|
||||
return Response::error(404, '{$modelClass} not found');
|
||||
}
|
||||
|
||||
\$item->delete();
|
||||
return Response::success(null, '{$modelClass} deleted successfully');
|
||||
}
|
||||
|
||||
PHP;
|
||||
|
||||
return $methods;
|
||||
}
|
||||
|
||||
private function showRouteHint(string $className, ?string $resource, bool $api): void
|
||||
{
|
||||
$controllerName = str_replace('Controller', '', $className);
|
||||
$this->output->writeln('');
|
||||
$this->output->writeln('<comment>Route registration hint:</comment>');
|
||||
|
||||
if ($api) {
|
||||
$this->output->writeln("Add this to your routes configuration:");
|
||||
$this->output->writeln("<info>\$router->mount('/api', function(\$router) {");
|
||||
$this->output->writeln(" \$router->registerController(new {$this->getFullNamespace('Controller\\Api')}\\{$className}());");
|
||||
$this->output->writeln("});</info>");
|
||||
} else {
|
||||
$this->output->writeln("Add this to your routes configuration:");
|
||||
$this->output->writeln("<info>\$router->registerController(new {$this->getFullNamespace('Controller')}\\{$className}());</info>");
|
||||
}
|
||||
}
|
||||
|
||||
private function getControllerTemplate(): string
|
||||
{
|
||||
return <<<PHP
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace {{namespace}};
|
||||
|
||||
{{use_block}}class {{class_name}}
|
||||
{
|
||||
{{methods}}
|
||||
}
|
||||
PHP;
|
||||
}
|
||||
|
||||
private function getMethodTemplate(): string
|
||||
{
|
||||
return <<<PHP
|
||||
{{doc_block}}
|
||||
public function {{method_name}}({{parameters}})
|
||||
{
|
||||
{{body}}
|
||||
}
|
||||
|
||||
PHP;
|
||||
}
|
||||
|
||||
private function getApiControllerTemplate(): string
|
||||
{
|
||||
return <<<PHP
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace {{namespace}};
|
||||
|
||||
{{use_block}}#[Controller('/api')]
|
||||
class {{class_name}}
|
||||
{
|
||||
{{methods}}
|
||||
}
|
||||
PHP;
|
||||
}
|
||||
|
||||
private function getResourceControllerTemplate(): string
|
||||
{
|
||||
return <<<PHP
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace {{namespace}};
|
||||
|
||||
{{use_block}}#[Controller('/api')]
|
||||
class {{class_name}}
|
||||
{
|
||||
{{methods}}
|
||||
}
|
||||
PHP;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user