对话摘要和推荐回复
This commit is contained in:
parent
c6f1ef1f54
commit
43e4375b4f
File diff suppressed because it is too large
Load Diff
163
apps/chat/services/goal_service.py
Normal file
163
apps/chat/services/goal_service.py
Normal file
@ -0,0 +1,163 @@
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from apps.chat.models import ChatHistory
|
||||
from apps.common.services.ai_service import AIService
|
||||
import traceback
|
||||
from django.db.models import Q
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def get_conversation(conversation_id):
|
||||
"""
|
||||
获取给定对话ID的对话内容
|
||||
|
||||
参数:
|
||||
- conversation_id: 对话ID
|
||||
|
||||
返回:
|
||||
- 对话数据,包含消息列表,如无法获取则返回None
|
||||
"""
|
||||
try:
|
||||
# 获取对话消息
|
||||
messages = ChatHistory.objects.filter(
|
||||
conversation_id=conversation_id,
|
||||
is_deleted=False
|
||||
).order_by('created_at')
|
||||
|
||||
if not messages:
|
||||
logger.warning(f"对话 {conversation_id} 没有消息记录")
|
||||
return None
|
||||
|
||||
# 构造消息列表
|
||||
message_list = []
|
||||
for msg in messages:
|
||||
message_list.append({
|
||||
'id': str(msg.id),
|
||||
'content': msg.content,
|
||||
'is_user': msg.role == 'user',
|
||||
'timestamp': msg.created_at.isoformat(),
|
||||
'metadata': msg.metadata or {}
|
||||
})
|
||||
|
||||
# 获取对话标题
|
||||
title = messages.first().title if messages.exists() else "新对话"
|
||||
|
||||
return {
|
||||
'id': conversation_id,
|
||||
'title': title,
|
||||
'messages': message_list
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取对话时发生错误: {str(e)}")
|
||||
logger.error(traceback.format_exc())
|
||||
return None
|
||||
|
||||
def get_conversation_summary(conversation_id):
|
||||
"""
|
||||
获取对话摘要
|
||||
|
||||
Args:
|
||||
conversation_id: 对话ID
|
||||
|
||||
Returns:
|
||||
str: 摘要内容或None
|
||||
"""
|
||||
try:
|
||||
# 获取对话消息
|
||||
chat_history = ChatHistory.objects.filter(
|
||||
conversation_id=conversation_id,
|
||||
is_deleted=False
|
||||
).order_by('-created_at')[:5]
|
||||
|
||||
if not chat_history:
|
||||
return None
|
||||
|
||||
# 生成简单摘要(最近几条消息)
|
||||
messages = []
|
||||
for msg in chat_history:
|
||||
if len(messages) < 3: # 只取最新的3条
|
||||
role = "用户" if msg.role == "user" else "助手"
|
||||
content = msg.content
|
||||
if len(content) > 100:
|
||||
content = content[:100] + "..."
|
||||
messages.append(f"{role}: {content}")
|
||||
|
||||
if messages:
|
||||
return "最近对话: " + " | ".join(reversed(messages))
|
||||
|
||||
# 如果简单摘要方式不行,可以通过AI服务生成摘要
|
||||
conversation_data = get_conversation(conversation_id)
|
||||
if conversation_data and conversation_data.get('messages'):
|
||||
# 将消息数据转换为AI服务需要的格式
|
||||
conv_messages = []
|
||||
for msg in conversation_data['messages']:
|
||||
conv_messages.append({
|
||||
'content': msg['content'],
|
||||
'is_from_user': msg['is_user']
|
||||
})
|
||||
|
||||
# 调用AI服务生成摘要
|
||||
summary, error = AIService.generate_conversation_summary(conv_messages)
|
||||
if not error and summary:
|
||||
return summary
|
||||
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"获取对话摘要失败: {str(e)}")
|
||||
logger.error(traceback.format_exc())
|
||||
return None
|
||||
|
||||
def get_last_message(conversation_id):
|
||||
"""
|
||||
获取给定对话的最后一条消息
|
||||
|
||||
参数:
|
||||
- conversation_id: 对话ID
|
||||
|
||||
返回:
|
||||
- 最后一条消息文本,如果无法获取则返回None
|
||||
"""
|
||||
try:
|
||||
# 获取对话消息
|
||||
chat_messages = ChatHistory.objects.filter(
|
||||
conversation_id=conversation_id,
|
||||
is_deleted=False
|
||||
).order_by('created_at')
|
||||
|
||||
if not chat_messages:
|
||||
logger.warning(f"对话 {conversation_id} 没有消息记录")
|
||||
return None
|
||||
|
||||
# 过滤出助手发送的消息
|
||||
assistant_messages = [msg for msg in chat_messages if msg.role == 'assistant']
|
||||
|
||||
if not assistant_messages:
|
||||
logger.warning(f"对话 {conversation_id} 中没有助手发送的消息")
|
||||
return None
|
||||
|
||||
# 返回最后一条助手消息
|
||||
last_message = assistant_messages[-1].content
|
||||
return last_message
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取最后一条消息时发生错误: {str(e)}")
|
||||
logger.error(traceback.format_exc())
|
||||
return None
|
||||
|
||||
def generate_recommended_reply(user, goal_description, conversation_summary, last_message):
|
||||
"""
|
||||
根据用户目标、对话摘要和最后一条消息生成推荐话术
|
||||
|
||||
Args:
|
||||
user: 用户对象
|
||||
goal_description: 用户目标描述
|
||||
conversation_summary: 对话摘要
|
||||
last_message: 助手最后发送的消息内容
|
||||
|
||||
Returns:
|
||||
tuple: (推荐话术内容, 错误信息)
|
||||
"""
|
||||
# 直接调用AIService生成回复
|
||||
return AIService.generate_email_reply(goal_description, conversation_summary, last_message)
|
@ -18,6 +18,9 @@ from apps.chat.services.chat_api import (
|
||||
ExternalAPIError, stream_chat_answer, get_chat_answer,
|
||||
generate_conversation_title_from_deepseek
|
||||
)
|
||||
from apps.chat.services.goal_service import (
|
||||
get_conversation_summary, get_last_message, generate_recommended_reply
|
||||
)
|
||||
from apps.daren_detail.models import CreatorProfile
|
||||
from apps.daren_detail.serializers import CreatorProfileSerializer, CreatorProfileListSerializer
|
||||
|
||||
@ -656,3 +659,111 @@ class ChatHistoryViewSet(viewsets.ModelViewSet):
|
||||
'message': f'获取达人信息失败: {str(e)}',
|
||||
'data': None
|
||||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
@action(detail=False, methods=['get'])
|
||||
def generate_summary(self, request):
|
||||
"""获取对话摘要"""
|
||||
try:
|
||||
conversation_id = request.query_params.get('conversation_id')
|
||||
if not conversation_id:
|
||||
return Response({
|
||||
'code': 400,
|
||||
'message': '缺少必要参数: conversation_id',
|
||||
'data': None
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 获取对话摘要
|
||||
summary = get_conversation_summary(conversation_id)
|
||||
|
||||
if summary is None:
|
||||
return Response({
|
||||
'code': 404,
|
||||
'message': '未找到对话或无法生成摘要',
|
||||
'data': None
|
||||
}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
return Response({
|
||||
'code': 200,
|
||||
'message': '获取摘要成功',
|
||||
'data': {
|
||||
'conversation_id': conversation_id,
|
||||
'summary': summary
|
||||
}
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取对话摘要失败: {str(e)}")
|
||||
logger.error(traceback.format_exc())
|
||||
return Response({
|
||||
'code': 500,
|
||||
'message': f'获取对话摘要失败: {str(e)}',
|
||||
'data': None
|
||||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
@action(detail=False, methods=['post'])
|
||||
def generate_reply(self, request):
|
||||
"""生成推荐回复话术"""
|
||||
try:
|
||||
data = request.data
|
||||
conversation_id = data.get('conversation_id')
|
||||
goal_description = data.get('goal_description')
|
||||
|
||||
if not conversation_id:
|
||||
return Response({
|
||||
'code': 400,
|
||||
'message': '缺少必要参数: conversation_id',
|
||||
'data': None
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
if not goal_description:
|
||||
return Response({
|
||||
'code': 400,
|
||||
'message': '缺少必要参数: goal_description',
|
||||
'data': None
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 获取对话摘要
|
||||
conversation_summary = get_conversation_summary(conversation_id)
|
||||
|
||||
# 获取助手最后一条消息
|
||||
last_message = get_last_message(conversation_id)
|
||||
|
||||
if last_message is None:
|
||||
return Response({
|
||||
'code': 404,
|
||||
'message': '未找到对话或无法获取最后一条消息',
|
||||
'data': None
|
||||
}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
# 生成推荐回复
|
||||
reply, error = generate_recommended_reply(
|
||||
request.user,
|
||||
goal_description,
|
||||
conversation_summary,
|
||||
last_message
|
||||
)
|
||||
|
||||
if error:
|
||||
return Response({
|
||||
'code': 500,
|
||||
'message': f'生成推荐回复失败: {error}',
|
||||
'data': None
|
||||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
return Response({
|
||||
'code': 200,
|
||||
'message': '生成推荐回复成功',
|
||||
'data': {
|
||||
'conversation_id': conversation_id,
|
||||
'reply': reply
|
||||
}
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"生成推荐回复失败: {str(e)}")
|
||||
logger.error(traceback.format_exc())
|
||||
return Response({
|
||||
'code': 500,
|
||||
'message': f'生成推荐回复失败: {str(e)}',
|
||||
'data': None
|
||||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
@ -1,329 +0,0 @@
|
||||
# Discovery API 接口文档
|
||||
|
||||
## 简介
|
||||
|
||||
Discovery API是一个用于发现和搜索创作者的接口。它提供了创作者搜索、搜索会话管理等功能。所有API响应均遵循统一格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200, // 状态码,200表示成功
|
||||
"message": "操作成功", // 操作提示消息
|
||||
"data": { // 实际数据
|
||||
// 具体内容
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 使用Apifox测试接口
|
||||
|
||||
1. 下载并安装Apifox: https://www.apifox.cn/
|
||||
2. 创建新项目,命名为"Creator Discovery"
|
||||
3. 导入API或手动创建以下接口
|
||||
|
||||
## API 接口列表
|
||||
|
||||
### 1. 搜索创作者
|
||||
|
||||
- **URL**: `http://localhost:8000/api/discovery/creators/search/`
|
||||
- **方法**: POST
|
||||
- **描述**: 根据条件搜索创作者,并创建新的搜索会话
|
||||
- **请求参数**:
|
||||
|
||||
```json
|
||||
{
|
||||
"query": "创作者",
|
||||
"category": "Health",
|
||||
"ecommerce_level": "L5",
|
||||
"exposure_level": "KOL-2"
|
||||
}
|
||||
```
|
||||
|
||||
- **响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "搜索创作者成功",
|
||||
"data": {
|
||||
"id": 4,
|
||||
"creators": [
|
||||
{
|
||||
"id": 37,
|
||||
"name": "Mock Creator 5",
|
||||
"avatar": null,
|
||||
"category": "Health",
|
||||
"ecommerce_level": "L5",
|
||||
"exposure_level": "KOL-2",
|
||||
"followers": 162.2,
|
||||
"gmv": 534.1,
|
||||
"items_sold": 18.1,
|
||||
"avg_video_views": 1.9,
|
||||
"has_ecommerce": false,
|
||||
"tiktok_url": null,
|
||||
"session": 4
|
||||
}
|
||||
],
|
||||
"session_number": 4,
|
||||
"creator_count": 1,
|
||||
"shoppable_creators": 0,
|
||||
"avg_followers": 162.2,
|
||||
"avg_gmv": 534.1,
|
||||
"avg_video_views": 1.9,
|
||||
"date_created": "2023-10-02"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 获取搜索会话列表
|
||||
|
||||
- **URL**: `http://localhost:8000/api/discovery/sessions/`
|
||||
- **方法**: GET
|
||||
- **描述**: 获取所有搜索会话的历史记录
|
||||
- **查询参数**:
|
||||
- `page`: 页码,默认为1
|
||||
- `page_size`: 每页条数,默认为20,最大为100
|
||||
- **响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取数据成功",
|
||||
"data": {
|
||||
"count": 3,
|
||||
"next": "http://localhost:8000/api/discovery/sessions/?page=2",
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": 1,
|
||||
"session_number": 1,
|
||||
"creator_count": 42,
|
||||
"shoppable_creators": 24,
|
||||
"avg_followers": 162.2,
|
||||
"avg_gmv": 534.1,
|
||||
"avg_video_views": 1.9,
|
||||
"date_created": "2024-01-06"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"session_number": 2,
|
||||
"creator_count": 53,
|
||||
"shoppable_creators": 13,
|
||||
"avg_followers": 162.2,
|
||||
"avg_gmv": 534.1,
|
||||
"avg_video_views": 1.9,
|
||||
"date_created": "2022-01-07"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 获取搜索会话详情
|
||||
|
||||
- **URL**: `http://localhost:8000/api/discovery/sessions/{id}/`
|
||||
- **方法**: GET
|
||||
- **描述**: 获取特定搜索会话的详细信息,包含该会话中的所有创作者
|
||||
- **请求参数**: 路径参数 `id`
|
||||
- **响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取搜索会话详情成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"creators": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Creator 1 in Session 1",
|
||||
"avatar": null,
|
||||
"category": "Phones & Electronics",
|
||||
"ecommerce_level": "L2",
|
||||
"exposure_level": "KOC-1",
|
||||
"followers": 162.2,
|
||||
"gmv": 534.1,
|
||||
"items_sold": 18.1,
|
||||
"avg_video_views": 1.9,
|
||||
"has_ecommerce": true,
|
||||
"tiktok_url": null,
|
||||
"session": 1
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Creator 9 in Session 1",
|
||||
"avatar": null,
|
||||
"category": "Womenswear & Underwear",
|
||||
"ecommerce_level": "L3",
|
||||
"exposure_level": "KOL-3",
|
||||
"followers": 162.2,
|
||||
"gmv": 534.1,
|
||||
"items_sold": 18.1,
|
||||
"avg_video_views": 1.9,
|
||||
"has_ecommerce": false,
|
||||
"tiktok_url": null,
|
||||
"session": 1
|
||||
}
|
||||
],
|
||||
"session_number": 1,
|
||||
"creator_count": 42,
|
||||
"shoppable_creators": 24,
|
||||
"avg_followers": 162.2,
|
||||
"avg_gmv": 534.1,
|
||||
"avg_video_views": 1.9,
|
||||
"date_created": "2024-01-06"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 获取会话中的创作者
|
||||
|
||||
- **URL**: `http://localhost:8000/api/discovery/sessions/{id}/results/`
|
||||
- **方法**: GET
|
||||
- **描述**: 获取特定会话中的所有创作者
|
||||
- **请求参数**:
|
||||
- 路径参数 `id`
|
||||
- 查询参数 `page`、`page_size`(分页参数)
|
||||
- **响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取数据成功",
|
||||
"data": {
|
||||
"count": 42,
|
||||
"next": "http://localhost:8000/api/discovery/sessions/1/results/?page=2",
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Creator 1 in Session 1",
|
||||
"avatar": null,
|
||||
"category": "Phones & Electronics",
|
||||
"ecommerce_level": "L2",
|
||||
"exposure_level": "KOC-1",
|
||||
"followers": 162.2,
|
||||
"gmv": 534.1,
|
||||
"items_sold": 18.1,
|
||||
"avg_video_views": 1.9,
|
||||
"has_ecommerce": true,
|
||||
"tiktok_url": null,
|
||||
"session": 1
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Creator 9 in Session 1",
|
||||
"avatar": null,
|
||||
"category": "Womenswear & Underwear",
|
||||
"ecommerce_level": "L3",
|
||||
"exposure_level": "KOL-3",
|
||||
"followers": 162.2,
|
||||
"gmv": 534.1,
|
||||
"items_sold": 18.1,
|
||||
"avg_video_views": 1.9,
|
||||
"has_ecommerce": false,
|
||||
"tiktok_url": null,
|
||||
"session": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 获取所有创作者
|
||||
|
||||
- **URL**: `http://localhost:8000/api/discovery/creators/`
|
||||
- **方法**: GET
|
||||
- **描述**: 获取系统中的所有创作者
|
||||
- **请求参数**: 查询参数 `page`、`page_size`(分页参数)
|
||||
- **响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取数据成功",
|
||||
"data": {
|
||||
"count": 150,
|
||||
"next": "http://localhost:8000/api/discovery/creators/?page=2",
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Creator 1 in Session 1",
|
||||
"avatar": null,
|
||||
"category": "Phones & Electronics",
|
||||
"ecommerce_level": "L2",
|
||||
"exposure_level": "KOC-1",
|
||||
"followers": 162.2,
|
||||
"gmv": 534.1,
|
||||
"items_sold": 18.1,
|
||||
"avg_video_views": 1.9,
|
||||
"has_ecommerce": true,
|
||||
"tiktok_url": null,
|
||||
"session": 1
|
||||
},
|
||||
// 更多创作者...
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 获取创作者详情
|
||||
|
||||
- **URL**: `http://localhost:8000/api/discovery/creators/{id}/`
|
||||
- **方法**: GET
|
||||
- **描述**: 获取特定创作者的详细信息
|
||||
- **请求参数**: 路径参数 `id`
|
||||
- **响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取创作者详情成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"name": "Creator 1 in Session 1",
|
||||
"avatar": null,
|
||||
"category": "Phones & Electronics",
|
||||
"ecommerce_level": "L2",
|
||||
"exposure_level": "KOC-1",
|
||||
"followers": 162.2,
|
||||
"gmv": 534.1,
|
||||
"items_sold": 18.1,
|
||||
"avg_video_views": 1.9,
|
||||
"has_ecommerce": true,
|
||||
"tiktok_url": null,
|
||||
"session": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 在Apifox中设置环境变量
|
||||
|
||||
创建一个名为"本地开发环境"的环境,设置以下变量:
|
||||
- `baseUrl`: `http://localhost:8000/api`
|
||||
|
||||
这样可以在所有请求中使用`{{baseUrl}}/discovery/...`来替代完整URL。
|
||||
|
||||
## 测试流程示例
|
||||
|
||||
1. 启动Django服务器:`python manage.py runserver`
|
||||
2. 在Apifox中发送请求"获取搜索会话列表"
|
||||
3. 在响应中选择一个会话ID
|
||||
4. 使用该ID获取会话详情
|
||||
5. 使用"搜索创作者"接口创建新的搜索会话
|
||||
6. 验证新创建的会话是否出现在会话列表中
|
||||
|
||||
## 在Apifox中导入API
|
||||
|
||||
1. 在Apifox中,点击"导入"按钮
|
||||
2. 选择"导入API"
|
||||
3. 将本文档中的API信息整理成集合导入
|
||||
4. 设置每个接口的请求和响应格式
|
||||
5. 设置示例响应
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 所有API响应均遵循统一的格式:`code`、`message`和`data`
|
||||
- 分页接口返回格式为:`{ "code": 200, "message": "获取数据成功", "data": { "count": 总数, "next": 下一页URL, "previous": 上一页URL, "results": [] } }`
|
||||
- 即使发生错误,HTTP状态码始终为200,错误信息在响应体的`code`和`message`中提供
|
||||
- 接口不需要认证,可直接访问
|
@ -1,48 +1,24 @@
|
||||
# Discovery 模块 API 文档
|
||||
# Discovery模块API文档
|
||||
|
||||
本文档详细说明了 Discovery 模块的 API 接口,包括请求方法、URL、参数说明和响应格式。
|
||||
## 概述
|
||||
|
||||
## 目录
|
||||
Discovery (发现) 模块是一个用于搜索和发现创作者/达人的系统。该模块提供了一系列RESTful API接口,用于创建搜索会话、搜索创作者和查询历史搜索结果。
|
||||
|
||||
1. [通用说明](#通用说明)
|
||||
2. [创作者搜索会话接口](#创作者搜索会话接口)
|
||||
3. [创作者发现接口](#创作者发现接口)
|
||||
## 通用响应格式
|
||||
|
||||
## 通用说明
|
||||
|
||||
### 基础URL
|
||||
|
||||
所有 API 的基础 URL 为:`http://127.0.0.1:8000/api/discovery/`
|
||||
|
||||
### 认证方式
|
||||
|
||||
所有 API 都需要 Token 认证。请在请求头中添加:
|
||||
|
||||
```
|
||||
Authorization: Token <your_token>
|
||||
```
|
||||
|
||||
### 响应格式
|
||||
|
||||
所有 API 返回的数据格式统一为:
|
||||
所有API响应都遵循以下统一的JSON格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200, // 状态码,200表示成功,其他表示错误
|
||||
"message": "成功", // 状态描述
|
||||
"data": {} // 返回的数据,可能是对象、数组或null
|
||||
"code": 200, // 状态码,200表示成功,其他值表示错误
|
||||
"message": "成功", // 响应消息
|
||||
"data": {} // 响应数据,可能是对象、数组或null
|
||||
}
|
||||
```
|
||||
|
||||
### 分页
|
||||
## 分页响应格式
|
||||
|
||||
列表接口支持分页,默认每页 20 条数据,最大每页 100 条。
|
||||
|
||||
分页参数:
|
||||
- `page`: 页码,从1开始
|
||||
- `page_size`: 每页数量,默认20
|
||||
|
||||
分页响应格式:
|
||||
使用分页的接口将返回以下格式:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -50,134 +26,168 @@ Authorization: Token <your_token>
|
||||
"message": "获取数据成功",
|
||||
"data": {
|
||||
"count": 100, // 总记录数
|
||||
"next": "下一页URL", // 下一页链接,如果没有则为null
|
||||
"previous": "上一页URL", // 上一页链接,如果没有则为null
|
||||
"results": [] // 当前页数据
|
||||
"next": "下一页URL或null", // 下一页链接
|
||||
"previous": "上一页URL或null", // 上一页链接
|
||||
"results": [] // 当前页的数据
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 创作者搜索会话接口
|
||||
## 认证方式
|
||||
|
||||
搜索会话是指用户进行的一次创作者搜索,包含搜索结果和相关统计信息。
|
||||
所有接口都需要使用自定义Token认证,请在HTTP请求头中添加以下字段:
|
||||
|
||||
### 获取搜索会话列表
|
||||
```
|
||||
Authorization: Token your_token_here
|
||||
```
|
||||
|
||||
## 1. 搜索会话管理 (Sessions)
|
||||
|
||||
搜索会话保存了搜索历史记录和搜索结果,便于追踪和回顾之前的搜索。
|
||||
|
||||
### 1.1 获取搜索会话列表
|
||||
|
||||
- **URL**: `/sessions/`
|
||||
- **方法**: GET
|
||||
- **方法**: `GET`
|
||||
- **描述**: 获取所有搜索会话的列表
|
||||
- **参数**:
|
||||
- 分页参数,参见[分页](#分页)部分
|
||||
- **响应示例**:
|
||||
- **请求参数**:
|
||||
- `page`: 页码,默认为1
|
||||
- `page_size`: 每页记录数,默认为20,最大为100
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取搜索会话列表成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"session_number": 123,
|
||||
"creator_count": 100,
|
||||
"shoppable_creators": 26,
|
||||
"avg_followers": 162.2,
|
||||
"avg_gmv": 534.1,
|
||||
"avg_video_views": 1.9,
|
||||
"date_created": "2023-01-01"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 获取搜索会话详情
|
||||
|
||||
- **URL**: `/sessions/{session_id}/`
|
||||
- **方法**: GET
|
||||
- **描述**: 获取指定ID的搜索会话详细信息,包含搜索到的创作者列表
|
||||
- **参数**:
|
||||
- `session_id`: 会话ID (路径参数)
|
||||
- **响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取搜索会话详情成功",
|
||||
"data": {
|
||||
"count": 10,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": 1,
|
||||
"session_number": 123,
|
||||
"creator_count": 100,
|
||||
"shoppable_creators": 26,
|
||||
"avg_followers": 162.2,
|
||||
"avg_gmv": 534.1,
|
||||
"avg_video_views": 1.9,
|
||||
"date_created": "2023-01-01",
|
||||
"creators": [
|
||||
// 创作者列表,见创作者数据结构
|
||||
"session_number": 1,
|
||||
"creator_count": 20,
|
||||
"shoppable_creators": 15,
|
||||
"avg_followers": 10000.5,
|
||||
"avg_gmv": 5000.25,
|
||||
"avg_video_views": 20000.75,
|
||||
"date_created": "2023-06-01"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 创建搜索会话
|
||||
### 1.2 创建搜索会话
|
||||
|
||||
- **URL**: `/sessions/`
|
||||
- **方法**: POST
|
||||
- **描述**: 创建新的搜索会话
|
||||
- **方法**: `POST`
|
||||
- **描述**: 创建一个新的搜索会话
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"session_number": 123,
|
||||
"creator_count": 100,
|
||||
"shoppable_creators": 26,
|
||||
"avg_followers": 162.2,
|
||||
"avg_gmv": 534.1,
|
||||
"avg_video_views": 1.9,
|
||||
"date_created": "2023-01-01"
|
||||
"session_number": 1, // 可选,默认为1
|
||||
"creator_count": 0, // 可选,默认为0
|
||||
"shoppable_creators": 0, // 可选,默认为0
|
||||
"avg_followers": 0, // 可选,默认为0
|
||||
"avg_gmv": 0, // 可选,默认为0
|
||||
"avg_video_views": 0, // 可选,默认为0
|
||||
"date_created": "2023-06-01" // 可选,默认为当前日期
|
||||
}
|
||||
```
|
||||
- **响应示例**:
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "创建搜索会话成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"session_number": 123,
|
||||
"creator_count": 100,
|
||||
"shoppable_creators": 26,
|
||||
"avg_followers": 162.2,
|
||||
"avg_gmv": 534.1,
|
||||
"avg_video_views": 1.9,
|
||||
"date_created": "2023-01-01"
|
||||
"session_number": 1,
|
||||
"creator_count": 0,
|
||||
"shoppable_creators": 0,
|
||||
"avg_followers": 0,
|
||||
"avg_gmv": 0,
|
||||
"avg_video_views": 0,
|
||||
"date_created": "2023-06-01"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 更新搜索会话
|
||||
### 1.3 获取搜索会话详情
|
||||
|
||||
- **URL**: `/sessions/{session_id}/`
|
||||
- **方法**: PUT/PATCH
|
||||
- **描述**: 更新搜索会话信息
|
||||
- **参数**:
|
||||
- `session_id`: 会话ID (路径参数)
|
||||
- 请求体包含要更新的字段
|
||||
- **响应示例**:
|
||||
- **URL**: `/sessions/{id}/`
|
||||
- **方法**: `GET`
|
||||
- **描述**: 获取指定ID的搜索会话详情,包含相关的创作者数据
|
||||
- **请求参数**: 无
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取搜索会话详情成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"session_number": 1,
|
||||
"creator_count": 20,
|
||||
"shoppable_creators": 15,
|
||||
"avg_followers": 10000.5,
|
||||
"avg_gmv": 5000.25,
|
||||
"avg_video_views": 20000.75,
|
||||
"date_created": "2023-06-01",
|
||||
"creators": [
|
||||
{
|
||||
"id": 1,
|
||||
"session": 1,
|
||||
"name": "创作者名称",
|
||||
"avatar": "https://example.com/avatar.jpg",
|
||||
"category": "Sports & Outdoor",
|
||||
"ecommerce_level": "L3",
|
||||
"exposure_level": "KOL-2",
|
||||
"followers": 15000,
|
||||
"gmv": 8000,
|
||||
"items_sold": 500,
|
||||
"avg_video_views": 25000,
|
||||
"has_ecommerce": true,
|
||||
"tiktok_url": "https://tiktok.com/@username",
|
||||
"hashtags": "#sport#fitness#outdoor",
|
||||
"trends": "summer fitness",
|
||||
"profile": "tiktok"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 1.4 更新搜索会话
|
||||
|
||||
- **URL**: `/sessions/{id}/`
|
||||
- **方法**: `PUT`/`PATCH`
|
||||
- **描述**: 更新指定ID的搜索会话信息
|
||||
- **请求参数**: 同创建搜索会话
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "更新搜索会话成功",
|
||||
"data": {
|
||||
// 更新后的会话信息
|
||||
"id": 1,
|
||||
"session_number": 2,
|
||||
"creator_count": 25,
|
||||
"shoppable_creators": 18,
|
||||
"avg_followers": 12000.5,
|
||||
"avg_gmv": 6000.25,
|
||||
"avg_video_views": 22000.75,
|
||||
"date_created": "2023-06-01"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 删除搜索会话
|
||||
### 1.5 删除搜索会话
|
||||
|
||||
- **URL**: `/sessions/{session_id}/`
|
||||
- **方法**: DELETE
|
||||
- **描述**: 删除搜索会话
|
||||
- **参数**:
|
||||
- `session_id`: 会话ID (路径参数)
|
||||
- **响应示例**:
|
||||
- **URL**: `/sessions/{id}/`
|
||||
- **方法**: `DELETE`
|
||||
- **描述**: 删除指定ID的搜索会话
|
||||
- **请求参数**: 无
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
@ -186,186 +196,374 @@ Authorization: Token <your_token>
|
||||
}
|
||||
```
|
||||
|
||||
### 获取会话创作者列表
|
||||
### 1.6 获取会话创作者列表
|
||||
|
||||
- **URL**: `/sessions/{session_id}/results/`
|
||||
- **方法**: GET
|
||||
- **URL**: `/sessions/{id}/results/`
|
||||
- **方法**: `GET`
|
||||
- **描述**: 获取指定会话的搜索结果(创作者列表)
|
||||
- **参数**:
|
||||
- `session_id`: 会话ID (路径参数)
|
||||
- 分页参数,参见[分页](#分页)部分
|
||||
- **响应示例**:
|
||||
- **请求参数**:
|
||||
- `page`: 页码,默认为1
|
||||
- `page_size`: 每页记录数,默认为20,最大为100
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取会话创作者列表成功",
|
||||
"data": {
|
||||
"count": 20,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": 1,
|
||||
"session": 1,
|
||||
"name": "创作者名称",
|
||||
"avatar": "https://example.com/avatar.jpg",
|
||||
"category": "Sports & Outdoor",
|
||||
"ecommerce_level": "L3",
|
||||
"exposure_level": "KOL-2",
|
||||
"followers": 15000,
|
||||
"gmv": 8000,
|
||||
"items_sold": 500,
|
||||
"avg_video_views": 25000,
|
||||
"has_ecommerce": true,
|
||||
"tiktok_url": "https://tiktok.com/@username",
|
||||
"hashtags": "#sport#fitness#outdoor",
|
||||
"trends": "summer fitness",
|
||||
"profile": "tiktok"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 1.7 获取会话摘要
|
||||
|
||||
- **URL**: `/sessions/summary/`
|
||||
- **方法**: `GET`
|
||||
- **描述**: 获取所有会话的摘要数据,用于展示在表格中
|
||||
- **请求参数**: 无
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取会话摘要列表成功",
|
||||
"data": [
|
||||
// 创作者列表,见创作者数据结构
|
||||
{
|
||||
"id": 1,
|
||||
"session_number": 1,
|
||||
"date": "2023-06-01",
|
||||
"creator_count": 20,
|
||||
"shoppable_creators": 15,
|
||||
"avg_followers": 10000.5,
|
||||
"avg_gmv": 5000.25,
|
||||
"avg_video_views": 20000.75
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 创作者发现接口
|
||||
## 2. 创作者管理 (Creators)
|
||||
|
||||
### 获取创作者列表
|
||||
创作者是系统中的核心数据实体,代表平台上的内容创作者/达人。
|
||||
|
||||
### 2.1 获取创作者列表
|
||||
|
||||
- **URL**: `/creators/`
|
||||
- **方法**: GET
|
||||
- **方法**: `GET`
|
||||
- **描述**: 获取所有创作者的列表
|
||||
- **参数**:
|
||||
- 分页参数,参见[分页](#分页)部分
|
||||
- **响应示例**:
|
||||
- **请求参数**:
|
||||
- `page`: 页码,默认为1
|
||||
- `page_size`: 每页记录数,默认为20,最大为100
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取创作者列表成功",
|
||||
"data": [
|
||||
"data": {
|
||||
"count": 100,
|
||||
"next": "http://example.com/api/creators/?page=2",
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": 1,
|
||||
"session": 1,
|
||||
"name": "创作者名称",
|
||||
"avatar": "头像URL",
|
||||
"category": "Phones & Electronics",
|
||||
"ecommerce_level": "L2",
|
||||
"exposure_level": "KOC-1",
|
||||
"followers": 162.2,
|
||||
"gmv": 534.1,
|
||||
"items_sold": 18.1,
|
||||
"avg_video_views": 1.9,
|
||||
"avatar": "https://example.com/avatar.jpg",
|
||||
"category": "Sports & Outdoor",
|
||||
"ecommerce_level": "L3",
|
||||
"exposure_level": "KOL-2",
|
||||
"followers": 15000,
|
||||
"gmv": 8000,
|
||||
"items_sold": 500,
|
||||
"avg_video_views": 25000,
|
||||
"has_ecommerce": true,
|
||||
"tiktok_url": "抖音链接",
|
||||
"session": 1
|
||||
"tiktok_url": "https://tiktok.com/@username",
|
||||
"hashtags": "#sport#fitness#outdoor",
|
||||
"trends": "summer fitness",
|
||||
"profile": "tiktok"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 获取创作者详情
|
||||
### 2.2 获取创作者详情
|
||||
|
||||
- **URL**: `/creators/{creator_id}/`
|
||||
- **方法**: GET
|
||||
- **URL**: `/creators/{id}/`
|
||||
- **方法**: `GET`
|
||||
- **描述**: 获取指定ID的创作者详细信息
|
||||
- **参数**:
|
||||
- `creator_id`: 创作者ID (路径参数)
|
||||
- **响应示例**:
|
||||
- **请求参数**: 无
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取创作者详情成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"session": 1,
|
||||
"name": "创作者名称",
|
||||
"avatar": "头像URL",
|
||||
"category": "Phones & Electronics",
|
||||
"ecommerce_level": "L2",
|
||||
"exposure_level": "KOC-1",
|
||||
"followers": 162.2,
|
||||
"gmv": 534.1,
|
||||
"items_sold": 18.1,
|
||||
"avg_video_views": 1.9,
|
||||
"avatar": "https://example.com/avatar.jpg",
|
||||
"category": "Sports & Outdoor",
|
||||
"ecommerce_level": "L3",
|
||||
"exposure_level": "KOL-2",
|
||||
"followers": 15000,
|
||||
"gmv": 8000,
|
||||
"items_sold": 500,
|
||||
"avg_video_views": 25000,
|
||||
"has_ecommerce": true,
|
||||
"tiktok_url": "抖音链接",
|
||||
"session": 1
|
||||
"tiktok_url": "https://tiktok.com/@username",
|
||||
"hashtags": "#sport#fitness#outdoor",
|
||||
"trends": "summer fitness",
|
||||
"profile": "tiktok"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 搜索创作者
|
||||
### 2.3 搜索创作者
|
||||
|
||||
- **URL**: `/creators/search/`
|
||||
- **方法**: POST
|
||||
- **描述**: 根据条件搜索创作者并创建新的搜索会话
|
||||
- **方法**: `POST`
|
||||
- **描述**: 根据多种条件搜索创作者,会自动创建搜索会话并保存搜索结果
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"query": "搜索关键词",
|
||||
"category": "Phones & Electronics", // 可选,见类别列表
|
||||
"ecommerce_level": "L2", // 可选,见电商等级列表
|
||||
"exposure_level": "KOC-1" // 可选,见曝光等级列表
|
||||
"query": "运动", // 可选,搜索关键词
|
||||
"category": "Sports & Outdoor", // 可选,类别
|
||||
"ecommerce_level": "L3", // 可选,电商等级(L1-L5)
|
||||
"exposure_level": "KOL-2", // 可选,曝光等级
|
||||
"hashtag": "fitness", // 可选,标签
|
||||
"trend": "summer", // 可选,趋势
|
||||
"profile": "tiktok" // 可选,平台(tiktok、instagram等)
|
||||
}
|
||||
```
|
||||
- **响应示例**:
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "搜索创作者成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"session_number": 123,
|
||||
"session_number": 1,
|
||||
"creator_count": 5,
|
||||
"shoppable_creators": 3,
|
||||
"avg_followers": 162.2,
|
||||
"avg_gmv": 534.1,
|
||||
"avg_video_views": 1.9,
|
||||
"date_created": "2023-01-01",
|
||||
"avg_followers": 12000.5,
|
||||
"avg_gmv": 5500.25,
|
||||
"avg_video_views": 20500.75,
|
||||
"date_created": "2023-06-01",
|
||||
"creators": [
|
||||
// 创作者列表,见创作者数据结构
|
||||
{
|
||||
"id": 1,
|
||||
"session": 1,
|
||||
"name": "创作者名称",
|
||||
"avatar": "https://example.com/avatar.jpg",
|
||||
"category": "Sports & Outdoor",
|
||||
"ecommerce_level": "L3",
|
||||
"exposure_level": "KOL-2",
|
||||
"followers": 15000,
|
||||
"gmv": 8000,
|
||||
"items_sold": 500,
|
||||
"avg_video_views": 25000,
|
||||
"has_ecommerce": true,
|
||||
"tiktok_url": "https://tiktok.com/@username",
|
||||
"hashtags": "#sport#fitness#outdoor",
|
||||
"trends": "summer fitness",
|
||||
"profile": "tiktok"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 数据结构
|
||||
### 2.4 搜索标签和趋势
|
||||
|
||||
### 创作者类别
|
||||
|
||||
- `Phones & Electronics`: 手机与电子产品
|
||||
- `Womenswear & Underwear`: 女装与内衣
|
||||
- `Sports & Outdoor`: 运动与户外
|
||||
- `Food & Beverage`: 食品与饮料
|
||||
- `Health`: 健康
|
||||
- `Kitchenware`: 厨具
|
||||
- `Furniture`: 家具
|
||||
- `Shoes`: 鞋类
|
||||
- `Home Supplies`: 家居用品
|
||||
|
||||
### 电商等级
|
||||
|
||||
- `L1`: Level 1
|
||||
- `L2`: Level 2
|
||||
- `L3`: Level 3
|
||||
- `L4`: Level 4
|
||||
- `L5`: Level 5
|
||||
- `New tag`: 新标签
|
||||
|
||||
### 曝光等级
|
||||
|
||||
- `KOC-1`: Key Opinion Consumer 1级
|
||||
- `KOC-2`: Key Opinion Consumer 2级
|
||||
- `KOL-2`: Key Opinion Leader 2级
|
||||
- `KOL-3`: Key Opinion Leader 3级
|
||||
- `New tag`: 新标签
|
||||
|
||||
### 创作者数据结构
|
||||
|
||||
```json
|
||||
{
|
||||
- **URL**: `/creators/search_tags/`
|
||||
- **方法**: `POST`
|
||||
- **描述**: 专门用于搜索标签和趋势,会创建搜索会话并保存搜索结果
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"mode": "hashtag", // 必填,搜索模式,"hashtag"或"trend"
|
||||
"keyword": "fitness", // 必填,搜索关键词
|
||||
"profile": "tiktok" // 可选,平台
|
||||
}
|
||||
```
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "搜索hashtag成功,关键词: fitness",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"session_number": 1,
|
||||
"creator_count": 8,
|
||||
"shoppable_creators": 5,
|
||||
"avg_followers": 13000.5,
|
||||
"avg_gmv": 6500.25,
|
||||
"avg_video_views": 22500.75,
|
||||
"date_created": "2023-06-01",
|
||||
"creators": [
|
||||
{
|
||||
"id": 1,
|
||||
"session": 1,
|
||||
"name": "创作者名称",
|
||||
"avatar": "头像URL",
|
||||
"category": "Phones & Electronics",
|
||||
"ecommerce_level": "L2",
|
||||
"exposure_level": "KOC-1",
|
||||
"followers": 162.2, // 单位:K (千)
|
||||
"gmv": 534.1, // 单位:K (千)
|
||||
"items_sold": 18.1, // 单位:K (千)
|
||||
"avg_video_views": 1.9, // 单位:M (百万)
|
||||
"has_ecommerce": true, // 是否有电商能力
|
||||
"tiktok_url": "抖音链接",
|
||||
"session": 1 // 所属搜索会话ID
|
||||
}
|
||||
```
|
||||
"avatar": "https://example.com/avatar.jpg",
|
||||
"category": "Sports & Outdoor",
|
||||
"ecommerce_level": "L3",
|
||||
"exposure_level": "KOL-2",
|
||||
"followers": 15000,
|
||||
"gmv": 8000,
|
||||
"items_sold": 500,
|
||||
"avg_video_views": 25000,
|
||||
"has_ecommerce": true,
|
||||
"tiktok_url": "https://tiktok.com/@username",
|
||||
"hashtags": "#sport#fitness#outdoor",
|
||||
"trends": "summer fitness",
|
||||
"profile": "tiktok"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 搜索会话数据结构
|
||||
### 2.5 自然语言搜索创作者
|
||||
|
||||
```json
|
||||
{
|
||||
- **URL**: `/creators/search_individual/`
|
||||
- **方法**: `POST`
|
||||
- **描述**: 根据用户输入的自然语言文本搜索达人,使用外部API进行处理
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"criteria": "我需要粉丝超过10万的健身类达人,擅长做运动装备测评", // 必填,搜索条件
|
||||
"top_n": 10 // 可选,返回结果数量,默认10
|
||||
}
|
||||
```
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "搜索创作者成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"session_number": 123, // 会话编号
|
||||
"creator_count": 100, // 创作者数量
|
||||
"shoppable_creators": 26, // 可购物创作者数量
|
||||
"avg_followers": 162.2, // 平均粉丝数 (K)
|
||||
"avg_gmv": 534.1, // 平均GMV (K)
|
||||
"avg_video_views": 1.9, // 平均视频观看量 (M)
|
||||
"date_created": "2023-01-01" // 创建日期
|
||||
"session_number": 1,
|
||||
"creator_count": 10,
|
||||
"shoppable_creators": 7,
|
||||
"avg_followers": 150000.5,
|
||||
"avg_gmv": 9500.25,
|
||||
"avg_video_views": 35000.75,
|
||||
"date_created": "2023-06-01",
|
||||
"creators": [
|
||||
{
|
||||
"id": 1,
|
||||
"session": 1,
|
||||
"name": "创作者名称",
|
||||
"avatar": "https://example.com/avatar.jpg",
|
||||
"category": "Sports & Outdoor",
|
||||
"ecommerce_level": "L4",
|
||||
"exposure_level": "KOL-2",
|
||||
"followers": 180000,
|
||||
"gmv": 12000,
|
||||
"items_sold": 800,
|
||||
"avg_video_views": 45000,
|
||||
"has_ecommerce": true,
|
||||
"tiktok_url": "https://tiktok.com/@username",
|
||||
"hashtags": "#sport#fitness#outdoor#review",
|
||||
"trends": "fitness equipment review",
|
||||
"profile": "tiktok"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 3. 字段说明
|
||||
|
||||
### 3.1 搜索会话字段
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|------------------|---------|------------------------------|
|
||||
| id | 整数 | 会话ID |
|
||||
| session_number | 整数 | 会话编号 |
|
||||
| creator_count | 整数 | 创作者数量 |
|
||||
| shoppable_creators | 整数 | 可购物创作者数量 |
|
||||
| avg_followers | 浮点数 | 平均粉丝数 |
|
||||
| avg_gmv | 浮点数 | 平均GMV(商品总价值) |
|
||||
| avg_video_views | 浮点数 | 平均视频观看量 |
|
||||
| date_created | 日期 | 创建日期 |
|
||||
|
||||
### 3.2 创作者字段
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|------------------|---------|------------------------------|
|
||||
| id | 整数 | 创作者ID |
|
||||
| session | 整数 | 所属会话ID |
|
||||
| name | 字符串 | 创作者名称 |
|
||||
| avatar | URL | 头像链接 |
|
||||
| category | 字符串 | 类别,可选值:Phones & Electronics, Womenswear & Underwear等 |
|
||||
| ecommerce_level | 字符串 | 电商等级,可选值:L1, L2, L3, L4, L5, New tag |
|
||||
| exposure_level | 字符串 | 曝光等级,可选值:KOC-1, KOC-2, KOL-2, KOL-3, New tag |
|
||||
| followers | 浮点数 | 粉丝数 |
|
||||
| gmv | 浮点数 | GMV(商品总价值) |
|
||||
| items_sold | 浮点数 | 已售项目数 |
|
||||
| avg_video_views | 浮点数 | 平均视频观看量 |
|
||||
| has_ecommerce | 布尔值 | 是否有电商 |
|
||||
| tiktok_url | URL | 抖音链接 |
|
||||
| hashtags | 字符串 | 标签,格式如"#sport#fitness" |
|
||||
| trends | 字符串 | 趋势,格式如"summer fitness" |
|
||||
| profile | 字符串 | 达人平台,可选值:tiktok, instagram, youtube, xiaohongshu, other |
|
||||
|
||||
## 4. 使用示例
|
||||
|
||||
### 4.1 搜索标签为"fitness"的TikTok创作者
|
||||
|
||||
```http
|
||||
POST /api/creators/search_tags/
|
||||
Content-Type: application/json
|
||||
Authorization: Token your_token_here
|
||||
|
||||
{
|
||||
"mode": "hashtag",
|
||||
"keyword": "fitness",
|
||||
"profile": "tiktok"
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 获取最近一次搜索会话的详情
|
||||
|
||||
```http
|
||||
GET /api/sessions/1/
|
||||
Authorization: Token your_token_here
|
||||
```
|
||||
|
||||
### 4.3 使用自然语言搜索创作者
|
||||
|
||||
```http
|
||||
POST /api/creators/search_individual/
|
||||
Content-Type: application/json
|
||||
Authorization: Token your_token_here
|
||||
|
||||
{
|
||||
"criteria": "需要3个粉丝超过50万的美妆达人,产品转化率高",
|
||||
"top_n": 3
|
||||
}
|
||||
```
|
||||
|
475
apps/template/template.md
Normal file
475
apps/template/template.md
Normal file
@ -0,0 +1,475 @@
|
||||
# Template模块API文档
|
||||
|
||||
## 概述
|
||||
|
||||
Template (模板) 模块用于管理各种模板内容,支持按任务类型、平台、合作模式和服务类型等分类管理模板。主要包括模板分类和模板两大类接口。
|
||||
|
||||
## 通用响应格式
|
||||
|
||||
所有API响应都遵循以下统一的JSON格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200, // 状态码,200表示成功,其他值表示错误
|
||||
"message": "成功", // 响应消息
|
||||
"data": {} // 响应数据,可能是对象、数组或null
|
||||
}
|
||||
```
|
||||
|
||||
## 分页响应格式
|
||||
|
||||
使用分页的接口将返回以下格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取数据成功",
|
||||
"data": {
|
||||
"count": 100, // 总记录数
|
||||
"next": "下一页URL或null", // 下一页链接
|
||||
"previous": "上一页URL或null", // 上一页链接
|
||||
"results": [], // 当前页的数据
|
||||
"total_pages": 10, // 总页数
|
||||
"current_page": 1 // 当前页码
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 认证方式
|
||||
|
||||
所有接口都需要使用自定义Token认证,请在HTTP请求头中添加以下字段:
|
||||
|
||||
```
|
||||
Authorization: Token your_token_here
|
||||
```
|
||||
|
||||
## 1. 模板分类管理 (Template Categories)
|
||||
|
||||
模板分类用于对模板进行分类和归类,便于管理和检索。
|
||||
|
||||
### 1.1 获取模板分类列表
|
||||
|
||||
- **URL**: `/categories/`
|
||||
- **方法**: `GET`
|
||||
- **描述**: 获取所有模板分类的列表
|
||||
- **请求参数**:
|
||||
- `page`: 页码,默认为1
|
||||
- `page_size`: 每页记录数,默认为10,最大为100
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取模板分类列表成功",
|
||||
"data": {
|
||||
"count": 5,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "营销模板",
|
||||
"description": "用于营销推广的模板集合",
|
||||
"created_at": "2023-06-01T10:00:00Z",
|
||||
"updated_at": "2023-06-01T10:00:00Z"
|
||||
}
|
||||
],
|
||||
"total_pages": 1,
|
||||
"current_page": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 1.2 创建模板分类
|
||||
|
||||
- **URL**: `/categories/`
|
||||
- **方法**: `POST`
|
||||
- **描述**: 创建一个新的模板分类
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"name": "营销模板", // 必填,分类名称
|
||||
"description": "用于营销推广的模板集合" // 可选,分类描述
|
||||
}
|
||||
```
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 201,
|
||||
"message": "模板分类创建成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"name": "营销模板",
|
||||
"description": "用于营销推广的模板集合",
|
||||
"created_at": "2023-06-01T10:00:00Z",
|
||||
"updated_at": "2023-06-01T10:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 1.3 获取模板分类详情
|
||||
|
||||
- **URL**: `/categories/{id}/`
|
||||
- **方法**: `GET`
|
||||
- **描述**: 获取指定ID的模板分类详情
|
||||
- **请求参数**: 无
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取模板分类详情成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"name": "营销模板",
|
||||
"description": "用于营销推广的模板集合",
|
||||
"created_at": "2023-06-01T10:00:00Z",
|
||||
"updated_at": "2023-06-01T10:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 1.4 更新模板分类
|
||||
|
||||
- **URL**: `/categories/{id}/`
|
||||
- **方法**: `PUT`/`PATCH`
|
||||
- **描述**: 更新指定ID的模板分类信息
|
||||
- **请求参数**: 同创建模板分类
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "模板分类更新成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"name": "更新后的营销模板",
|
||||
"description": "这是更新后的描述",
|
||||
"created_at": "2023-06-01T10:00:00Z",
|
||||
"updated_at": "2023-06-02T10:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 1.5 删除模板分类
|
||||
|
||||
- **URL**: `/categories/{id}/`
|
||||
- **方法**: `DELETE`
|
||||
- **描述**: 删除指定ID的模板分类
|
||||
- **请求参数**: 无
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "模板分类删除成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
## 2. 模板管理 (Templates)
|
||||
|
||||
模板是系统中的核心内容,可以按各种条件进行分类和检索。
|
||||
|
||||
### 2.1 获取模板列表
|
||||
|
||||
- **URL**: `/`
|
||||
- **方法**: `GET`
|
||||
- **描述**: 获取所有模板的列表,支持多种过滤和排序
|
||||
- **请求参数**:
|
||||
- `page`: 页码,默认为1
|
||||
- `page_size`: 每页记录数,默认为10,最大为100
|
||||
- `title`: 按标题模糊搜索
|
||||
- `content`: 按内容模糊搜索
|
||||
- `mission`: 按任务类型筛选,可选值:initial_contact, follow_up, negotiation, closing, other
|
||||
- `platform`: 按平台筛选,可选值:tiktok, instagram, youtube, facebook, twitter, other
|
||||
- `collaboration_type`: 按合作模式筛选,可选值:paid_promotion, affiliate, sponsored_content, brand_ambassador, other
|
||||
- `service`: 按服务类型筛选,可选值:voice, text, video, image, other
|
||||
- `category`: 按分类ID筛选
|
||||
- `category_name`: 按分类名称模糊搜索
|
||||
- `is_public`: 按是否公开筛选,true或false
|
||||
- `created_after`: 按创建时间筛选,格式:YYYY-MM-DDThh:mm:ssZ
|
||||
- `created_before`: 按创建时间筛选,格式:YYYY-MM-DDThh:mm:ssZ
|
||||
- `ordering`: 排序字段,可选值:created_at, -created_at, updated_at, -updated_at, title, -title
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取模板列表成功",
|
||||
"data": {
|
||||
"count": 20,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": 1,
|
||||
"title": "TikTok初次合作邀请",
|
||||
"preview": "亲爱的[创作者名称],我们是[品牌名称],我们注意到您的内容非常精彩,希望能与您合作...",
|
||||
"category_name": "营销模板",
|
||||
"mission": "initial_contact",
|
||||
"mission_display": "初步联系",
|
||||
"platform": "tiktok",
|
||||
"platform_display": "TikTok",
|
||||
"service": "text",
|
||||
"service_display": "文本",
|
||||
"collaboration_type": "paid_promotion",
|
||||
"collaboration_type_display": "付费推广",
|
||||
"is_public": true,
|
||||
"created_at": "2023-06-01T10:00:00Z",
|
||||
"updated_at": "2023-06-01T10:00:00Z"
|
||||
}
|
||||
],
|
||||
"total_pages": 2,
|
||||
"current_page": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 创建模板
|
||||
|
||||
- **URL**: `/`
|
||||
- **方法**: `POST`
|
||||
- **描述**: 创建一个新的模板
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"title": "TikTok初次合作邀请", // 必填,模板标题
|
||||
"content": "亲爱的[创作者名称],我们是[品牌名称],我们注意到您的内容非常精彩,希望能与您合作...", // 必填,模板内容
|
||||
"category": 1, // 必填,模板分类ID
|
||||
"mission": "initial_contact", // 可选,任务类型,默认为initial_contact
|
||||
"platform": "tiktok", // 可选,平台,默认为tiktok
|
||||
"collaboration_type": "paid_promotion", // 可选,合作模式,默认为paid_promotion
|
||||
"service": "text", // 可选,服务类型,默认为text
|
||||
"is_public": true // 可选,是否公开,默认为true
|
||||
}
|
||||
```
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 201,
|
||||
"message": "模板创建成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"title": "TikTok初次合作邀请",
|
||||
"content": "亲爱的[创作者名称],我们是[品牌名称],我们注意到您的内容非常精彩,希望能与您合作...",
|
||||
"category": 1,
|
||||
"mission": "initial_contact",
|
||||
"platform": "tiktok",
|
||||
"service": "text",
|
||||
"collaboration_type": "paid_promotion",
|
||||
"is_public": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 获取模板详情
|
||||
|
||||
- **URL**: `/{id}/`
|
||||
- **方法**: `GET`
|
||||
- **描述**: 获取指定ID的模板详情
|
||||
- **请求参数**: 无
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取模板详情成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"title": "TikTok初次合作邀请",
|
||||
"content": "亲爱的[创作者名称],我们是[品牌名称],我们注意到您的内容非常精彩,希望能与您合作...",
|
||||
"preview": "亲爱的[创作者名称],我们是[品牌名称],我们注意到您的内容非常精彩,希望能与您合作...",
|
||||
"category": {
|
||||
"id": 1,
|
||||
"name": "营销模板",
|
||||
"description": "用于营销推广的模板集合",
|
||||
"created_at": "2023-06-01T10:00:00Z",
|
||||
"updated_at": "2023-06-01T10:00:00Z"
|
||||
},
|
||||
"mission": "initial_contact",
|
||||
"mission_display": "初步联系",
|
||||
"platform": "tiktok",
|
||||
"platform_display": "TikTok",
|
||||
"service": "text",
|
||||
"service_display": "文本",
|
||||
"collaboration_type": "paid_promotion",
|
||||
"collaboration_type_display": "付费推广",
|
||||
"is_public": true,
|
||||
"created_at": "2023-06-01T10:00:00Z",
|
||||
"updated_at": "2023-06-01T10:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.4 更新模板
|
||||
|
||||
- **URL**: `/{id}/`
|
||||
- **方法**: `PUT`/`PATCH`
|
||||
- **描述**: 更新指定ID的模板信息
|
||||
- **请求参数**: 同创建模板
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "模板更新成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"title": "更新后的TikTok合作邀请",
|
||||
"content": "更新后的内容...",
|
||||
"category": 1,
|
||||
"mission": "follow_up",
|
||||
"platform": "tiktok",
|
||||
"service": "text",
|
||||
"collaboration_type": "paid_promotion",
|
||||
"is_public": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.5 删除模板
|
||||
|
||||
- **URL**: `/{id}/`
|
||||
- **方法**: `DELETE`
|
||||
- **描述**: 删除指定ID的模板
|
||||
- **请求参数**: 无
|
||||
- **响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "模板删除成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
### 2.6 获取我的模板
|
||||
|
||||
- **URL**: `/mine/`
|
||||
- **方法**: `GET`
|
||||
- **描述**: 获取所有模板,实际上与获取模板列表功能相同
|
||||
- **请求参数**: 同获取模板列表
|
||||
- **响应数据**: 同获取模板列表
|
||||
|
||||
### 2.7 获取公开模板
|
||||
|
||||
- **URL**: `/public/`
|
||||
- **方法**: `GET`
|
||||
- **描述**: 获取所有公开的模板
|
||||
- **请求参数**: 同获取模板列表
|
||||
- **响应数据**: 同获取模板列表,但只返回is_public=true的模板
|
||||
|
||||
### 2.8 按任务类型获取模板
|
||||
|
||||
- **URL**: `/by_mission/`
|
||||
- **方法**: `GET`
|
||||
- **描述**: 按任务类型获取模板
|
||||
- **请求参数**:
|
||||
- `mission`: 必填,任务类型,可选值:initial_contact, follow_up, negotiation, closing, other
|
||||
- 其他参数同获取模板列表
|
||||
- **响应数据**: 同获取模板列表,但只返回指定任务类型的模板
|
||||
|
||||
### 2.9 按平台获取模板
|
||||
|
||||
- **URL**: `/by_platform/`
|
||||
- **方法**: `GET`
|
||||
- **描述**: 按平台获取模板
|
||||
- **请求参数**:
|
||||
- `platform`: 必填,平台,可选值:tiktok, instagram, youtube, facebook, twitter, other
|
||||
- 其他参数同获取模板列表
|
||||
- **响应数据**: 同获取模板列表,但只返回指定平台的模板
|
||||
|
||||
### 2.10 按合作模式获取模板
|
||||
|
||||
- **URL**: `/by_collaboration/`
|
||||
- **方法**: `GET`
|
||||
- **描述**: 按合作模式获取模板
|
||||
- **请求参数**:
|
||||
- `collaboration_type`: 必填,合作模式,可选值:paid_promotion, affiliate, sponsored_content, brand_ambassador, other
|
||||
- 其他参数同获取模板列表
|
||||
- **响应数据**: 同获取模板列表,但只返回指定合作模式的模板
|
||||
|
||||
### 2.11 按服务类型获取模板
|
||||
|
||||
- **URL**: `/by_service/`
|
||||
- **方法**: `GET`
|
||||
- **描述**: 按服务类型获取模板
|
||||
- **请求参数**:
|
||||
- `service`: 必填,服务类型,可选值:voice, text, video, image, other
|
||||
- 其他参数同获取模板列表
|
||||
- **响应数据**: 同获取模板列表,但只返回指定服务类型的模板
|
||||
|
||||
## 3. 模板字段说明
|
||||
|
||||
### 3.1 模板分类字段
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|-------------|-----------|-------------|
|
||||
| id | 整数 | 分类ID |
|
||||
| name | 字符串 | 分类名称 |
|
||||
| description | 字符串 | 分类描述 |
|
||||
| created_at | 日期时间 | 创建时间 |
|
||||
| updated_at | 日期时间 | 更新时间 |
|
||||
|
||||
### 3.2 模板字段
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|----------------------------|-----------|------------------------------|
|
||||
| id | 整数 | 模板ID |
|
||||
| title | 字符串 | 模板标题 |
|
||||
| content | 字符串 | 模板内容 |
|
||||
| preview | 字符串 | 内容预览,自动生成 |
|
||||
| category | 对象/整数 | 模板分类对象或ID |
|
||||
| category_name | 字符串 | 分类名称 |
|
||||
| mission | 字符串 | 任务类型代码 |
|
||||
| mission_display | 字符串 | 任务类型显示名称 |
|
||||
| platform | 字符串 | 平台代码 |
|
||||
| platform_display | 字符串 | 平台显示名称 |
|
||||
| service | 字符串 | 服务类型代码 |
|
||||
| service_display | 字符串 | 服务类型显示名称 |
|
||||
| collaboration_type | 字符串 | 合作模式代码 |
|
||||
| collaboration_type_display | 字符串 | 合作模式显示名称 |
|
||||
| is_public | 布尔值 | 是否公开 |
|
||||
| created_at | 日期时间 | 创建时间 |
|
||||
| updated_at | 日期时间 | 更新时间 |
|
||||
|
||||
## 4. 使用示例
|
||||
|
||||
### 4.1 创建一个新的模板分类
|
||||
|
||||
```http
|
||||
POST /api/categories/
|
||||
Content-Type: application/json
|
||||
Authorization: Token your_token_here
|
||||
|
||||
{
|
||||
"name": "电商推广模板",
|
||||
"description": "专门用于电商产品推广的各类模板"
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 创建一个新的TikTok初次联系模板
|
||||
|
||||
```http
|
||||
POST /api/
|
||||
Content-Type: application/json
|
||||
Authorization: Token your_token_here
|
||||
|
||||
{
|
||||
"title": "TikTok品牌合作初次邀请",
|
||||
"content": "亲爱的[创作者名称],\n\n我是[品牌名称]的[您的姓名]。我们非常欣赏您在TikTok上分享的[内容类型]内容,特别是您关于[具体内容]的视频,展现了很高的创意和专业性。\n\n我们希望能与您合作,进行一次付费推广活动。我们的产品是[产品描述],我们认为这与您的内容风格和受众非常匹配。\n\n如果您有兴趣,我们可以提供[报酬说明]的报酬,以及[其他福利]。希望能得到您的回复,进一步讨论合作细节。\n\n期待您的回复!\n\n谢谢,\n[您的姓名]\n[品牌名称]",
|
||||
"category": 1,
|
||||
"mission": "initial_contact",
|
||||
"platform": "tiktok",
|
||||
"collaboration_type": "paid_promotion",
|
||||
"service": "text",
|
||||
"is_public": true
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 查找所有TikTok平台的文本类模板
|
||||
|
||||
```http
|
||||
GET /api/?platform=tiktok&service=text
|
||||
Authorization: Token your_token_here
|
||||
```
|
||||
|
||||
### 4.4 按任务类型查询模板
|
||||
|
||||
```http
|
||||
GET /api/by_mission/?mission=follow_up
|
||||
Authorization: Token your_token_here
|
||||
```
|
@ -102,7 +102,7 @@ DATABASES = {
|
||||
'NAME': 'daren_detail',
|
||||
'USER': 'root',
|
||||
'PASSWORD': '123456',
|
||||
'HOST': 'localhost',
|
||||
'HOST': '192.168.31.138',
|
||||
'PORT': '3306',
|
||||
'OPTIONS': {
|
||||
'charset': 'utf8mb4',
|
||||
|
Loading…
Reference in New Issue
Block a user