lty/qy_lty/docs/api/achievement_api.md
2026-03-17 13:17:02 +08:00

782 lines
20 KiB
Markdown
Raw Permalink 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.

# 成就系统 API 文档
本文档详细说明成就系统的API接口包括成就管理和用户成就进度跟踪功能。
## 接口基础信息
- **基础路径**: `/api/achievement/`
- **认证方式**: Token 认证
- **返回格式**: JSON
## API 概览
| 接口路径 | 方法 | 描述 |
|---------|------|------|
| `/api/achievement/achievements/` | GET, POST | 成就管理 |
| `/api/achievement/achievements/{id}/` | GET, PUT, DELETE | 成就详情操作 |
| `/api/achievement/user-achievements/` | GET, POST | 用户成就管理 |
| `/api/achievement/user-achievements/{id}/` | GET, PUT, DELETE | 用户成就详情 |
## 1. 成就管理
### 1.1 获取成就列表
获取系统中所有可用成就的列表。
- **URL**: `/api/achievement/achievements/`
- **方法**: `GET`
- **认证**: 需要
- **查询参数**:
| 参数名 | 类型 | 描述 |
|-------|-----|------|
| category | string | 按类别筛选 |
| rarity | string | 按稀有度筛选 |
| is_active | boolean | 按激活状态筛选 |
| page | integer | 页码 |
| page_size | integer | 每页数量 |
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"count": 25,
"next": "http://localhost:8000/api/achievement/achievements/?page=2",
"previous": null,
"results": [
{
"id": 1,
"name": "舞蹈新手",
"description": "完成第一支舞蹈学习",
"category": "dance",
"type": "milestone",
"rarity": "common",
"icon": "https://example.com/icons/dance_beginner.png",
"requirements": {
"dance_cards_used": 1,
"min_difficulty": "初级"
},
"rewards": {
"experience": 100,
"title": "舞蹈新手",
"badge": "dance_beginner_badge"
},
"is_active": true,
"is_hidden": false,
"unlock_conditions": null,
"total_earned": 1250,
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
},
{
"id": 2,
"name": "音乐大师",
"description": "学会50首不同风格的歌曲",
"category": "music",
"type": "progression",
"rarity": "legendary",
"icon": "https://example.com/icons/music_master.png",
"requirements": {
"song_cards_used": 50,
"unique_genres": 5,
"min_difficulty": "中级"
},
"rewards": {
"experience": 2000,
"title": "音乐大师",
"special_card": "master_song_template",
"avatar_frame": "golden_music_frame"
},
"is_active": true,
"is_hidden": false,
"unlock_conditions": {
"required_achievements": [1, 3, 5],
"min_level": 10
},
"total_earned": 12,
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
}
]
}
}
```
### 1.2 创建成就
创建新的成就。
- **URL**: `/api/achievement/achievements/`
- **方法**: `POST`
- **认证**: 需要(管理员权限)
- **请求体**:
```json
{
"name": "时尚达人",
"description": "收集10套不同风格的服装",
"category": "fashion",
"type": "collection",
"rarity": "rare",
"icon": "https://example.com/icons/fashion_icon.png",
"requirements": {
"clothing_cards_used": 10,
"unique_styles": 3
},
"rewards": {
"experience": 500,
"title": "时尚达人",
"special_card": "exclusive_fashion_card"
},
"is_active": true,
"is_hidden": false
}
```
**请求参数说明:**
| 参数名 | 类型 | 必填 | 描述 |
|-------|-----|------|-----|
| name | string | 是 | 成就名称 |
| description | string | 是 | 成就描述 |
| category | string | 是 | 成就类别 |
| type | string | 是 | 成就类型 |
| rarity | string | 否 | 稀有度默认common |
| icon | string | 否 | 成就图标URL |
| requirements | object | 是 | 完成要求 |
| rewards | object | 是 | 奖励内容 |
| is_active | boolean | 否 | 是否激活默认true |
| is_hidden | boolean | 否 | 是否隐藏默认false |
| unlock_conditions | object | 否 | 解锁条件 |
**成就类别:**
- `dance` - 舞蹈类
- `music` - 音乐类
- `fashion` - 时尚类
- `social` - 社交类
- `system` - 系统类
**成就类型:**
- `milestone` - 里程碑成就(一次性)
- `progression` - 进度成就(需要累积)
- `collection` - 收集成就
- `challenge` - 挑战成就
- `daily` - 每日成就
- `weekly` - 每周成就
**稀有度等级:**
- `common` - 普通 (白色)
- `rare` - 稀有 (蓝色)
- `epic` - 史诗 (紫色)
- `legendary` - 传说 (金色)
### 1.3 获取成就详情
- **URL**: `/api/achievement/achievements/{id}/`
- **方法**: `GET`
- **参数**:
- `id` (路径参数): 成就ID
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"id": 1,
"name": "舞蹈新手",
"description": "完成第一支舞蹈学习",
"category": "dance",
"type": "milestone",
"rarity": "common",
"icon": "https://example.com/icons/dance_beginner.png",
"requirements": {
"dance_cards_used": 1,
"min_difficulty": "初级"
},
"rewards": {
"experience": 100,
"title": "舞蹈新手",
"badge": "dance_beginner_badge"
},
"is_active": true,
"is_hidden": false,
"unlock_conditions": null,
"total_earned": 1250,
"recent_earners": [
{
"user_id": 123,
"username": "user123",
"earned_at": "2023-01-05T10:30:00Z"
}
],
"completion_rate": 0.85,
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
}
}
```
### 1.4 更新成就
- **URL**: `/api/achievement/achievements/{id}/`
- **方法**: `PUT`
- **认证**: 需要(管理员权限)
### 1.5 删除成就
- **URL**: `/api/achievement/achievements/{id}/`
- **方法**: `DELETE`
- **认证**: 需要(管理员权限)
## 2. 用户成就管理
### 2.1 获取用户成就列表
获取当前用户的成就进度和已获得的成就。
- **URL**: `/api/achievement/user-achievements/`
- **方法**: `GET`
- **认证**: 需要
- **查询参数**:
| 参数名 | 类型 | 描述 |
|-------|-----|------|
| status | string | 按状态筛选(earned/in_progress/locked) |
| category | string | 按类别筛选 |
| rarity | string | 按稀有度筛选 |
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"user_stats": {
"total_achievements": 25,
"earned_achievements": 8,
"in_progress": 5,
"locked": 12,
"completion_rate": 32.0,
"total_experience": 1800,
"current_titles": ["舞蹈新手", "音乐爱好者"],
"rarity_counts": {
"common": 5,
"rare": 2,
"epic": 1,
"legendary": 0
}
},
"achievements": [
{
"id": 101,
"achievement": {
"id": 1,
"name": "舞蹈新手",
"description": "完成第一支舞蹈学习",
"category": "dance",
"type": "milestone",
"rarity": "common",
"icon": "https://example.com/icons/dance_beginner.png",
"requirements": {
"dance_cards_used": 1,
"min_difficulty": "初级"
},
"rewards": {
"experience": 100,
"title": "舞蹈新手",
"badge": "dance_beginner_badge"
}
},
"status": "earned",
"progress": {
"dance_cards_used": 3,
"min_difficulty": "中级"
},
"completion_percentage": 100.0,
"earned_at": "2023-01-02T15:30:00Z",
"rewards_claimed": true,
"next_milestone": null
},
{
"id": 102,
"achievement": {
"id": 2,
"name": "音乐大师",
"description": "学会50首不同风格的歌曲",
"category": "music",
"type": "progression",
"rarity": "legendary",
"icon": "https://example.com/icons/music_master.png",
"requirements": {
"song_cards_used": 50,
"unique_genres": 5,
"min_difficulty": "中级"
}
},
"status": "in_progress",
"progress": {
"song_cards_used": 15,
"unique_genres": 2,
"min_difficulty": "初级"
},
"completion_percentage": 30.0,
"earned_at": null,
"rewards_claimed": false,
"next_milestone": {
"song_cards_used": 25,
"milestone_reward": {
"experience": 200,
"badge": "music_enthusiast"
}
}
}
]
}
}
```
### 2.2 获取特定用户成就详情
- **URL**: `/api/achievement/user-achievements/{id}/`
- **方法**: `GET`
- **参数**:
- `id` (路径参数): 用户成就记录ID
### 2.3 手动触发成就检查
手动检查用户是否达成某些成就条件。
- **URL**: `/api/achievement/user-achievements/check/`
- **方法**: `POST`
- **认证**: 需要
- **请求体**:
```json
{
"achievement_ids": [1, 2, 3],
"trigger_event": "card_used",
"event_data": {
"card_category": "dance",
"card_difficulty": "中级"
}
}
```
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"checked_achievements": 3,
"newly_earned": [
{
"achievement_id": 1,
"achievement_name": "舞蹈新手",
"rewards": {
"experience": 100,
"title": "舞蹈新手",
"badge": "dance_beginner_badge"
},
"earned_at": "2023-01-05T12:00:00Z"
}
],
"progress_updated": [
{
"achievement_id": 2,
"achievement_name": "音乐大师",
"old_progress": 29.0,
"new_progress": 32.0,
"completion_percentage": 32.0
}
]
}
}
```
### 2.4 领取成就奖励
领取已获得成就的奖励。
- **URL**: `/api/achievement/user-achievements/{id}/claim_rewards/`
- **方法**: `POST`
- **参数**:
- `id` (路径参数): 用户成就记录ID
- **认证**: 需要
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"achievement": {
"id": 1,
"name": "舞蹈新手"
},
"rewards_claimed": {
"experience": 100,
"title": "舞蹈新手",
"badge": "dance_beginner_badge"
},
"user_updated": {
"total_experience": 1900,
"new_titles": ["舞蹈新手"],
"new_badges": ["dance_beginner_badge"]
},
"claimed_at": "2023-01-05T13:00:00Z"
}
}
```
## 3. 成就系统事件
### 3.1 自动触发事件
系统会在以下事件发生时自动检查相关成就:
| 事件 | 描述 | 检查的成就类别 |
|-----|------|-------------|
| card_used | 使用卡片 | dance, music, fashion |
| user_login | 用户登录 | daily, social |
| user_register | 用户注册 | system |
| ai_chat | AI对话 | social |
| device_connect | 设备连接 | system |
### 3.2 事件数据结构
```json
{
"event_type": "card_used",
"user_id": 123,
"timestamp": "2023-01-05T12:00:00Z",
"event_data": {
"card_id": 1001,
"card_category": "dance",
"card_difficulty": "中级",
"card_style": "现代舞"
}
}
```
## 4. 成就要求系统
### 4.1 通用要求字段
```json
{
"requirements": {
"dance_cards_used": 10, // 使用舞蹈卡片数量
"song_cards_used": 5, // 使用音乐卡片数量
"clothing_cards_used": 3, // 使用服装卡片数量
"unique_genres": 3, // 不同类型数量
"min_difficulty": "中级", // 最低难度要求
"consecutive_days": 7, // 连续天数
"total_experience": 1000, // 总经验值
"user_level": 5, // 用户等级
"achievements_earned": 3, // 已获得成就数
"social_interactions": 10, // 社交互动次数
"device_connections": 5, // 设备连接次数
"ai_conversations": 20, // AI对话次数
"custom_conditions": { // 自定义条件
"field": "value"
}
}
}
```
### 4.2 奖励系统
```json
{
"rewards": {
"experience": 500, // 经验值
"title": "成就标题", // 用户称号
"badge": "badge_id", // 徽章ID
"avatar_frame": "frame_id", // 头像框ID
"special_card": "card_template", // 特殊卡片
"virtual_currency": 100, // 虚拟货币
"unlock_feature": "premium", // 解锁功能
"custom_rewards": { // 自定义奖励
"type": "value"
}
}
}
```
## 5. 成就统计和排行榜
### 5.1 获取成就统计
- **URL**: `/api/achievement/statistics/`
- **方法**: `GET`
- **认证**: 需要
- **查询参数**:
| 参数名 | 类型 | 描述 |
|-------|-----|------|
| period | string | 统计周期(daily/weekly/monthly/all) |
| category | string | 按类别筛选 |
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"period": "monthly",
"total_achievements": 25,
"total_users": 1500,
"statistics": {
"most_earned": {
"achievement_id": 1,
"achievement_name": "舞蹈新手",
"earned_count": 1250,
"earn_rate": 83.3
},
"rarest": {
"achievement_id": 2,
"achievement_name": "音乐大师",
"earned_count": 12,
"earn_rate": 0.8
},
"category_stats": {
"dance": {
"total_achievements": 8,
"average_earn_rate": 45.2
},
"music": {
"total_achievements": 6,
"average_earn_rate": 32.1
}
},
"recent_trending": [
{
"achievement_id": 3,
"achievement_name": "时尚新星",
"recent_earns": 45,
"trend_percentage": 125.5
}
]
}
}
}
```
### 5.2 获取成就排行榜
- **URL**: `/api/achievement/leaderboard/`
- **方法**: `GET`
- **认证**: 需要
- **查询参数**:
| 参数名 | 类型 | 描述 |
|-------|-----|------|
| type | string | 排行榜类型(total/monthly/category) |
| category | string | 类别筛选当type=category时 |
| limit | integer | 返回数量限制默认100 |
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"leaderboard_type": "total",
"period": "all_time",
"current_user_rank": 15,
"rankings": [
{
"rank": 1,
"user_id": 456,
"username": "achievement_hunter",
"total_achievements": 23,
"total_experience": 5800,
"rare_achievements": 8,
"recent_activity": "2023-01-05T10:30:00Z"
},
{
"rank": 2,
"user_id": 789,
"username": "dance_master",
"total_achievements": 21,
"total_experience": 5200,
"rare_achievements": 6,
"recent_activity": "2023-01-04T18:45:00Z"
}
]
}
}
```
## 6. 错误响应
### 6.1 常见错误码
| 错误码 | HTTP状态码 | 描述 |
|-------|-----------|------|
| ACHIEVEMENT_NOT_FOUND | 404 | 成就不存在 |
| ACHIEVEMENT_NOT_EARNED | 400 | 成就未获得 |
| REWARDS_ALREADY_CLAIMED | 400 | 奖励已领取 |
| INSUFFICIENT_PROGRESS | 400 | 进度不足 |
| ACHIEVEMENT_LOCKED | 400 | 成就被锁定 |
### 6.2 错误响应示例
```json
{
"status": "error",
"code": 400,
"message": "奖励已经领取",
"error_code": "REWARDS_ALREADY_CLAIMED",
"details": {
"achievement_id": 1,
"claimed_at": "2023-01-05T13:00:00Z"
}
}
```
## 7. 使用示例
### 7.1 Python 客户端示例
```python
import requests
class AchievementClient:
def __init__(self, base_url, token):
self.base_url = base_url
self.headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
def get_user_achievements(self, status=None):
"""获取用户成就列表"""
params = {}
if status:
params['status'] = status
response = requests.get(
f'{self.base_url}/user-achievements/',
headers=self.headers,
params=params
)
return response.json()
def check_achievements(self, event_type, event_data):
"""检查成就进度"""
data = {
'trigger_event': event_type,
'event_data': event_data
}
response = requests.post(
f'{self.base_url}/user-achievements/check/',
headers=self.headers,
json=data
)
return response.json()
def claim_rewards(self, user_achievement_id):
"""领取成就奖励"""
response = requests.post(
f'{self.base_url}/user-achievements/{user_achievement_id}/claim_rewards/',
headers=self.headers
)
return response.json()
def get_leaderboard(self, type='total', limit=10):
"""获取排行榜"""
params = {
'type': type,
'limit': limit
}
response = requests.get(
f'{self.base_url}/leaderboard/',
headers=self.headers,
params=params
)
return response.json()
# 使用示例
client = AchievementClient('http://localhost:8000/api/achievement', 'your-token')
# 获取用户已获得的成就
earned_achievements = client.get_user_achievements(status='earned')
print(f"已获得 {len(earned_achievements['data']['achievements'])} 个成就")
# 使用卡片后检查成就
result = client.check_achievements('card_used', {
'card_category': 'dance',
'card_difficulty': '中级'
})
# 如果有新获得的成就,领取奖励
if result['data']['newly_earned']:
for achievement in result['data']['newly_earned']:
print(f"获得新成就: {achievement['achievement_name']}")
# 获取排行榜
leaderboard = client.get_leaderboard('total', 20)
print(f"我的排名: {leaderboard['data']['current_user_rank']}")
```
### 7.2 自动触发成就检查示例
```python
# 在使用卡片后自动检查成就
def handle_card_usage(user_id, card):
# 记录卡片使用
usage_log = create_card_usage_log(user_id, card)
# 触发成就检查
achievement_client = AchievementClient(settings.API_BASE, get_user_token(user_id))
result = achievement_client.check_achievements('card_used', {
'card_id': card.id,
'card_category': card.category,
'card_difficulty': card.difficulty,
'card_style': card.style
})
# 处理新获得的成就
for achievement in result['data']['newly_earned']:
# 发送通知
send_achievement_notification(user_id, achievement)
# 自动领取奖励
user_achievement_id = achievement['user_achievement_id']
achievement_client.claim_rewards(user_achievement_id)
return result
```
## 8. 最佳实践
### 8.1 成就设计原则
- **渐进性**: 从简单到困难,让用户有成就感
- **多样性**: 覆盖不同的用户行为和兴趣
- **平衡性**: 避免过于简单或过于困难的成就
- **时效性**: 定期更新和添加新成就
### 8.2 性能优化
- 使用异步任务处理成就检查
- 缓存用户成就进度数据
- 批量更新数据库操作
- 定期清理过期的成就数据
### 8.3 用户体验
- 及时的成就通知
- 清晰的进度展示
- 有意义的奖励设计
- 社交分享功能