# 成就系统 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 用户体验
- 及时的成就通知
- 清晰的进度展示
- 有意义的奖励设计
- 社交分享功能