duoqi-api/docs/api-reference.md
Wang Zhuoxuan 1b142f2866 feat: 添加题目批量发布、归档和删除接口
- 新增 batchUpdateStatus 通用方法,带状态流转校验和 BatchResult 报告
- 改造 batchPublish 使用新方法,返回成功/失败详情
- 新增 batchArchive 和 batch-delete 端点(软删除)
- 使用 inArray 批量查询和更新,优化数据库往返
- 更新 API 文档,补充三个批量接口说明
2026-04-11 22:19:02 +08:00

1708 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Duoqi API Reference
> 多奇服务端 API 接口文档
> Base URL: `http://<host>:3000/v1`
## 目录
- [通用约定](#通用约定)
- [客户端 API](#客户端-api)
- [健康检查](#健康检查)
- [认证](#认证)
- [答题](#答题)
- [进度](#进度)
- [游戏化](#游戏化)
- [支付](#支付)
- [管理端 API](#管理端-api)
- [管理端认证](#管理端认证)
- [管理员管理](#管理员管理)
- [题目管理](#题目管理)
- [分类管理](#分类管理)
- [知识点卡片](#知识点卡片)
- [技能树管理](#技能树管理)
- [用户管理](#用户管理)
- [统计数据](#统计数据)
- [反馈管理](#反馈管理)
---
## 通用约定
### 认证方式
| 类型 | Header | 适用路径 |
|------|--------|----------|
| 无需认证 | - | `/v1/health`, `/v1/auth/*` |
| JWT | `Authorization: Bearer <jwt_token>` | 大多数客户端 API |
| Admin JWT | `Authorization: Bearer <admin_jwt_token>` | `/v1/admin/*` (推荐) |
| Admin Token | `Authorization: Bearer <admin_token>` | `/v1/admin/*` (向后兼容) |
### 统一响应格式
```typescript
// 成功响应
{
"success": true,
"data": <T>,
"error": null
}
// 错误响应
{
"success": false,
"data": null,
"error": {
"code": "ERROR_CODE",
"message": "错误描述"
}
}
// 分页响应(额外包含)
{
"success": true,
"data": [...],
"pagination": {
"total": 100,
"page": 1,
"limit": 20
},
"error": null
}
```
### 状态码
| 状态码 | 含义 |
|--------|------|
| 200 | 请求成功 |
| 400 | 请求参数验证失败 |
| 401 | 未认证 / 认证失败 |
| 404 | 资源不存在 |
| 501 | 功能未实现 |
---
## 客户端 API
### 健康检查
#### GET /health
健康检查端点,用于服务可用性探测。
**认证**: 无
**请求**: 无
**响应**:
```json
{
"success": true,
"data": {
"status": "ok",
"timestamp": "2026-04-10T12:00:00.000Z"
},
"error": null
}
```
---
### 认证
#### POST /auth/guest
游客登录,通过设备 ID 创建或获取用户账号。
**认证**: 无
**限流**: 10 次/分钟
**请求体**:
```json
{
"deviceId": "string (必填)"
}
```
**响应**:
```json
{
"success": true,
"data": {
"user": {
"id": "uuid",
"nickname": null,
"avatarUrl": null,
"tier": "free"
},
"tokens": {
"accessToken": "jwt_token",
"refreshToken": "jwt_token"
}
},
"error": null
}
```
---
#### POST /auth/huawei
华为账号登录。
**认证**: 无
**限流**: 10 次/分钟
**请求体**:
```json
{
"authorizationCode": "string (必填)"
}
```
**响应**:
```json
{
"success": true,
"data": {
"user": {
"id": "uuid",
"nickname": "用户昵称",
"avatarUrl": "头像URL",
"tier": "free"
},
"tokens": {
"accessToken": "jwt_token",
"refreshToken": "jwt_token"
}
},
"error": null
}
```
---
#### POST /auth/phone
手机号登录(未实现)。
**认证**: 无
**状态**: 501 Not Implemented
---
#### POST /auth/refresh
刷新访问令牌。
**认证**: 无
**限流**: 10 次/分钟
**请求体**:
```json
{
"refreshToken": "string (必填)"
}
```
**响应**:
```json
{
"success": true,
"data": {
"accessToken": "new_jwt_token",
"refreshToken": "new_refresh_token"
},
"error": null
}
```
---
#### GET /auth/me
获取当前用户信息。
**认证**: JWT
**响应**:
```json
{
"success": true,
"data": {
"id": "uuid",
"nickname": "用户昵称",
"avatarUrl": "头像URL",
"tier": "free | pro | proplus",
"xpTotal": 150,
"streakDays": 3,
"heartsRemaining": 5,
"dailyXpEarned": 20,
"dailyXpGoal": 50
},
"error": null
}
```
---
### 答题
#### GET /quiz/categories
获取所有题目分类列表。
**认证**: JWT
**响应**:
```json
{
"success": true,
"data": [
{
"id": "uuid",
"name": "历史",
"slug": "history",
"parentId": null
}
],
"error": null
}
```
---
#### GET /quiz/categories/:id/chapters
获取指定分类下的章节列表。
**认证**: JWT
**路径参数**:
- `id`: 分类 ID
**响应**:
```json
{
"success": true,
"data": [
{
"id": "uuid",
"categoryId": "uuid",
"title": "第一章",
"parentId": null,
"sortOrder": 1
}
],
"error": null
}
```
---
#### GET /quiz/chapters/:id/questions
获取章节下的题目(包含用户答题状态)。
**认证**: JWT
**路径参数**:
- `id`: 章节 ID
**响应**:
```json
{
"success": true,
"data": {
"chapterId": "uuid",
"title": "第一章",
"questionsRequired": 5,
"passThreshold": 3,
"questions": [
{
"id": "uuid",
"stem": { "text": "题目内容" },
"contentType": "text",
"options": ["A", "B", "C", "D"],
"answered": false,
"isCorrect": null
}
]
},
"error": null
}
```
---
#### POST /quiz/answer
提交答案。
**认证**: JWT
**请求体**:
```json
{
"questionId": "uuid (必填)",
"selectedAnswer": "string (必填)",
"timeMs": 1500
}
```
**响应**:
```json
{
"success": true,
"data": {
"correct": true,
"correctAnswer": "B",
"xpEarned": 10,
"streakBonus": 0,
"chapterCompleted": false
},
"error": null
}
```
---
#### POST /quiz/rate
评价题目质量。
**认证**: JWT
**请求体**:
```json
{
"questionId": "uuid (必填)",
"rating": "good | bad"
}
```
**响应**:
```json
{
"success": true,
"data": null,
"error": null
}
```
---
### 进度
#### GET /progress/dashboard
获取用户进度概览。
**认证**: JWT
**响应**:
```json
{
"success": true,
"data": {
"xpTotal": 150,
"streakDays": 3,
"heartsRemaining": 5,
"dailyXpEarned": 20,
"dailyXpGoal": 50,
"categoriesCompleted": 1,
"totalCategories": 5
},
"error": null
}
```
---
#### GET /progress/streak
获取连胜信息。
**认证**: JWT
**响应**:
```json
{
"success": true,
"data": {
"currentStreak": 3,
"longestStreak": 7,
"lastActiveDate": "2026-04-10"
},
"error": null
}
```
---
#### GET /progress/hearts
获取红心信息。
**认证**: JWT
**响应**:
```json
{
"success": true,
"data": {
"remaining": 5,
"max": 5,
"nextRestoreAt": "2026-04-10T13:00:00.000Z"
},
"error": null
}
```
---
#### POST /progress/hearts/restore
恢复红心。
**认证**: JWT
**请求体**:
```json
{
"method": "ad | wait | upgrade"
}
```
**响应**:
```json
{
"success": true,
"data": {
"remaining": 5,
"restored": 1
},
"error": null
}
```
---
#### GET /progress/chapters
获取所有章节进度。
**认证**: JWT
**响应**:
```json
{
"success": true,
"data": [
{
"chapterId": "uuid",
"title": "第一章",
"completedQuestions": 3,
"totalQuestions": 5,
"passed": false,
"passedAt": null
}
],
"error": null
}
```
---
#### POST /feedback
提交用户反馈。
**认证**: JWT
**请求体**:
```json
{
"content": "string (必填, 1-2000字符)",
"contact": "string (可选, 最多255字符)",
"pageContext": "string (可选, 最多200字符)"
}
```
**响应**:
```json
{
"success": true,
"data": null,
"error": null
}
```
---
### 游戏化
#### GET /leaderboard
获取排行榜。
**认证**: JWT
**查询参数**:
- `tier`: "free" | "pro" | "proplus" (可选)
- `page`: 页码 (默认: 1)
- `limit`: 每页数量 (默认: 20)
**响应**:
```json
{
"success": true,
"data": [
{
"rank": 1,
"userId": "uuid",
"nickname": "玩家昵称",
"avatarUrl": "头像URL",
"xpTotal": 5000
}
],
"pagination": {
"total": 100,
"page": 1,
"limit": 20
},
"error": null
}
```
---
#### GET /leaderboard/me
获取当前用户排名。
**认证**: JWT
**响应**:
```json
{
"success": true,
"data": {
"rank": 15,
"xpTotal": 1500
},
"error": null
}
```
---
#### GET /achievements
获取成就列表。
**认证**: JWT
**响应**:
```json
{
"success": true,
"data": [
{
"id": "uuid",
"code": "first_win",
"name": "初出茅庐",
"description": "完成第一道题",
"iconUrl": "图标URL",
"unlocked": true,
"unlockedAt": "2026-04-10T10:00:00.000Z"
}
],
"error": null
}
```
---
#### POST /achievements/check
检查并解锁新成就。
**认证**: JWT
**响应**:
```json
{
"success": true,
"data": {
"newlyUnlocked": [
{
"id": "uuid",
"code": "streak_7",
"name": "连胜达人",
"description": "连续7天活跃"
}
]
},
"error": null
}
```
---
### 支付
#### POST /payment/verify-huawei
验证华为 IAP 收据并激活订阅。
**认证**: JWT
**请求体**:
```json
{
"purchaseToken": "string (必填)",
"productId": "string (必填)",
"tier": "pro | proplus"
}
```
**响应**:
```json
{
"success": true,
"data": {
"tier": "pro",
"provider": "huawei",
"active": true,
"expiresAt": "2026-05-10T00:00:00.000Z"
},
"error": null
}
```
---
#### GET /payment/subscription
获取当前订阅状态。
**认证**: JWT
**响应**:
```json
{
"success": true,
"data": {
"tier": "pro",
"provider": "huawei",
"active": true,
"expiresAt": "2026-05-10T00:00:00.000Z",
"autoRenew": true
},
"error": null
}
```
---
## 管理端 API
### 管理端认证
#### POST /admin/auth/login
管理员用户名密码登录。
**认证**: 无
**请求体**:
```json
{
"username": "string (必填)",
"password": "string (必填, 最少8字符)"
}
```
**响应**:
```json
{
"success": true,
"data": {
"accessToken": "jwt_token (1h有效)",
"refreshToken": "jwt_token (30d有效)",
"admin": {
"id": "uuid",
"username": "admin",
"role": "super_admin"
}
},
"error": null
}
```
**错误 (401)**:
```json
{
"success": false,
"data": null,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid username or password"
}
}
```
---
#### POST /admin/auth
管理端 Token 认证(向后兼容,推荐使用 `/admin/auth/login`)。
**认证**: 无
**请求体**:
```json
{
"token": "string (必填)"
}
```
**响应**:
```json
{
"success": true,
"data": {
"authenticated": true
},
"error": null
}
```
**错误 (401)**:
```json
{
"success": false,
"data": null,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid admin token"
}
}
```
---
### 管理员管理
> 仅 super_admin 角色可执行写操作POST、PUT、DELETE读操作GET所有管理员均可访问。
#### GET /admin/admins
获取管理员列表。
**认证**: Admin JWT
**查询参数**:
- `page`: 页码 (默认: 1, 必须 ≥ 1)
- `limit`: 每页数量 (默认: 20, 范围: 1-50)
- `role`: "admin" | "super_admin" (可选,按角色筛选)
- `isActive`: 0 | 1 (可选,按状态筛选)
**响应**:
```json
{
"success": true,
"data": [
{
"id": "uuid",
"username": "admin",
"role": "super_admin",
"isActive": 1,
"lastLoginAt": "2026-04-11T10:00:00.000Z",
"createdAt": "2026-04-01T00:00:00.000Z",
"updatedAt": "2026-04-11T10:00:00.000Z"
}
],
"pagination": {
"total": 5,
"page": 1,
"limit": 20
},
"error": null
}
```
---
#### GET /admin/admins/:id
获取管理员详情。
**认证**: Admin JWT
**路径参数**:
- `id`: 管理员 ID
**响应**:
```json
{
"success": true,
"data": {
"id": "uuid",
"username": "admin",
"role": "super_admin",
"isActive": 1,
"lastLoginAt": "2026-04-11T10:00:00.000Z",
"createdAt": "2026-04-01T00:00:00.000Z",
"updatedAt": "2026-04-11T10:00:00.000Z"
},
"error": null
}
```
**错误 (404)**:
```json
{
"success": false,
"data": null,
"error": {
"code": "NOT_FOUND",
"message": "Admin user not found"
}
}
```
---
#### POST /admin/admins
创建新管理员super_admin 专属)。
**认证**: Admin JWT (super_admin)
**请求体**:
```json
{
"username": "string (必填, 3-50字符)",
"password": "string (必填, 8-128字符)",
"role": "admin | super_admin (必填)"
}
```
**响应**:
```json
{
"success": true,
"data": {
"id": "uuid",
"username": "newadmin",
"role": "admin",
"isActive": 1,
"lastLoginAt": null,
"createdAt": "2026-04-11T12:00:00.000Z",
"updatedAt": "2026-04-11T12:00:00.000Z",
"plainPassword": "随机生成的初始密码"
},
"error": null
}
```
**错误 (403)**:
```json
{
"success": false,
"data": null,
"error": {
"code": "FORBIDDEN",
"message": "Super admin privileges required"
}
}
```
**错误 (400)**:
```json
{
"success": false,
"data": null,
"error": {
"code": "VALIDATION_ERROR",
"message": "Username \"admin\" already exists"
}
}
```
---
#### PUT /admin/admins/:id
更新管理员信息super_admin 专属)。
**认证**: Admin JWT (super_admin)
**路径参数**:
- `id`: 管理员 ID
**请求体**:
```json
{
"username": "string (可选, 3-50字符)",
"role": "admin | super_admin (可选)",
"isActive": 0 | 1 (可选)"
}
```
**响应**:
```json
{
"success": true,
"data": {
"id": "uuid",
"username": "updated_username",
"role": "admin",
"isActive": 0,
"lastLoginAt": "2026-04-11T10:00:00.000Z",
"createdAt": "2026-04-01T00:00:00.000Z",
"updatedAt": "2026-04-11T12:00:00.000Z"
},
"error": null
}
```
**安全规则**:
- 禁止删除或降级最后一个 super_admin
- 用户名必须唯一
---
#### DELETE /admin/admins/:id
软删除管理员super_admin 专属)。
**认证**: Admin JWT (super_admin)
**路径参数**:
- `id`: 管理员 ID
**响应**:
```json
{
"success": true,
"data": {
"id": "uuid",
"username": "deleted_admin",
"role": "admin",
"isActive": 0,
"lastLoginAt": "2026-04-11T10:00:00.000Z",
"createdAt": "2026-04-01T00:00:00.000Z",
"updatedAt": "2026-04-11T12:00:00.000Z"
},
"error": null
}
```
**说明**:
- 软删除:将 `isActive` 设为 0不删除记录
- 禁止删除最后一个 super_admin
---
#### POST /admin/admins/:id/reset-password
重置管理员密码super_admin 专属)。
**认证**: Admin JWT (super_admin)
**路径参数**:
- `id`: 管理员 ID
**响应**:
```json
{
"success": true,
"data": {
"adminId": "uuid",
"username": "admin",
"plainPassword": "新随机生成的12位密码"
},
"error": null
}
```
**说明**:
- 生成 12 位随机密码,包含大小写字母、数字、符号
- 明文密码仅在响应中返回一次,请妥善保存
- 密码使用 BCrypt 哈希后存储到数据库
---
### 题目管理
#### GET /admin/questions
获取题目列表。
**认证**: Admin Token
**查询参数**:
- `page`: 页码 (默认: 1)
- `limit`: 每页数量 (默认: 20)
- `status`: draft | reviewing | published | archived (可选)
- `categoryId`: 分类 ID (可选)
**响应**:
```json
{
"success": true,
"data": [
{
"id": "uuid",
"stem": { "text": "题目内容" },
"contentType": "text",
"correctAnswer": "B",
"distractors": ["A", "C", "D"],
"categoryId": "uuid",
"difficulty": 3,
"status": "published"
}
],
"pagination": {
"total": 100,
"page": 1,
"limit": 20
},
"error": null
}
```
---
#### GET /admin/questions/:id
获取题目详情。
**认证**: Admin Token
**路径参数**:
- `id`: 题目 ID
**响应**:
```json
{
"success": true,
"data": {
"id": "uuid",
"stem": { "text": "题目内容" },
"contentType": "text",
"correctAnswer": "B",
"distractors": ["A", "C", "D"],
"categoryId": "uuid",
"difficulty": 3,
"status": "published",
"knowledgeCard": {
"id": "uuid",
"summary": "知识点摘要",
"deepDive": "深入解析",
"sourceRef": "来源引用"
}
},
"error": null
}
```
---
#### POST /admin/questions
创建新题目。
**认证**: Admin Token
**请求体**:
```json
{
"stem": { "text": "题目内容" },
"contentType": "text | image | video | audio",
"correctAnswer": "B (必填)",
"distractors": ["A", "C", "D"],
"categoryId": "uuid (必填)",
"difficulty": 3,
"knowledgeCard": {
"summary": "知识点摘要 (必填)",
"deepDive": "深入解析",
"sourceRef": "来源引用"
}
}
```
**响应**:
```json
{
"success": true,
"data": {
"id": "uuid",
"status": "draft"
},
"error": null
}
```
---
#### PUT /admin/questions/:id
更新题目。
**认证**: Admin Token
**路径参数**:
- `id`: 题目 ID
**请求体**:
```json
{
"stem": { "text": "题目内容" },
"contentType": "text | image | video | audio",
"correctAnswer": "B",
"distractors": ["A", "C", "D"],
"categoryId": "uuid",
"difficulty": 3,
"status": "draft | reviewing | published | archived"
}
```
---
#### DELETE /admin/questions/:id
归档题目。
**认证**: Admin Token
**路径参数**:
- `id`: 题目 ID
**响应**:
```json
{
"success": true,
"data": null,
"error": null
}
```
---
#### PATCH /admin/questions/:id/status
变更题目状态(带流转校验)。
**认证**: Admin Token
**路径参数**:
- `id`: 题目 ID
**请求体**:
```json
{
"status": "draft | reviewing | published | archived (必填)"
}
```
**允许的状态流转**:
| 当前状态 | 可变更到 |
|----------|----------|
| draft | reviewing, archived |
| reviewing | published, draft, archived |
| published | archived |
| archived | draft |
**响应**:
```json
{
"success": true,
"data": {
"id": "uuid",
"stem": { "text": "题目内容" },
"contentType": "text",
"correctAnswer": "B",
"distractors": ["A", "C", "D"],
"categoryId": "uuid",
"difficulty": 3,
"status": "published",
"knowledgeCard": { ... }
},
"error": null
}
```
**错误 (404)**:
```json
{
"success": false,
"data": null,
"error": {
"code": "NOT_FOUND",
"message": "题目不存在"
}
}
```
**错误 (400)**:
```json
{
"success": false,
"data": null,
"error": {
"code": "INVALID_STATUS_TRANSITION",
"message": "不允许从 published 变更为 reviewing"
}
}
```
---
#### POST /admin/questions/batch-publish
批量发布题目(带状态流转校验,仅 reviewing 状态可发布)。
**认证**: Admin Token
**请求体**:
```json
{
"ids": ["uuid1", "uuid2"]
}
```
**参数说明**:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| ids | string[] | 是 | 题目 ID 数组1-200 个,每个为合法 UUID |
**响应**:
```json
{
"success": true,
"data": {
"total": 3,
"succeeded": 2,
"failed": [
{ "id": "uuid3", "reason": "不允许从 draft 变更为 published" }
]
},
"error": null
}
```
**data 字段说明**:
| 字段 | 类型 | 说明 |
|------|------|------|
| total | number | 提交的 ID 总数 |
| succeeded | number | 成功更新的数量 |
| failed | array | 失败记录列表(包含 id 和 reason |
---
#### POST /admin/questions/batch-archive
批量归档题目带状态流转校验draft/reviewing/published 状态可归档)。
**认证**: Admin Token
**请求体**:
```json
{
"ids": ["uuid1", "uuid2"]
}
```
**参数说明**:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| ids | string[] | 是 | 题目 ID 数组1-200 个,每个为合法 UUID |
**响应**: 与 batch-publish 相同的 `BatchResult` 格式。
---
#### POST /admin/questions/batch-delete
批量删除题目(软删除,等同于批量归档)。
**认证**: Admin Token
**请求体**:
```json
{
"ids": ["uuid1", "uuid2"]
}
```
**参数说明**:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| ids | string[] | 是 | 题目 ID 数组1-200 个,每个为合法 UUID |
**响应**: 与 batch-publish 相同的 `BatchResult` 格式。
---
### 分类管理
#### GET /admin/categories
获取分类列表。
**认证**: Admin Token
**查询参数**:
- `page`: 页码 (默认: 1, 必须 ≥ 1)
- `limit`: 每页数量 (默认: 20, 范围: 1-50)
**响应**:
```json
{
"success": true,
"data": [
{
"id": "uuid",
"name": "历史",
"slug": "history",
"parentId": null,
"sortOrder": 1,
"questionCount": 120,
"status": "active"
}
],
"pagination": {
"total": 45,
"page": 1,
"limit": 20
},
"error": null
}
```
---
#### POST /admin/categories
创建分类。
**认证**: Admin Token
**请求体**:
```json
{
"id": "uuid (必填)",
"name": "分类名称 (必填)",
"slug": "分类slug (必填)",
"parentId": "uuid",
"sortOrder": 1
}
```
---
#### PUT /admin/categories/:id
更新分类。
**认证**: Admin Token
**请求体**:
```json
{
"name": "分类名称",
"slug": "分类slug",
"parentId": "uuid | null",
"sortOrder": 1,
"status": "active | inactive"
}
```
---
#### DELETE /admin/categories/:id
归档分类。
**认证**: Admin Token
---
### 知识点卡片
#### GET /admin/knowledge-cards
获取知识点卡片列表。
**认证**: Admin Token
**查询参数**:
- `page`: 页码 (默认: 1)
- `limit`: 每页数量 (默认: 20)
---
#### GET /admin/knowledge-cards/by-question/:questionId
根据题目 ID 获取知识点卡片。
**认证**: Admin Token
---
#### PUT /admin/knowledge-cards/:id
更新知识点卡片。
**认证**: Admin Token
**请求体**:
```json
{
"summary": "摘要 (必填)",
"deepDive": "深入解析",
"sourceRef": "来源引用"
}
```
---
### 技能树管理
#### GET /admin/skill-tree
获取章节列表。
**认证**: Admin Token
**查询参数**:
- `categoryId`: 分类 ID (可选)
---
#### POST /admin/skill-tree
创建章节。
**认证**: Admin Token
**请求体**:
```json
{
"categoryId": "uuid (必填)",
"title": "章节标题 (必填)",
"parentId": "uuid",
"sortOrder": 1,
"questionsRequired": 5,
"passThreshold": 3
}
```
---
#### PUT /admin/skill-tree/:id
更新章节。
**认证**: Admin Token
**请求体**:
```json
{
"title": "章节标题",
"parentId": "uuid | null",
"sortOrder": 1,
"questionsRequired": 5,
"passThreshold": 3
}
```
---
#### DELETE /admin/skill-tree/:id
删除章节。
**认证**: Admin Token
---
### 用户管理
#### GET /admin/users
获取用户列表。
**认证**: Admin Token
**查询参数**:
- `page`: 页码 (默认: 1)
- `limit`: 每页数量 (默认: 20)
- `search`: 搜索关键词 (昵称/ID)
**响应**:
```json
{
"success": true,
"data": [
{
"id": "uuid",
"nickname": "玩家昵称",
"avatarUrl": "头像URL",
"tier": "free",
"xpTotal": 150,
"streakDays": 3,
"banned": false
}
],
"pagination": { ... },
"error": null
}
```
---
#### GET /admin/users/:id
获取用户详情。
**认证**: Admin Token
---
#### PUT /admin/users/:id/ban
封禁用户。
**认证**: Admin Token
---
#### PUT /admin/users/:id/unban
解封用户。
**认证**: Admin Token
---
### 统计数据
#### GET /admin/stats
获取仪表盘统计数据。
**认证**: Admin Token
**响应**:
```json
{
"success": true,
"data": {
"totalUsers": 1000,
"activeUsers": 150,
"totalQuestions": 500,
"publishedQuestions": 450,
"averageXp": 200
},
"error": null
}
```
---
### 反馈管理
#### GET /admin/feedback
获取用户反馈列表。
**认证**: Admin Token
**查询参数**:
- `page`: 页码 (默认: 1)
- `limit`: 每页数量 (默认: 20)
**响应**:
```json
{
"success": true,
"data": [
{
"id": "uuid",
"userId": "uuid",
"content": "反馈内容",
"contact": "联系方式",
"pageContext": "页面上下文",
"createdAt": "2026-04-10T10:00:00.000Z"
}
],
"pagination": { ... },
"error": null
}
```
---
## 附录
### 错误代码
| 代码 | 说明 |
|------|------|
| VALIDATION_ERROR | 请求参数验证失败 |
| UNAUTHORIZED | 未认证或认证失败 |
| FORBIDDEN | 权限不足(需要 super_admin |
| NOT_FOUND | 资源不存在 |
| INVALID_STATUS_TRANSITION | 题目状态流转不合法 |
| INVALID_RECEIPT | 支付收据验证失败 |
| NOT_IMPLEMENTED | 功能未实现 |
| INTERNAL_ERROR | 服务器内部错误 |
### 数据模型
#### User (用户)
```typescript
{
id: string; // UUID
nickname: string | null; // 昵称
avatarUrl: string | null; // 头像URL
tier: 'free' | 'pro' | 'proplus'; // 会员等级
xpTotal: number; // 总经验值
streakDays: number; // 连续天数
heartsRemaining: number; // 剩余红心
banned: boolean; // 是否封禁
}
```
#### Question (题目)
```typescript
{
id: string; // UUID
stem: Record<string, unknown>; // 题目内容(支持多语言)
contentType: 'text' | 'image' | 'video' | 'audio';
correctAnswer: string; // 正确答案
distractors: string[]; // 干扰项
categoryId: string; // 分类ID
difficulty: 1-5; // 难度等级
status: 'draft' | 'reviewing' | 'published' | 'archived';
}
```
#### Chapter (章节)
```typescript
{
id: string; // UUID
categoryId: string; // 分类ID
title: string; // 章节标题
parentId: string | null; // 父章节ID
sortOrder: number; // 排序
questionsRequired: number; // 需要答题数
passThreshold: number; // 通过阈值
}
```