# 卡片系统 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缓存热门卡片信息 - 批量操作时使用数据库事务