geo/docs/plans/2026-06-01-006-feat-geo-fro...

324 lines
15 KiB
Markdown
Raw Permalink 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.

---
date: 2026-06-01
status: completed
origin: docs/brainstorms/2026-06-01-geo-frontend-visualization-requirements.md
---
## Summary
为 GEO 平台已有后端 API 补建前端可视化页面分三批交付P0 监测页面改造 + 竞品分析新建P1 引用统计 + 健康评分 + 检测任务 + Dashboard Agent 区域P2 导出入口 + 公开评分落地页 + Agent 配置 + 趋势/Schema 页面。可视化优先,复用 recharts + 现有 CompetitorRadarChart 组件。
## Problem Frame
后端 API 完整但前端多处断裂:监测页面展示告警而非监测记录,竞品分析无前端,引用统计/健康评分/检测任务等 API 未对接。用户在 Onboarding 看到健康评分后进入 Dashboard 却找不到对应页面。
## Requirements
**P0 核心可视化闭环:** R1R9
**P1 数据深度可视化:** R10R15
**P2 体验补全:** R16R21
Full requirements in origin document.
## Key Technical Decisions
**KTD1. 监测页面改造为主 Tab 模式** — 监测记录为主 Tab告警为子 Tab。替换侧边栏"数据监测"入口(原 `/dashboard/analytics`)指向 `/dashboard/monitoring`。保留现有告警逻辑不删除。
**KTD2. 竞品分析独立页面** — 新建 `/dashboard/competitors` 页面,复用现有 `CompetitorRadarChart` 组件(`components/charts/CompetitorRadarChart.tsx`)。侧边栏新增"竞品分析"导航项。
**KTD3. 复用 recharts + 现有图表组件** — 不引入新图表库。引用趋势用 `trend-chart.tsx`,平台分布用 `platform-chart.tsx`,竞品雷达图用 `CompetitorRadarChart.tsx`。健康评分仪表盘用 recharts `PieChart` 半圆实现。
**KTD4. 监测任务由 Onboarding 自动创建** — 在 Onboarding Step3 创建品牌后自动调用 `monitoringApi.createTask`,不在监测页面提供手动创建 UI。
**KTD5. API 模块复用现有模式** — 新增 `lib/api/competitor.ts`、`lib/api/scoring.ts`、`lib/api/detection.ts`、`lib/api/trends.ts`、`lib/api/schema-suggestions.ts`,遵循 `fetchWithAuth` + typed interfaces + const object export 模式。已有 `monitoring.ts``alerts.ts` 直接复用。
## Implementation Units
### U1. 监测页面改造
**Goal:** 将 monitoring 页面从纯告警改为监测记录 + 告警双 Tab监测记录为主 Tab对接 `/api/v1/monitoring` 的 5 个端点。
**Requirements:** R1, R2, R3, R4, R5
**Dependencies:** none
**Files:**
- `frontend/app/(dashboard)/dashboard/monitoring/page.tsx` — 重写
- `frontend/app/(dashboard)/layout.tsx` — 替换"数据监测"导航项 href
**Approach:**
- 页面顶部使用 shadcn `Tabs` 组件Tab1"监测记录"Tab2"告警通知"
- Tab1 调用 `monitoringApi.getBrandRecords(token, brandId)` 获取记录列表
- 每条记录展示:平台、上次检测时间、变化类型 Badgepositive=绿/negative=红/neutral=灰)、变化摘要
- 点击记录展开详情:调用 `monitoringApi.getReport(token, recordId)` 获取变化报告,展示指标对比和建议
- "立即检测"按钮调用 `monitoringApi.triggerCheck(token, recordId)`loading 状态后刷新列表
- 状态切换active/paused调用 `monitoringApi.updateStatus(token, recordId, status)`
- Tab2 保留现有告警逻辑,提取为 `AlertsTab` 子组件
- 侧边栏 `NAV_GROUPS``analytics` 项的 href 从 `/dashboard/analytics` 改为 `/dashboard/monitoring`label 改为"品牌监测"
**Patterns to follow:** `citations/page.tsx` 的 useApi + useState 模式;`api-states.tsx` 的 LoadingState/ErrorState/EmptyState
**Test scenarios:**
- 监测记录列表加载并展示变化类型 Badge
- 点击记录展开变化报告详情
- 点击"立即检测"触发检测并刷新列表
- 切换监测状态 active/paused
- 告警 Tab 保留现有功能不受影响
**Verification:** 页面加载显示监测记录 Tab 为默认,告警 Tab 可切换,监测 API 被正确调用
---
### U2. 竞品分析页面
**Goal:** 新建竞品分析页面展示竞品列表、雷达图对比、差距评分、LLM 推荐。
**Requirements:** R6, R7, R8, R9
**Dependencies:** none
**Files:**
- `frontend/app/(dashboard)/dashboard/competitors/page.tsx` — 新建
- `frontend/lib/api/competitor.ts` — 新建
- `frontend/app/(dashboard)/layout.tsx` — 新增"竞品分析"导航项
- `frontend/lib/api/index.ts` — 添加 competitor 导出
**Approach:**
- 新建 `lib/api/competitor.ts`,封装 6 个端点:竞品 CRUD、推荐、分析、差距评分、洞察详情
- 页面布局:顶部竞品列表卡片 + 添加竞品按钮,中部雷达图对比区,底部差距评分卡片
- 竞品列表调用 `GET /{brand_id}/competitors/`,添加调用 `POST /{brand_id}/competitors/`(上限 5 个)
- 添加竞品时展示推荐列表:调用 `GET /{brand_id}/competitors/recommendations/`
- 雷达图复用 `CompetitorRadarChart` 组件,数据来自 `POST /competitor/analyze`
- 差距评分调用 `GET /competitor/brand/{brand_id}/gap-summary`
- 侧边栏新增导航项:`{ id: "competitors", label: "竞品分析", href: "/dashboard/competitors", icon: <Swords /> }`
**Patterns to follow:** `CompetitorRadarChart.tsx` 已有雷达图实现;`citations/page.tsx` 的列表 + 详情模式
**Test scenarios:**
- 竞品列表加载并展示
- 添加竞品(从推荐列表选择 + 手动输入)
- 删除竞品(上限 5 个校验)
- 执行竞品分析并展示雷达图
- 差距评分卡片展示
**Verification:** 页面加载显示竞品列表,雷达图可交互,差距评分正确展示
---
### U3. Onboarding 自动创建监测任务
**Goal:** 在 Onboarding Step3 创建品牌后自动调用 `monitoringApi.createTask` 创建监测任务。
**Requirements:** KTD4
**Dependencies:** U1
**Files:**
- `frontend/app/(dashboard)/onboarding/page.tsx` — 修改 handleStep3Next/handleStep3Skip
- `frontend/lib/hooks/use-onboarding-data.ts` — 添加 createMonitoringTask 方法
**Approach:**
-`useOnboardingData` hook 中添加 `createMonitoringTask` 方法,调用 `monitoringApi.createTask`
-`handleStep3Next``handleStep3Skip` 中,品牌创建成功后立即调用 `createMonitoringTask`
- 传入品牌 ID 和选择的平台列表,频率使用用户选择的 frequency
- 监测任务创建失败不阻塞 onboarding 流程静默失败console.warn 级别)
**Patterns to follow:** `useOnboardingData` hook 的 `createBrand` 模式
**Test scenarios:**
- Onboarding Step3 完成后自动创建监测任务
- 监测任务创建失败不阻塞 onboarding
**Verification:** 完成 onboarding 后在监测页面能看到自动创建的监测记录
---
### U4. 引用统计可视化
**Goal:** 在引用页面添加统计图表区域展示引用率、平台分布、30 天趋势。
**Requirements:** R10
**Dependencies:** none
**Files:**
- `frontend/app/(dashboard)/dashboard/citations/page.tsx` — 修改
- `frontend/lib/api/citations.ts` — 新建或扩展
**Approach:**
- 新建 `lib/api/citations.ts`,封装 `getCitationStats` 端点
- 在引用页面顶部添加统计区域3 个统计卡片 + 2 个图表)
- 统计卡片:引用率、平均位置、总引用数
- 图表 1平台分布饼图recharts PieChart复用 analytics 页面的饼图模式
- 图表 230 天趋势折线图,复用 `trend-chart.tsx` 组件
- 统计数据调用 `GET /api/v1/citations/stats`
**Patterns to follow:** `trend-chart.tsx` 折线图;`usage/page.tsx` 饼图模式;`api-states.tsx` 加载状态
**Test scenarios:**
- 统计卡片正确展示引用率、平均位置、总数
- 平台分布饼图按平台着色
- 30 天趋势折线图展示变化曲线
- 无数据时展示空状态
**Verification:** 引用页面顶部展示统计图表,数据与后端 API 一致
---
### U5. 健康评分页面
**Goal:** 新建健康评分页面,展示 V2 五维度评分仪表盘、竞品对比雷达图、评分历史趋势。
**Requirements:** R11, R12, R13
**Dependencies:** U2复用 CompetitorRadarChart
**Files:**
- `frontend/app/(dashboard)/dashboard/health-score/page.tsx` — 新建
- `frontend/lib/api/scoring.ts` — 新建
- `frontend/app/(dashboard)/layout.tsx` — 新增"健康评分"导航项
- `frontend/lib/api/index.ts` — 添加 scoring 导出
**Approach:**
- 新建 `lib/api/scoring.ts`,封装 4 个端点V2 评分、V1 兼容、历史趋势、竞品对比
- 页面布局顶部总评分仪表盘recharts PieChart 半圆),中部 5 维度评分卡片,底部 Tab 切换(竞品对比 / 历史趋势)
- 总评分仪表盘recharts `PieChart` 两个弧形(已得分 + 剩余),中心显示分数
- 5 维度卡片:提及率、推荐排名、情感倾向、引用质量、竞品对比,每项显示分数 + 进度条
- 竞品对比 Tab复用 `CompetitorRadarChart`,数据来自 `GET /{brand_id}/compare/`
- 历史趋势 Tab复用 `trend-chart.tsx`,数据来自 `GET /{brand_id}/score/history/`
- 侧边栏新增导航项:`{ id: "health-score", label: "健康评分", href: "/dashboard/health-score", icon: <Heart /> }`
**Patterns to follow:** `CompetitorRadarChart.tsx``trend-chart.tsx``onboarding/Step0HealthScore.tsx` 的评分展示模式
**Test scenarios:**
- 总评分仪表盘正确显示分数和弧形
- 5 维度卡片展示各维度分数和进度条
- 竞品对比雷达图展示品牌与竞品对比
- 历史趋势折线图展示评分变化
- 无品牌时展示空状态引导
**Verification:** 页面加载展示完整评分仪表盘,图表交互正常
---
### U6. 检测任务管理 + Dashboard Agent 区域
**Goal:** 新建检测任务管理页面,替换 Dashboard 主页 Agent 活动占位内容。
**Requirements:** R14, R15
**Dependencies:** none
**Files:**
- `frontend/app/(dashboard)/dashboard/detection/page.tsx` — 新建
- `frontend/lib/api/detection.ts` — 新建
- `frontend/app/(dashboard)/dashboard/page.tsx` — 修改 Agent 活动区域
- `frontend/app/(dashboard)/layout.tsx` — 新增"检测任务"导航项
- `frontend/lib/api/index.ts` — 添加 detection 导出
**Approach:**
- 新建 `lib/api/detection.ts`,封装检测任务 CRUD + 触发端点
- 检测任务页面任务列表Table+ 创建任务 Dialog + 手动触发按钮
- 任务列表展示:查询词、平台、频率、状态、上次运行时间、下次运行时间
- 创建任务 Dialog选择查询词、平台、频率
- 手动触发调用 `POST /tasks/{task_id}/trigger`
- Dashboard 主页 Agent 活动区域:调用 `agentsApi.listTasks(token, {limit: 5})` 获取最近 5 条执行记录,展示为紧凑列表(任务类型 + 状态 Badge + 耗时 + 时间)
- 侧边栏新增导航项:`{ id: "detection", label: "检测任务", href: "/dashboard/detection", icon: <ScanSearch /> }`
**Patterns to follow:** `queries/page.tsx` 的 CRUD 模式;`agents/page.tsx` 的任务列表模式
**Test scenarios:**
- 检测任务列表加载并展示
- 创建新检测任务
- 手动触发检测
- 删除检测任务
- Dashboard Agent 区域展示最近执行记录
**Verification:** 检测任务页面 CRUD 正常Dashboard Agent 区域不再显示"功能开发中"
---
### U7. P2 体验补全
**Goal:** 添加导出入口、公开评分落地页、Agent 配置 UI、趋势/Schema 页面。
**Requirements:** R16, R17, R18, R19, R20, R21
**Dependencies:** U4, U5
**Files:**
- `frontend/app/(dashboard)/dashboard/citations/page.tsx` — 添加导出按钮
- `frontend/app/(dashboard)/dashboard/reports/page.tsx` — 添加导出按钮
- `frontend/app/(public)/health-score/page.tsx` — 新建
- `frontend/app/(dashboard)/dashboard/agents/page.tsx` — 添加配置面板
- `frontend/app/(dashboard)/dashboard/trends/page.tsx` — 新建
- `frontend/app/(dashboard)/dashboard/schema/page.tsx` — 新建
- `frontend/lib/api/trends.ts` — 新建
- `frontend/lib/api/schema-suggestions.ts` — 新建
- `frontend/app/(dashboard)/layout.tsx` — 添加新导航项
- `frontend/lib/api/index.ts` — 添加新模块导出
**Approach:**
- 引用页面添加"导出 CSV"和"导出 PDF"按钮,调用 `fetchWithAuth` blob 模式
- 报告页面添加导出按钮(已有逻辑,确认按钮存在且可用)
- 公开健康评分落地页:无需登录,输入品牌名调用 `/api/v1/public/health-score`,展示 3 维度评分 + "注册查看完整报告" CTA
- Agent 配置面板:在 agents 页面添加配置 Dialog调用 `GET/PUT /{agent_name}/config`
- 趋势洞察页面:调用 `/api/v1/trends` 获取洞察列表和趋势摘要
- Schema 建议页面:调用 `/api/v1/schema` 获取和管理建议
**Patterns to follow:** `reports.ts` 的 blob 导出模式;`Step0HealthScore.tsx` 的公开评分展示
**Test scenarios:**
- 引用页面 CSV/PDF 导出按钮可用
- 公开评分页面无需登录即可查看
- Agent 配置 Dialog 展示和修改配置
- 趋势洞察页面展示洞察列表
- Schema 建议页面展示建议列表
**Verification:** 所有 P2 功能页面可访问且 API 对接正确
---
## Scope Boundaries
**Deferred for later:**
- 监测任务手动创建 UIOnboarding 自动创建已覆盖)
- Agent 手动创建任务 UI
- 内容编辑器深度优化和版本对比
- 国际化i18n改造
- 实时数据推送WebSocket
**Outside this product's identity:**
- 后端 API 新增或修改
- 移动端适配
## Open Questions
**Deferred to implementation:**
- 竞品雷达图的具体维度映射(后端 5 种分析类型如何映射到雷达图轴)
- 公开健康评分落地页的 URL 路由和 SEO 策略
- Dashboard Agent 区域的数据刷新策略
## Risks & Dependencies
- **后端 API 数据格式未验证** — 计划基于代码扫描,未做运行时验证。实现时可能需要适配实际响应格式
- **品牌 ID 获取** — 多个页面需要当前用户的品牌 ID需确认获取方式useApi 调用 brands 端点 or useUserStore
- **recharts 雷达图数据格式** — CompetitorRadarChart 已有实现,但竞品分析 API 返回格式可能需要适配
## Sources & Research
- `frontend/app/(dashboard)/dashboard/citations/page.tsx` — 页面模式参考
- `frontend/lib/api/client.ts` — fetchWithAuth 统一客户端
- `frontend/lib/api/monitoring.ts` — 已有监测 API 模块(完全未使用)
- `frontend/lib/api/alerts.ts` — 告警 API 模块
- `frontend/components/charts/CompetitorRadarChart.tsx` — 已有雷达图组件
- `frontend/components/charts/trend-chart.tsx` — 已有趋势图组件
- `frontend/components/charts/platform-chart.tsx` — 已有平台分布图组件
- `frontend/components/ui/api-states.tsx` — 共享加载/错误/空状态组件
- `frontend/app/(dashboard)/layout.tsx` — 侧边栏导航配置
- `backend/app/api/v1/monitoring.py` — 监测端点
- `backend/app/api/v1/competitors.py` + `backend/app/api/v1/competitor.py` — 竞品端点
- `backend/app/api/v1/citations.py` — 引用统计端点
- `backend/app/api/v1/scoring.py` — 评分端点
- `backend/app/api/v1/detection.py` — 检测任务端点