17 KiB
17 KiB
卡片系统 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 | 每页数量 |
响应示例:
{
"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 - 认证: 需要(管理员权限)
- 请求体:
{
"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: 游戏卡片
响应示例:
{
"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 - 认证: 需要
响应示例:
{
"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 - 认证: 需要(管理员权限)
- 请求体:
{
"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 | 否 | 批次编码(自动生成) |
响应示例:
{
"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 | 按使用用户筛选 |
响应示例:
{
"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
响应示例:
{
"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 - 认证: 需要
- 请求体:
{
"card_code": "DANCE_20230101_001_1001"
}
响应示例:
{
"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 - 认证: 需要(管理员权限)
- 响应示例:
{
"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 | 使用结束日期 |
响应示例:
{
"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- 游戏类
响应示例:
{
"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 舞蹈卡片属性
{
"difficulty": "初级/中级/高级",
"duration": "时长(分钟)",
"style": "舞蹈风格",
"choreographer": "编舞师",
"music_bpm": "音乐BPM"
}
6.2 音乐卡片属性
{
"genre": "音乐风格",
"difficulty": "难度等级",
"bpm": "节拍",
"language": "语言",
"artist": "艺术家",
"duration": "时长",
"key": "调性",
"audio_file": "音频文件URL"
}
6.3 服装卡片属性
{
"color": "颜色",
"size": "尺码",
"style": "风格",
"season": "适用季节",
"material": "材质",
"brand": "品牌"
}
7. 统计和报告
7.1 获取卡片使用统计
- URL:
/api/card/statistics/ - 方法:
GET - 认证: 需要(管理员权限)
- 查询参数:
| 参数名 | 类型 | 描述 |
|---|---|---|
| start_date | string | 统计开始日期 |
| end_date | string | 统计结束日期 |
| category | string | 按类别筛选 |
响应示例:
{
"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 错误响应示例
{
"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 客户端示例
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缓存热门卡片信息
- 批量操作时使用数据库事务