diff --git a/backend/api/main.py b/backend/api/main.py index b87ce61..8e43049 100644 --- a/backend/api/main.py +++ b/backend/api/main.py @@ -3,7 +3,7 @@ FastAPI应用主入口 """ from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware -from api.routes import config, trades, stats, dashboard +from api.routes import config, trades, stats, dashboard, account import os from pathlib import Path @@ -45,6 +45,7 @@ app.include_router(config.router, prefix="/api/config", tags=["配置管理"]) app.include_router(trades.router, prefix="/api/trades", tags=["交易记录"]) app.include_router(stats.router, prefix="/api/stats", tags=["统计分析"]) app.include_router(dashboard.router, prefix="/api/dashboard", tags=["仪表板"]) +app.include_router(account.router, prefix="/api/account", tags=["账户数据"]) @app.get("/") diff --git a/backend/api/routes/stats.py b/backend/api/routes/stats.py index 39e23f8..0c57079 100644 --- a/backend/api/routes/stats.py +++ b/backend/api/routes/stats.py @@ -40,12 +40,29 @@ async def get_performance_stats(days: int = Query(7, ge=1, le=365)): async def get_dashboard_data(): """获取仪表板数据""" try: - # 最近的账户快照 - snapshots = AccountSnapshot.get_recent(1) - latest_snapshot = snapshots[0] if snapshots else None + account_data = None - # 最近的交易 - recent_trades = Trade.get_all(status='open')[:10] + # 优先尝试获取实时账户数据 + try: + from api.routes.account import get_realtime_account_data + account_data = await get_realtime_account_data() + except Exception as e: + logger.warning(f"获取实时账户数据失败,使用数据库快照: {e}") + # 回退到数据库快照 + snapshots = AccountSnapshot.get_recent(1) + account_data = snapshots[0] if snapshots else None + + # 获取持仓数据(优先实时,回退到数据库) + open_trades = [] + try: + from api.routes.account import get_realtime_positions + positions = await get_realtime_positions() + # 转换为前端需要的格式 + open_trades = positions + except Exception as e: + logger.warning(f"获取实时持仓失败,使用数据库记录: {e}") + # 回退到数据库记录 + open_trades = Trade.get_all(status='open')[:10] # 最近的扫描记录 recent_scans = MarketScan.get_recent(10) @@ -54,10 +71,11 @@ async def get_dashboard_data(): recent_signals = TradingSignal.get_recent(20) return { - "account": latest_snapshot, - "open_trades": recent_trades, + "account": account_data, + "open_trades": open_trades, "recent_scans": recent_scans, "recent_signals": recent_signals } except Exception as e: + logger.error(f"获取仪表板数据失败: {e}", exc_info=True) raise HTTPException(status_code=500, detail=str(e)) diff --git a/frontend/src/components/StatsDashboard.css b/frontend/src/components/StatsDashboard.css index 80d0308..c36d607 100644 --- a/frontend/src/components/StatsDashboard.css +++ b/frontend/src/components/StatsDashboard.css @@ -75,6 +75,16 @@ padding: 0.75rem; background: white; border-radius: 4px; + gap: 1rem; +} + +.trade-info { + display: flex; + flex-direction: column; + gap: 0.25rem; + font-size: 0.85rem; + color: #666; + flex: 1; } .trade-symbol { diff --git a/frontend/src/components/StatsDashboard.jsx b/frontend/src/components/StatsDashboard.jsx index 5266aa9..52b29b1 100644 --- a/frontend/src/components/StatsDashboard.jsx +++ b/frontend/src/components/StatsDashboard.jsx @@ -70,14 +70,27 @@ const StatsDashboard = () => {