diff --git a/apps/brands/brands.md b/apps/brands/brands.md index 4748e2e..35de6ed 100644 --- a/apps/brands/brands.md +++ b/apps/brands/brands.md @@ -1,169 +1,138 @@ -# Brands 模块 API 文档 +# 品牌模块API文档 -本文档详细说明了 Brands 模块的 API 接口,包括请求方法、URL、参数说明和响应格式。 +## 概述 -## 目录 +品牌模块是负责管理品牌、产品、活动以及品牌聊天会话的系统。该模块提供了一系列RESTful API接口,用于创建、查询、更新和删除品牌相关的资源。 -1. [通用说明](#通用说明) -2. [品牌相关接口](#品牌相关接口) -3. [产品相关接口](#产品相关接口) -4. [活动相关接口](#活动相关接口) -5. [WebSocket 接口](#websocket-接口) -6. [状态轮询管理](#状态轮询管理) +## 通用响应格式 -## 通用说明 - -### 基础URL - -所有 API 的基础 URL 为:`http://127.0.0.1:8000/api/` - -### 认证方式 - -除特殊说明外,所有 API 都需要 Token 认证。请在请求头中添加: - -``` -Authorization: Token -``` - -### 响应格式 - -所有 API 返回的数据格式统一为: +所有API响应都遵循以下统一的JSON格式: ```json { - "code": 200, // 状态码,200表示成功,其他表示错误 - "message": "成功", // 状态描述 - "data": {} // 返回的数据,可能是对象、数组或null + "code": 200, // 状态码,200表示成功,其他值表示错误 + "message": "成功", // 响应消息 + "data": {} // 响应数据,可能是对象、数组或null } ``` -## 品牌相关接口 +## 认证方式 -### 获取品牌列表 +所有接口都需要使用自定义Token认证,请在HTTP请求头中添加以下字段: + +``` +Authorization: Token your_token_here +``` + +## 1. 品牌管理 (Brands) + +### 1.1 获取品牌列表 - **URL**: `/brands/` -- **方法**: GET +- **方法**: `GET` - **描述**: 获取所有品牌的列表 -- **参数**: 无 -- **响应示例**: +- **请求参数**: 无 +- **响应数据**: ```json { "code": 200, "message": "成功", "data": [ { - "id": "uuid-string", + "id": "uuid字符串", "name": "品牌名称", "description": "品牌描述", "logo_url": "品牌Logo链接", "category": "品牌分类", "source": "来源", - "collab_count": 10, - "creators_count": 20, + "collab_count": 0, + "creators_count": 0, "campaign_id": "活动ID", - "total_gmv_achieved": "1000.00", - "total_views_achieved": "5000.00", - "shop_overall_rating": "4.5", - "dataset_id_list": ["id1", "id2"], - "created_at": "2023-01-01T00:00:00Z", - "updated_at": "2023-01-01T00:00:00Z", + "total_gmv_achieved": "0.00", + "total_views_achieved": "0.00", + "shop_overall_rating": "0.0", + "dataset_id_list": [], + "created_at": "创建时间", + "updated_at": "更新时间", "is_active": true } ] } ``` -### 获取单个品牌详情 +### 1.2 创建品牌 -- **URL**: `/brands/{brand_id}/` -- **方法**: GET -- **描述**: 获取指定ID的品牌详细信息 -- **参数**: - - `brand_id`: 品牌ID (路径参数) -- **响应示例**: +- **URL**: `/brands/` +- **方法**: `POST` +- **描述**: 创建一个新的品牌 +- **请求参数**: + ```json + { + "name": "品牌名称", // 必填,唯一 + "description": "品牌描述", // 可选 + "logo_url": "品牌Logo链接", // 可选 + "category": "品牌分类", // 可选 + "source": "来源", // 可选 + "collab_count": 0, // 可选,默认0 + "creators_count": 0, // 可选,默认0 + "campaign_id": "活动ID", // 可选 + "total_gmv_achieved": "0.00", // 可选,默认0 + "total_views_achieved": "0.00", // 可选,默认0 + "shop_overall_rating": "0.0", // 可选,默认0 + "is_active": true // 可选,默认true + } + ``` +- **响应数据**: 返回创建的品牌信息 + +### 1.3 获取品牌详情 + +- **URL**: `/brands/{id}/` +- **方法**: `GET` +- **描述**: 获取指定ID的品牌详细信息,包括关联的产品和活动 +- **请求参数**: 无 +- **响应数据**: ```json { "code": 200, "message": "成功", "data": { - "id": "uuid-string", + "id": "uuid字符串", "name": "品牌名称", "description": "品牌描述", "logo_url": "品牌Logo链接", "category": "品牌分类", "source": "来源", - "collab_count": 10, - "creators_count": 20, + "collab_count": 0, + "creators_count": 0, "campaign_id": "活动ID", - "total_gmv_achieved": "1000.00", - "total_views_achieved": "5000.00", - "shop_overall_rating": "4.5", - "dataset_id_list": ["id1", "id2"], - "created_at": "2023-01-01T00:00:00Z", - "updated_at": "2023-01-01T00:00:00Z", - "is_active": true, - "products": [...], // 品牌关联的产品列表 - "campaigns": [...] // 品牌关联的活动列表 + "total_gmv_achieved": "0.00", + "total_views_achieved": "0.00", + "shop_overall_rating": "0.0", + "dataset_id_list": [], + "products": [], + "campaigns": [], + "created_at": "创建时间", + "updated_at": "更新时间", + "is_active": true } } ``` -### 创建品牌 +### 1.4 更新品牌 -- **URL**: `/brands/` -- **方法**: POST -- **描述**: 创建新的品牌 -- **请求参数**: - ```json - { - "name": "品牌名称", // 必填 - "description": "品牌描述", - "logo_url": "品牌Logo链接", - "category": "品牌分类", - "source": "来源" - } - ``` -- **响应示例**: - ```json - { - "code": 200, - "message": "成功", - "data": { - "id": "uuid-string", - "name": "品牌名称", - "description": "品牌描述", - // ... 其他字段 - } - } - ``` +- **URL**: `/brands/{id}/` +- **方法**: `PUT`/`PATCH` +- **描述**: 更新指定ID的品牌信息 +- **请求参数**: 同创建品牌 +- **响应数据**: 返回更新后的品牌信息 -### 更新品牌 +### 1.5 删除品牌 -- **URL**: `/brands/{brand_id}/` -- **方法**: PUT/PATCH -- **描述**: 更新品牌信息 -- **参数**: - - `brand_id`: 品牌ID (路径参数) - - 请求体包含要更新的字段 -- **响应示例**: - ```json - { - "code": 200, - "message": "成功", - "data": { - // 更新后的品牌信息 - } - } - ``` - -### 删除品牌 - -- **URL**: `/brands/{brand_id}/` -- **方法**: DELETE -- **描述**: 删除品牌(软删除) -- **参数**: - - `brand_id`: 品牌ID (路径参数) -- **响应示例**: +- **URL**: `/brands/{id}/` +- **方法**: `DELETE` +- **描述**: 删除指定ID的品牌 +- **请求参数**: 无 +- **响应数据**: ```json { "code": 200, @@ -172,176 +141,136 @@ Authorization: Token } ``` -### 获取品牌产品列表 +### 1.6 获取品牌产品列表 -- **URL**: `/brands/{brand_id}/products/` -- **方法**: GET +- **URL**: `/brands/{id}/products/` +- **方法**: `GET` - **描述**: 获取指定品牌下的所有产品 -- **参数**: - - `brand_id`: 品牌ID (路径参数) -- **响应示例**: - ```json - { - "code": 200, - "message": "成功", - "data": [ - // 产品列表 - ] - } - ``` +- **请求参数**: 无 +- **响应数据**: 返回产品列表 -### 获取品牌活动列表 +### 1.7 获取品牌活动列表 -- **URL**: `/brands/{brand_id}/campaigns/` -- **方法**: GET +- **URL**: `/brands/{id}/campaigns/` +- **方法**: `GET` - **描述**: 获取指定品牌下的所有活动 -- **参数**: - - `brand_id`: 品牌ID (路径参数) -- **响应示例**: - ```json - { - "code": 200, - "message": "成功", - "data": [ - // 活动列表 - ] - } - ``` +- **请求参数**: 无 +- **响应数据**: 返回活动列表 -### 获取品牌知识库ID列表 +### 1.8 获取品牌知识库ID列表 -- **URL**: `/brands/{brand_id}/dataset_ids/` -- **方法**: GET -- **描述**: 获取指定品牌的所有知识库ID -- **参数**: - - `brand_id`: 品牌ID (路径参数) -- **响应示例**: +- **URL**: `/brands/{id}/dataset_ids/` +- **方法**: `GET` +- **描述**: 获取品牌的所有知识库ID +- **请求参数**: 无 +- **响应数据**: ```json { "code": 200, "message": "成功", "data": { - "dataset_id_list": ["id1", "id2", "id3"] + "dataset_id_list": [] } } ``` -## 产品相关接口 +## 2. 产品管理 (Products) -### 获取产品列表 +### 2.1 获取产品列表 - **URL**: `/products/` -- **方法**: GET -- **描述**: 获取所有产品列表 -- **参数**: 无 -- **响应示例**: +- **方法**: `GET` +- **描述**: 获取所有产品的列表 +- **请求参数**: 无 +- **响应数据**: ```json { "code": 200, "message": "成功", "data": [ { - "id": "uuid-string", + "id": "uuid字符串", "brand": "品牌ID", + "brand_name": "品牌名称", "name": "产品名称", "description": "产品描述", - "image_url": "产品图片", + "image_url": "产品图片链接", "pid": "产品ID", - "commission_rate": "10.00", - "open_collab": "5.00", - "available_samples": 10, - "sales_price_min": "50.00", - "sales_price_max": "100.00", - "stock": 100, - "items_sold": 50, - "product_rating": "4.5", - "reviews_count": 20, - "collab_creators": 5, + "commission_rate": "0.00", + "open_collab": "0.00", + "available_samples": 0, + "sales_price_min": "0.00", + "sales_price_max": "0.00", + "stock": 0, + "items_sold": 0, + "product_rating": "0.0", + "reviews_count": 0, + "collab_creators": 0, "tiktok_shop": false, "dataset_id": "知识库ID", "external_id": "外部ID", - "created_at": "2023-01-01T00:00:00Z", - "updated_at": "2023-01-01T00:00:00Z", + "created_at": "创建时间", + "updated_at": "更新时间", "is_active": true } ] } ``` -### 获取单个产品详情 - -- **URL**: `/products/{product_id}/` -- **方法**: GET -- **描述**: 获取指定ID的产品详情 -- **参数**: - - `product_id`: 产品ID (路径参数) -- **响应示例**: - ```json - { - "code": 200, - "message": "成功", - "data": { - // 产品详情 - } - } - ``` - -### 创建产品 +### 2.2 创建产品 - **URL**: `/products/` -- **方法**: POST -- **描述**: 创建新的产品 +- **方法**: `POST` +- **描述**: 创建一个新的产品,会自动更新关联品牌的dataset_id_list - **请求参数**: ```json { - "brand": "品牌ID", // 必填 - "name": "产品名称", // 必填 - "description": "产品描述", - "image_url": "产品图片", - "pid": "产品ID", - "commission_rate": 10.00, - "dataset_id": "知识库ID" // 必填 - // ... 其他字段 - } - ``` -- **响应示例**: - ```json - { - "code": 200, - "message": "成功", - "data": { - // 创建的产品信息 - } + "brand": "品牌ID", // 必填 + "name": "产品名称", // 必填 + "description": "产品描述", // 可选 + "image_url": "产品图片链接", // 可选 + "pid": "产品ID", // 可选 + "commission_rate": "0.00", // 可选 + "open_collab": "0.00", // 可选 + "available_samples": 0, // 可选 + "sales_price_min": "0.00", // 可选 + "sales_price_max": "0.00", // 可选 + "stock": 0, // 可选 + "items_sold": 0, // 可选 + "product_rating": "0.0", // 可选 + "reviews_count": 0, // 可选 + "collab_creators": 0, // 可选 + "tiktok_shop": false, // 可选 + "dataset_id": "知识库ID", // 必填 + "external_id": "外部ID", // 可选 + "is_active": true // 可选 } ``` +- **响应数据**: 返回创建的产品信息 -### 更新产品 +### 2.3 获取产品详情 -- **URL**: `/products/{product_id}/` -- **方法**: PUT/PATCH -- **描述**: 更新产品信息 -- **参数**: - - `product_id`: 产品ID (路径参数) - - 请求体包含要更新的字段 -- **响应示例**: - ```json - { - "code": 200, - "message": "成功", - "data": { - // 更新后的产品信息 - } - } - ``` +- **URL**: `/products/{id}/` +- **方法**: `GET` +- **描述**: 获取指定ID的产品详细信息 +- **请求参数**: 无 +- **响应数据**: 返回产品详情 -### 删除产品 +### 2.4 更新产品 -- **URL**: `/products/{product_id}/` -- **方法**: DELETE -- **描述**: 删除产品(软删除) -- **参数**: - - `product_id`: 产品ID (路径参数) -- **响应示例**: +- **URL**: `/products/{id}/` +- **方法**: `PUT`/`PATCH` +- **描述**: 更新指定ID的产品信息,会自动更新关联品牌的dataset_id_list +- **请求参数**: 同创建产品 +- **响应数据**: 返回更新后的产品信息 + +### 2.5 删除产品 + +- **URL**: `/products/{id}/` +- **方法**: `DELETE` +- **描述**: 软删除指定ID的产品,并从品牌的dataset_id_list中移除对应的ID +- **请求参数**: 无 +- **响应数据**: ```json { "code": 200, @@ -350,126 +279,104 @@ Authorization: Token } ``` -## 活动相关接口 +## 3. 活动管理 (Campaigns) -### 获取活动列表 +### 3.1 获取活动列表 - **URL**: `/campaigns/` -- **方法**: GET -- **描述**: 获取所有活动列表 -- **参数**: 无 -- **响应示例**: +- **方法**: `GET` +- **描述**: 获取所有活动的列表 +- **请求参数**: 无 +- **响应数据**: ```json { "code": 200, "message": "成功", "data": [ { - "id": "活动ID", + "id": "uuid字符串", "brand": "品牌ID", + "brand_name": "品牌名称", "name": "活动名称", "description": "活动描述", - "image_url": "活动图片", + "image_url": "活动图片链接", "service": "服务类型", "creator_type": "创作者类型", "creator_level": "创作者等级", "creator_category": "创作者分类", - "creators_count": 10, + "creators_count": 0, "gmv": "GMV范围", "followers": "粉丝数范围", "views": "浏览量范围", "budget": "预算范围", "link_product": ["产品ID1", "产品ID2"], - "start_date": "2023-01-01T00:00:00Z", - "end_date": "2023-02-01T00:00:00Z", + "link_product_details": [产品详情对象数组], + "start_date": "开始日期", + "end_date": "结束日期", "dataset_id": "知识库ID", "external_id": "外部ID", - "status": "待处理", // pending, accepted, rejected, completed, in_progress - "gmv_achieved": "实现GMV", - "views_achieved": "实现观看量", - "video_link": "视频链接", - "created_at": "2023-01-01T00:00:00Z", - "updated_at": "2023-01-01T00:00:00Z", + "created_at": "创建时间", + "updated_at": "更新时间", "is_active": true } ] } ``` -### 获取单个活动详情 - -- **URL**: `/campaigns/{campaign_id}/` -- **方法**: GET -- **描述**: 获取指定ID的活动详情 -- **参数**: - - `campaign_id`: 活动ID (路径参数) -- **响应示例**: - ```json - { - "code": 200, - "message": "成功", - "data": { - // 活动详情 - } - } - ``` - -### 创建活动 +### 3.2 创建活动 - **URL**: `/campaigns/` -- **方法**: POST -- **描述**: 创建新的活动 +- **方法**: `POST` +- **描述**: 创建一个新的活动,会自动更新关联品牌的dataset_id_list - **请求参数**: ```json { - "brand": "品牌ID", // 必填 - "name": "活动名称", // 必填 - "description": "活动描述", - "image_url": "活动图片", - "service": "服务类型", - "creator_type": "创作者类型", - "dataset_id": "知识库ID", // 必填 - // ... 其他字段 - } - ``` -- **响应示例**: - ```json - { - "code": 200, - "message": "成功", - "data": { - // 创建的活动信息 - } + "brand": "品牌ID", // 必填 + "name": "活动名称", // 必填 + "description": "活动描述", // 可选 + "image_url": "活动图片链接", // 可选 + "service": "服务类型", // 可选 + "creator_type": "创作者类型", // 可选 + "creator_level": "创作者等级", // 可选 + "creator_category": "创作者分类", // 可选 + "creators_count": 0, // 可选 + "gmv": "GMV范围", // 可选 + "followers": "粉丝数范围", // 可选 + "views": "浏览量范围", // 可选 + "budget": "预算范围", // 可选 + "link_product": ["产品ID1"], // 可选 + "start_date": "开始日期", // 可选 + "end_date": "结束日期", // 可选 + "dataset_id": "知识库ID", // 必填 + "external_id": "外部ID", // 可选 + "is_active": true // 可选 } ``` +- **响应数据**: 返回创建的活动信息 -### 更新活动 +### 3.3 获取活动详情 -- **URL**: `/campaigns/{campaign_id}/` -- **方法**: PUT/PATCH -- **描述**: 更新活动信息 -- **参数**: - - `campaign_id`: 活动ID (路径参数) - - 请求体包含要更新的字段 -- **响应示例**: - ```json - { - "code": 200, - "message": "成功", - "data": { - // 更新后的活动信息 - } - } - ``` +- **URL**: `/campaigns/{id}/` +- **方法**: `GET` +- **描述**: 获取指定ID的活动详细信息 +- **请求参数**: 无 +- **响应数据**: 返回活动详情 -### 删除活动 +### 3.4 更新活动 -- **URL**: `/campaigns/{campaign_id}/` -- **方法**: DELETE -- **描述**: 删除活动(软删除) -- **参数**: - - `campaign_id`: 活动ID (路径参数) -- **响应示例**: +- **URL**: `/campaigns/{id}/` +- **方法**: `PUT`/`PATCH` +- **描述**: 更新指定ID的活动信息,会自动更新关联品牌的dataset_id_list +- **请求参数**: 同创建活动 +- **响应数据**: 返回更新后的活动信息 + +### 3.5 删除活动 + +- **URL**: `/campaigns/{id}/` +- **方法**: `DELETE` +- **描述**: 软删除指定ID的活动,并从品牌的dataset_id_list中移除对应的ID +- **请求参数**: 无 +- **响应数据**: ```json { "code": 200, @@ -478,20 +385,42 @@ Authorization: Token } ``` -### 向活动添加产品 +### 3.6 获取Token信息 -- **URL**: `/campaigns/{campaign_id}/add_product/` -- **方法**: POST -- **描述**: 将产品添加到活动中 -- **参数**: - - `campaign_id`: 活动ID (路径参数) - - 请求体: - ```json - { - "product_id": "产品ID" +- **URL**: `/campaigns/token-info/` +- **方法**: `GET` +- **描述**: 获取当前用户的token信息和WebSocket URL示例 +- **请求参数**: 无 +- **响应数据**: + ```json + { + "code": 200, + "message": "成功", + "data": { + "user_id": 1, + "email": "user@example.com", + "token": "token字符串", + "token_expired_at": "过期时间", + "websocket_examples": { + "活动状态WebSocket": "ws://example.com/ws/campaigns/1/status/?token=token字符串", + "活动产品状态WebSocket": "ws://example.com/ws/campaigns/1/products/123/status/?token=token字符串" + } } - ``` -- **响应示例**: + } + ``` + +### 3.7 添加产品到活动 + +- **URL**: `/campaigns/{id}/add_product/` +- **方法**: `POST` +- **描述**: 将产品添加到活动中 +- **请求参数**: + ```json + { + "product_id": "产品ID" // 必填 + } + ``` +- **响应数据**: ```json { "code": 200, @@ -500,20 +429,18 @@ Authorization: Token } ``` -### 从活动移除产品 +### 3.8 从活动中移除产品 -- **URL**: `/campaigns/{campaign_id}/remove_product/` -- **方法**: POST +- **URL**: `/campaigns/{id}/remove_product/` +- **方法**: `POST` - **描述**: 从活动中移除产品 -- **参数**: - - `campaign_id`: 活动ID (路径参数) - - 请求体: - ```json - { - "product_id": "产品ID" - } - ``` -- **响应示例**: +- **请求参数**: + ```json + { + "product_id": "产品ID" // 必填 + } + ``` +- **响应数据**: ```json { "code": 200, @@ -522,46 +449,88 @@ Authorization: Token } ``` -### 获取活动创作者列表 +### 3.9 获取活动达人列表 -- **URL**: `/campaigns/{campaign_id}/creator_list/` -- **方法**: GET -- **描述**: 获取指定活动的创作者列表 -- **参数**: - - `campaign_id`: 活动ID (路径参数) -- **响应示例**: +- **URL**: `/campaigns/{id}/creator_list/` +- **方法**: `GET` +- **描述**: 获取活动关联的达人列表,并启动状态轮询 +- **请求参数**: 无 +- **响应数据**: ```json { "code": 200, "message": "成功", "data": { "campaign": { - "id": "活动ID", "name": "活动名称", "description": "活动描述", - "image_url": "活动图片", + "image_url": "活动图片链接", "service": "服务类型", "creator_type": "创作者类型", "creator_level": "创作者等级", "creator_category": "创作者分类", - "creators_count": 10, + "creators_count": 0, "gmv": "GMV范围", "followers": "粉丝数范围", "views": "浏览量范围", "budget": "预算范围", - "start_date": "2023-01-01T00:00:00Z", - "end_date": "2023-02-01T00:00:00Z", + "start_date": "开始日期", + "end_date": "结束日期", "status": "状态" }, "creators": [ { - "id": "创作者ID", - "name": "创作者名称", - "category": "创作者分类", - "followers": 5000, - "gmv_generated": "1000.00", - "views_generated": "5000", - "pricing": "100.00", + "name": "达人名称", + "category": "达人分类", + "followers": "粉丝数", + "GMV Generated": "GMV", + "Views Generated": "观看量", + "Pricing": "价格", + "Status": "状态" + } + ] + } + } + ``` + +### 3.10 更新达人状态 + +- **URL**: `/campaigns/{id}/update_creator_status/` +- **方法**: `POST` +- **描述**: 手动更新达人状态 +- **请求参数**: + ```json + { + "creator_id": "达人ID", // 必填 + "product_id": "产品ID" // 可选 + } + ``` +- **响应数据**: 返回更新后的达人列表 + +### 3.11 获取活动产品达人列表 + +- **URL**: `/campaigns/{id}/product_creators/` +- **方法**: `GET` +- **描述**: 根据活动ID和产品ID获取达人列表,并启动状态轮询 +- **请求参数**: + - `product_id`: 产品ID (可选) +- **响应数据**: + ```json + { + "code": 200, + "message": "成功", + "data": { + "campaign_id": "活动ID", + "product_id": "产品ID", + "product_name": "产品名称", + "creators": [ + { + "creator_name": "达人名称", + "category": "达人分类", + "followers": "粉丝数", + "gmv_generated": "GMV", + "views_generated": "观看量", + "pricing": "价格", "status": "状态" } ] @@ -569,151 +538,139 @@ Authorization: Token } ``` -### 获取WebSocket连接URL +### 3.12 停止状态轮询 -- **URL**: `/campaigns/{campaign_id}/websocket_url/` -- **方法**: GET -- **描述**: 获取带有认证Token的WebSocket连接URL -- **参数**: - - `campaign_id`: 活动ID (路径参数) - - 查询参数: - - `product_id`: 可选,用于获取特定产品的WebSocket连接 -- **响应示例**: +- **URL**: `/campaigns/stop-polling/` +- **方法**: `POST` +- **描述**: 停止指定活动或所有活动的状态轮询 +- **请求参数**: + ```json + { + "campaign_id": "活动ID" // 可选,不提供则停止所有轮询 + } + ``` +- **响应数据**: ```json { "code": 200, - "message": "成功", - "data": { - "websocket_url": "ws://127.0.0.1:8000/ws/campaigns/12345/status/?token=abc123" - } - } - ``` - -### 获取当前Token信息 - -- **URL**: `/campaigns/token_info/` -- **方法**: GET -- **描述**: 获取当前用户的认证Token信息和WebSocket连接示例 -- **参数**: 无 -- **响应示例**: - ```json - { - "code": 200, - "message": "成功", - "data": { - "user_id": "用户ID", - "email": "用户邮箱", - "token": "认证Token", - "expires_at": "过期时间", - "websocket_example": { - "campaign": "ws://127.0.0.1:8000/ws/campaigns/campaign_id/status/?token=abc123", - "product": "ws://127.0.0.1:8000/ws/campaigns/campaign_id/status/?product_id=product_id&token=abc123" - } - } - } - ``` - -## WebSocket 接口 - -### 建立活动状态WebSocket连接 - -- **URL**: `ws://127.0.0.1:8000/ws/campaigns/{campaign_id}/status/?token={token}` -- **描述**: 建立WebSocket连接,获取活动状态的实时更新 -- **参数**: - - `campaign_id`: 活动ID (路径参数) - - 查询参数: - - `token`: 用户认证Token (必填) - - `product_id`: 可选,用于获取特定产品的状态 -- **连接成功后接收的数据格式**: - ```json - { - "campaign": { - // 活动信息 - }, - "creators": [ - // 创作者列表 - ] - } - ``` - -### WebSocket连接JavaScript示例 - -```javascript -// 获取WebSocket URL -const response = await fetch(`http://127.0.0.1:8000/api/campaigns/${campaignId}/websocket_url/`); -const data = await response.json(); -const wsUrl = data.data.websocket_url; - -// 建立WebSocket连接 -const socket = new WebSocket(wsUrl); - -// 连接打开事件 -socket.onopen = function(e) { - console.log("WebSocket连接已建立"); -}; - -// 接收消息事件 -socket.onmessage = function(event) { - const data = JSON.parse(event.data); - console.log("接收到的数据:", data); - // 处理接收到的数据 -}; - -// 错误事件 -socket.onerror = function(error) { - console.error("WebSocket错误:", error); -}; - -// 连接关闭事件 -socket.onclose = function(event) { - console.log("WebSocket连接已关闭"); -}; -``` - -## 状态轮询管理 - -### 停止轮询 - -- **URL**: `/campaigns/{campaign_id}/stop_polling/` -- **方法**: POST -- **描述**: 停止指定活动的状态轮询 -- **参数**: - - `campaign_id`: 活动ID (路径参数) - - 请求体: - ```json - { - "product_id": "产品ID" // 可选,不提供则停止整个活动的轮询 - } - ``` -- **响应示例**: - ```json - { - "code": 200, - "message": "轮询已停止", + "message": "已停止活动轮询", "data": null } ``` -### 获取活跃轮询任务 +### 3.13 获取活动轮询列表 -- **URL**: `/campaigns/active_polling_tasks/` -- **方法**: GET -- **描述**: 获取当前系统中所有活跃的轮询任务 -- **参数**: 无 -- **响应示例**: +- **URL**: `/campaigns/active-pollings/` +- **方法**: `GET` +- **描述**: 获取当前正在运行的所有轮询任务信息 +- **请求参数**: 无 +- **响应数据**: 返回活动轮询列表 + +### 3.14 获取WebSocket连接URL + +- **URL**: `/campaigns/{id}/websocket-url/` +- **方法**: `GET` +- **描述**: 获取带认证的WebSocket连接URL +- **请求参数**: + - `product_id`: 产品ID (可选) +- **响应数据**: ```json { "code": 200, "message": "成功", "data": { - "active_tasks": [ - { - "campaign_id": "活动ID", - "product_id": "产品ID", // 如果存在 - "interval": 30, // 轮询间隔,单位为秒 - "last_poll": "2023-01-01T00:00:00Z" - } - ] + "websocket_url": "ws://example.com/ws/campaigns/1/status/?token=token字符串" } } ``` + +## 4. 品牌聊天会话管理 (Chat Sessions) + +### 4.1 获取聊天会话列表 + +- **URL**: `/chat-sessions/` +- **方法**: `GET` +- **描述**: 获取所有品牌聊天会话的列表 +- **请求参数**: 无 +- **响应数据**: + ```json + { + "code": 200, + "message": "成功", + "data": [ + { + "id": "uuid字符串", + "brand": "品牌ID", + "brand_name": "品牌名称", + "session_id": "会话ID", + "title": "会话标题", + "dataset_id_list": [], + "created_at": "创建时间", + "updated_at": "更新时间", + "is_active": true + } + ] + } + ``` + +### 4.2 创建聊天会话 + +- **URL**: `/chat-sessions/` +- **方法**: `POST` +- **描述**: 创建一个新的品牌聊天会话,如果未提供dataset_id_list,则使用品牌的dataset_id_list +- **请求参数**: + ```json + { + "brand": "品牌ID", // 必填 + "session_id": "会话ID", // 必填,唯一 + "title": "会话标题", // 可选,默认"新对话" + "dataset_id_list": [], // 可选,默认为品牌的dataset_id_list + "is_active": true // 可选,默认true + } + ``` +- **响应数据**: 返回创建的聊天会话信息 + +### 4.3 获取聊天会话详情 + +- **URL**: `/chat-sessions/{id}/` +- **方法**: `GET` +- **描述**: 获取指定ID的聊天会话详细信息 +- **请求参数**: 无 +- **响应数据**: 返回聊天会话详情 + +### 4.4 更新聊天会话 + +- **URL**: `/chat-sessions/{id}/` +- **方法**: `PUT`/`PATCH` +- **描述**: 更新指定ID的聊天会话信息 +- **请求参数**: 同创建聊天会话 +- **响应数据**: 返回更新后的聊天会话信息 + +### 4.5 删除聊天会话 + +- **URL**: `/chat-sessions/{id}/` +- **方法**: `DELETE` +- **描述**: 删除指定ID的聊天会话 +- **请求参数**: 无 +- **响应数据**: + ```json + { + "code": 200, + "message": "删除成功", + "data": null + } + ``` + +## 5. WebSocket接口 + +brands模块提供了WebSocket接口,用于实时获取活动和产品状态更新。 + +### 5.1 活动状态WebSocket + +- **URL**: `ws://domain/ws/campaigns/{campaign_id}/status/?token={token}` +- **描述**: 接收指定活动的状态更新 + +### 5.2 活动产品状态WebSocket + +- **URL**: `ws://domain/ws/campaigns/{campaign_id}/products/{product_id}/status/?token={token}` +- **描述**: 接收指定活动和产品组合的状态更新 diff --git a/apps/chat/services/goal_service.py b/apps/chat/services/goal_service.py new file mode 100644 index 0000000..3b1b227 --- /dev/null +++ b/apps/chat/services/goal_service.py @@ -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) \ No newline at end of file diff --git a/apps/chat/views.py b/apps/chat/views.py index 3d19297..18a3e4b 100644 --- a/apps/chat/views.py +++ b/apps/chat/views.py @@ -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) diff --git a/apps/discovery/README.md b/apps/discovery/README.md deleted file mode 100644 index d2733b2..0000000 --- a/apps/discovery/README.md +++ /dev/null @@ -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`中提供 -- 接口不需要认证,可直接访问 \ No newline at end of file diff --git a/apps/discovery/discovery.md b/apps/discovery/discovery.md index fc480b8..3fb0ce2 100644 --- a/apps/discovery/discovery.md +++ b/apps/discovery/discovery.md @@ -1,183 +1,193 @@ -# 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 -``` - -### 响应格式 - -所有 API 返回的数据格式统一为: +所有API响应都遵循以下统一的JSON格式: ```json { - "code": 200, // 状态码,200表示成功,其他表示错误 - "message": "成功", // 状态描述 - "data": {} // 返回的数据,可能是对象、数组或null + "code": 200, // 状态码,200表示成功,其他值表示错误 + "message": "成功", // 响应消息 + "data": {} // 响应数据,可能是对象、数组或null } ``` -### 分页 +## 分页响应格式 -列表接口支持分页,默认每页 20 条数据,最大每页 100 条。 - -分页参数: -- `page`: 页码,从1开始 -- `page_size`: 每页数量,默认20 - -分页响应格式: +使用分页的接口将返回以下格式: ```json { "code": 200, "message": "获取数据成功", "data": { - "count": 100, // 总记录数 - "next": "下一页URL", // 下一页链接,如果没有则为null - "previous": "上一页URL", // 上一页链接,如果没有则为null - "results": [] // 当前页数据 + "count": 100, // 总记录数 + "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": { - "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": [ - // 创作者列表,见创作者数据结构 + "count": 10, + "next": null, + "previous": null, + "results": [ + { + "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" + } ] } } ``` -### 创建搜索会话 +### 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 } ``` -### 获取会话创作者列表 +### 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": [ - // 创作者列表,见创作者数据结构 - ] + "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**: `/creators/` -- **方法**: GET -- **描述**: 获取所有创作者的列表 -- **参数**: - - 分页参数,参见[分页](#分页)部分 -- **响应示例**: +- **URL**: `/sessions/summary/` +- **方法**: `GET` +- **描述**: 获取所有会话的摘要数据,用于展示在表格中 +- **请求参数**: 无 +- **响应数据**: ```json { "code": 200, - "message": "获取创作者列表成功", + "message": "获取会话摘要列表成功", "data": [ { "id": 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, - "has_ecommerce": true, - "tiktok_url": "抖音链接", - "session": 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) -- **URL**: `/creators/{creator_id}/` -- **方法**: GET +创作者是系统中的核心数据实体,代表平台上的内容创作者/达人。 + +### 2.1 获取创作者列表 + +- **URL**: `/creators/` +- **方法**: `GET` +- **描述**: 获取所有创作者的列表 +- **请求参数**: + - `page`: 页码,默认为1 + - `page_size`: 每页记录数,默认为20,最大为100 +- **响应数据**: + ```json + { + "code": 200, + "message": "获取创作者列表成功", + "data": { + "count": 100, + "next": "http://example.com/api/creators/?page=2", + "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" + } + ] + } + } + ``` + +### 2.2 获取创作者详情 + +- **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 搜索标签和趋势 -### 创作者类别 +- **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": "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" + } + ] + } + } + ``` -- `Phones & Electronics`: 手机与电子产品 -- `Womenswear & Underwear`: 女装与内衣 -- `Sports & Outdoor`: 运动与户外 -- `Food & Beverage`: 食品与饮料 -- `Health`: 健康 -- `Kitchenware`: 厨具 -- `Furniture`: 家具 -- `Shoes`: 鞋类 -- `Home Supplies`: 家居用品 +### 2.5 自然语言搜索创作者 -### 电商等级 +- **URL**: `/creators/search_individual/` +- **方法**: `POST` +- **描述**: 根据用户输入的自然语言文本搜索达人,使用外部API进行处理 +- **请求参数**: + ```json + { + "criteria": "我需要粉丝超过10万的健身类达人,擅长做运动装备测评", // 必填,搜索条件 + "top_n": 10 // 可选,返回结果数量,默认10 + } + ``` +- **响应数据**: + ```json + { + "code": 200, + "message": "搜索创作者成功", + "data": { + "id": 1, + "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" + } + ] + } + } + ``` -- `L1`: Level 1 -- `L2`: Level 2 -- `L3`: Level 3 -- `L4`: Level 4 -- `L5`: Level 5 -- `New tag`: 新标签 +## 3. 字段说明 -### 曝光等级 +### 3.1 搜索会话字段 -- `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`: 新标签 +| 字段名 | 类型 | 说明 | +|------------------|---------|------------------------------| +| 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 -```json { - "id": 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 + "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 -```json { - "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" // 创建日期 + "criteria": "需要3个粉丝超过50万的美妆达人,产品转化率高", + "top_n": 3 } ``` diff --git a/apps/template/template.md b/apps/template/template.md new file mode 100644 index 0000000..072a471 --- /dev/null +++ b/apps/template/template.md @@ -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 +``` diff --git a/daren/settings.py b/daren/settings.py index c18061c..218a8fe 100644 --- a/daren/settings.py +++ b/daren/settings.py @@ -102,7 +102,7 @@ DATABASES = { 'NAME': 'daren_detail', 'USER': 'root', 'PASSWORD': '123456', - 'HOST': 'localhost', + 'HOST': '192.168.31.138', 'PORT': '3306', 'OPTIONS': { 'charset': 'utf8mb4',