mirror of
https://devops.lemonos.cn/lawson/FendxPHP.git
synced 2026-06-15 15:02:49 +08:00
- 创建用户表(users)包含基本信息和认证字段 - 创建角色表(roles)用于权限控制 - 创建权限表(permissions)定义系统权限 - 创建用户角色关联表(user_roles)建立用户与角色关系 - 创建角色权限关联表(role_permissions)建立角色与权限关系 - 创建迁移记录表(migrations)追踪数据库变更 - 添加AdminController提供管理员面板功能 - 实现系统监控、配置管理、缓存清理等功能 - 添加AOP切面编程支持的各种通知类型 - 实现告警管理AlertManager支持多渠道告警 - 添加文档注解接口规范
437 lines
14 KiB
PHP
437 lines
14 KiB
PHP
<?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;
|
|
}
|
|
}
|