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

767 lines
17 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/card/`
- **认证方式**: Token 认证
- **返回格式**: JSON
## API 概览
| 接口路径 | 方法 | 描述 |
|---------|------|------|
| `/api/card/templates/` | GET, POST | 卡片模板管理 |
| `/api/card/templates/{id}/` | GET, PUT, DELETE | 卡片模板详情操作 |
| `/api/card/batches/` | GET, POST | 卡片批次管理 |
| `/api/card/batches/{id}/` | GET, PUT, DELETE | 卡片批次详情操作 |
| `/api/card/cards/` | GET, POST | 卡片管理 |
| `/api/card/cards/{id}/` | GET, PUT, DELETE | 卡片详情操作 |
| `/api/card/user/cards/` | GET | 用户卡片列表 |
| `/api/card/category/{category}/` | GET | 按类别查询模板 |
## 1. 卡片模板管理
### 1.1 获取模板列表
获取所有卡片模板的列表。
- **URL**: `/api/card/templates/`
- **方法**: `GET`
- **认证**: 需要
- **查询参数**:
| 参数名 | 类型 | 描述 |
|-------|-----|------|
| category | string | 按类别筛选 |
| is_active | boolean | 按激活状态筛选 |
| page | integer | 页码 |
| page_size | integer | 每页数量 |
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"count": 50,
"next": "http://localhost:8000/api/card/templates/?page=2",
"previous": null,
"results": [
{
"id": 1,
"name": "舞蹈卡片模板",
"category": "dance",
"description": "用于舞蹈技能学习的卡片",
"image": "https://example.com/card_templates/dance_template.jpg",
"attributes": {
"difficulty": "初级",
"duration": "30分钟",
"style": "现代舞"
},
"rarity": "common",
"is_active": true,
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
}
]
}
}
```
### 1.2 创建卡片模板
创建新的卡片模板。
- **URL**: `/api/card/templates/`
- **方法**: `POST`
- **认证**: 需要(管理员权限)
- **请求体**:
```json
{
"name": "唱歌卡片模板",
"category": "song",
"description": "用于音乐技能学习的卡片",
"image": "https://example.com/card_templates/song_template.jpg",
"attributes": {
"genre": "流行",
"difficulty": "中级",
"bpm": 120,
"language": "中文"
},
"rarity": "rare",
"is_active": true
}
```
**请求参数说明:**
| 参数名 | 类型 | 必填 | 描述 |
|-------|-----|------|-----|
| name | string | 是 | 模板名称 |
| category | string | 是 | 卡片类别 |
| description | string | 否 | 模板描述 |
| image | string | 否 | 模板图片URL |
| attributes | object | 否 | 模板属性(根据类别不同) |
| rarity | string | 否 | 稀有度(common/rare/epic/legendary) |
| is_active | boolean | 否 | 是否激活默认true |
**支持的卡片类别:**
- **dance**: 舞蹈卡片
- **song**: 音乐卡片
- **clothing**: 服装卡片
- **game**: 游戏卡片
**响应示例:**
```json
{
"status": "success",
"code": 201,
"data": {
"id": 2,
"name": "唱歌卡片模板",
"category": "song",
"description": "用于音乐技能学习的卡片",
"image": "https://example.com/card_templates/song_template.jpg",
"attributes": {
"genre": "流行",
"difficulty": "中级",
"bpm": 120,
"language": "中文"
},
"rarity": "rare",
"is_active": true,
"created_at": "2023-01-02T10:00:00Z",
"updated_at": "2023-01-02T10:00:00Z"
}
}
```
### 1.3 获取模板详情
- **URL**: `/api/card/templates/{id}/`
- **方法**: `GET`
- **参数**:
- `id` (路径参数): 模板ID
### 1.4 更新模板
- **URL**: `/api/card/templates/{id}/`
- **方法**: `PUT`
- **认证**: 需要(管理员权限)
### 1.5 删除模板
- **URL**: `/api/card/templates/{id}/`
- **方法**: `DELETE`
- **认证**: 需要(管理员权限)
## 2. 卡片批次管理
### 2.1 获取批次列表
- **URL**: `/api/card/batches/`
- **方法**: `GET`
- **认证**: 需要
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"count": 10,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"name": "2023年第一批舞蹈卡片",
"template": 1,
"template_name": "舞蹈卡片模板",
"category": "dance",
"total_quantity": 1000,
"generated_quantity": 1000,
"used_quantity": 150,
"start_id": 1001,
"end_id": 2000,
"batch_code": "DANCE_20230101_001",
"is_published": true,
"expiry_date": "2023-12-31",
"qr_code_base_url": "https://example.com/cards/",
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
}
]
}
}
```
### 2.2 创建卡片批次
创建新的卡片批次并自动生成指定数量的卡片。
- **URL**: `/api/card/batches/`
- **方法**: `POST`
- **认证**: 需要(管理员权限)
- **请求体**:
```json
{
"name": "2023年第二批音乐卡片",
"template": 2,
"total_quantity": 500,
"expiry_date": "2023-12-31",
"batch_code": "SONG_20230201_001"
}
```
**请求参数说明:**
| 参数名 | 类型 | 必填 | 描述 |
|-------|-----|------|-----|
| name | string | 是 | 批次名称 |
| template | integer | 是 | 卡片模板ID |
| total_quantity | integer | 是 | 生成卡片数量 |
| expiry_date | string | 否 | 过期日期 (YYYY-MM-DD) |
| batch_code | string | 否 | 批次编码(自动生成) |
**响应示例:**
```json
{
"status": "success",
"code": 201,
"data": {
"id": 2,
"name": "2023年第二批音乐卡片",
"template": 2,
"template_name": "唱歌卡片模板",
"category": "song",
"total_quantity": 500,
"generated_quantity": 500,
"used_quantity": 0,
"start_id": 2001,
"end_id": 2500,
"batch_code": "SONG_20230201_001",
"is_published": false,
"expiry_date": "2023-12-31",
"qr_code_base_url": "https://example.com/cards/",
"created_at": "2023-02-01T10:00:00Z",
"updated_at": "2023-02-01T10:00:00Z"
}
}
```
## 3. 卡片管理
### 3.1 获取卡片列表
- **URL**: `/api/card/cards/`
- **方法**: `GET`
- **认证**: 需要
- **查询参数**:
| 参数名 | 类型 | 描述 |
|-------|-----|------|
| batch | integer | 按批次筛选 |
| category | string | 按类别筛选 |
| is_used | boolean | 按使用状态筛选 |
| user | integer | 按使用用户筛选 |
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"count": 1000,
"next": "http://localhost:8000/api/card/cards/?page=2",
"previous": null,
"results": [
{
"id": 1001,
"batch": 1,
"batch_name": "2023年第一批舞蹈卡片",
"template": 1,
"template_name": "舞蹈卡片模板",
"category": "dance",
"card_code": "DANCE_20230101_001_1001",
"qr_code": "https://example.com/cards/DANCE_20230101_001_1001",
"qr_code_image": "https://example.com/qr/DANCE_20230101_001_1001.png",
"is_used": false,
"used_by": null,
"used_at": null,
"expires_at": "2023-12-31T23:59:59Z",
"created_at": "2023-01-01T00:00:00Z"
}
]
}
}
```
### 3.2 获取卡片详情
- **URL**: `/api/card/cards/{id}/`
- **方法**: `GET`
- **参数**:
- `id` (路径参数): 卡片ID
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"id": 1001,
"batch": {
"id": 1,
"name": "2023年第一批舞蹈卡片",
"category": "dance"
},
"template": {
"id": 1,
"name": "舞蹈卡片模板",
"category": "dance",
"attributes": {
"difficulty": "初级",
"duration": "30分钟",
"style": "现代舞"
},
"rarity": "common"
},
"card_code": "DANCE_20230101_001_1001",
"qr_code": "https://example.com/cards/DANCE_20230101_001_1001",
"qr_code_image": "https://example.com/qr/DANCE_20230101_001_1001.png",
"is_used": false,
"used_by": null,
"used_at": null,
"expires_at": "2023-12-31T23:59:59Z",
"created_at": "2023-01-01T00:00:00Z"
}
}
```
### 3.3 使用卡片
用户扫描或输入卡片码来使用卡片。
- **URL**: `/api/card/cards/use/`
- **方法**: `POST`
- **认证**: 需要
- **请求体**:
```json
{
"card_code": "DANCE_20230101_001_1001"
}
```
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"card": {
"id": 1001,
"card_code": "DANCE_20230101_001_1001",
"template": {
"name": "舞蹈卡片模板",
"category": "dance",
"attributes": {
"difficulty": "初级",
"duration": "30分钟",
"style": "现代舞"
}
}
},
"usage_log": {
"id": 1,
"card": 1001,
"user": 1,
"used_at": "2023-01-02T14:30:00Z",
"ip_address": "192.168.1.100",
"user_agent": "Mozilla/5.0..."
},
"message": "卡片使用成功!您获得了舞蹈技能:现代舞(初级)"
}
}
```
### 3.4 批量生成卡片二维码
为指定批次生成二维码图片。
- **URL**: `/api/card/batches/{batch_id}/generate_qrcodes/`
- **方法**: `POST`
- **认证**: 需要(管理员权限)
- **响应示例**:
```json
{
"status": "success",
"code": 200,
"data": {
"batch_id": 1,
"generated_count": 1000,
"zip_download_url": "https://example.com/downloads/batch_1_qrcodes.zip",
"expires_at": "2023-01-03T00:00:00Z"
}
}
```
## 4. 用户卡片
### 4.1 获取用户卡片列表
获取当前用户使用过的卡片列表。
- **URL**: `/api/card/user/cards/`
- **方法**: `GET`
- **认证**: 需要
- **查询参数**:
| 参数名 | 类型 | 描述 |
|-------|-----|------|
| category | string | 按类别筛选 |
| start_date | string | 使用开始日期 |
| end_date | string | 使用结束日期 |
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"count": 5,
"next": null,
"previous": null,
"results": [
{
"usage_log_id": 1,
"card": {
"id": 1001,
"card_code": "DANCE_20230101_001_1001",
"template": {
"name": "舞蹈卡片模板",
"category": "dance",
"attributes": {
"difficulty": "初级",
"duration": "30分钟",
"style": "现代舞"
},
"rarity": "common"
}
},
"used_at": "2023-01-02T14:30:00Z",
"ip_address": "192.168.1.100"
}
]
}
}
```
## 5. 按类别查询
### 5.1 按类别获取模板
- **URL**: `/api/card/category/{category}/`
- **方法**: `GET`
- **参数**:
- `category` (路径参数): 卡片类别
- **认证**: 需要
**支持的类别:**
- `dance` - 舞蹈类
- `song` - 音乐类
- `clothing` - 服装类
- `game` - 游戏类
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"category": "dance",
"templates": [
{
"id": 1,
"name": "舞蹈卡片模板",
"description": "用于舞蹈技能学习的卡片",
"attributes": {
"difficulty": "初级",
"duration": "30分钟",
"style": "现代舞"
},
"rarity": "common",
"available_batches": [
{
"id": 1,
"name": "2023年第一批舞蹈卡片",
"available_quantity": 850
}
]
}
]
}
}
```
## 6. 卡片属性系统
### 6.1 舞蹈卡片属性
```json
{
"difficulty": "初级/中级/高级",
"duration": "时长(分钟)",
"style": "舞蹈风格",
"choreographer": "编舞师",
"music_bpm": "音乐BPM"
}
```
### 6.2 音乐卡片属性
```json
{
"genre": "音乐风格",
"difficulty": "难度等级",
"bpm": "节拍",
"language": "语言",
"artist": "艺术家",
"duration": "时长",
"key": "调性",
"audio_file": "音频文件URL"
}
```
### 6.3 服装卡片属性
```json
{
"color": "颜色",
"size": "尺码",
"style": "风格",
"season": "适用季节",
"material": "材质",
"brand": "品牌"
}
```
## 7. 统计和报告
### 7.1 获取卡片使用统计
- **URL**: `/api/card/statistics/`
- **方法**: `GET`
- **认证**: 需要(管理员权限)
- **查询参数**:
| 参数名 | 类型 | 描述 |
|-------|-----|------|
| start_date | string | 统计开始日期 |
| end_date | string | 统计结束日期 |
| category | string | 按类别筛选 |
**响应示例:**
```json
{
"status": "success",
"code": 200,
"data": {
"period": {
"start_date": "2023-01-01",
"end_date": "2023-01-31"
},
"summary": {
"total_cards": 2000,
"used_cards": 350,
"usage_rate": 17.5,
"unique_users": 125
},
"by_category": {
"dance": {
"total": 1000,
"used": 200,
"usage_rate": 20.0
},
"song": {
"total": 500,
"used": 100,
"usage_rate": 20.0
},
"clothing": {
"total": 300,
"used": 30,
"usage_rate": 10.0
},
"game": {
"total": 200,
"used": 20,
"usage_rate": 10.0
}
},
"daily_usage": [
{
"date": "2023-01-01",
"count": 15
},
{
"date": "2023-01-02",
"count": 23
}
]
}
}
```
## 8. 错误响应
### 8.1 常见错误码
| 错误码 | HTTP状态码 | 描述 |
|-------|-----------|------|
| CARD_NOT_FOUND | 404 | 卡片不存在 |
| CARD_EXPIRED | 400 | 卡片已过期 |
| CARD_ALREADY_USED | 400 | 卡片已被使用 |
| BATCH_FULL | 400 | 批次已满 |
| INSUFFICIENT_PERMISSION | 403 | 权限不足 |
### 8.2 错误响应示例
```json
{
"status": "error",
"code": 400,
"message": "卡片已被使用",
"error_code": "CARD_ALREADY_USED",
"details": {
"card_code": "DANCE_20230101_001_1001",
"used_by": "user123",
"used_at": "2023-01-02T14:30:00Z"
}
}
```
## 9. 使用示例
### 9.1 Python 客户端示例
```python
import requests
class CardClient:
def __init__(self, base_url, token):
self.base_url = base_url
self.headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
def create_template(self, name, category, **kwargs):
"""创建卡片模板"""
data = {
'name': name,
'category': category,
**kwargs
}
response = requests.post(
f'{self.base_url}/templates/',
headers=self.headers,
json=data
)
return response.json()
def create_batch(self, template_id, quantity, name):
"""创建卡片批次"""
data = {
'template': template_id,
'total_quantity': quantity,
'name': name
}
response = requests.post(
f'{self.base_url}/batches/',
headers=self.headers,
json=data
)
return response.json()
def use_card(self, card_code):
"""使用卡片"""
data = {'card_code': card_code}
response = requests.post(
f'{self.base_url}/cards/use/',
headers=self.headers,
json=data
)
return response.json()
def get_user_cards(self):
"""获取用户卡片"""
response = requests.get(
f'{self.base_url}/user/cards/',
headers=self.headers
)
return response.json()
# 使用示例
client = CardClient('http://localhost:8000/api/card', 'your-token')
# 创建舞蹈卡片模板
template = client.create_template(
name='爵士舞模板',
category='dance',
attributes={
'difficulty': '中级',
'style': '爵士舞',
'duration': '45分钟'
},
rarity='rare'
)
# 创建卡片批次
batch = client.create_batch(
template_id=template['data']['id'],
quantity=100,
name='爵士舞卡片第一批'
)
# 使用卡片
result = client.use_card('DANCE_20230101_001_1001')
```
## 10. 最佳实践
### 10.1 卡片码格式
推荐的卡片码格式:`{CATEGORY}_{DATE}_{BATCH}_{ID}`
- 示例:`DANCE_20230101_001_1001`
### 10.2 批次管理
- 建议按月或季度创建批次
- 每个批次的数量不超过10000张
- 定期清理过期未使用的卡片
### 10.3 安全考虑
- 卡片码应足够复杂,避免被猜测
- 实施速率限制防止恶意扫描
- 记录使用日志用于审计
### 10.4 性能优化
- 对于高频查询的字段建立数据库索引
- 使用Redis缓存热门卡片信息
- 批量操作时使用数据库事务