---
date: 2026-06-01
status: active
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 核心可视化闭环:** R1–R9
**P1 数据深度可视化:** R10–R15
**P2 体验补全:** R16–R21

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)` 获取记录列表
- 每条记录展示：平台、上次检测时间、变化类型 Badge（positive=绿/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 页面的饼图模式
- 图表 2：30 天趋势折线图，复用 `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:**
- 监测任务手动创建 UI（Onboarding 自动创建已覆盖）
- 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` — 检测任务端点
