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