# Arbitrage Engine 前端页面说明 > 本文从“用户看到的界面”出发,按页面/导航顺序描述整个前端。 > 代码和数据层的详细结构,请参考 `docs/arbitrage-engine-full-spec.md`。 --- ## 0. 全局框架与导航 ### 0.1 布局 前端采用 Next.js App Router,根布局在 `frontend/app/layout.tsx` 中定义: - 左侧:`` - 固定在左侧,白底,带边框,可折叠(桌面端)。 - 包含项目 Logo 和主导航按钮。 - 右侧:顶部为 ``,下面为当前页面内容: - `AuthHeader` 只在桌面端显示,用于展示登录状态(邮箱/Admin 徽章/退出按钮)。 - 实际页面内容通过 `children` 渲染。 移动端(`md` 以下)顶栏和抽屉菜单也由 `Sidebar` 组件负责: - 顶部条:左侧为 Logo,右侧为“登录/注册”或“退出”按钮 + 菜单汉堡按钮。 - 点击菜单按钮后,从左侧滑出抽屉式侧边栏,内容与桌面端导航一致。 ### 0.2 顶部登录区(AuthHeader) 文件:`frontend/components/AuthHeader.tsx` 仅在桌面端显示(`hidden md:flex`)。 - 未登录: - 右上角显示: - `登录` 按钮:灰边,hover 变为蓝边。 - `注册` 按钮:蓝底白字主按钮。 - 点击分别跳转到 `/login` 与 `/register`。 - 已登录: - 显示当前用户邮箱(`user.email`)。 - 如果 `user.role === "admin"`,在邮箱后显示一个黄色的 `Admin` 徽章。 - 右侧是 `退出` 按钮,点击调用 `logout()` 退出登录。 > 手机端的登录/注册/退出按钮由 `Sidebar` 内部负责,不走 `AuthHeader`。 ### 0.3 侧边栏导航(Sidebar) 文件:`frontend/components/Sidebar.tsx` - 顶部 Logo: - 闪电图标(`Zap`)+ 文本 `Arbitrage Engine`(两行排版)。 - 导航项(`navItems`)定义如下: ```ts const navItems = [ { href: "/", label: "仪表盘", icon: LayoutDashboard }, { href: "/trades", label: "成交流", icon: Activity }, { href: "/live", label: "⚡ 实盘交易", icon: Bolt, section: "── 实盘 ──" }, { href: "/strategy-plaza", label: "策略广场", icon: Zap, section: "── 策略 ──" }, { href: "/strategy-plaza/deprecated", label: "废弃策略", icon: Archive }, { href: "/server", label: "服务器", icon: Monitor }, { href: "/about", label: "说明", icon: Info }, ]; ``` 从用户视角,这些入口对应的主要功能是: - `/` → **仪表盘**:资金费率实时监控与套利统计的首页。 - `/trades` → **成交流**:逐笔成交明细与交易流量分析。 - `/live` → **⚡ 实盘交易**:实盘风控与一键止血面板(L0/L1/L1.5 等区域)。 - `/strategy-plaza` → **策略广场**:V5.4 策略工厂的主入口,展示所有策略表现。 - `/strategy-plaza/deprecated` → **废弃策略**:已停用策略的列表视图。 - `/server` → **服务器**:服务器与 PM2 进程监控。 - `/about` → **说明**:策略原理、历史年化与风险说明。 > 账号相关页面 `/login`、`/register`、`/dashboard` 不在侧边栏中出现,通过右上角或跳转访问。 --- ## 1. 首页 `/`(仪表盘) 文件:`frontend/app/page.tsx` 导出的组件名:`Dashboard` ### 1.1 页面目标 从用户视角,首页是一个**资金费率套利的总览仪表盘**,具备两个层次: 1. **未登录用户**:能看到 BTC/ETH 的实时资金费率、运行状态等,了解当前市场情况。 2. **已登录用户**:解锁完整的统计信息: - 套利策略的历史统计(7天均值、年化、50/50组合等); - 资金费率与价格的 K 线图; - 历史费率明细表格; - 已触发的资金费率“信号历史”; - 策略原理说明。 首页不直接操作策略或模拟盘,更像是一个“观测面板 + 教程”,帮助用户理解当前资金费率环境和策略收益。 ### 1.2 未登录状态下的展示 未登录逻辑由组件 `AuthGate` 控制: - 上半部分(不受登录状态影响): 1. **标题行** - 左侧: - 主标题:`资金费率套利监控` - 副标题(小字):`实时监控 BTC / ETH 永续合约资金费率` - 右侧: - 圆点状态灯:`运行中`(绿色) / `连接失败`(红色) / `加载中...`(灰色),根据 `/api/rates` 请求结果变化。 - “更新于 HH:MM:SS” 时间戳,表示最近一次成功更新资金费率的本地时间。 2. **资金费率卡片(RateCard)** - 左卡:BTC,右卡:ETH。 - 每张卡展示: - 当前资金费率; - 标记价格、指数价格; - 相关统计(具体字段由 `RateCard` 渲染)。 - 下半部分(被 `AuthGate` 包裹): - 未登录时,`AuthGate` 渲染一个**模糊遮罩**效果: - 内部真实内容会被 blur + 降低不透明度,作为背景。 - 上方覆盖一层白色半透明遮罩。 - 中间显示: - 图标:`🔒` - 文案:`登录后查看完整数据` - 按钮: - `登录`(蓝底按钮) → 跳转 `/login` - `注册`(灰边按钮) → 跳转 `/register` **结论**:未登录用户只能看到**实时费率卡片**和运行状态,不能查看历史统计、K 线和详细信号数据。 ### 1.3 登录后的完整内容 当用户已登录且 `AuthGate` 放行时,首页显示以下完整模块: 1. **套利统计卡片(StatsCard,三张)** - 在 `stats` 数据存在时渲染: - `BTC 套利`:`mean7d` + `annualized` - `ETH 套利` - `50/50 组合`:BTC/ETH 各 50% 的组合年化表现 - 这些数据由 `/api/stats` 提供,用于给出近 7 天和年化收益的粗略估计。 2. **K 线大卡片(资金费率 & 标记价格)** - 卡片标题:`K 线图` - 币种切换按钮:`BTC` / `ETH`(控制 `symbol` 状态)。 - 内含两个子图: 1. **资金费率 K 线** - 标题:`{symbol} 资金费率(万分之)` - 顶部右侧 interval 选择器(`INTERVALS`),可选: - `1m`, `5m`, `30m`, `1h`, `4h`, `8h`, `日(1d)`, `周(1w)`, `月(1M)` - 使用 `MiniKChart` + `mode="rate"`,展示资金费率蜡烛图。 2. **标记价格 K 线** - 标题:`{symbol} 标记价格(USD)` - 使用同样的 interval 选择器,但 `mode="price"`,展示价格蜡烛图。 - 下层数据来源:`/api/kline?symbol=BTC&interval=...`(通过 `api.kline` 封装)。 3. **历史费率走势(7天双线图)** - 标题:`历史费率走势(过去7天)` - 使用 Recharts `LineChart` 绘制: - X 轴:时间(按小时聚合,如 `MM-DD HH`) - Y 轴:资金费率(百分比,格式化显示如 `0.1234%`) - 两条线: - `BTC`:蓝色; - `ETH`:紫色; - 中间有一条 `y=0` 的虚线参考线。 - 数据来自 `api.history()` 返回的 `HistoryResponse` 中的 `BTC` / `ETH` 历史 fundingRate 序列。 4. **历史费率明细表(左侧表格)** - 标题:`历史费率明细(最近30条)` - 表头:时间 / BTC / ETH - 每行: - 时间:`yyyy-MM-dd HH:mm`(字符串处理自 `timestamp`) - BTC/ETH 列: - 正值:绿色; - 负值:红色; - 无数据:灰色、显示 `--`。 - 数据来源同上(`HistoryResponse`),只是格式化和截取最近 30 条。 5. **信号历史表(右侧表格)** - 标题:`信号历史` - 表头:时间 / 币种 / 年化 - 内容: - 当 `signals.length === 0`:显示提示行 `暂无信号(年化>10%时自动触发)`。 - 否则每行显示: - 触发时间 `sent_at`(本地时间格式); - 币种 `symbol`; - 年化收益率 `annualized`(加 `%`)。 - 数据来源:`api.signalsHistory()`(封装了 `/api/signals/signal-history` 或类似接口)。 6. **策略原理说明卡片(蓝色 Info 区域)** - 蓝色边框+淡蓝底的 info 卡片,标题 `策略原理:` - 内容简述: - 使用“现货多头 + 永续空头”构建无方向风险的套利组合; - 每 8 小时收取资金费率作为收益; - 核心是赚“费率”,不是赌方向。 整体上,登录后的首页是一个聚合视图,把“当前状态 + 历史表现 + 策略简介”集中在一个页面上。 ### 1.4 首页依赖的主要 API 首页通过 `api` 封装(`frontend/lib/api`)访问后端,核心依赖至少包括: - `GET /api/rates` → `api.rates()` - 读取最新资金费率快照(BTC/ETH 的 markPrice/indexPrice/lastFundingRate 等)。 - `GET /api/stats` → `api.stats()` - 返回 BTC/ETH 以及 50/50 组合的近 7 天均值与年化统计。 - `GET /api/history` → `api.history()` - 返回过去若干天(如 7 天)的按小时聚合资金费率序列。 - `GET /api/signals/history` 或类似 → `api.signalsHistory()` - 返回最近触发的资金费率套利信号(满足一定年化阈值)。 - `GET /api/stats/ytd` → `api.statsYtd()` - 年初至今(YTD)的收益统计,用于 `RateCard` 等组件。 - `GET /api/kline?symbol=&interval=` → `api.kline(symbol, interval)` - 提供资金费率和价格 K 线数据,用于首页的 K 线卡片。 这些接口的详细字段与 SQL 逻辑请以 `docs/arbitrage-engine-full-spec.md` 和 `backend/main.py` 中定义为准。 --- ## 2. /trades(成交流) 文件:`frontend/app/trades/page.tsx` 导出的组件名:`TradesPage` ### 2.1 页面目标 `/trades` 页面从“逐笔成交”的角度,帮助用户观察: - 当前市场是多方主动吃单更多,还是空方主动砸盘更多; - 在过去一段时间内,不同时间粒度下买卖量的累积情况; - 成交换手是否集中(成交量、最大单笔成交量等)。 它是一个 **成交流量分析工具页**,为信号研究和盘前/盘后复盘服务,不直接开仓/平仓。 ### 2.2 登录要求与未登录展示 页面开头使用 `useAuth()` 判断登录状态: - `loading === true`:显示“加载中...”占位。 - `!isLoggedIn`:渲染一个居中的锁屏提示: - 图标:`🔒` - 文案:`请先登录查看成交流数据` - 按钮: - `登录`(蓝底) → `/login` - `注册`(灰边) → `/register` 只有登录用户可以看到实时成交流和图表。 ### 2.3 页面主要区域布局 登录后,`TradesPage` 页面结构如下: 1. **标题 + 币种切换** - 标题:`成交流分析` - 副标题:`实时成交记录 + 买卖 Delta 分析` - 右侧有一个币种选择按钮组: - 支持四种:`BTC` / `ETH` / `XRP` / `SOL` - 通过内部状态 `symbol` 切换,影响下方所有数据请求。 2. **实时成交 + 分析图 并排** - 布局:`lg` 以上为两列,左侧实时成交,右侧流量分析;小屏则上下排列。 - 左侧组件:`` - 右侧组件:`` 3. **读图说明 Info 卡片** - 底部一块蓝色边框的说明区域: - “读图方法”:解释 Delta 为正/负的含义(多方/空方占优)。 - “复盘思路”:建议用户结合 K 线大涨大跌时间点,回看前 15–30 分钟的 Delta 走势寻找前兆。 ### 2.4 左侧:实时成交流列表(LiveTrades) 组件:`LiveTrades` 功能:展示选中币种的最新 20 条逐笔成交记录,实时滚动更新。 行为与布局: - 加载逻辑: - 使用 `authFetch("/api/trades/latest?symbol=...&limit=20")` 每 2 秒轮询一次。 - 首次加载时 `loading=true`,显示“加载中...”; - 后续每次拉取: - 根据返回的 `data.data` 更新本地 `trades` 列表; - 新来的成交在顶部(最新在前),最多保留 20 条; - 用 `agg_id` 去重,避免重复插入。 - 卡片顶部: - 标题:`实时成交 · {symbol}/USDT` - 右上角状态: - 一个绿色闪烁的小圆点; - 文案:`实时`。 - 下方说明: - `▲ 绿 = 主动买(多方发动)` - `▼ 红 = 主动卖(空方发动)` - 表格内容: - 表头:价格 / 数量 / 时间 - 每行表示一笔 agg_trade: - 价格列: - 用 `fmtPrice` 按数量级格式化; - 根据 `is_buyer_maker` 渲染颜色和三角符号: - `0` → 主动买:绿色、带 `▲`; - `1` → 主动卖:红色、带 `▼`。 - 数量列: - 大额数量(>= 1000)以 `K` 单位显示(如 `1.23K`); - 不同币种有不同小数位(BTC 显示 4 位,小币种 3 位)。 - 时间列: - 使用 `timeStr` 将 `time_ms` 格式化为北京时间 `HH:MM:SS`。 - 滚动与响应式: - 桌面端:内部区域固定高度,启用垂直滚动(`lg:h-[420px]`)。 - 移动端:不限制高度,避免嵌套滚动影响体验,表头 sticky 仅在桌面端启用。 ### 2.5 右侧:成交流量分析(FlowAnalysis) 组件:`FlowAnalysis` 功能:按时间聚合的买卖量与 Delta 分析图,帮助判断一段时间内多空力量对比。 行为与布局: - 时间粒度切换: - 顶部右侧有一组 interval 按钮: - `1m`, `5m`, `15m`, `1h` - 使用本地状态 `interval` 控制聚合粒度。 - 数据获取: - 使用 `authFetch("/api/trades/summary?...")` 周期性拉取数据: - 路径:`/api/trades/summary` - 查询参数: - `symbol`:当前币种(BTC/ETH/XRP/SOL) - `start_ms`:根据 interval 动态计算(例如 1m 粒度时取过去 1 小时) - `end_ms`:当前时间 - `interval`:`"1m" | "5m" | "15m" | "1h"` - 接口返回 `data` 数组,每个元素为一个 `SummaryBar`: - `buy_vol` / `sell_vol`:该时间段的主动买/卖量; - `delta`:买-卖; - `trade_count`:成交笔数; - `vwap`:该段时间的成交量加权平均价; - `time_ms`:该段开始时间。 - 首次加载时显示 loading 提示; - 之后每 30 秒刷新一次数据,但不再显示 loading 动画,以避免视觉抖动。 - 上方摘要卡片: - “统计时间窗口”:根据 interval 用人话表达: - 1m → 过去 1 小时 - 5m → 过去 4 小时 - 15m → 过去 12 小时 - 1h → 过去 48 小时 - 四个小卡片: 1. 主动买量(绿色):总 buy_vol; 2. 主动卖量(红色):总 sell_vol; 3. Delta(买-卖):正值多头占优,负值空头占优; 4. 买方占比: - 计算公式:`buy_vol / (buy_vol + sell_vol)`; - 文案提示: - >= 55%:强势买盘; - 45–55%:买卖均衡; - < 45%:强势卖盘。 - 中间图一:Delta + 价格双轴图 - 使用 `ComposedChart` 绘制: - X 轴:时间(短格式,如 `HH:MM`); - 左 Y 轴:Delta 数值; - 右 Y 轴:价格(VWAP),带 ±0.3% 的缓冲区,自动压缩显示范围; - 一条 `ReferenceLine` 表示 Delta = 0; - `Area` 图展示 Delta 区域,颜色偏蓝; - `Line` 图展示价格,右侧刻度以美元单位,并在大数值时转换成 `$xx.xk` 形式。 - Tooltip 中同时显示 Delta 和价格。 - 下方图二:主动买量 vs 主动卖量 - 再次使用 `ComposedChart`: - X 轴:时间; - Y 轴:成交量; - 两个 `Area`: - `buy`:绿色区域; - `sell`:红色区域。 - Tooltip 展示各时间段买/卖量。 - 底部说明: - 一行小字:`数据跨度约 X 分钟 · N 根K · 每30秒刷新`: - `X` 为从当前时间到最早一根 bar 的跨度; - `N` 为当前聚合出的 K 数量。 如果接口当前没有返回任何数据(例如新启动时),则展示一个“暂无数据,正在积累中”的占位说明,而不是空白图表。 ### 2.6 /trades 依赖的主要 API `/trades` 页面通过 `authFetch` 调用后端,需要登录状态。主要接口包括: - `GET /api/trades/latest?symbol=&limit=20` - 用于 `LiveTrades`; - 返回最近的逐笔成交(agg_trades 快照)。 - `GET /api/trades/summary?symbol=&start_ms=&end_ms=&interval=` - 用于 `FlowAnalysis`; - 返回按时间粒度聚合的买卖量、Delta、VWAP 等。 接口的具体字段与实现细节以 `docs/arbitrage-engine-full-spec.md` 和 `backend/main.py` 中对应章节为准。 --- ## 3. /live(⚡ 实盘交易) 文件:`frontend/app/live/page.tsx` 导出的组件名:`LiveTradingPage` ### 3.1 页面目标 `/live` 是实盘控制与风控中枢页面,主要功能: - 全局监控:实盘账户的当前风险状态、R 预算、对账情况、系统健康; - 快速止血:一键全平、禁新仓、恢复交易; - 配置管理:在线调整实盘参数(每笔风险、杠杆、最大仓位数、启用策略等); - 执行与对比:查看当前持仓、执行质量、实盘 vs 模拟盘表现差异。 整体设计成多层级面板(L0–L11),从“风险总览 → 止血按钮 → 配置 → 持仓 → 质量 → 对账 → 事件流 → 对比与历史”逐层深入。 ### 3.2 登录要求与未登录展示 页面使用 `useAuth()` 进行访问控制: - `loading === true`:显示简单的“加载中...”提示。 - `!isLoggedIn`: - 显示锁屏提示: - 图标:`🔒` - 文案:`请先登录查看实盘` - 按钮:`登录`(蓝底),跳转 `/login` - 不提供注册入口(实盘页面假定仅对已有账号开放)。 只有登录用户可以访问 L0–L11 各层面板。 ### 3.3 总体布局与层级概览 `LiveTradingPage` 登录后渲染顺序如下: 1. `L0_RiskBar`:顶部固定风险条(sticky) 2. 页面标题区:`⚡ 实盘交易` + 简短说明(V5.2 策略、币安 USDT 永续、测试网) 3. `L1_EmergencyPanel`:一键止血区(全平/禁新仓/恢复) 4. `L15_LiveConfig`:实盘配置(风险参数) 5. `L2_AccountOverview`:账户概览 8 卡片(权益、保证金、PnL、胜率等) 6. `L3_Positions`:当前持仓(实时价+风险指标) 7. `L4_ExecutionQuality`:执行质量统计 8. `L5_Reconciliation`:本地 vs 交易所对账 9. `L6_RiskStatus`:风控门槛状态 10. `L7_EventStream`:实时事件流 11. `L8_PaperComparison`:实盘 vs 模拟盘对照 12. `L9_EquityCurve`:权益曲线 + 回撤 13. `L10_TradeHistory`:历史交易表 14. `L11_SystemHealth`:系统健康(进程与数据新鲜度) 下面按层级简述关键行为和用途。 ### 3.4 L0 风险条(L0_RiskBar) 功能:作为页面顶部的 sticky 风险指示条,始终可见,用于快速扫一眼当日风险与对账情况。 - 数据来源: - 周期性轮询: - `/api/live/risk-status` - `/api/live/reconciliation` - `/api/live/account` - 每 5 秒刷新一次。 - 显示内容: 1. **交易状态** - 彩色圆点 + 文案: - `normal` → 绿色点 + `运行中` - `circuit_break` → 红点 + `熔断` 提示(有表情符号) - `warning` → 黄点 + `警告` - 其它 → 灰色 + `未知` - 标记: - `禁新仓`:如果 `risk.block_new_entries` 为真; - `只减仓`:如果 `risk.reduce_only` 为真。 2. **R 预算** - 已实现 R:`today_realized_r`(正绿负红); - 未实现 R:`today_unrealized_r`; - 日限对比:`totalR = realized + min(unrealized, 0)`,显示为 `totalR/-5R`: - 根据占用比例着色:<80% 绿,80–100% 黄,>=100% 红。 3. **对账与连亏** - 对账状态:从 `/api/live/reconciliation` 的 `status` 推导: - ok → 绿色小点 + `对账✓` - 其它 → 红色小点 + `对账✗(差异条数)` - 连续亏损次数:`risk.consecutive_losses`; - 如果存在 `risk.circuit_break_reason`,在右侧以小字体显示熔断原因。 ### 3.5 L1 一键止血区(L1_EmergencyPanel) 功能:提供三种紧急操作: - `🔴 全平`:调用 `POST /api/live/emergency-close`; - `🟡 禁新仓`:调用 `POST /api/live/block-new`; - `✅ 恢复`:调用 `POST /api/live/resume`。 交互特点: - 对危险操作(全平/禁新仓)增加二次确认: - 首次点击显示“确认?” + 确认/取消按钮; - 确认后才真正发起请求。 - 操作结果通过顶端一行小字提醒:成功/失败提示文本会显示数秒后自动消失。 使用场景:实盘出现异常时,快速全平或冻结新仓入口,降低风险暴露时间。 ### 3.6 L1.5 实盘配置面板(L15_LiveConfig) 功能:展示并编辑实盘关键配置,用于调整风险参数与交易环境。 - 数据来源: - 初始化时调用 `GET /api/live/config` 获取配置对象; - 保存时调用 `PUT /api/live/config`,之后再 `GET` 一次以刷新展示。 - 配置项顺序(configOrder): - `risk_per_trade_usd`:每笔风险金额(USDT),决定 1R 对应的资金; - `initial_capital`:初始资金; - `risk_pct`:每笔风险占比(%); - `max_positions`:最大持仓数; - `leverage`:杠杆倍数; - `enabled_strategies`:启用的策略列表; - `trade_env`:交易环境(正式/测试网等)。 - 展示形式: - 标题:`⚙️ 实盘配置`,旁边强调 `1R = $X.XX`(从 `risk_per_trade_usd` 推导)。 - 每个配置项显示图标 + label + 当前值: - windown 模式:显示只读值,如 `5%`、`10x`; - 编辑模式:变成文本输入框。 - 编辑流程: 1. 点击“编辑”按钮 → 进入编辑模式,当前配置复制到 `draft`; 2. 修改各字段; 3. 点击“保存”: - 发 `PUT /api/live/config`,体是 `draft`; - 成功后重新拉配置并退出编辑模式; 4. 点击“取消” → 撤销编辑,恢复显示模式。 该面板是实盘风险参数的唯一修改入口,页面其他部分(仓位 R 计算等)会引用这里的 `risk_per_trade_usd`。 ### 3.7 L2 账户概览(L2_AccountOverview) 功能:用 8 个小卡片概览账户与策略表现: - 数据来源: - `GET /api/live/account`:账户层面数据; - `GET /api/live/summary?strategy=v52_8signals`:指定策略的汇总表现。 - 卡片内容示例: 1. 账户权益:`equity`(USDT) 2. 可用保证金:`available_margin` 3. 已用保证金:`used_margin` 4. 有效杠杆:`effective_leverage`(超过 10x 时高亮为红色) 5. 今日净 PnL:`today_realized_r` + 对应 USDT 金额(正绿负红) 6. 总净 PnL:`total_pnl_r` + `total_pnl_usdt` 7. 成本占比:费用 + 资金费率成本(`total_fee_usdt + total_funding_usdt`) 8. 胜率/PF:`win_rate` 和 `profit_factor` 这些卡片给出“当前实盘表现是否健康”的快速量化视图。 ### 3.8 L3 当前持仓(L3_Positions) 功能:实时展示实盘持仓详情,包括价格、TP/SL、风险、执行质量等。 - 数据来源: - 周期性轮询: - `GET /api/live/positions?strategy=v52_8signals`:当前实盘持仓列表; - `GET /api/live/reconciliation`:用于计算清算价与距离; - `GET /api/live/config`:获取 `risk_per_trade_usd`。 - WebSocket 实时价格: - 连接 `wss://fstream.binance.com/stream?streams=btcusdt@aggTrade/...`; - 实时更新 `wsPrices[symbol]` 作为当前价。 - 每个持仓块显示信息包括: - 头行: - 标题:`🟢/🔴 {symbol} {LONG/SHORT}`(方向 + 币种),颜色区分多空; - 评分与仓位档位:`评分 score · 加仓/标准`; - 清算距离 badge: - 从对账数据里计算 mark price 到 liquidation price 的距离百分比; - 不同区间用不同颜色强调(例如 <8% 深色、8–12% 红色、12–20% 橙色、>20% 绿色)。 - 实时浮盈: - 以 R 表示:`unrealR`(考虑 TP1 是否已触发,用全程 R 和 TP1 R 的组合); - 以 USDT 表示:`unrealUsdt = unrealR * riskUsd`。 - 持仓时长:`holdMin` 分钟,超过 45/60 分钟用不同颜色提示。 - 价格行: - 入场价、实际成交价、当前价(websocket/备选 current_price)、TP1/TP2/SL; - TP1 打到时在 TP1 旁边标记 `✅`。 - 执行指标行: - 滑点(bps); - “裸奔时间”(保护下单前裸暴露时长); - 信号→下单延迟(S→O)、下单→成交延迟(O→F); - 交易所订单 ID。 - 根据阈值用红/黄/绿背景表达是否超出合理范围。 如果当前没有持仓,则显示一条“暂无活跃持仓”的提示卡片。 ### 3.9 L4–L11 其他面板简述 1. **L4 执行质量(L4_ExecutionQuality)** - 数据源:`GET /api/live/execution-quality`; - 展示整体统计和按币种统计: - 滑点、信号→下单延迟、下单→成交延迟、裸奔时间; - 每项有 avg / P50 / P95 三个分位数; - 根据 P95 与阈值比较决定颜色(绿/黄/红)。 2. **L5 对账面板(L5_Reconciliation)** - 数据源:`GET /api/live/reconciliation`; - 显示: - 本地持仓列表 vs 交易所持仓列表; - 挂单数量对比; - 差异列表 `diffs`,按严重程度着色(critical 用红色,警告用橙色)。 3. **L6 风控状态(L6_RiskStatus)** - 数据源:`GET /api/live/risk-status`; - 将风控规则用几条检查项呈现: - 单日亏损是否大于 -5R; - 连续亏损是否小于 5 次; - API 是否正常; - 如存在 `circuit_break_reason` 和 `auto_resume_time`,以红色块形式显示熔断原因和预计恢复时间。 4. **L7 实时事件流(L7_EventStream)** - 数据源:`GET /api/live/events?limit=30&level=...`(每 5 秒刷新); - 支持按级别过滤:全部/严重/警告/信息; - 每条事件包含: - 时间(日期 + 时分秒); - category(trade/risk/system/reconciliation 等); - symbol(如 BTC/ETH); - message 文本; - 使用不同颜色和图标表示级别(info/warn/error/critical)。 5. **L8 实盘 vs 模拟盘(L8_PaperComparison)** - 数据源:`GET /api/live/paper-comparison?limit=20`; - 表格比较每笔实盘 vs 对应模拟盘交易: - 入场价差(bps)、PnL 差异(R)等; - 表头包括币种、方向、实盘/模拟入场、价差、PnL、R 差; - 标题中显示平均 R 差。 6. **L9 权益曲线 + 回撤(L9_EquityCurve)** - 数据源:`GET /api/live/equity-curve?strategy=v52_8signals`; - 绘制以 R 为单位的累计 PnL 曲线,以及对应回撤曲线: - 计算峰值与当前差值作为回撤; - 以两条 Area 图显示(绿色累计 PnL、红色回撤)。 7. **L10 历史交易(L10_TradeHistory)** - 数据源:`GET /api/live/trades?symbol=&result=&strategy=&limit=50`; - 支持币种(全部/BTC/ETH/XRP/SOL)和结果(全部/盈/亏)筛选; - 表格字段: - 币种、方向、入场/出场价; - Gross R、Fee R、FR R(资金费率)、Slip R; - Net R(总盈亏); - 状态(止盈/止损/保本/其他); - 持仓时长(分钟)。 8. **L11 系统健康(L11_SystemHealth)** - 数据源:`GET /api/live/health`; - 展示: - 各进程状态(online/offline、内存占用、重启次数等); - 行情数据新鲜度(最近一次数据更新时间与状态)。 整体上,`/live` 将实盘运行过程中所有关键视角集中在一个页面里: 从风险和止血,到配置与持仓,再到执行质量、对账、事件和系统健康,方便在出现问题时快速定位和处理。 --- ## 4. /strategy-plaza(策略广场) 主页面文件:`frontend/app/strategy-plaza/page.tsx` 废弃策略页面:`frontend/app/strategy-plaza/deprecated/page.tsx` ### 4.1 页面目标 `/strategy-plaza` 是 V5.4 策略工厂的“策略广场”,面向策略研究者,用来: - 一眼看到当前所有策略的运行状态与收益表现; - 对比不同策略(币种、CVD 周期、TP/SL 方案)的表现好坏; - 快速进入单策略详情页(查看信号引擎 + 模拟盘全貌); - 对策略进行管理:调整参数、追加余额、废弃/恢复。 从用户视角,它更像是一个“策略排行榜 + 控制台”,而不是直接操作信号详情的页面。 ### 4.2 登录与加载行为 `StrategyPlazaPage` 顶部调用 `useAuth()`,用于确保身份信息已经加载(具体权限控制由后端决定)。 - 加载数据: - 使用 `authFetch("/api/strategies")` 获取所有策略; - 响应中取 `data.strategies` 填充本地 `strategies` 列表; - 首次加载时显示“加载中...”; - 之后每 30 秒自动刷新一次数据(定时调用 `fetchData`)。 这里的 `/api/strategies` 会返回当前所有策略实例(包括运行中和暂停中的,废弃策略则在 deprecated 页通过 `include_deprecated=true` 过滤)。 ### 4.3 主页面结构(/strategy-plaza) 页面由三部分组成: 1. 顶部 Header 2. 策略卡片网格 3. 追加余额弹窗 #### 4.3.1 Header - 标题区: - 标题:`策略广场` - 副标题:`点击策略名查看信号引擎和模拟盘详情`(提示点击行为会进入 `/strategy-plaza/[id]` 类页面) - 右侧工具区: - 最近更新时间: - 一个绿色小圆点 + “HH:MM:SS” 本地时间,用 `lastUpdated` 来表示最近一次成功拉取 `/api/strategies` 的时间; - “新增策略”按钮: - 蓝色按钮,文案 `新增策略`; - 点击跳转到 `/strategy-plaza/create`,进入新建策略表单。 #### 4.3.2 策略卡片网格 - 使用 `StrategyCardComponent` 渲染每个 `StrategyCard`(从 `/api/strategies` 得到的数据结构); - 网格布局: - 小屏:单列; - 中屏:两列; - 大屏:三列。 **每张卡片内容:** 1. **Header 行** - 左侧: - 策略名:`display_name`,点击标题会跳转到 `/strategy-plaza/{strategy_id}`(单策略详情页,展示信号+paper 详情); - 状态徽章 `StatusBadge`: - `running` → 绿色 “运行中”; - `paused` → 橙色 “已暂停”; - 其它 → 红色 “异常”; - 币种标签:例如 `BTC` / `ETH`,从 `symbol.replace("USDT","")` 抽取。 - 右侧: - 启动时长:`formatDuration(started_at)`,以“x天 x小时 / x小时 x分 / x分钟”形式显示策略持续运行时间。 2. **主要收益与余额** - 左侧: - 标题:`当前余额`; - 数值:`current_balance`(USDT),大号字体。 - 右侧: - 标题:`累计盈亏`; - 数值:`net_usdt`: - 正数加 `+` 号,并用绿色; - 负数用红色。 3. **余额进度条** - 显示当前余额相对于初始资金的百分比: - `balancePct = current_balance / initial_balance * 100%`; - 文字显示 `balancePct%` 和 `initial_balance`; - 下方进度条宽度按百分比缩放,颜色随盈亏变动: - 盈利 → 绿色; - 亏损 → 红色。 4. **关键统计行** - 三个小卡片: 1. 胜率:`win_rate%`,>50% 绿色,45–50% 橙色,<45% 红色; 2. 净 R:`net_r`,正值绿色、负值红色; 3. 交易数:`trade_count`。 5. **平均赢/亏** - 左:绿色背景的“平均赢”,显示 `+avg_win_r R`; - 右:红色背景的“平均亏”,显示 `avg_loss_r R`; - 进一步帮助判断盈亏比是否合理。 6. **Footer 行:24 小时表现 + 持仓状态** - 左侧: - 24 小时 PnL: - 图标 `TrendingUp` 或 `TrendingDown`; - 文案:`24h +X U` 或 `24h -X U`,根据 `pnl_usdt_24h` 的正负着色(绿/红)。 - 右侧: - 如果 `open_positions > 0`: - 显示 `{open_positions} 仓持仓中`,着橙色强调; - 否则: - 显示最近一次交易时间:`上次: formatTime(last_trade_at)`(格式为 `MM-DD HH:mm`)。 7. **操作按钮行** - 三个按钮,从左到右: 1. `调整参数`: - 链接到 `/strategy-plaza/{strategy_id}/edit`; - 进入策略编辑表单(修改权重、窗口、TP/SL 等配置)。 2. `追加余额`: - 打开 `AddBalanceModal`; - 输入追加金额(USDT),调用 `/api/strategies/{id}/add-balance`,更新初始资金与当前余额。 3. 红色垃圾桶按钮: - 点击后调用 `onDeprecate`,触发废弃流程。 #### 4.3.3 底部空状态与追加余额弹窗 - 当 `strategies.length === 0`: - 显示“暂无运行中的策略”提示; - 提供 “创建第一个策略” 按钮,跳转 `/strategy-plaza/create`。 - `AddBalanceModal`: - 显示当前选中策略名与输入框; - 校验金额 > 0; - 提交时调用 `POST /api/strategies/{sid}/add-balance`; - 成功后关闭弹窗并重新拉取策略列表。 ### 4.4 废弃策略页(/strategy-plaza/deprecated) 文件:`frontend/app/strategy-plaza/deprecated/page.tsx` 导出的组件名:`DeprecatedStrategiesPage` 功能:展示所有 `status="deprecated"` 的策略,并允许“重新启用”。 - 数据加载: - 调用 `GET /api/strategies?include_deprecated=true`; - 前端在得到的 `strategies` 中筛选 `status === "deprecated"`。 - 页面结构: 1. Header: - 标题:`废弃策略`; - 副标题:`数据永久保留,可随时重新启用`; - 右侧链接:`← 返回策略广场`,跳转 `/strategy-plaza`。 2. 如果没有废弃策略: - 显示“暂无废弃策略”。 3. 否则: - 使用网格展示每个废弃策略卡片(布局类似主广场,但视觉上更淡一些)。 - 废弃策略卡片要点: - Header: - 策略名; - “已废弃”灰色徽章; - 右侧显示币种简称。 - PnL 与余额: - 展示“废弃时余额”和累计盈亏; - 余额进度条同样显示当前余额与初始资金的比例(但整体卡片透明度略低,以示已停用)。 - 统计卡片: - 胜率、净 R、交易数。 - Footer: - 左侧:最近废弃时间 `废弃于 {deprecated_at}`; - 右侧:`重新启用` 按钮: - 点击前二次确认:“确认重新启用策略,将继续使用原有余额和历史数据。”; - 调用 `POST /api/strategies/{sid}/restore`; - 成功后刷新列表。 ### 4.5 主要依赖的 API `/strategy-plaza` 和 `/strategy-plaza/deprecated` 主要依赖以下后端接口: - `GET /api/strategies` - 返回所有非废弃策略; - 前端使用:策略广场卡片列表; - 数据中包含策略 ID、展示名、币种、状态、余额、PnL、胜率、平均盈亏、近 24 小时表现等。 - `GET /api/strategies?include_deprecated=true` - 返回包括废弃策略在内的完整列表; - 前端从中筛出 `status="deprecated"` 用于“废弃策略”页面。 - `POST /api/strategies/{sid}/deprecate` - 废弃策略:将 `status` 设为 `deprecated`,停止策略运行但保留数据; - 前端在废弃前弹出确认对话框。 - `POST /api/strategies/{sid}/restore` - 恢复废弃策略为运行状态; - 保持原有余额和历史记录。 - `POST /api/strategies/{sid}/add-balance` - 向指定策略追加模拟资金; - 影响 `initial_balance` 和 `current_balance`,并在 card 上体现。 单个策略的详细行为(信号引擎配置、模拟盘表现)由 `/strategy-plaza/[id]` 下的页面承载,这里作为入口不展开细节;实现上这部分是 V5.4 Strategy Factory 的前端展示层。 --- ## 5. /server(服务器监控) 文件:`frontend/app/server/page.tsx` 导出的组件名:`ServerPage` ### 5.1 页面目标 `/server` 页面用来监控部署 Arbitrage Engine 的服务器与关键进程状态,帮助你: - 了解 CPU / 内存 / 硬盘 / 网络使用情况; - 看到 PM2 管理的各个进程是否正常(arb-web / arb-api / signal-engine / collectors 等); - 观察 PostgreSQL 数据库的体量和各 symbol 数据覆盖范围; - 了解回补任务是否在运行。 它的目标是提供运维层的**健康检查面板**,方便在出现延迟、缺数据或者服务挂掉时快速判断是资源问题还是进程问题。 ### 5.2 登录要求与数据刷新 - 使用 `useAuth()` 判断登录状态: - 未登录:显示提示“请先登录查看服务器状态”,并给出 `登录` / `注册` 按钮; - 已登录:开始加载 `/api/server/status`。 - 刷新策略: - 初次加载时调用 `fetchData()`; - 之后每 10 秒自动轮询一次; - `loading` 为真时显示“加载中...”;如果请求失败则显示“获取失败”。 接口返回的数据结构在前端定义为 `ServerStatus`,包含 CPU/内存/磁盘/负载/网络/PM2 列表/Postgres 信息/回补标志等。 ### 5.3 页面布局概览 登录且成功获取数据后,布局为: 1. 顶部标题行; 2. 系统概览四张卡片(CPU / 内存 / 硬盘 / 系统); 3. PM2 进程表格; 4. PostgreSQL 概览与数据覆盖范围; 5. 底部说明提示。 ### 5.4 顶部标题行 - 标题:`服务器监控`; - 副标题:`GCP asia-northeast1-b · 每10秒自动刷新`(标明部署区域和刷新频率); - 右侧状态标记: - 当 `data.backfill_running === true` 时,显示: - 蓝色小圆点 + 文案 `回补运行中`; - 提示当前 CPU/网络负载偏高可能是正常的回补行为。 ### 5.5 系统概览四卡片 使用一个 2x2 或 4 列的网格展示四个方面: 1. **CPU** - 显示: - 核数:`data.cpu.cores`; - 当前使用率:`data.cpu.percent%`; - 下方以 `ProgressBar` 表示 CPU 利用率,>70% 黄色,>90% 红色; - 一行 load 信息:`load1 / load5 / load15`。 2. **内存** - 显示: - 占用:`used_gb / total_gb`; - 当前使用率百分比; - `ProgressBar` 显示利用率; - 如果 `swap_percent > 0`,额外显示 Swap 使用率,以橙色提示。 3. **硬盘** - 显示: - 可用空间:`free_gb`; - 使用率百分比 + `ProgressBar`; - 已用/总容量:`used_gb / total_gb`。 4. **系统运行时间与网络** - 显示: - 运行时间:`uptime_hours`(小时),超过 24 小时时会用“X天”的形式; - 网络: - 上行总量:`bytes_sent_gb`; - 下行总量:`bytes_recv_gb`。 ### 5.6 PM2 进程表格 功能:查看每个 PM2 管理的进程状态,确认关键服务是否在线。 - 数据来源:`data.pm2` 数组,每个元素 `PM2Proc` 包含: - `name`:进程名(例如 arb-web/arb-api/signal-engine 等); - `status`:`online` 或其他; - `cpu`:CPU 使用率; - `memory_mb`:内存使用 MB; - `restarts`:重启次数; - `uptime_ms`:运行时长。 - 表格列: - 名称(等宽字体显示); - 状态: - 使用圆点 + badge 样式: - `online` → 绿色背景圆角标; - 其他状态 → 红色背景圆角标; - CPU 百分比; - 内存 MB; - 重启次数; - 运行时间:通过 `uptimeStr` 格式化为 `Xd Yh` 或 `Xh Ym`。 这部分是判断“某个服务是不是挂了 / 频繁重启”的第一视角。 ### 5.7 PostgreSQL 概览 功能:监控数据库大小、关键表数据量以及各交易对的历史数据覆盖范围。 数据来自 `data.postgres`: - 上半部分卡片: 1. 数据库大小: - `db_size_mb`,> 1024 MB 时以 GB 显示; 2. `agg_trades` 行数: - `agg_trades_count`,以千分位格式化(如 89,000,000); 3. `rate_snapshots` 行数: - `rate_snapshots_count`; 4. 回补状态: - 使用 `data.backfill_running` 显示 “运行中” 或 “已停止”,并用颜色区分。 - 下半部分数据覆盖范围: - `data.postgres.symbols` 是一个记录,键为 symbol(如 BTCUSDT/ETHUSDT 等),值包含: - `earliest_ms`:最早一条数据的时间戳; - `latest_ms`:最新一条数据时间戳; - `span_hours`:时间跨度(小时)。 - 对每个 symbol,展示: - 左侧:symbol 名,等宽字体; - 右侧:时间范围: - `earliest_ms` → `latest_ms`,使用 `bjtStr` 转换为北京时间(简短日期+时间); - 下一行显示 `span_hours`,如果 >24 小时,则用“X.X 天”,否则“X.X 小时”。 这部分帮助确认“数据从什么时候开始积累、到什么时候为止、是否有断档”。 ### 5.8 底部说明 最后是一个蓝色 Info 卡片,说明: - 数据每 10 秒自动刷新; - PM2 进程状态实时反映服务运行情况; - 回补运行中时 CPU 和网络负载偏高属于正常现象,不一定是异常。 ### 5.9 依赖的主要 API `/server` 页面只依赖一个后端接口: - `GET /api/server/status` - 返回 `ServerStatus` 结构; - 包含: - CPU/内存/磁盘/负载信息; - uptime 和网络流量; - PM2 进程列表; - Postgres 概览(整体大小、表行数、各 symbol 的数据覆盖范围); - 回补任务状态标记。 具体字段定义与计算方式以 `docs/arbitrage-engine-full-spec.md` 和 `backend/main.py` 中对应接口描述为准。 --- ## 6. /about(策略说明与风险) 文件:`frontend/app/about/page.tsx` 导出的组件名:`AboutPage` ### 6.1 页面目标 `/about` 页面是一个纯信息页,用来向用户解释: - 资金费率套利策略的基本原理(现货多 + 永续空,对冲方向风险,收资金费率); - 历史年化收益数据(基于长期统计的 BTC/ETH/组合毛年化和净年化); - 策略的主要风险点及其等级。 这个页面不依赖登录状态、不调用任何 API,主要用于教育和风险披露。 ### 6.2 页面结构 页面宽度限制在 `max-w-3xl`,内容自上而下分为三块: 1. 标题区; 2. 策略原理说明; 3. 历史年化数据; 4. 风险说明。 #### 6.2.1 标题区 - 主标题:`策略说明` - 副标题:`资金费率套利原理与历史数据` 用于告诉用户:本页不是实时数据,而是解释策略设计与历史表现。 #### 6.2.2 策略原理卡片 第一块白底卡片标题:`策略原理`。 内容用通俗文字说明永续合约资金费率机制和套利思路: - 永续合约每 8 小时结算一次资金费率; - 多头多时,资金费率为正,多头付钱给空头; - 空头多时,资金费率为负,空头付钱给多头。 套利做法用一段高亮文字说明: - “套利做法:现货买入 + 永续做空,完全对冲币价风险,净收资金费率(USDT 结算)。” 下面有一个小示例框(等宽字体): - 买入 1 BTC 现货(例如 96,000 美元); - 做空 1 BTC 永续(同样 96,000 美元,1 倍杠杆); - 分隔线; - 结论: - `BTC 涨跌:两边对冲,净盈亏 = 0`; - `资金费率:每 8 小时直接收 USDT`。 这个例子帮助用户在不看数学公式的情况下理解“赚费率、不赌方向”的本质。 #### 6.2.3 历史年化数据卡片 第二块白底卡片标题: `历史年化数据(2019-2026,露露×小周15轮验证)` 内容是一个简单表格,列出: - 资产:BTC / ETH / 50/50 组合; - 全周期毛年化; - PM 净年化(考虑 Portfolio Margin 下的资金利用率和费用); - 负费率占比(BTC/ETH)。 表格中的示例数值(固定写死在前端): - BTC: - 全周期毛年化:12.33%; - PM 净年化:11.67%; - 负费率占比:13.07%。 - ETH: - 全周期毛年化:14.87%; - PM 净年化:14.09%; - 负费率占比:12.17%。 - 50/50 组合: - 全周期毛年化:13.81%; - PM 净年化:13.08%; - 负费率占比:`—`(组合没有单独统计)。 表格下面有一行小字说明: - `PM = Portfolio Margin 模式,资金利用率约 95%。数据来源:Binance fapi/v1/fundingRate 官方 API` 这块内容用于给出“如果长期做这个套利,大致收益区间在哪”的历史参考,但没有和当前系统直接联动。 #### 6.2.4 风险说明卡片 第三块白底卡片标题:`风险说明`。 以列表形式列出若干风险点,每一行包括: - 风险等级:例如 `🟡 中` 或 `🟢 低`; - 风险类型:如“市场周期”、“费率持续为负”、“交易所对手方”、“爆仓风险”、“基差波动”等; - 简短说明文本。 示例风险点: - 市场周期(中):熊市年化可降至 0–4%,但本金不亏; - 费率持续为负(低):历史负费率占比仅 12–13%,长期均值为正; - 交易所对手方(中):有交易所倒闭风险(FTX 教训),建议资金分散; - 爆仓风险(低):1 倍杠杆 + 对冲,理论需要 BTC 翻倍才触发爆仓; - 基差波动(低):长期持有不影响盈亏,只影响平仓时机。 整块卡片通过背景色和图标表达“这是一份认真写过的风险披露”,帮助用户建立合理预期。 ### 6.3 依赖的 API 与状态 `/about` 页面完全静态: - 不依赖任何远端 API; - 不区分登录/未登录展示; - 所有数据都写死在前端代码中(作为文案与示例数值)。 因此,它更像是项目内置的“策略白皮书摘要”,是用户理解系统的背景材料,也可以为将来的 AI 提供策略语义上的上下文。 --- ## 7. 账号相关页面(/login /register /dashboard) 相关文件: - 登录:`frontend/app/login/page.tsx`(`LoginPage`) - 注册:`frontend/app/register/page.tsx`(`RegisterPage`) - 我的账户:`frontend/app/dashboard/page.tsx`(`DashboardPage`) ### 7.1 /login(登录页) 目标:为已有账号提供登录入口,获取 JWT 后进入系统。 - 表单字段: - 邮箱(必填,type=email); - 密码(必填,type=password)。 - 提交逻辑: - 使用 `useAuth().login(email, password)` 调用后端登录接口; - 成功后 `router.push("/")` 返回首页; - 失败时在表单下方显示错误信息文本(`err.message` 或 “登录失败”)。 - 布局/交互: - 全屏居中白卡片,标题为 `⚡ Arbitrage Engine` + “登录您的账户”; - 提交按钮文案: - 未提交:`登录`; - 提交中:`登录中...`,按钮禁用且透明度降低; - 卡片底部有引导文案: - `没有账户? 注册` → 点击跳转 `/register`。 ### 7.2 /register(注册页) 目标:在邀请码机制下创建新账户。 - 表单字段: - 邀请码(必填,字符串,自动转换为大写); - 邮箱(必填,type=email); - 密码(必填,type=password,至少 6 位)。 - 提交逻辑: - 提交前本地校验密码长度: - 如果 `< 6`,直接显示 “密码至少6位”,不发送请求; - 调用 `useAuth().register(email, password, inviteCode)`; - 成功后重定向到首页 `/`; - 失败时在表单下显示错误信息(`err.message` 或 “注册失败”)。 - 布局/交互: - 布局与登录页相似,标题同样是 `⚡ Arbitrage Engine`; - 副标题提示:`注册新账户(需要邀请码)`; - 提交按钮文案: - 未提交:`注册`; - 提交中:`注册中...`; - 卡片底部提供: - `已有账户? 登录` 链接回 `/login`。 ### 7.3 /dashboard(我的账户) 目标:展示当前登录用户的账号信息、推送设置与订阅等级,并提供登出入口。 - 访问控制: - 使用 `useAuth()`: - 如果 `loading` 还未结束,暂时显示“加载中...”; - 如果 `!isLoggedIn`,直接 `router.push("/login")`; - 数据加载: - 使用 `authFetch("/api/auth/me")` 获取当前用户信息; - 如果请求失败,回退到 `/login`。 - 用户信息结构(前端视角): - `id`:用户 ID; - `email`:邮箱; - `discord_id`:绑定的 Discord 用户 ID(可空); - `subscription`: - `tier`:订阅等级("free" / "pro" / "premium" 等); - `expires_at`:到期时间(可空,空则视为“永久免费”)。 - 页面结构: 1. 顶部标题与登出按钮 - 标题:`我的账户`; - 右侧:`退出` 按钮,调用 `logout()`。 2. 账户信息卡片 - 展示: - 邮箱; - 订阅等级: - 使用 `tierLabel` 将内部值映射为 “免费版” / “Pro” / “Premium”; - 未识别的 tier 值直接原样显示; - 到期时间: - 有值时转为本地日期显示; - 无值时显示“永久免费”。 3. Discord 信号推送卡片 - 说明:绑定 Discord ID 后,当套利信号触发时会自动 @ 用户; - 输入框: - 绑定的 Discord 用户 ID(18 位数字),初始值为后端返回的 `discord_id`; - “绑定”按钮: - 点击调用 `POST /api/user/bind-discord`: - body:`{ discord_id }`; - 提交中按钮禁用,文本为 “保存中...”; - 完成后: - 成功:显示 “绑定成功”(绿字),并更新本地 user 对象; - 失败:显示错误提示(红字); - 下方有一条小字说明如何在 Discord 客户端中获取用户 ID(开启开发者模式后右键复制)。 4. 升级订阅卡片 - 展示三个订阅档位的静态信息: - Free:`¥0`,功能如“实时费率面板”; - Pro:`¥99/月`,功能如“实时费率面板 + 信号 Discord 推送 + 历史数据”; - Premium:`¥299/月`,功能如“Pro 全部功能 + 定制阈值 + 优先客服”。 - 当前 tier 对应的卡片会用高亮边框显示; - 对于非当前档位且不为 Free 的卡片,会展示一个 `升级(即将开放)` 的占位按钮(目前仅为 UI 提示,不实际发请求)。 整体上,`/dashboard` 是一个账号控制面板,主要用于查看订阅信息、管理 Discord 推送绑定、执行登出操作。