# Swagger **Repository Path**: motion-code/swagger ## Basic Information - **Project Name**: Swagger - **Description**: madong 管理后台swagger扩展服务 - **Primary Language**: PHP - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-11-13 - **Last Updated**: 2026-03-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Madong Swagger 模块 [![PHP >= 8.1](https://img.shields.io/badge/PHP-%3E%3D8.1-8892BF)](https://www.php.net/releases/8.1/en.php) [![OpenAPI 3.0](https://img.shields.io/badge/OpenAPI-3.0-green)](https://swagger.io/specification/) [![Webman](https://img.shields.io/badge/Webman-^2.0-blue)](https://www.workerman.net/webman) 一个功能强大、结构清晰的 Swagger/OpenAPI 文档生成模块,专为 Webman 框架设计。 ## 📋 目录 - [功能特性](#功能特性) - [目录结构](#目录结构) - [快速开始](#快速开始) - [注解分类](#注解分类) - [详细使用指南](#详细使用指南) - [AnnotationHelper 使用](#annotationhelper-使用) - [IS_REPEATABLE 支持](#is_repeatable-支持) - [最佳实践](#最佳实践) - [向后兼容](#向后兼容) - [常见问题](#常见问题) - [更新日志](#更新日志) ## ✨ 功能特性 - **完整的 OpenAPI 3.0 支持**:基于 `zircote/swagger-php` 和 `webman-tech/swagger` - **清晰的注解分类**:认证、操作、响应三类注解,职责分明 - **强大的响应注解**:支持 6 种响应类型(Data、Page、List、Tree、Result、Simple) - **权限注解集成**:内置 AllowAnonymous 和 Permission 注解,支持权限中间件 - **AnnotationHelper 工具**:便捷获取控制器和方法的注解信息 - **IS_REPEATABLE 支持**:响应注解支持在同一个方法上重复使用 - **向后兼容**:提供 `core\attribute` 别名类,兼容旧代码 - **灵活的示例数据**:支持多种数据格式(类、对象、JSON、数组) ## 📁 目录结构 ``` packages/swagger/src/ ├── attribute/ # 认证门面类(简化使用) │ ├── AllowAnonymous.php # 跳过认证注解 │ ├── Permission.php # 权限注解 │ └── ValidationRule.php # 验证规则注解 │ ├── annotation/ # 完整注解分类(实际实现) │ ├── auth/ # 认证注解 │ │ ├── AllowAnonymous.php │ │ ├── Permission.php │ │ └── ValidationRule.php │ │ │ ├── operation/ # 操作注解 │ │ ├── ApiOperation.php │ │ ├── ApiParameter.php │ │ └── ApiRequestBody.php │ │ │ └── response/ # 响应注解(支持 IS_REPEATABLE) │ ├── AbstractResponse.php │ ├── DataResponse.php │ ├── PageResponse.php │ ├── ListResponse.php │ ├── TreeResponse.php │ ├── ResultResponse.php │ ├── SimpleResponse.php │ └── ResponseSchema.php │ ├── schema/ # Schema 基类 │ └── SchemaBase.php │ └── helper/ # 辅助工具类 ├── AnnotationHelper.php # 注解查询工具 ├── ResponseHelper.php # 响应注解创建工具 ├── ExampleHelper.php # 示例数据生成工具 └── SchemaHelper.php # Schema 辅助工具 ``` ### 命名空间规范 | 注解类型 | 命名空间 | 说明 | |---------|---------|------| | 响应注解 | `madong\swagger\annotation\response\*` | 只在 annotation 中,支持 IS_REPEATABLE | | 认证注解 | `madong\swagger\attribute\*` | 推荐使用的门面类 | | 认证注解 | `madong\swagger\annotation\auth\*` | 实际实现(可用但不推荐)| | 操作注解 | `madong\swagger\annotation\operation\*` | 只在 annotation 中 | | Schema 注解 | `madong\swagger\annotation\schema\*` | 只在 annotation 中 | **重要**:响应类(DataResponse、PageResponse 等)只在 `annotation/response` 中存在,没有对应的 `attribute` 版本。认证类则同时存在于 `attribute` 和 `annotation/auth` 中。 ## 🚀 快速开始 ### 1. 安装 ```bash cd server/packages/swagger composer install ``` ### 2. 配置路由 在 `app/adminapi/config/route.php` 中注册 Swagger: ```php use Webman\Route; use WebmanTech\Swagger\Swagger; use OpenApi\Annotations as OA; Route::group('/adminapi', function () { // Swagger 文档路由配置 Swagger::create()->registerRoute([ 'route_prefix' => '/openapi', 'register_route' => true, 'openapi_doc' => [ 'scan_path' => [ base_path('app/adminapi'), base_path('app/schema'), // Schema 目录 ], 'exclude' => [ // 排除不需要扫描的文件 ], 'modify' => function (OA\OpenApi $openapi) { $openapi->info->title = config('app.name') . ' API'; $openapi->info->version = '1.0.0'; $openapi->servers = [ new OA\Server([ 'url' => '/adminapi', 'description' => request()->host(), ]), ]; // 配置安全认证 if (!$openapi->components instanceof OA\Components) { $openapi->components = new OA\Components([]); } $openapi->components->securitySchemes = [ new OA\SecurityScheme([ 'securityScheme' => 'api_key', 'type' => 'apiKey', 'name' => config('madong.jwt.app.token_name', 'Authorization'), 'in' => 'header', ]), ]; }, ], ]); }); ``` ### 3. 创建 Schema ```php '用户不存在'], description: '用户未找到' )] #[AllowAnonymous] public function getUser(Request $request, int $id) { // ... } } ``` ### 5. 访问文档 启动服务后,访问:`http://localhost:8787/adminapi/openapi` ## 📚 注解分类详解 ### 一、认证注解(attribute/ 或 annotation/auth/) #### 1. AllowAnonymous - 跳过认证 用于标记需要跳过 Token 验证或权限验证的接口。 **推荐使用 attribute 命名空间:** ```php use madong\swagger\attribute\AllowAnonymous; class UserController { // 跳过所有认证 #[AllowAnonymous(requireToken: true, requirePermission: true)] public function login() { // ... } // 仅跳过 Token 验证(需要权限验证) #[AllowAnonymous(requireToken: true, requirePermission: false)] public function getPublicInfo() { // ... } // 仅跳过权限验证(需要 Token 获取用户信息) #[AllowAnonymous(requireToken: false, requirePermission: true)] public function getCurrentUser() { // ... } // 使用便捷静态方法 #[AllowAnonymous::all('跳过所有认证')] public function register() { // ... } #[AllowAnonymous::token('仅跳过 Token 验证')] public function checkPermission() { // ... } #[AllowAnonymous::permission('仅跳过权限验证')] public function getUserInfo() { // ... } } ``` **属性说明:** - `$requireToken` (bool): 是否跳过 Token 验证,默认为 `false` - `$requirePermission` (bool): 是否跳过权限验证,默认为 `false` - `$description` (?string): 描述,用于文档生成 #### 2. Permission - 权限注解 用于标记控制器或方法需要的权限。 ```php use madong\swagger\attribute\Permission; class UserController { // 单个权限 #[Permission('user:list')] public function getUserList() { // ... } // 多个权限(AND 关系,需全部满足) #[Permission(['user:view', 'user:detail'])] public function getUserDetail() { // ... } // 多个权限(OR 关系,任一满足即可) #[Permission(['user:admin', 'user:super'], operation: 'or')] public function deleteUser() { // ... } // 使用便捷静态方法 #[Permission::create('user:create')] public function createUser() { // ... } #[Permission::all(['user:view', 'user:export'])] public function exportUsers() { // ... } #[Permission::any(['user:admin', 'user:manager', 'user:super'])] public function manageUser() { // ... } } ``` **属性说明:** - `$code` (string|array): 权限码,可以是字符串或数组 - `$operation` (string): 操作类型,`and` 或 `or`,默认为 `and` - `$description` (?string): 权限描述,用于文档 **方法说明:** - `create(string $code)`: 创建单个权限 - `all(array $codes)`: 创建 AND 关系的多个权限 - `any(array $codes)`: 创建 OR 关系的多个权限 - `getCodes(): array`: 获取权限码列表 - `getOperation(): string`: 获取操作类型 - `isAnd(): bool`: 检查是否为 AND 操作 - `isOr(): bool`: 检查是否为 OR 操作 #### 3. ValidationRule - 验证规则注解 用于在 Request 类的属性上定义验证规则,并可在 API 文档中展示验证信息。 ```php namespace app\request; use madong\swagger\attribute\ValidationRule; class UserRequest { #[ValidationRule( rules: 'required|string|max:50', messages: ['required' => '用户名不能为空'], description: '用户名' )] public string $username; #[ValidationRule( rules: ['required', 'email', 'max:100'], description: '邮箱地址' )] public string $email; #[ValidationRule( rules: 'required|min:6|confirmed', attributes: ['confirmed' => '密码确认'], description: '密码' )] public string $password; #[ValidationRule( rules: 'nullable|integer|min:0|max:120', example: 25, description: '年龄' )] public ?int $age; } ``` **属性说明:** - `$rules` (string|array): 验证规则 - `$messages` (array): 自定义错误消息 - `$attributes` (array): 字段名称映射 - `$description` (?string): 字段描述 - `$example` (mixed): 示例值 **方法说明:** - `getRulesString(): string`: 获取验证规则字符串 - `getRulesArray(): array`: 获取验证规则数组 - `hasRule(string $rule): bool`: 检查是否包含指定规则 - `getRulesDescription(): string`: 获取规则描述(用于文档展示) ### 二、响应注解(annotation/response/) 所有响应注解都支持 `IS_REPEATABLE`,可以在同一个方法上重复使用,用于定义不同状态码的响应。 #### 1. DataResponse - 数据对象响应 返回单个数据对象的响应模板。 ```php use madong\swagger\annotation\response\DataResponse; use app\schema\UserSchema; class UserController { #[DataResponse( response: 200, schema: UserSchema::class, description: '成功获取用户信息' )] #[DataResponse( response: 404, example: ['error' => '用户不存在'], description: '用户未找到' )] public function getUser(int $id) { // ... } } ``` **参数说明:** - `$schema` (mixed): Schema 类名、类对象或 JSON 字符串 - `$example` (mixed): 示例值(JSON 字符串、数组或对象) - `$description` (string): 响应描述 - `$response` (int): HTTP 状态码,默认为 200 - `$headers` (array): 响应头 **响应格式:** ```json { "code": 0, "message": "success", "data": { "id": 1, "name": "admin" } } ``` #### 2. PageResponse - 分页响应 返回分页数据的响应模板。 ```php use madong\swagger\annotation\response\PageResponse; use app\schema\UserListSchema; class UserController { #[PageResponse( response: 200, schema: UserListSchema::class, description: '成功获取用户列表' )] public function getUserList() { // ... } } ``` **响应格式:** ```json { "code": 0, "message": "success", "data": { "total": 100, "page": 1, "limit": 10, "list": [ { "id": 1, "name": "admin" }, { "id": 2, "name": "user" } ] } } ``` #### 3. ListResponse - 列表响应 返回列表数据的响应模板。 ```php use madong\swagger\annotation\response\ListResponse; class UserController { #[ListResponse( response: 200, schema: UserListSchema::class, description: '成功获取用户列表' )] public function getAllUsers() { // ... } } ``` **响应格式:** ```json { "code": 0, "message": "success", "data": { "list": [ { "id": 1, "name": "admin" }, { "id": 2, "name": "user" } ] } } ``` #### 4. TreeResponse - 树形数据响应 返回树形数据的响应模板。 ```php use madong\swagger\annotation\response\TreeResponse; use app\schema\MenuSchema; class MenuController { #[TreeResponse( response: 200, schema: MenuSchema::class, description: '成功获取菜单树' )] public function getMenuTree() { // ... } } ``` **响应格式:** ```json { "code": 0, "message": "success", "data": [ { "id": 1, "name": "系统管理", "children": [ { "id": 2, "name": "用户管理", "children": [] } ] } ] } ``` #### 5. ResultResponse - 通用结果响应 返回通用结果的响应模板。 ```php use madong\swagger\annotation\response\ResultResponse; class AuthController { #[ResultResponse( response: 200, jsonExample: '{"code": 0, "message": "操作成功"}', description: '操作成功' )] #[ResultResponse( response: 401, jsonExample: '{"code": 401, "message": "未授权"}', description: '认证失败' )] public function login() { // ... } } ``` **参数说明:** - `$jsonExample` (?string): JSON 字符串示例 - `$schema` (?string): Schema 类名(可选) - `$dataExample` (mixed): 数据示例(可选) - `$description` (string): 响应描述 - `$response` (int): HTTP 状态码,默认为 200 - `$headers` (array): 响应头 #### 6. SimpleResponse - 简单响应 返回简单成功消息的响应模板。 ```php use madong\swagger\annotation\response\SimpleResponse; class UserController { #[SimpleResponse( response: 200, example: ['flag' => true], description: '操作成功' )] #[SimpleResponse( response: 422, example: ['error' => '验证失败'], description: '验证错误' )] public function updateStatus() { // ... } } ``` **响应格式:** ```json { "code": 0, "message": "success", "data": null // 或使用 example 指定的值 } ``` ### 三、操作注解(annotation/operation/) #### 1. ApiOperation - 操作信息 ```php use madong\swagger\annotation\operation\ApiOperation; #[ApiOperation( summary: '创建用户', description: '创建一个新的用户账号,需要管理员权限', tags: ['用户管理'] )] public function createUser() { // ... } ``` #### 2. ApiParameter - 参数定义 ```php use madong\swagger\annotation\operation\ApiParameter; #[ApiParameter( name: 'id', in: 'path', description: '用户ID', required: true, type: 'integer' )] public function getUser(int $id) { // ... } ``` #### 3. ApiRequestBody - 请求体 ```php use madong\swagger\annotation\operation\ApiRequestBody; use app\request\UserRequest; #[ApiRequestBody( description: '用户信息', required: true, schema: UserRequest::class )] public function createUser() { // ... } ``` ## 🔧 AnnotationHelper 使用 `AnnotationHelper` 提供了一组便捷方法来获取控制器和方法的注解信息,主要用于中间件和文档生成。 ### 基本用法 ```php use madong\swagger\helper\AnnotationHelper; use madong\swagger\attribute\AllowAnonymous; use madong\swagger\attribute\Permission; // 获取方法上的 AllowAnonymous 注解 $AllowAnonymous = AnnotationHelper::getMethodAnnotation( 'app\adminapi\controller\UserController', 'login', AllowAnonymous::class ); if ($AllowAnonymous && $AllowAnonymous->shouldrequirePermission()) { // 跳过权限验证 } // 检查方法是否存在 Permission 注解 $hasPermission = AnnotationHelper::hasMethodAnnotation( $controllerClass, $action, Permission::class ); // 获取方法上的所有 OA 注解 $oaAnnotations = AnnotationHelper::getMethodOaAnnotations( $controllerClass, $action ); ``` ### 完整 API #### 获取注解 ```php // 获取方法上的指定注解实例 AnnotationHelper::getMethodAnnotation( string $controllerClass, // 控制器完整类名 string $methodName, // 方法名 string $annotationClass // 注解类名 ): ?object // 获取类上的指定注解实例 AnnotationHelper::getClassAnnotation( string $controllerClass, string $annotationClass ): ?object // 获取方法上的所有 OA 注解实例 AnnotationHelper::getMethodOaAnnotations( string $controllerClass, string $methodName ): array // 获取类上的所有 OA 注解实例 AnnotationHelper::getClassOaAnnotations( string $controllerClass ): array // 获取方法上的所有注解实例 AnnotationHelper::getAllMethodAnnotations( string $controllerClass, string $methodName ): array // 获取类上的所有注解实例 AnnotationHelper::getAllClassAnnotations( string $controllerClass ): array ``` #### 检查注解 ```php // 检查方法是否存在指定注解 AnnotationHelper::hasMethodAnnotation( string $controllerClass, string $methodName, string $annotationClass ): bool // 检查类是否存在指定注解 AnnotationHelper::hasClassAnnotation( string $controllerClass, string $annotationClass ): bool ``` ### 实际应用场景 #### 场景 1:权限中间件 ```php namespace app\adminapi\middleware; use madong\swagger\helper\AnnotationHelper; use madong\swagger\attribute\AllowAnonymous; use madong\swagger\attribute\Permission; use Webman\Http\Request; use Webman\Http\Response; use Webman\MiddlewareInterface; class PermissionMiddleware implements MiddlewareInterface { public function process(Request $request, callable $handler): Response { $controllerClass = $request->controller; $action = $request->action; // 检查是否跳过认证 $AllowAnonymous = AnnotationHelper::getMethodAnnotation( $controllerClass, $action, AllowAnonymous::class ); if ($AllowAnonymous && $AllowAnonymous->shouldrequirePermission()) { return $handler($request); } // 获取权限注解 $permission = AnnotationHelper::getMethodAnnotation( $controllerClass, $action, Permission::class ); if ($permission) { // 执行权限验证逻辑 $this->validatePermission($permission, $request); } return $handler($request); } private function validatePermission(Permission $permission, Request $request): void { $codes = $permission->getCodes(); $operation = $permission->getOperation(); // 执行 Casbin 或其他权限验证逻辑 // ... } } ``` #### 场景 2:文档生成 ```php use madong\swagger\helper\AnnotationHelper; use OpenApi\Attributes as OA; class DocGenerator { public function generatePath(string $controllerClass, string $methodName): array { $paths = []; // 获取所有 OA 注解 $oaAnnotations = AnnotationHelper::getMethodOaAnnotations( $controllerClass, $methodName ); foreach ($oaAnnotations as $annotation) { if ($annotation instanceof OA\Get) { $paths['get'] = $this->generateGetDoc($annotation); } elseif ($annotation instanceof OA\Post) { $paths['post'] = $this->generatePostDoc($annotation); } // ... 其他 HTTP 方法 } return $paths; } } ``` #### 场景 3:API 元数据收集 ```php use madong\swagger\helper\AnnotationHelper; use madong\swagger\attribute\Permission; use madong\swagger\annotation\operation\ApiOperation; class ApiMetadataCollector { public function collect(string $controllerClass, string $methodName): array { $metadata = []; // 获取 API 操作信息 $apiOperation = AnnotationHelper::getMethodAnnotation( $controllerClass, $methodName, ApiOperation::class ); if ($apiOperation) { $metadata['summary'] = $apiOperation->summary; $metadata['description'] = $apiOperation->description; } // 获取认证信息 $AllowAnonymous = AnnotationHelper::getMethodAnnotation( $controllerClass, $methodName, AllowAnonymous::class ); $metadata['requiresAuth'] = $AllowAnonymous === null || !$AllowAnonymous->shouldrequireToken(); // 获取权限信息 $permission = AnnotationHelper::getMethodAnnotation( $controllerClass, $methodName, Permission::class ); if ($permission) { $metadata['permissions'] = $permission->getCodes(); $metadata['permissionOperation'] = $permission->getOperation(); } return $metadata; } } ``` ## 🔄 IS_REPEATABLE 支持 ### 问题描述 在 PHP 8 中,属性默认不允许在同一个目标上重复使用。如果需要在同一个方法上定义多个响应(例如不同状态码的响应),会出现以下错误: ``` Error: Attribute "madong\swagger\annotation\response\DataResponse" must not be repeated ``` ### 解决方案 本模块已为所有响应注解添加了 `Attribute::IS_REPEATABLE` 标志,支持在同一个方法上重复使用。 ### 使用示例 ```php use madong\swagger\annotation\response\DataResponse; use app\schema\UserSchema; #[DataResponse( response: 200, schema: UserSchema::class, description: '成功获取用户信息' )] #[DataResponse( response: 404, example: ['error' => '用户不存在'], description: '用户未找到' )] #[DataResponse( response: 403, example: ['error' => '无权访问该用户'], description: '权限不足' )] public function getUser(int $id): Response { // ... } ``` ### 支持 IS_REPEATABLE 的注解 所有响应注解都支持重复使用: - `DataResponse` - `PageResponse` - `ListResponse` - `TreeResponse` - `ResultResponse` - `SimpleResponse` ### 不支持重复的注解 以下注解不需要重复,因此不添加 `IS_REPEATABLE` 标志: - `AllowAnonymous` - 跳过认证(一个方法只需要一个) - `Permission` - 权限(一个方法只需要一个) - `ValidationRule` - 验证规则(用于属性) - `ApiOperation` - 操作信息(一个方法只需要一个) ## 💡 最佳实践 ### 1. 统一命名空间使用 **推荐做法:** - 响应注解使用 `madong\swagger\annotation\response\*` - 认证注解使用 `madong\swagger\attribute\*` ```php use madong\swagger\annotation\response\DataResponse; use madong\swagger\attribute\AllowAnonymous; use madong\swagger\attribute\Permission; ``` **不推荐做法:** ```php // 避免混用 use madong\swagger\attribute\DataResponse; // 错误:attribute 中没有 DataResponse use madong\swagger\annotation\auth\AllowAnonymous; // 可用但不推荐 ``` ### 2. 合理使用响应注解重复 虽然支持重复,但建议根据实际业务需求合理使用: **推荐(2-3 个响应):** ```php #[DataResponse(response: 200, schema: UserSchema::class)] #[DataResponse(response: 404, example: ['error' => '用户不存在'])] #[DataResponse(response: 403, example: ['error' => '无权访问'])] ``` **不推荐(过多响应):** ```php // 避免定义过多不常用的响应 #[DataResponse(response: 200, schema: UserSchema::class)] #[DataResponse(response: 400, example: ['error' => 'Bad Request'])] #[DataResponse(response: 401, example: ['error' => 'Unauthorized'])] #[DataResponse(response: 403, example: ['error' => 'Forbidden'])] #[DataResponse(response: 404, example: ['error' => 'Not Found'])] #[DataResponse(response: 500, example: ['error' => 'Server Error'])] ``` ### 3. 使用 ResponseHelper 简化代码 ```php use madong\swagger\helper\ResponseHelper; // 推荐:使用 ResponseHelper #[ResponseHelper::data(UserSchema::class, [ 'description' => '成功', 'response' => 200 ])] // 不推荐:直接实例化 #[new DataResponse( schema: UserSchema::class, description: '成功', response: 200 )] ``` ### 4. 权限注解的层级使用 **类级别权限(作用于所有方法):** ```php use madong\swagger\attribute\Permission; #[Permission('user:manage')] class UserController { // 所有方法都需要 user:manage 权限 } ``` **方法级别权限(覆盖或补充类级别):** ```php class UserController { #[Permission('user:view')] public function getUser() { // 只需要 user:view 权限 } #[Permission('user:delete')] public function deleteUser() { // 需要 user:delete 权限 } } ``` ### 5. 使用 ExampleHelper 生成示例数据 ```php use madong\swagger\helper\ExampleHelper; // 分页示例 #[PageResponse( response: 200, schema: UserSchema::class, listExample: ExampleHelper::page([ ['id' => 1, 'name' => 'admin'], ['id' => 2, 'name' => 'user'] ], 100, 1, 10) )] // 树形示例 #[TreeResponse( response: 200, schema: MenuSchema::class, dataExample: ExampleHelper::tree([ ['id' => 1, 'name' => '系统', 'parent_id' => 0], ['id' => 2, 'name' => '用户', 'parent_id' => 1] ]) )] ``` ## 🔄 向后兼容 为了向后兼容,项目保留了 `core\attribute` 命名空间下的别名类: - `core\attribute\AllowAnonymous` - 继承自 `madong\swagger\attribute\AllowAnonymous` - `core\attribute\Permission` - 继承自 `madong\swagger\annotation\auth\Permission` ### 兼容性说明 **旧代码(继续有效):** ```php use core\attribute\AllowAnonymous; use core\attribute\Permission; class UserController { #[AllowAnonymous] public function login() { // ... } #[Permission('user:list')] public function getUserList() { // ... } } ``` **新代码(推荐):** ```php use madong\swagger\attribute\AllowAnonymous; use madong\swagger\attribute\Permission; class UserController { #[AllowAnonymous] public function login() { // ... } #[Permission('user:list')] public function getUserList() { // ... } } ``` **注意:** 响应类(DataResponse、PageResponse 等)没有 `core\attribute` 别名,因为它们主要在控制器中使用,不需要被中间件频繁查询。 ## ❓ 常见问题 ### Q1: 为什么响应类只在 annotation/response 中,没有 attribute 版本? **A:** 响应类主要用于控制器文档注解,不需要被中间件频繁查询。认证类(AllowAnonymous/Permission)需要被中间件频繁查询,因此提供 `attribute` 门面简化使用。 ### Q2: 使用 attribute 和 annotation/auth 有什么区别? **A:** 没有区别,`attribute\*` 类继承自 `annotation\auth\*` 类,两者完全等价。推荐使用 `attribute` 命名空间,更简洁。 ### Q3: AnnotationHelper 获取注解时应该用哪个类? **A:** 推荐统一使用 `attribute\*` 类: ```php // 推荐 AnnotationHelper::getMethodAnnotation($class, $method, AllowAnonymous::class); // 等价(但不推荐混用) AnnotationHelper::getMethodAnnotation($class, $method, \madong\...\auth\AllowAnonymous::class); ``` ### Q4: 为什么我的响应注解还是提示不能重复? **A:** 请检查: 1. 是否使用了正确的命名空间: ```php // 正确 use madong\swagger\annotation\response\DataResponse; // 错误(不存在) use madong\swagger\attribute\DataResponse; ``` 2. 是否重新生成了自动加载: ```bash composer dump-autoload ``` 3. 是否更新了 vendor 目录: ```bash # 确保 packages/swagger/src 同步到 vendor/madong/swagger/src composer install ``` ### Q5: 如何在中间件中获取注解? **A:** 使用 `AnnotationHelper`: ```php use madong\swagger\helper\AnnotationHelper; use madong\swagger\attribute\AllowAnonymous; class PermissionMiddleware { public function process(Request $request, callable $handler): Response { $controller = $request->controller; $action = $request->action; $AllowAnonymous = AnnotationHelper::getMethodAnnotation( $controller, $action, AllowAnonymous::class ); if ($AllowAnonymous && $AllowAnonymous->shouldrequirePermission()) { return $handler($request); } // ... } } ``` ### Q6: 如何排除测试控制器不生成文档? **A:** 在路由配置中排除: ```php Swagger::create()->registerRoute([ 'openapi_doc' => [ 'scan_path' => [ base_path('app/adminapi'), ], 'exclude' => [ base_path('app/adminapi/controller/test'), // 排除测试目录 ], ], ]); ``` ## 📄 更新日志 ### v1.0.0 (2026-03-11) #### 新增功能 - ✅ 完整的 OpenAPI 3.0 支持 - ✅ 6 种响应注解(Data、Page、List、Tree、Result、Simple) - ✅ 3 种认证注解(AllowAnonymous、Permission、ValidationRule) - ✅ 3 种操作注解(ApiOperation、ApiParameter、ApiRequestBody) - ✅ AnnotationHelper 注解查询工具 - ✅ ResponseHelper 响应注解创建工具 - ✅ ExampleHelper 示例数据生成工具 - ✅ SchemaHelper Schema 辅助工具 #### 优化改进 - ✅ 优化目录结构:attribute(门面)+ annotation(实现) - ✅ 添加 IS_REPEATABLE 支持,响应注解可重复使用 - ✅ 修复命名空间大小写问题 - ✅ 修复访问级别错误(private → protected) - ✅ 添加向后兼容别名(core\attribute) #### 文档完善 - ✅ 完整的 README.md - ✅ 命名空间规范指南 - ✅ IS_REPEATABLE 修复说明 - ✅ AnnotationHelper 使用示例 - ✅ 最佳实践指南 ## 🤝 贡献 欢迎提交 Issue 和 Pull Request! ## 📄 许可证 MIT License ## 🙏 致谢 - [Webman](https://www.workerman.net/webman) - 高性能 HTTP 框架 - [Swagger PHP](https://github.com/zircote/swagger-php) - OpenAPI 注解库 - [Webman Swagger](https://github.com/webman-tech/swagger) - Webman Swagger 集成 ## 📞 联系方式 - **作者**:Mr. April - **邮箱**:405784684@qq.com - **官方网站**:http://www.madong.tech - **Gitee**:https://gitee.com/motion-code --- **Made with ❤️ by Madong**