- docs/api-reference.md: comprehensive API documentation for client and admin endpoints - docs/env-secrets-guide.md: guide for generating secure keys and tokens
1275 lines
17 KiB
Markdown
1275 lines
17 KiB
Markdown
# 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 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
|
|
|
|
管理端认证。
|
|
|
|
**认证**: 无
|
|
|
|
**请求体**:
|
|
```json
|
|
{
|
|
"token": "string (必填)"
|
|
}
|
|
```
|
|
|
|
**响应**:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"authenticated": true
|
|
},
|
|
"error": null
|
|
}
|
|
```
|
|
|
|
**错误 (401)**:
|
|
```json
|
|
{
|
|
"success": false,
|
|
"data": null,
|
|
"error": {
|
|
"code": "UNAUTHORIZED",
|
|
"message": "Invalid admin token"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 题目管理
|
|
|
|
#### 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
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
#### POST /admin/questions/batch-publish
|
|
|
|
批量发布题目。
|
|
|
|
**认证**: Admin Token
|
|
|
|
**请求体**:
|
|
```json
|
|
{
|
|
"ids": ["uuid1", "uuid2"]
|
|
}
|
|
```
|
|
|
|
**响应**:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": null,
|
|
"error": null
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 分类管理
|
|
|
|
#### GET /admin/categories
|
|
|
|
获取所有分类。
|
|
|
|
**认证**: Admin Token
|
|
|
|
**响应**:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"id": "uuid",
|
|
"name": "历史",
|
|
"slug": "history",
|
|
"parentId": null,
|
|
"sortOrder": 1,
|
|
"status": "active"
|
|
}
|
|
],
|
|
"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 | 未认证或认证失败 |
|
|
| NOT_FOUND | 资源不存在 |
|
|
| 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; // 通过阈值
|
|
}
|
|
```
|