---
author: Peanut
created_at: 2026-05-23
purpose: 设计接口管理页面的中文描述补全和测试面板表单化改造
---

# 接口管理中文描述与测试面板改造设计

## 1. 目标

- 所有接口均有对应的中文描述（summary + description），在接口列表和详情中可直观理解接口用途
- 所有参数均有中文描述，在详情和测试面板中可理解参数含义
- 测试面板从"空白 JSON 输入框"改造为"预填充 JSON 编辑器"——参数 key 和结构预填充，用户只需修改值即可测试
- 操作列增加"测试"按钮，点击直接打开弹窗并切换到测试标签

## 2. 架构

```
后端 Controller (@Operation/@Parameter/@Schema 注解)
    → SpringDoc 自动生成 OpenAPI 3 JSON (/v3/api-docs)
    → ApiEndpointService.syncFromOpenApi() 解析并入库
    → 前端 getEndpointList/getEndpointDetail 展示
    → 前端 EndpointDetailDialog 测试面板渲染预填充 JSON 表单
```

## 3. 后端改造

### 3.1 Controller 注解补全

为 `server/src/main/java/com/emotion/controller/` 下所有 Controller 补全注解：

**类级别注解：**
```java
@Tag(name = "用户管理", description = "用户的增删改查、状态管理等操作")
public class UserController { ... }
```

**方法级别注解：**
```java
@Operation(summary = "分页查询用户列表", description = "支持按用户名、状态、角色等条件筛选")
@GetMapping("/list")
public Result<Page<UserVO>> list(@Validated UserQueryRequest request) { ... }
```

**参数级别注解（路径参数/查询参数）：**
```java
@Parameter(description = "用户ID", required = true)
@RequestParam String userId
```

**DTO 字段注解（请求体参数）：**
```java
public class LoginRequest {
    @Schema(description = "手机号")
    private String phone;

    @Schema(description = "短信验证码")
    private String smsCode;
}
```

### 3.2 注解补全范围与批次

按优先级分批补全，每批完成后触发同步验证：

**Batch 1 (P0 - 认证与管理，约 5 个 Controller，~25 个接口):**
- AuthController, AdminAuthController, GuestUserController, TokenController, AdminController
- 涉及核心请求体：登录/注册/重置密码等，参数描述最关键

**Batch 2 (P1 - AI 与社区，约 8 个 Controller，~40 个接口):**
- AiChatController, AiConfigController, AiRoutingController, CozeApiCallController
- CommunityPostController, CommentController, SocialContentController, SocialInsightController
- UserProfileController, UserController

**Batch 3 (P1 - 日记与情绪，约 8 个 Controller，~35 个接口):**
- DiaryPostController, DiaryCommentController, GrowthTopicController, TopicInteractionController
- EmotionAnalysisController, EmotionRecordController, EmotionSummaryController, LifeEventController
- ConversationController, MessageController

**Batch 4 (P2 - 其他，约 10+ 个 Controller，~30 个接口):**
- DictionaryController, EpicScriptController, LifePathController, AchievementController
- RewardController, UserStatsController, TtsController, AsrController, HealthController
- AnalyticsController, AdminAnalyticsController, ChatWebSocketController

**完成标准：** 每个批次的 Controller 及其关联的 Request/Response DTO 全部注解补全。

### 3.3 同步逻辑

`ApiEndpointServiceImpl.syncFromOpenApi()` 已经正确解析 OpenAPI 规范中的 `summary`、`description`、`parameters[].description`、`requestBody` schema 中的字段描述。补全注解后在管理后台点击"手动同步"即可生效。

## 4. 前端改造

### 4.1 EndpointList.vue — 操作列增加"测试"按钮

在操作列添加"测试"按钮，点击后打开详情弹窗并自动切换到测试标签页：

```vue
<el-table-column label="操作" width="150" align="center">
  <template #default="{ row }">
    <el-button type="primary" link size="small" @click="showDetail(row)">详情</el-button>
    <el-button type="success" link size="small" @click="showTest(row)">测试</el-button>
  </template>
</el-table-column>
```

`showTest(row)` 方法：加载详情后，通过 `defaultTab` prop 控制子组件默认打开测试标签。

### 4.2 EndpointDetailDialog.vue — 测试面板改造

#### 4.2.1 新增 defaultTab prop

父组件可控制默认打开的标签页：

```typescript
const props = defineProps<{
  modelValue: boolean
  detail: ApiEndpointDetail | null
  defaultTab?: 'detail' | 'test'  // 新增，默认 'detail'
}>()
```

watch 逻辑中：
```typescript
watch(() => props.detail, (ep) => {
  if (ep) {
    testForm.value.path = ep.path
    testForm.value.method = ep.method
    testForm.value.params = {}
    testForm.value.body = ''
    testResult.value = null
    activeTab.value = props.defaultTab || 'detail'  // 使用传入的默认标签
  }
}, { immediate: true })
```

#### 4.2.2 查询参数表单化（GET/DELETE 等无请求体的接口）

对于 `paramType` 为 `query` 或 `path` 的参数，渲染为表单输入框：

| paramTypeDef | enumValues 有值 | 渲染组件 |
|-------------|----------------|---------|
| string | 有 | `<el-select>` 下拉选择 |
| string | 无 | `<el-input>` 文本输入 |
| integer/number | 有 | `<el-select>` 下拉选择 |
| integer/number | 无 | `<el-input-number>` 数字输入 |
| boolean | - | `<el-switch>` 开关 |
| array | - | `<el-input>` 文本输入（逗号分隔） |
| object | - | 暂不支持，fallback 到文本输入 |

每个参数显示：
- **label**: 参数中文描述（description），无描述则显示参数名（name）
- **placeholder**: 示例值（example）或数据类型提示
- **必填标记**: required=1 时 label 旁显示红色星号

#### 4.2.3 请求体预填充（POST/PUT/PATCH）

对于有请求体的接口，使用 JSON 编辑器（`<el-input type="textarea">`）但预填充完整结构：

**预填充算法：**

```
function generateJsonTemplate(schema):
  if schema is null or empty object: return ""
  result = {}
  for each [key, prop] in schema.properties:
    if prop.example exists and is not empty:
      result[key] = parseExample(prop.example)  // 尝试解析为对应类型
    else if prop.type == "string":
      result[key] = ""
    else if prop.type == "integer":
      result[key] = 0
    else if prop.type == "number":
      result[key] = 0.0
    else if prop.type == "boolean":
      result[key] = false
    else if prop.type == "array":
      result[key] = []
    else if prop.type == "object" and prop.properties:
      result[key] = generateJsonTemplate(prop)  // 递归
    else:
      result[key] = null
  
  // 对 required 字段但没有 example 的，保留空值占位
  // 对非 required 且无 example 的可选字段，省略该 key
  for each key in result:
    if key not in schema.required and result[key] in [null, "", 0, false, []]:
      delete result[key]
  
  return JSON.stringify(result, null, 2)
```

**数据来源优先级：**
1. 先从 `detail.params` 中找 `paramType === 'body'` 的参数，用其 description/example 填充
2. 如果没有 body 类型参数，从 `detail.requestSchema` 解析 JSON Schema 生成

**UI 展示：**

```
请求体 (JSON)
──────────────────────────────────────────┐
│ {                                        │
│   "phone": "13800138000",                │
│   "smsCode": "123456"                    │
│ }                                        │
└──────────────────────────────────────────┘
💡 参数结构已预填充，修改值后点击"发送请求"即可
```

#### 4.2.4 请求头展示

在参数配置区域下方展示自动添加的请求头（只读）：

```
请求头
┌──────────────────────────────────────────┐
│ Authorization: Bearer eyJhbGci...xxx     │
│ Content-Type: application/json           │
└──────────────────────────────────────────┘
```

- `Authorization`: 根据 tokenSource 自动设置
- `Content-Type`: POST/PUT/PATCH 且有请求体时自动添加

#### 4.2.5 路径处理

测试代理接口要求路径以 `/api` 开头（SSRF 防护）。前端发送测试请求时，自动在 endpoint path 前拼接 `/api`：

```typescript
path: '/api' + testForm.value.path  // 例如 /api + /auth/login = /api/auth/login
```

### 4.3 边缘情况处理

| 场景 | 处理方式 |
|------|---------|
| `requestSchema` 为 `{}` 或 `null` | 请求体显示空 textarea，placeholder: "此接口无请求体参数" |
| `params` 数组为空 | 不显示参数表单区域，直接显示请求体或提示"此接口无需参数" |
| 测试请求返回非 200 状态 | 响应结果区域正常显示，status tag 标红，body 正常展示 |
| 网络错误/超时 | testResult.display 显示错误信息，status 显示 0 |
| JSON 预填充解析失败 | 回退到空字符串 `""` |
| 示例值是 JSON 字符串（如 `{"key":"value"}`） | 尝试 JSON.parse，失败则作为字符串处理 |

### 4.4 文件改动清单

| 文件 | 改动内容 |
|------|---------|
| `web-admin/src/views/endpoint/EndpointList.vue` | 操作列加"测试"按钮，新增 `showTest` 方法 |
| `web-admin/src/views/endpoint/EndpointDetailDialog.vue` | 新增 `defaultTab` prop，测试面板改造：参数表单 + JSON 预填充 + 请求头展示 |
| `web-admin/src/api/endpoint.ts` | 类型定义无需修改（`operationId` 已存在） |
| `server/src/main/java/com/emotion/controller/*.java` | 补全 @Tag/@Operation/@Parameter/@Schema 注解（按 4 个批次） |
| `server/src/main/java/com/emotion/dto/request/**/*.java` | 补全 @Schema 注解（请求体参数描述来源） |
| `server/src/main/java/com/emotion/dto/response/**/*.java` | 补全 @Schema 注解（响应体参数描述来源，可选） |

## 5. 实施顺序

1. **后端 Batch 1 注解补全** — Auth + Admin 相关 Controller 和 DTO
2. **触发同步 + 验证** — 确认中文描述正确展示
3. **前端操作列加"测试"按钮 + defaultTab** — 简单改动
4. **前端测试面板改造** — 参数表单 + JSON 预填充 + 请求头展示
5. **后端 Batch 2-4 注解补全** — 逐批完成剩余 Controller
6. **浏览器验证** — 打开接口管理页面，确认列表、详情、测试面板均正常

## 6. 验收标准

- [ ] 接口列表中，每个接口的"简述"列显示有意义的中文描述（非空、非英文路径名）
- [ ] 接口详情中，描述字段有中文说明
- [ ] 接口详情中，参数列表的"描述"列有中文说明
- [ ] 操作列有"测试"按钮，点击后打开弹窗并自动切换到测试标签
- [ ] 测试面板中，GET/DELETE 接口的查询参数以表单形式展示（input/select/switch 等），不是空白输入框
- [ ] 测试面板中，POST/PUT 接口的请求体预填充了完整的 JSON 结构（字段名 + 示例值），用户只需改值
- [ ] 请求头区域正确展示 Authorization 和 Content-Type
- [ ] 使用当前管理员 token 测试接口时，请求正常发出并返回结果
- [ ] 响应结果区域正确展示状态码、耗时和响应体
- [ ] 枚举值参数渲染为下拉选择框，非枚举值渲染为对应类型的输入框
