wxs 6cc703ada2 feat: monorepo 重构 + 新增 5 个平台适配器
项目从单体结构重构为 pnpm monorepo (shared/backend/frontend),
新增 YouTube、Instagram、Twitter/X、哔哩哔哩、微博 5 个平台适配器,
包含完整的单元测试和 E2E 测试覆盖。

- 完成 T-031~T-044: 5 个适配器实现、注册、配置和测试
- 重构前后端分离: Hono 后端 + Next.js 前端
- 151 个单元测试 + 21 个 Mock E2E + 25 个真实 E2E
- 适配器基于真实 TikHub API 响应结构实现

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 15:43:25 +08:00

351 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Muse Creative Hotspots — 产品需求文档 (PRD)
## 1. 产品概述
### 1.1 产品名称
Muse Creative Hotspots秒思创意热点
### 1.2 产品定位
面向个人创意工作者的**全平台热点内容聚合浏览器**,一站式查看 17 个主流社交媒体平台的热门内容及数据表现。
### 1.3 目标用户
个人独立使用者(创意工作者/内容创作者/自媒体从业者)
### 1.4 核心价值
- **效率提升**:告别逐个打开 17 个平台 APP/网站的低效模式
- **全局视野**:跨平台热点趋势一目了然
- **数据洞察**:热门内容的关键数据指标集中展示、可排序对比
- **灵感沉淀**:收藏感兴趣的内容,构建个人灵感库
### 1.5 核心使用场景
| 场景 | 描述 |
|------|------|
| 创意灵感获取 | 每天浏览各平台热点趋势,发现创意表达和内容形式 |
| 竞品/行业监控 | 跟踪特定领域在各平台的热门内容表现 |
| 数据分析研究 | 对比同类内容在不同平台的数据差异 |
| 内容搬运/分发 | 发现优质内容后进行跨平台二次创作 |
---
## 2. 平台覆盖范围
### 2.1 支持平台清单(共 17 个)
| 分类 | 平台 | 内容类型 | 优先级 |
|------|------|----------|--------|
| 国内短视频 | 抖音 | 短视频 | **MVP** |
| 国际短视频 | TikTok | 短视频 | **MVP** |
| 国内图文 | 小红书 | 图文+短视频 | **MVP** |
| 国际视频 | YouTube | 中长视频 | P1 |
| 国际图文 | Instagram | 图文+Reels | P1 |
| 国际社交 | Twitter/X | 文字+图文 | P1 |
| 国内视频 | 哔哩哔哩 | 中长视频 | P1 |
| 国内社交 | 微博 | 文字+图文+视频 | P1 |
| 国际社交 | Threads | 文字+图文 | P2 |
| 国际社交 | Reddit | 文字+图文+视频 | P2 |
| 国际职场 | 领英 (LinkedIn) | 文字+图文 | P2 |
| 国内问答 | 知乎 | 文字+图文 | P2 |
| 国际图文 | Lemon8 | 图文 | P2 |
| 国内短视频 | 快手 | 短视频 | P2 |
| 国内社交 | 微信 (公众号+视频号) | 图文+短视频 | P2 |
| 国内趣味 | 皮皮虾 | 短视频+图文 | P2 |
| AI 视频 | Sora | AI 生成视频 | P2 |
### 2.2 开发节奏
- **MVP 阶段**:抖音 + TikTok + 小红书3 个平台)
- **P1 阶段**YouTube + Instagram + Twitter/X + 哔哩哔哩 + 微博5 个平台)
- **P2 阶段**:其余 9 个平台
---
## 3. 功能需求
### 3.1 核心功能:热点内容聚合浏览
#### 3.1.1 内容获取
- 获取各平台**官方热榜/推荐内容**(如抖音热榜、微博热搜等)
- 每个平台展示热榜 Top N 条内容(默认 20-50 条)
- 数据刷新策略:**自动定时刷新(默认 30 分钟)+ 手动刷新按钮**
#### 3.1.2 内容展示 — 卡片信息流
- 采用**瀑布流/网格卡片**布局(类似小红书/Pinterest
- 每张卡片包含:
- 封面图/视频缩略图
- 内容标题/描述(截断展示)
- 来源平台标识(图标+名称)
- 关键数据指标(播放量/浏览量、点赞数、评论数、分享数)
- 发布时间
- 作者头像+昵称
- 卡片支持 hover 预览更多信息
#### 3.1.3 内容筛选与排序
- **按平台切换**:顶部 Tab 栏或侧边导航切换不同平台,支持"全部"聚合视图
- **按数据指标排序**:按播放量/浏览量、点赞数、评论数、发布时间等排序
- 支持切换排序方向(升序/降序)
#### 3.1.4 内容详情页
- 点击卡片进入**站内详情页**,展示:
- 完整的内容信息(标题、描述、标签等)
- 完整的数据指标面板
- 作者信息
- "查看原文"按钮(跳转原平台页面)
- 收藏按钮
### 3.2 辅助功能
#### 3.2.1 收藏/书签
- 支持将任意内容卡片添加到收藏夹
- 收藏夹独立页面查看
- 收藏数据持久化存储(本地存储/后端数据库)
#### 3.2.2 设置页面
- TikHub API Key 配置
- 自动刷新间隔设置
- 每个平台的启用/禁用开关
- 每个平台默认展示数量设置
---
## 4. 数据需求
### 4.1 数据源
- **API 提供商**TikHub (https://www.tikhub.io)
- **认证方式**Bearer Token已有 API Key
- **调用限制**10 请求/秒
- **计费方式**$0.001/请求
### 4.2 各平台核心 API 端点
#### MVP 平台
##### 抖音
| 功能 | 端点 |
|------|------|
| 热搜榜 | `/api/v1/douyin/web/fetch_hot_search_result` |
| 内容详情 | `/api/v1/douyin/web/fetch_one_video` |
| 用户信息 | `/api/v1/douyin/web/fetch_user_profile` |
##### TikTok
| 功能 | 端点 |
|------|------|
| 趋势内容 | `/api/v1/tiktok/web/fetch_trending_post` |
| 探索内容 | `/api/v1/tiktok/web/fetch_explore_post` |
| 内容详情 | `/api/v1/tiktok/web/fetch_post_detail` |
##### 小红书
| 功能 | 端点 |
|------|------|
| 推荐内容 | `/api/v1/xiaohongshu/app/v2/fetch_feed` (App V2 API) |
| 内容详情 | `/api/v1/xiaohongshu/app/v2/fetch_note_detail` |
| 用户信息 | `/api/v1/xiaohongshu/app/v2/fetch_user_info` |
#### P1 平台
> 以下端点来自 TikHub API 文档,实现前建议在 TikHub 控制台确认最新版本。
##### YouTube
| 功能 | 端点 |
|------|------|
| 趋势视频 | `/api/v1/youtube/web/fetch_trending_video` |
| 视频详情 | `/api/v1/youtube/web/fetch_video_detail` |
**字段映射**: `videoId``id`, `title``title`, `thumbnails.high.url``cover_url`, `contentDetails.videoId``video_url` (需拼接播放页 URL), `statistics.viewCount``play_count`, `statistics.likeCount``like_count`, `statistics.commentCount``comment_count`, `snippet.publishedAt``publish_time`
**内容类型**: 中长视频,封面比例 16:9
##### Instagram
| 功能 | 端点 |
|------|------|
| 探索内容 | `/api/v1/instagram/web/fetch_explore_feed` |
| 内容详情 | `/api/v1/instagram/web/fetch_post_detail` |
**字段映射**: `code``id`, `caption.text``title`, `image_versions2.candidates[0].url` / `thumbnail_url``cover_url`, `video_url``video_url` (Reels 有值,图文为 undefined), `user.username``author_name`, `like_count``like_count`, `comment_count``comment_count`, `taken_at``publish_time`
**内容类型**: 图文 (3:4) + Reels (9:16),通过是否有 `video_url` 区分
##### Twitter/X
| 功能 | 端点 |
|------|------|
| 热搜话题 | `/api/v1/twitter/web/fetch_trending_topics` |
| 推文详情 | `/api/v1/twitter/web/fetch_tweet_detail` |
**字段映射**: `id_str``id`, `full_text``title`, `entities.media[0].media_url_https``cover_url` (纯文字推文为 undefined), `user.name``author_name`, `user.profile_image_url_https``author_avatar`, `favorite_count``like_count`, `reply_count``comment_count`, `retweet_count``share_count`, `created_at``publish_time`
**内容类型**: 以文字卡片为主(无封面图时使用文字卡片样式)
##### 哔哩哔哩
| 功能 | 端点 |
|------|------|
| 热门视频 | `/api/v1/bilibili/web/fetch_popular_video_list` |
| 视频详情 | `/api/v1/bilibili/web/fetch_video_detail` |
**字段映射**: `bvid``id`, `title``title`, `pic``cover_url`, `owner.name``author_name`, `owner.face``author_avatar`, `stat.view``play_count`, `stat.like``like_count`, `stat.reply``comment_count`, `stat.share``share_count`, `pubdate` (Unix 时间戳) → `publish_time`
**内容类型**: 中长视频,封面比例 16:9
##### 微博
| 功能 | 端点 |
|------|------|
| 热搜榜 | `/api/v1/weibo/app/fetch_hot_search` |
| 微博详情 | `/api/v1/weibo/app/fetch_post_detail` |
**字段映射**: `id``id`, `text` (去 HTML 标签) → `title`, `pic_ids[0]` 拼接图片 URL → `cover_url` (无图时为 undefined), `user.screen_name``author_name`, `user.avatar_hd``author_avatar`, `attitudes_count``like_count`, `comments_count``comment_count`, `reposts_count``share_count`, `created_at``publish_time`
**内容类型**: 文字+图文,热搜词条无封面图时展示文字卡片
#### P2 平台
> 以下平台的 API 端点待根据 TikHub 最新文档确认,适配器实现时以实际接口为准。
| 平台 | 推测热榜端点 | 推测详情端点 |
|------|-------------|-------------|
| Threads | `/api/v1/threads/web/fetch_trending_post` | `/api/v1/threads/web/fetch_post_detail` |
| Reddit | `/api/v1/reddit/web/fetch_hot_post` | `/api/v1/reddit/web/fetch_post_detail` |
| LinkedIn | `/api/v1/linkedin/web/fetch_trending_post` | `/api/v1/linkedin/web/fetch_post_detail` |
| 知乎 | `/api/v1/zhihu/app/fetch_hot_question` | `/api/v1/zhihu/app/fetch_question_detail` |
| Lemon8 | `/api/v1/lemon8/web/fetch_trending_post` | `/api/v1/lemon8/web/fetch_post_detail` |
| 快手 | `/api/v1/kuaishou/app/fetch_hot_video` | `/api/v1/kuaishou/app/fetch_video_detail` |
| 微信 | `/api/v1/wechat/mp/fetch_hot_article` | `/api/v1/wechat/mp/fetch_article_detail` |
| 皮皮虾 | `/api/v1/pipix/app/fetch_hot_video` | `/api/v1/pipix/app/fetch_video_detail` |
| Sora | `/api/v1/sora/web/fetch_featured_video` | `/api/v1/sora/web/fetch_video_detail` |
### 4.3 每条内容需采集的数据字段
| 字段 | 说明 | 展示位置 |
|------|------|----------|
| title | 标题/描述 | 卡片+详情页 |
| cover_url | 封面图 URL | 卡片 |
| video_url | 视频播放地址 | 详情页 |
| author_name | 作者昵称 | 卡片+详情页 |
| author_avatar | 作者头像 | 卡片+详情页 |
| play_count | 播放量/浏览量 | 卡片+详情页 |
| like_count | 点赞数 | 卡片+详情页 |
| comment_count | 评论数 | 卡片+详情页 |
| share_count | 分享/转发数 | 详情页 |
| publish_time | 发布时间 | 卡片+详情页 |
| platform | 来源平台 | 卡片+详情页 |
| original_url | 原文链接 | 详情页 |
| tags | 标签/话题 | 详情页 |
---
## 5. 技术方案(推荐)
### 5.1 技术栈选择
| 层级 | 技术 | 理由 |
|------|------|------|
| 框架 | **Next.js 14+ (App Router)** | 全栈能力、API Routes 做后端代理、SSR 支持、Vercel 一键部署 |
| UI 库 | **Tailwind CSS + shadcn/ui** | 简约现代风格、组件丰富、高度可定制 |
| 状态管理 | **Zustand** | 轻量、简洁、适合中小型项目 |
| 数据请求 | **TanStack Query (React Query)** | 缓存管理、自动刷新、loading/error 状态 |
| 本地存储 | **localStorage / IndexedDB** | 收藏数据持久化MVP 阶段无需数据库) |
| 包管理器 | **pnpm** | 速度快、磁盘占用小 |
### 5.2 项目架构
```
muse_creative_hotspots/
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── layout.tsx # 全局布局
│ │ ├── page.tsx # 首页(热点内容流)
│ │ ├── detail/[id]/ # 内容详情页
│ │ ├── favorites/ # 收藏页
│ │ ├── settings/ # 设置页
│ │ └── api/ # API Routes代理 TikHub
│ │ └── tikhub/
│ │ └── [platform]/route.ts
│ ├── components/ # UI 组件
│ │ ├── layout/ # 布局组件Header, Sidebar, etc.
│ │ ├── card/ # 内容卡片组件
│ │ └── ui/ # shadcn/ui 基础组件
│ ├── lib/ # 工具库
│ │ ├── tikhub.ts # TikHub API 封装
│ │ ├── platforms.ts # 平台配置与适配器
│ │ └── utils.ts # 通用工具函数
│ ├── stores/ # Zustand 状态管理
│ │ ├── favorites.ts # 收藏状态
│ │ └── settings.ts # 设置状态
│ └── types/ # TypeScript 类型定义
│ └── content.ts # 统一内容数据结构
├── public/ # 静态资源
├── tailwind.config.ts
├── next.config.ts
├── package.json
└── PRD.md
```
### 5.3 关键设计决策
1. **API 代理层**:通过 Next.js API Routes 代理 TikHub 请求,避免前端暴露 API Key
2. **统一数据模型**:所有平台的内容映射为统一的 `ContentItem` 类型,平台差异在适配器层处理
3. **平台适配器模式**:每个平台实现一个适配器,负责 API 调用和数据格式转换,方便后续扩展新平台
---
## 6. 页面设计规格
### 6.1 设计风格
- **简约现代**(参考 Notion/Linear 风格)
- 大量留白,信息层次清晰
- 浅色主题为主,后期可扩展暗色模式
- 平台图标采用各平台官方 logo 配色,便于快速识别
### 6.2 页面结构
```
┌─────────────────────────────────────────────┐
│ Logo [全部][抖音][TikTok][小红书]... ⚙️ │ ← 顶部导航:平台 Tab 切换
├─────────────────────────────────────────────┤
│ 排序: [最热] [最新] 🔄 刷新 上次: 10:30 │ ← 工具栏:排序+刷新
├─────────────────────────────────────────────┤
│ │
│ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │
│ │封面│ │封面│ │封面│ │封面│ │封面│ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │标题│ │标题│ │标题│ │标题│ │标题│ │ ← 卡片网格信息流
│ │数据│ │数据│ │数据│ │数据│ │数据│ │
│ └────┘ └────┘ └────┘ └────┘ └────┘ │
│ │
│ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │
│ │ .. │ │ .. │ │ .. │ │ .. │ │ .. │ │
│ └────┘ └────┘ └────┘ └────┘ └────┘ │
│ │
└─────────────────────────────────────────────┘
```
---
## 7. 非功能需求
| 项目 | 要求 |
|------|------|
| 部署方式 | 先本地开发localhost后期部署到 Vercel 或云服务器 |
| 响应式 | 桌面端优先,基本适配平板 |
| 性能 | 首屏加载 < 3s支持图片懒加载 |
| API 成本控制 | 默认 30 分钟刷新一次支持手动调整需展示当日 API 调用量 |
---
## 8. MVP 验收标准
- [ ] 成功接入抖音TikTok小红书三个平台的热榜/推荐内容
- [ ] 卡片流展示内容包含封面图标题关键数据
- [ ] 可按平台 Tab 切换查看
- [ ] 可按播放量/点赞数排序
- [ ] 点击卡片进入站内详情页展示完整数据+原文链接
- [ ] 收藏功能可用收藏数据本地持久化
- [ ] 支持手动刷新 + 自动定时刷新
- [ ] 设置页可配置 API Key 和刷新间隔
---
## 验证方式
1. `pnpm dev` 启动本地开发服务器
2. 访问首页确认三个平台的热点内容正常加载和展示
3. 测试平台切换排序收藏详情页等功能
4. 检查 API 代理层是否正确隐藏了 API Key
5. 测试自动刷新和手动刷新功能