# 管理后台与可视化设计文档 ## 一、设计原则 ### 1.1 核心理念 **克制、高效、数据为先** - 不做花哨的动效,所有设计都服务于「快速定位问题」 - 深色主题为主,长时间盯着不累眼 - 信息分层明确,重要的信息一眼看到,次要的信息收起来 - 操作路径短:3 次点击以内能到达任何核心页面 ### 1.2 技术选型 | 层级 | 技术 | 说明 | |------|------|------| | 框架 | React 18 | 生态成熟,社区活跃 | | 构建 | Vite 5 | 快,开发体验好 | | 语言 | TypeScript | 类型安全,减少 bug | | UI 库 | Ant Design 5 | 后台管理组件最全,深色主题好 | | 路由 | React Router v6 | 官方推荐,功能完整 | | 状态管理 | Zustand | 轻量,比 Redux 简单太多 | | 数据请求 | TanStack Query (React Query) | 缓存、重发、分页都有了 | | 图表 | ECharts 5 | 功能强大,国内用得多 | | HTTP 客户端 | Axios | 拦截器、取消请求都方便 | | 样式 | CSS Modules + Less | 按需定制主题 | | 代码规范 | ESLint + Prettier | 统一代码风格 | ### 1.3 为什么选 Ant Design - **组件最丰富**:表格、表单、弹窗、树形...后台需要的都有 - **深色主题好**:AntD 5 原生支持 ConfigProvider 切换主题 - **ProComponents**:ProTable、ProForm 等高级组件,开发效率翻倍 - **生态成熟**:遇到问题搜一下就有答案 - **设计语言统一**:有自己的设计规范,不用从零定 ### 1.3 页面清单 | 页面 | 路径 | 优先级 | 说明 | |------|------|--------|------| | 项目列表 | `/manage/` | P0 | 项目管理(已有) | | 项目概览 | `#/overview` | P0 | 项目总览、关键指标 | | 错误列表 | `#/errors` | P0 | 错误 Issue 列表、详情 | | 错误详情 | `#/errors/:id` | P0 | 单个错误的详细分析 | | 性能分析 | `#/performance` | P1 | Web Vitals、性能趋势 | | 网络分析 | `#/network` | P2 | 接口请求统计 | | 行为分析 | `#/behavior` | P2 | PV、用户行为 | | 告警中心 | `#/alerts` | P1 | 告警规则、告警历史 | | 日志查询 | `#/logs` | P1 | Loki 原始日志查询 | | 接入指南 | `#/integration` | P0 | SDK 接入文档(已有) | | 项目设置 | `#/settings` | P1 | 项目配置、成员、采样率 | --- ## 二、设计系统 ### 2.1 配色系统 **主色调**:蓝色系(专业、可信赖) | 用途 | 颜色 | 色值 | |------|------|------| | 品牌主色 | 亮蓝 | `#0090f9` | | 品牌主色(悬停) | 蓝 | `#1da1f2` | | 成功 | 绿 | `#26a641` | | 警告 | 黄 | `#e9c46a` | | 错误 | 红 | `#e63946` | | 信息 | 紫 | `#a855f7` | **中性色(深色主题)**: | 用途 | 色值 | 说明 | |------|------|------| | 背景(最深) | `#0d1117` | 页面底色 | | 背景(卡片) | `#161b22` | 卡片、弹窗 | | 背景(悬浮) | `#21262d` | hover、选中 | | 边框 | `#30363d` | 分割线、边框 | | 文字(主) | `#e6edf3` | 标题、正文 | | 文字(次) | `#8b949e` | 辅助说明、时间 | | 文字(弱) | `#6e7681` | 占位符、disabled | ### 2.2 字体与间距 **字体栈**: ```css font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; ``` **字号阶梯**: | 用途 | 大小 | 字重 | |------|------|------| | 页面大标题 | 24px | 600 | | 区块标题 | 18px | 600 | | 卡片标题 | 16px | 600 | | 正文 | 14px | 400 | | 辅助文字 | 12px | 400 | **间距阶梯**(4px 基准): `4px / 8px / 12px / 16px / 20px / 24px / 32px / 48px` ### 2.3 圆角与阴影 | 元素 | 圆角 | 阴影 | |------|------|------| | 按钮 | 6px | 无 | | 输入框 | 6px | 无 | | 卡片 | 8px | 无(用边框区分) | | 弹窗 | 12px | `0 8px 24px rgba(0,0,0,0.4)` | | 下拉菜单 | 8px | `0 4px 12px rgba(0,0,0,0.3)` | --- ## 三、整体布局 ### 3.1 布局结构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ Top Bar(64px) │ │ ┌──────┐ ┌──────────────┐ ┌─────────────┐ │ │ │ Logo │ │ 项目选择器 ▼ │ │ 🔔 👤 设置 │ │ │ └──────┘ └──────────────┘ └─────────────┘ │ ├────────┬────────────────────────────────────────────────────────┤ │ │ │ │ Side │ Content Area │ │ Nav │ ┌──────────────────────────────────────────────────┐ │ │(64px │ │ Page Header(标题 + 操作 + 筛选) │ │ │ 展开 │ └──────────────────────────────────────────────────┘ │ │ 220px)│ ┌──────────────────────────────────────────────────┐ │ │ │ │ Metric Cards(指标卡片行) │ │ │ │ └──────────────────────────────────────────────────┘ │ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ │ Charts / Tables(主内容区) │ │ │ │ │ │ │ │ │ │ │ │ │ │ └──────────────────────────────────────────────────┘ │ │ │ │ └────────┴────────────────────────────────────────────────────────┘ ``` ### 3.2 侧边栏(可折叠) **收起态(64px)**:只显示图标 ``` 📊 ← 概览 🐛 ← 错误 ⚡ ← 性能 🌐 ← 网络 📈 ← 看板 🔔 ← 告警 ⚙️ ← 设置 ``` **展开态(220px)**:图标 + 文字 + 角标 ``` 📊 概览 🐛 错误 12 ← 未解决错误数 ⚡ 性能 3 ← 有性能告警 🌐 网络 📈 看板 🔔 告警 5 ← 未读告警 ⚙️ 设置 ``` ### 3.3 顶部栏 ``` ┌─────────────────────────────────────────────────────────────┐ │ ◀▶ 🪲 Light-Sentry [▼ 前端项目 - my-app ] 🔔 ⚙️ │ └─────────────────────────────────────────────────────────────┘ ``` - 左侧:折叠按钮 + Logo + 产品名 - 中间:项目选择器(下拉,可搜索) - 右侧:告警铃(有未读红点) + 设置 ### 3.4 页面头(每个页面都有) ``` ┌─────────────────────────────────────────────────────────────┐ │ 错误 Issues [时间范围: 24h ▼] [搜索] │ │ 12 个未解决 · 3 个今日新增 [导出] [刷新] │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 四、核心页面详细设计 ### 4.1 概览页(Overview) **定位**:一屏看完项目健康状况,有问题快速跳转到对应页面 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 概览 [24h ▼] [环境: 全部 ▼] │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 错误数 │ │ 错误率 │ │ 影响用户│ │ LCP P95 │ │ CLS P95 │ │ │ │ 128 │ │ 2.3% │ │ 1,234 │ │ 3.2s │ │ 0.15 │ │ │ │ ↑15% │ │ ↑0.8% │ │ ↑12% │ │ 🔴 差 │ │ 🟡 中 │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ ┌──────────────────────────┐ ┌───────────────────────────────┐ │ │ │ 错误趋势(24h) │ │ Top 5 错误 │ │ │ │ ╱╲ │ │ 1. TypeError: Cannot read... │ │ │ │ ╱ ╲ ╱╲ │ │ 2. AxiosError: 500 Inter... │ │ │ │ ╱╲╱ ╲╱ ╲ │ │ 3. ReferenceError: x is ... │ │ │ │ │ │ 4. ChunkLoadError: Loadin... │ │ │ │ │ │ 5. TypeError: Cannot set... │ │ │ └──────────────────────────┘ └───────────────────────────────┘ │ │ │ │ ┌──────────────────────────┐ ┌───────────────────────────────┐ │ │ │ 性能趋势(LCP/FID/CLS) │ │ 新错误(今日新增) │ │ │ │ 🟢 LCP 2.5s │ │ • TypeError: Cannot read... │ │ │ │ 🟡 FID 120ms │ │ • AxiosError: Network Er... │ │ │ │ 🟢 CLS 0.08 │ │ • ReferenceError: foo i... │ │ │ │ │ │ │ │ │ └──────────────────────────┘ └───────────────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 实时错误流(最近 5 分钟) │ │ │ │ 14:32:15 TypeError: Cannot read property 'foo' │ │ │ │ 14:32:10 AxiosError: Request failed with 500 │ │ │ │ 14:32:05 ReferenceError: x is not defined │ │ │ │ ... │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` **设计要点**: - 5 个核心指标卡片放在最上面,一眼看完 - 指标卡片底部的小数字是「同比昨日」,红涨绿跌 - 左图右表,趋势 + Top 排行 - 底部实时流,让你感知系统状态 ### 4.2 错误列表页(Errors) **定位**:浏览和管理错误 Issue,找到要处理的问题 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 错误 Issues [24h ▼] [🔍 搜索错误消息] │ │ 128 个错误 · 12 个未解决 · 3 个今日新增 [状态: 全部 ▼] [级别: ▼] │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌───┬─────────────────────┬──────┬───────┬───────┬──────────┐ │ │ │ ✓ │ 错误消息 │ 级别 │ 次数 │ 用户 │ 最后出现 │ │ │ ├───┼─────────────────────┼──────┼───────┼───────┼──────────┤ │ │ │ 🔴│Cannot read property│error │ 456 │ 123 │ 2 分钟前 │ │ │ │ │ 'foo' of undefined│ │ │ │ │ │ │ ├───┼─────────────────────┼──────┼───────┼───────┼──────────┤ │ │ │ 🔴│AxiosError: Request │error │ 234 │ 89 │ 5 分钟前 │ │ │ │ │ failed with 500 │ │ │ │ │ │ │ ├───┼─────────────────────┼──────┼───────┼───────┼──────────┤ │ │ │ 🟡│ReferenceError: x is│warning│ 123 │ 45 │ 12 分钟前 │ │ │ │ │ not defined │ │ │ │ │ │ │ └───┴─────────────────────┴──────┴───────┴───────┴──────────┘ │ │ │ │ ◀ 1 2 3 4 ... 12 ▶ 每页 20 条 ▼ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` **筛选器**: - 时间范围(15m / 1h / 6h / 24h / 7d / 30d / 自定义) - 状态(全部 / 未解决 / 已解决 / 已忽略) - 级别(全部 / fatal / error / warning / info) - 搜索(错误消息、指纹、文件路径) - 环境 - 版本(release) **列表交互**: - 点击行 → 进入错误详情 - 行前 checkbox → 批量操作(标记已解决、忽略) - hover 行 → 显示快捷操作(查看、已解决、忽略) ### 4.3 错误详情页 **定位**:深入分析单个错误,定位根因 ``` ┌─────────────────────────────────────────────────────────────────┐ │ ← 返回列表 [标记已解决] [忽略] [分配给 ▼] │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 🔴 TypeError: Cannot read property 'foo' of undefined │ │ Uncaught exception · active · 来自浏览器 JS │ │ │ │ 📊 概览 📝 堆栈 📋 Breadcrumbs 👥 用户 🌐 分布 ⏱️ 趋势 │ │ ───── │ │ │ │ ┌──────────────┬──────────────┬──────────────┬──────────────┐ │ │ │ 总次数 │ 影响用户 │ 首次出现 │ 最后出现 │ │ │ │ 456 │ 123 │ 3 天前 │ 2 分钟前 │ │ │ └──────────────┴──────────────┴──────────────┴──────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 发生趋势(7 天) │ │ │ │ ╱╲ │ │ │ │ ╱ ╲ ╱╲ │ │ │ │ ╱╲╱ ╲╱ ╲ │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 堆栈跟踪 │ │ │ │ 📄 app.js:123 onClick │ │ │ │ 📄 utils.js:45 handleClick │ │ │ │ 📄 index.js:8 main │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 最近出现(最新 5 条) │ │ │ │ 14:32:15 user_123 Chrome 120 macOS 点击按钮时 │ │ │ │ 14:31:45 user_456 Safari 17 iOS 加载页面时 │ │ │ │ ... │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` **Tab 内容**: - **概览**:核心数据 + 趋势图 + 最近出现 - **堆栈**:完整堆栈跟踪,可折叠,点击跳源码(如果配置了 sourcemap) - **Breadcrumbs**:用户操作路径,时间线展示 - **用户**:受影响的用户列表 - **分布**:浏览器、OS、设备、地区分布 - **趋势**:更长时间的趋势图 ### 4.4 性能分析页 **定位**:看页面性能好不好,哪里慢 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 性能分析 [24h ▼] [页面: 全部 ▼] │ │ Web Vitals 指标 [浏览器: 全部 ▼] │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │ │ │ LCP │ │ FID │ │ CLS │ │ FCP │ │ │ │ 3.2s 🔴 │ │ 120ms 🟡 │ │ 0.15 🟢 │ │ 1.8s 🟡 │ │ │ │ P95: 4.5s │ │ P95: 200ms │ │ P95: 0.25 │ │ P95: 2.5s│ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └───────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 性能趋势(P50 / P75 / P95 / P99) │ │ │ │ ╭────────────────────────────────────────────────────╮ │ │ │ │ │ ▲ P99 ── P95 ─ ─ P75 ┄ ┄ P50 │ │ │ │ │ │ │╲ │ │ │ │ │ │ │ ╲──────╮ │ │ │ │ │ │ │ ╲╱╲ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────╯ │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 页面性能排行 [按 LCP 排序 ▼] │ │ │ ├─────────────────────┬──────┬──────┬──────┬──────┬───────┤ │ │ │ 页面 │ LCP │ FID │ CLS │ 样本 │ 评级 │ │ │ ├─────────────────────┼──────┼──────┼──────┼──────┼───────┤ │ │ │ /home │ 2.8s │ 80ms │ 0.10 │ 1.2k │ 🟢 良 │ │ │ │ /product/:id │ 4.2s │ 150ms│ 0.20 │ 800 │ 🔴 差 │ │ │ │ /checkout │ 3.5s │ 120ms│ 0.15 │ 500 │ 🟡 中 │ │ │ │ ... │ │ │ │ │ │ │ │ └─────────────────────┴──────┴──────┴──────┴──────┴───────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` ### 4.5 告警中心 **定位**:配置告警规则,查看告警历史 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 告警中心 │ │ ┌─────────┐ │ │ │ 告警规则 │ 告警历史 │ │ └─────────┘ │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ [+ 新建告警规则] │ │ │ │ ┌───┬─────────────────────┬──────────┬───────┬────────┬─────┐ │ │ │ ✓ │ 规则名称 │ 类型 │ 级别 │ 状态 │ 操作 │ │ │ ├───┼─────────────────────┼──────────┼───────┼────────┼─────┤ │ │ │ 🔔│ 错误数量突增 │ 突增告警 │ 严重 │ ✅ 启用 │ ... │ │ │ ├───┼─────────────────────┼──────────┼───────┼────────┼─────┤ │ │ │ 🔔│ 新错误出现 │ 新错误 │ 警告 │ ✅ 启用 │ ... │ │ │ ├───┼─────────────────────┼──────────┼───────┼────────┼─────┤ │ │ │ 🔔│ LCP 超过 4s │ 阈值告警 │ 警告 │ ✅ 启用 │ ... │ │ │ └───┴─────────────────────┴──────────┴───────┴────────┴─────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## 五、组件设计 ### 5.1 指标卡片 ``` ┌─────────────────┐ │ 错误总数 │ ← 标题(小字、灰色) │ 128 │ ← 数值(大字、粗体) │ ↑ 15% vs 昨日 │ ← 趋势(红涨绿跌) │ ╱╲ │ ← 迷你趋势图(可选) │ ╱ ╲ │ └─────────────────┘ ``` **变体**: - 标准:数字 + 趋势 - 带评级:数字 + 颜色评级(性能指标用) - 极简:只有数字 ### 5.2 状态标签 | 状态 | 颜色 | 示例 | |------|------|------| | Active(未解决) | 红底白字 | `active` | | Resolved(已解决) | 绿底白字 | `resolved` | | Ignored(已忽略) | 灰底灰字 | `ignored` | | Firing(告警中) | 红底白字 | `FIRING` | | Resolved(已恢复) | 绿底白字 | `RESOLVED` | ### 5.3 错误级别标记 | 级别 | 颜色 | |------|------| | Fatal | 🔴 深红 | | Error | 🔴 红 | | Warning | 🟡 黄 | | Info | 🔵 蓝 | | Debug | ⚪ 灰 | ### 5.4 性能评级 | 评级 | 颜色 | LCP | FID | CLS | |------|------|-----|-----|-----| | Good 🟢 | 绿 | < 2.5s | < 100ms | < 0.1 | | Needs Improvement 🟡 | 黄 | 2.5-4s | 100-300ms | 0.1-0.25 | | Poor 🔴 | 红 | > 4s | > 300ms | > 0.25 | --- ## 六、图表设计 ### 6.1 图表库选型 | 库 | 体积 | 功能 | 适合场景 | |----|------|------|----------| | Chart.js | ~60KB gzip | 基础图表够用 | 轻量、简单 | | ECharts | ~150KB gzip | 功能强大 | 复杂图表、交互多 | | uPlot | ~15KB gzip | 时序图表 | 极致轻量、性能好 | **推荐方案**: - 默认用 Chart.js(够用、轻量、生态好) - 性能监控页面用 ECharts(需要更复杂的交互) - 可按需加载,首屏只加载必要的 ### 6.2 图表类型 | 图表 | 用途 | 页面 | |------|------|------| | 折线图 | 错误趋势、性能趋势 | 概览、错误、性能 | | 柱状图 | Top N 排行、分布 | 错误、性能 | | 饼图 / 环形图 | 占比、分布 | 概览、错误 | | 面积图 | 堆叠趋势 | 性能 | | 热力图 | 时间段分布 | 错误 | ### 6.3 与 Grafana 的关系 **管理后台解决的问题**: - 错误 Issue 管理(状态、分配、标记) - 项目配置和管理 - 告警规则配置 - 更友好的错误详情展示 **Grafana 解决的问题**: - 灵活的自定义仪表盘 - 复杂的数据探索 - 多种数据源联合查询 - 告警(可复用 Grafana Alerting) **分工原则**: - 常用功能做进管理后台(开箱即用) - 高级分析用 Grafana(灵活强大) - 管理后台提供一键跳转到 Grafana 的链接 --- ## 七、前端架构 ### 7.1 目录结构 ``` frontend/ # 前端工程(独立目录) ├── public/ │ └── favicon.ico ├── src/ │ ├── assets/ # 静态资源 │ │ ├── images/ │ │ └── icons/ │ ├── components/ # 通用组件 │ │ ├── layout/ # 布局组件 │ │ │ ├── MainLayout.tsx # 主布局(侧边栏+顶栏+内容) │ │ │ ├── Sidebar.tsx # 侧边栏 │ │ │ ├── Header.tsx # 顶部栏 │ │ │ └── PageHeader.tsx # 页面头 │ │ ├── chart/ # 图表组件 │ │ │ ├── LineChart.tsx # 折线图 │ │ │ ├── BarChart.tsx # 柱状图 │ │ │ └── PieChart.tsx # 饼图 │ │ ├── metrics/ # 指标组件 │ │ │ └── MetricCard.tsx # 指标卡片 │ │ └── common/ # 其他通用组件 │ │ ├── StatusTag.tsx # 状态标签 │ │ └── CopyButton.tsx # 复制按钮 │ ├── pages/ # 页面 │ │ ├── overview/ # 概览页 │ │ │ └── index.tsx │ │ ├── errors/ # 错误管理 │ │ │ ├── List.tsx # 错误列表 │ │ │ └── Detail.tsx # 错误详情 │ │ ├── performance/ # 性能分析 │ │ │ └── index.tsx │ │ ├── network/ # 网络分析 │ │ │ └── index.tsx │ │ ├── alerts/ # 告警中心 │ │ │ ├── Rules.tsx # 告警规则 │ │ │ └── History.tsx # 告警历史 │ │ ├── logs/ # 日志查询 │ │ │ └── index.tsx │ │ ├── settings/ # 项目设置 │ │ │ └── index.tsx │ │ ├── projects/ # 项目管理 │ │ │ └── List.tsx │ │ └── integration/ # 接入指南 │ │ └── index.tsx │ ├── store/ # 状态管理 (Zustand) │ │ ├── index.ts # 导出 │ │ ├── useAppStore.ts # 全局状态(主题、侧边栏等) │ │ └── useProjectStore.ts # 当前项目状态 │ ├── services/ # API 服务 │ │ ├── request.ts # Axios 封装 │ │ ├── project.ts # 项目相关 API │ │ ├── error.ts # 错误相关 API │ │ ├── performance.ts # 性能相关 API │ │ └── alert.ts # 告警相关 API │ ├── hooks/ # 自定义 Hooks │ │ ├── useProject.ts # 当前项目 hook │ │ ├── useTimeRange.ts # 时间范围 hook │ │ └── useChartTheme.ts # 图表主题 hook │ ├── router/ # 路由配置 │ │ ├── index.tsx # 路由入口 │ │ └── routes.ts # 路由表 │ ├── utils/ # 工具函数 │ │ ├── format.ts # 格式化(时间、数字等) │ │ ├── date.ts # 日期工具 │ │ └── storage.ts # 本地存储 │ ├── types/ # TypeScript 类型定义 │ │ ├── api.ts # API 类型 │ │ ├── error.ts # 错误相关类型 │ │ ├── performance.ts # 性能相关类型 │ │ └── common.ts # 通用类型 │ ├── styles/ # 全局样式 │ │ ├── global.less │ │ └── variables.less │ ├── App.tsx # 根组件 │ └── main.tsx # 入口文件 ├── .eslintrc.js # ESLint 配置 ├── .prettierrc # Prettier 配置 ├── tsconfig.json # TypeScript 配置 ├── vite.config.ts # Vite 配置 └── package.json ``` ### 7.2 路由设计 使用 React Router v6,嵌套路由 + 懒加载: ```typescript // router/routes.ts const routes = [ { path: '/', element: , children: [ { index: true, element: }, { path: 'overview', lazy: () => import('@/pages/overview') }, { path: 'errors', children: [ { index: true, lazy: () => import('@/pages/errors/List') }, { path: ':id', lazy: () => import('@/pages/errors/Detail') }, ], }, { path: 'performance', lazy: () => import('@/pages/performance') }, { path: 'network', lazy: () => import('@/pages/network') }, { path: 'alerts', children: [ { index: true, element: }, { path: 'rules', lazy: () => import('@/pages/alerts/Rules') }, { path: 'history', lazy: () => import('@/pages/alerts/History') }, ], }, { path: 'logs', lazy: () => import('@/pages/logs') }, { path: 'settings', lazy: () => import('@/pages/settings') }, { path: 'integration', lazy: () => import('@/pages/integration') }, ], }, { path: '/projects', element: }, { path: '*', element: }, ]; ``` ### 7.3 状态管理(Zustand) **为什么用 Zustand 而不是 Redux?** - 比 Redux 简单太多,没有 reducer、action、dispatch 那些概念 - 体积小(~1KB),性能好 - TypeScript 支持好 - 支持 middleware(persist、devtools 等) ```typescript // store/useAppStore.ts import { create } from 'zustand'; interface AppState { theme: 'dark' | 'light'; sidebarCollapsed: boolean; currentProject: Project | null; toggleTheme: () => void; toggleSidebar: () => void; setCurrentProject: (project: Project) => void; } export const useAppStore = create((set) => ({ theme: 'dark', sidebarCollapsed: false, currentProject: null, toggleTheme: () => set((s) => ({ theme: s.theme === 'dark' ? 'light' : 'dark' })), toggleSidebar: () => set((s) => ({ sidebarCollapsed: !s.sidebarCollapsed })), setCurrentProject: (project) => set({ currentProject: project }), })); ``` ### 7.4 数据请求(TanStack Query) **为什么用 TanStack Query?** - 自动缓存,相同请求不会重复发 - 后台自动刷新 - 分页、无限滚动都有封装 - 乐观更新、重试策略 - 和 Zustand 互补,不用把 API 数据放全局 store ```typescript // hooks/useErrors.ts import { useQuery } from '@tanstack/react-query'; import { getErrorList } from '@/services/error'; export function useErrorList(params: ErrorListParams) { return useQuery({ queryKey: ['errors', params], queryFn: () => getErrorList(params), keepPreviousData: true, staleTime: 30_000, // 30秒内认为是新鲜的 }); } ``` ### 7.5 请求封装(Axios) ```typescript // services/request.ts import axios from 'axios'; import { message } from 'antd'; const request = axios.create({ baseURL: '/api', timeout: 15000, }); // 请求拦截器:加 token request.interceptors.request.use((config) => { const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); // 响应拦截器:统一处理错误 request.interceptors.response.use( (res) => res.data, (err) => { const status = err.response?.status; const message = err.response?.data?.message || err.message; if (status === 401) { // 登录过期,跳登录页 } else { message.error(message); } return Promise.reject(err); } ); export default request; ``` ### 7.6 主题配置(Ant Design 5 深色主题) Ant Design 5 用 CSS-in-JS,通过 ConfigProvider 配置主题: ```typescript // App.tsx import { ConfigProvider, theme as antdTheme } from 'antd'; import { useAppStore } from '@/store'; function App() { const { theme } = useAppStore(); return ( ); } ``` **自定义暗色主题色板**(贴合 GitHub Dark 风格): ```typescript { colorBgLayout: '#0d1117', // 页面背景 colorBgContainer: '#161b22', // 卡片背景 colorBgElevated: '#21262d', // 悬浮背景 colorBorder: '#30363d', // 边框 colorText: '#e6edf3', // 主文字 colorTextSecondary: '#8b949e',// 次文字 colorTextTertiary: '#6e7681', // 弱文字 } ``` ### 7.7 图表封装 基于 ECharts 封装通用图表组件,自动适配主题和容器大小: ```typescript // components/chart/BaseChart.tsx import { useEffect, useRef } from 'react'; import * as echarts from 'echarts'; import { useAppStore } from '@/store'; interface BaseChartProps { option: echarts.EChartsOption; height?: number | string; className?: string; } export function BaseChart({ option, height = 300, className }: BaseChartProps) { const chartRef = useRef(null); const chartInstance = useRef(null); const { theme } = useAppStore(); useEffect(() => { if (!chartRef.current) return; chartInstance.current = echarts.init( chartRef.current, theme === 'dark' ? 'dark' : null ); const resizeObserver = new ResizeObserver(() => { chartInstance.current?.resize(); }); resizeObserver.observe(chartRef.current); return () => { resizeObserver.disconnect(); chartInstance.current?.dispose(); }; }, [theme]); useEffect(() => { chartInstance.current?.setOption(option, true); }, [option]); return
; } ``` ### 7.8 构建与部署 **开发环境**: ```bash pnpm dev # 启动开发服务器 pnpm build # 生产构建 pnpm preview # 预览构建结果 pnpm lint # ESLint 检查 pnpm type-check # TypeScript 类型检查 ``` **部署方案**: - 构建产物:`dist/` 目录 - Nginx 直接托管静态文件 - API 请求通过 Nginx 反向代理到后端 - 和现有 `public/manage/` 共存,新前端走 `/manage/` 路径 ```nginx location /manage/ { try_files $uri $uri/ /manage/index.html; root /path/to/frontend/dist; } ``` --- ## 八、交互设计原则 ### 8.1 快速导航 - 全局搜索:`⌘K` 唤起,可搜项目、错误、页面 - 面包屑:永远知道自己在哪 - 相关跳转:错误详情里可跳转到对应页面的性能分析 ### 8.2 数据加载 - 骨架屏:数据加载中显示骨架,不跳 - 增量加载:列表滚动加载 - 实时刷新:可开/关,默认 30 秒自动刷新 ### 8.3 操作反馈 - 重要操作(删除、标记已解决)有确认弹窗 - 成功操作顶部弹 toast,3 秒自动消失 - 操作失败显示错误原因,可重试 --- ## 九、API 设计 ### 9.1 统计 API ``` # 概览数据 GET /api/projects/{id}/overview?time_range=24h # 错误趋势 GET /api/projects/{id}/errors/trend?time_range=24h&interval=1h # 错误列表 GET /api/projects/{id}/errors?page=1&page_size=20&level=error&status=active # 错误详情 GET /api/projects/{id}/errors/{fingerprint} # 性能指标 GET /api/projects/{id}/performance/metrics?time_range=24h&metric=lcp # 告警规则 GET /api/projects/{id}/alerts/rules POST /api/projects/{id}/alerts/rules PUT /api/projects/{id}/alerts/rules/{rule_id} DELETE /api/projects/{id}/alerts/rules/{rule_id} # 告警历史 GET /api/projects/{id}/alerts/history?page=1&page_size=20 ``` --- ## 十、演进路线 ### 10.1 当前状态 现有的 [index.html](file:///Users/weidingjian/Desktop/work/ai/light-sentry/public/manage/index.html) 是项目列表页,只有最基础的 CRUD 功能。 ### 10.2 版本规划 **v1.1(下一个版本)**: - 改造成侧边栏 + 内容区的布局 - 新增概览页(核心指标 + 错误趋势) - 新增错误列表页(从聚合表读) - 项目选择器移到顶部 **v1.2**: - 错误详情页 - 性能分析页 - 告警规则管理 **v2.0**: - 完整的错误管理工作流 - 性能深入分析(瀑布图、资源时序) - 用户会话追踪