# KOL Insight - 功能摘要 ## 文档信息 | 项目 | 内容 | |------|------| | 版本 | v1.0 | | 创建日期 | 2025-01-28 | | 来源文档 | PRD.md | ## 1. 功能总览 ### 1.1 功能统计 | 类别 | 数量 | |------|------| | 功能模块 | 5 个 | | P0 功能 | 7 个 | | P1 功能 | 2 个 | | P2 功能 | 1 个 | ### 1.2 功能架构图 ``` ┌─────────────────────────────────────────────────────────────────────────────────┐ │ KOL Insight │ ├─────────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ │ 数据查询模块 │ │ 数据计算模块 │ │ 品牌API集成模块 │ │ │ │ ────────────── │ │ ────────────── │ │ ────────────── │ │ │ │ • 星图ID查询 │ │ • 预估自然CPM │ │ • 品牌名称批量 │ │ │ │ • 达人ID查询 │ │ • 预估看后搜人数 │ │ 获取(后端) │ │ │ │ • 昵称模糊查询 │ │ • 看后搜人数成本 │ │ │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ │ 数据展示模块 │ │ 数据导出模块 │ │ 外部服务依赖 │ │ │ │ ────────────── │ │ ────────────── │ │ ────────────── │ │ │ │ • 结果列表展示 │ │ • Excel/CSV导出 │ │ • PostgreSQL │ │ │ │ • 视频链接跳转 │ │ │ │ • 品牌API │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────────┘ ``` ### 1.3 模块依赖关系 ``` ┌──────────────────┐ │ 数据查询模块 │ │ (F-001~003) │ └────────┬─────────┘ │ │ 查询结果(含brand_id) ▼ ┌──────────────────┐ ┌──────────────────┐ │ 品牌API集成 │◀─│ 数据计算模块 │ │ (F-010) │ │ (F-004~006) │ │ 后端批量调用 │ └────────┬─────────┘ └────────┬─────────┘ │ │ │ 计算结果 │ 品牌名称 │ └─────────┬───────────┘ ▼ ┌──────────────────┐ │ 数据展示模块 │ │ (F-007~008) │ └────────┬─────────┘ │ │ 展示数据(含品牌名称) ▼ ┌──────────────────┐ │ 数据导出模块 │ │ (F-009) │ └──────────────────┘ ``` ## 2. 功能清单 ### 2.1 数据查询模块 **模块职责**: 接收用户输入的查询条件,从数据库检索匹配的KOL视频数据 #### 功能列表 | ID | 功能 | 描述 | 优先级 | 关联用户故事 | |----|------|------|--------|--------------| | F-001 | 星图ID查询 | 批量输入星图ID,精准匹配数据库 | P0 | US-001 | | F-002 | 达人ID查询 | 批量输入达人unique_id,精准匹配数据库 | P0 | US-002 | | F-003 | 昵称模糊查询 | 输入达人昵称,模糊匹配数据库 | P0 | US-003 | #### 功能契约详情 **F-001: 星图ID查询** | 契约项 | 说明 | |--------|------| | **触发条件** | 用户选择"星图ID"查询方式并提交查询 | | **输入** | 星图ID列表(换行分隔的字符串) | | **处理逻辑** | 1. 解析输入,按换行符分割为ID数组
2. 对每个ID执行 `WHERE star_id = ?` 精准匹配
3. 合并所有匹配结果 | | **输出** | 匹配的视频数据列表(包含26个输出字段) | | **异常情况** | 1. 输入为空:提示"请输入星图ID"
2. 无匹配结果:返回空列表,提示"未找到匹配数据"
3. 数据库连接失败:显示错误提示 | | **边界说明** | 仅支持精准匹配,不支持模糊匹配;单次查询建议不超过100个ID | **F-002: 达人ID查询** | 契约项 | 说明 | |--------|------| | **触发条件** | 用户选择"达人unique_id"查询方式并提交查询 | | **输入** | 达人unique_id列表(换行分隔的字符串) | | **处理逻辑** | 1. 解析输入,按换行符分割为ID数组
2. 对每个ID执行 `WHERE star_unique_id = ?` 精准匹配
3. 合并所有匹配结果 | | **输出** | 匹配的视频数据列表(包含26个输出字段) | | **异常情况** | 1. 输入为空:提示"请输入达人ID"
2. 无匹配结果:返回空列表
3. 数据库连接失败:显示错误提示 | | **边界说明** | 仅支持精准匹配;单次查询建议不超过100个ID | **F-003: 昵称模糊查询** | 契约项 | 说明 | |--------|------| | **触发条件** | 用户选择"达人昵称"查询方式并提交查询 | | **输入** | 达人昵称(字符串) | | **处理逻辑** | 1. 执行 `WHERE star_nickname LIKE '%{input}%'` 包含匹配
2. 返回所有匹配结果 | | **输出** | 匹配的视频数据列表(包含26个输出字段) | | **异常情况** | 1. 输入为空:提示"请输入达人昵称"
2. 无匹配结果:返回空列表
3. 匹配结果过多:返回前1000条并提示 | | **边界说明** | 支持模糊匹配(包含关系);结果数量可能较大 | --- ### 2.2 数据计算模块 **模块职责**: 对查询结果进行预估指标计算,生成CPM和看后搜成本数据 #### 功能列表 | ID | 功能 | 描述 | 优先级 | 关联用户故事 | |----|------|------|--------|--------------| | F-004 | 预估自然CPM计算 | 计算每千次自然曝光的成本 | P0 | US-004 | | F-005 | 预估自然看后搜人数计算 | 计算自然流量带来的看后搜人数 | P0 | US-004 | | F-006 | 预估自然看后搜人数成本计算 | 计算每个自然看后搜用户的成本 | P0 | US-004 | #### 功能契约详情 **F-004: 预估自然CPM计算** | 契约项 | 说明 | |--------|------| | **触发条件** | 查询返回结果后自动执行 | | **输入** | 视频数据中的 `estimated_video_cost`、`natural_play_cnt` 字段 | | **处理逻辑** | `预估自然CPM = estimated_video_cost / natural_play_cnt * 1000` | | **输出** | 预估自然CPM值(单位:元/千次曝光) | | **异常情况** | 1. natural_play_cnt = 0:返回 null 或 "-"
2. 字段缺失:返回 null | | **边界说明** | 结果保留2位小数;除零时不计算 | **F-005: 预估自然看后搜人数计算** | 契约项 | 说明 | |--------|------| | **触发条件** | 查询返回结果后自动执行 | | **输入** | 视频数据中的 `natural_play_cnt`、`total_play_cnt`、`after_view_search_uv` 字段 | | **处理逻辑** | `预估自然看后搜人数 = natural_play_cnt / total_play_cnt * after_view_search_uv` | | **输出** | 预估自然看后搜人数(单位:人) | | **异常情况** | 1. total_play_cnt = 0:返回 null
2. 字段缺失:返回 null | | **边界说明** | 结果取整或保留2位小数;除零时不计算 | **F-006: 预估自然看后搜人数成本计算** | 契约项 | 说明 | |--------|------| | **触发条件** | F-005 计算完成后自动执行 | | **输入** | `estimated_video_cost` 字段、F-005 的计算结果 | | **处理逻辑** | `预估自然看后搜人数成本 = estimated_video_cost / 预估自然看后搜人数` | | **输出** | 预估自然看后搜人数成本(单位:元/人) | | **异常情况** | 1. 预估自然看后搜人数 = 0 或 null:返回 null
2. 依赖计算失败:返回 null | | **边界说明** | 依赖 F-005 结果;结果保留2位小数 | --- ### 2.3 品牌API集成模块 **模块职责**: 在后端查询时批量调用品牌API,获取品牌名称并补充到查询结果中 #### 功能列表 | ID | 功能 | 描述 | 优先级 | 关联用户故事 | |----|------|------|--------|--------------| | F-010 | 品牌名称批量获取 | 后端批量调用品牌API获取品牌名称 | P0 | US-006 | #### 功能契约详情 **F-010: 品牌名称批量获取** | 契约项 | 说明 | |--------|------| | **触发条件** | 后端查询返回结果后,在返回给前端之前自动执行 | | **输入** | 查询结果中的 `brand_id` 列表(去重后) | | **处理逻辑** | 1. 从查询结果中提取所有唯一的 brand_id
2. 批量并发调用品牌API:`GET /v1/yuntu/brands/{brand_id}`
3. 构建 brand_id → brand_name 映射表
4. 将品牌名称填充到每条查询结果的 brand_name 字段 | | **输出** | 补充了 brand_name 字段的完整查询结果 | | **异常情况** | 1. 单个品牌API调用失败:该条记录 brand_name 降级显示 brand_id
2. 品牌API服务不可用:所有记录降级显示 brand_id
3. brand_id 为空:brand_name 显示为 "-" | | **边界说明** | 1. 在后端执行,前端无需调用
2. 使用并发控制,限制同时请求数(如最多10个并发)
3. 可选:缓存品牌名称,减少重复请求
4. 超时设置:单个请求超时3秒 | **批量调用策略**: ``` 查询结果 (100条) │ ▼ ┌─────────────────────────────────────┐ │ 1. 提取唯一 brand_id (假设30个) │ └─────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ 2. 批量并发请求 (限制10并发) │ │ Promise.all([ │ │ fetch(brand/id1), │ │ fetch(brand/id2), │ │ ... │ │ ]) │ └─────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ 3. 构建映射表 │ │ { id1: "品牌A", id2: "品牌B" } │ └─────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ 4. 填充 brand_name 到结果 │ └─────────────────────────────────────┘ ``` --- ### 2.4 数据展示模块 **模块职责**: 将查询和计算结果以表格形式展示给用户 #### 功能列表 | ID | 功能 | 描述 | 优先级 | 关联用户故事 | |----|------|------|--------|--------------| | F-007 | 结果列表展示 | 以表格形式展示查询结果的所有字段 | P1 | US-006 | | F-008 | 视频链接跳转 | 点击视频链接在新窗口打开原视频 | P2 | US-007 | #### 功能契约详情 **F-007: 结果列表展示** | 契约项 | 说明 | |--------|------| | **触发条件** | 查询完成且有结果数据 | | **输入** | 查询结果数据列表(含计算字段和品牌名称,由后端 F-010 处理完成) | | **处理逻辑** | 1. 渲染数据表格
2. 展示26个输出字段(含3个计算字段)
3. 品牌名称已由后端获取,直接展示 brand_name 字段 | | **输出** | HTML表格展示 | | **异常情况** | 1. 无数据:显示空状态提示
2. 品牌名称为空:显示 "-" | | **边界说明** | 支持分页(如数据量大);列名使用中文;品牌名称由后端处理,前端无需调用API | **F-008: 视频链接跳转** | 契约项 | 说明 | |--------|------| | **触发条件** | 用户点击视频链接 | | **输入** | 视频链接URL(video_url字段) | | **处理逻辑** | 在新窗口/标签页打开链接 | | **输出** | 浏览器新标签页打开视频页面 | | **异常情况** | 1. 链接为空:不可点击或显示提示
2. 链接无效:由浏览器处理 | | **边界说明** | 使用 `target="_blank"` 打开;需考虑安全属性 | --- ### 2.4 数据导出模块 **模块职责**: 将查询结果导出为Excel或CSV文件供用户下载 #### 功能列表 | ID | 功能 | 描述 | 优先级 | 关联用户故事 | |----|------|------|--------|--------------| | F-009 | Excel/CSV导出 | 将当前查询结果导出为文件 | P1 | US-005 | #### 功能契约详情 **F-009: Excel/CSV导出** | 契约项 | 说明 | |--------|------| | **触发条件** | 用户点击"导出"按钮 | | **输入** | 当前查询结果数据列表 | | **处理逻辑** | 1. 将数据转换为Excel/CSV格式
2. 使用中文列名作为表头
3. 生成文件并触发下载 | | **输出** | Excel(.xlsx)或CSV文件下载 | | **异常情况** | 1. 无数据:提示"无数据可导出"
2. 数据量过大:分批处理或提示限制 | | **边界说明** | 导出数据包含所有26个字段;文件名包含时间戳;单次导出建议不超过1000条 | --- ## 3. 功能依赖矩阵 | 功能 | F-001 | F-002 | F-003 | F-004 | F-005 | F-006 | F-007 | F-008 | F-009 | F-010 | |------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------| | F-001 | - | | | | | | | | | | | F-002 | | - | | | | | | | | | | F-003 | | | - | | | | | | | | | F-004 | ✓ | ✓ | ✓ | - | | | | | | | | F-005 | ✓ | ✓ | ✓ | | - | | | | | | | F-006 | | | | | ✓ | - | | | | | | F-007 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | - | | | ✓ | | F-008 | | | | | | | ✓ | - | | | | F-009 | | | | ✓ | ✓ | ✓ | ✓ | | - | ✓ | | F-010 | ✓ | ✓ | ✓ | | | | | | | - | **说明**: - ✓ 表示行功能依赖列功能 - F-004/005/006(计算模块)依赖 F-001/002/003(查询模块)的输出 - F-006 依赖 F-005 的计算结果 - F-010(品牌API)依赖查询模块获取 brand_id 列表,在后端批量调用 - F-007(展示)依赖查询、计算结果和 F-010 的品牌名称 - F-009(导出)依赖展示数据(含品牌名称) ## 4. 功能流程图 ### 4.1 核心业务流程:批量查询与导出 ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 用户输入 │ │ 选择查询 │ │ 提交查询 │ │ 查询条件 │ ──▶ │ 方式 │ ──▶ │ │ └─────────────┘ └─────────────┘ └──────┬──────┘ │ ┌──────────────────────────┘ ▼ ┌──────────────────────────────────────────────────────┐ │ 数据查询模块 │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ F-001 │ │ F-002 │ │ F-003 │ │ │ │ 星图ID │ / │ 达人ID │ / │ 昵称 │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ └───────┼─────────────┼─────────────┼─────────────────┘ └─────────────┼─────────────┘ ▼ ┌──────────────────────────────────────────────────────┐ │ 后端处理(并行执行) │ │ │ │ ┌────────────────────┐ ┌────────────────────┐ │ │ │ 数据计算模块 │ │ 品牌API集成模块 │ │ │ │ ┌─────┐ ┌─────┐ │ │ ┌──────────────┐ │ │ │ │ │F-004│ │F-005│ │ │ │ F-010 │ │ │ │ │ │ CPM │ │看后搜│ │ │ │ 批量获取品牌 │ │ │ │ │ └─────┘ └──┬──┘ │ │ │ 名称 │ │ │ │ │ │ │ │ └──────────────┘ │ │ │ │ ┌───┘ │ │ │ │ │ │ ▼ │ │ │ │ │ │ ┌─────┐ │ │ │ │ │ │ │F-006│ │ │ │ │ │ │ │成本 │ │ │ │ │ │ │ └─────┘ │ │ │ │ │ └────────────────────┘ └────────────────────┘ │ └─────────────────────┬────────────────────────────────┘ ▼ ┌──────────────────────────────────────────────────────┐ │ 数据展示模块 │ │ ┌───────────────────────────────────────┐ │ │ │ F-007 结果列表展示(含品牌名称) │ │ │ │ ┌─────────────────────────────────┐ │ │ │ │ │ F-008 视频链接(可点击跳转) │ │ │ │ │ └─────────────────────────────────┘ │ │ │ └───────────────────────────────────────┘ │ └─────────────────────┬────────────────────────────────┘ │ ┌────────────┴────────────┐ ▼ ▼ ┌─────────────┐ ┌─────────────┐ │ 继续查询 │ │ F-009 │ │ │ │ 导出数据 │ └─────────────┘ └─────────────┘ ``` ### 4.2 计算模块内部流程 ``` ┌──────────────────┐ │ 查询结果数据 │ └────────┬─────────┘ │ ▼ ┌────────────────────────────────────────────────────────────┐ │ 并行计算 │ │ │ │ ┌─────────────────────┐ ┌─────────────────────┐ │ │ │ F-004 │ │ F-005 │ │ │ │ 预估自然CPM │ │ 预估自然看后搜人数 │ │ │ │ │ │ │ │ │ │ cost/natural*1000 │ │ natural/total*uv │ │ │ └──────────┬──────────┘ └──────────┬──────────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌─────────────────────┐ ┌─────────────────────┐ │ │ │ 除零检查 │ │ 除零检查 │ │ │ │ null → 显示"-" │ │ null → 显示"-" │ │ │ └─────────────────────┘ └──────────┬──────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────┐ │ │ │ F-006 │ │ │ │ 预估看后搜人数成本 │ │ │ │ │ │ │ │ cost/看后搜人数 │ │ │ └─────────────────────┘ │ └────────────────────────────────────────────────────────────┘ ``` ## 5. 版本规划 | 版本 | 包含功能 | 功能ID | 目标 | |------|----------|--------|------| | MVP | 核心查询、计算、品牌API、展示、导出 | F-001 ~ F-007, F-009, F-010 | 完成核心批量查询和成本计算功能 | | v1.1 | 视频链接跳转、性能优化 | F-008 | 提升用户体验,优化查询性能 | ### MVP 功能清单 | 优先级 | 功能ID | 功能名称 | |--------|--------|----------| | P0 | F-001 | 星图ID查询 | | P0 | F-002 | 达人ID查询 | | P0 | F-003 | 昵称模糊查询 | | P0 | F-004 | 预估自然CPM计算 | | P0 | F-005 | 预估自然看后搜人数计算 | | P0 | F-006 | 预估自然看后搜人数成本计算 | | P0 | F-010 | 品牌名称批量获取(后端) | | P1 | F-007 | 结果列表展示 | | P1 | F-009 | Excel/CSV导出 | ### v1.1 功能清单 | 优先级 | 功能ID | 功能名称 | |--------|--------|----------| | P2 | F-008 | 视频链接跳转 | ## 6. 接口契约预览 > 详细接口定义在 DevelopmentPlan 中,此处仅列出关键接口 | 功能 | 接口类型 | 端点 | 简要说明 | |------|----------|------|----------| | F-001/002/003 | FastAPI 后端 | POST /api/v1/query | 批量查询,支持type参数区分查询方式 | | F-009 | FastAPI 后端 | GET /api/v1/export | 导出当前查询结果 | | F-010 | 外部API(后端调用) | GET /v1/yuntu/brands/{brand_id} | 后端批量获取品牌名称 | **技术架构说明**: - **后端**: Python FastAPI 框架,提供 RESTful API - **前端**: React + Next.js,通过 HTTP 请求调用后端 API - **架构**: 前后端完全分离,独立部署 - **API 版本**: 使用 `/api/v1/` 前缀进行版本管理 - **跨域**: FastAPI 配置 CORS 中间件支持前端调用 ### 查询接口预览 ``` POST /api/v1/query Content-Type: application/json { "type": "star_id" | "unique_id" | "nickname", "values": ["id1", "id2", ...] | "昵称关键词" } Response: { "success": true, "data": [...], // 视频数据列表 "total": 100 } ``` ### 导出接口预览 ``` GET /api/v1/export?format=xlsx|csv Response: 文件下载 ```