diff --git a/backend/api/routes/trades.py b/backend/api/routes/trades.py index 608d33d..4eb6ef3 100644 --- a/backend/api/routes/trades.py +++ b/backend/api/routes/trades.py @@ -50,6 +50,8 @@ async def get_trades( end_date: Optional[str] = Query(None, description="结束日期 (YYYY-MM-DD 或 YYYY-MM-DD HH:MM:SS)"), period: Optional[str] = Query(None, description="快速时间段筛选: '1d'(最近1天), '7d'(最近7天), '30d'(最近30天)"), symbol: Optional[str] = Query(None, description="交易对筛选"), + trade_type: Optional[str] = Query(None, description="交易类型筛选: 'buy', 'sell'"), + exit_reason: Optional[str] = Query(None, description="平仓原因筛选: 'stop_loss', 'take_profit', 'trailing_stop', 'manual', 'sync'"), status: Optional[str] = Query(None, description="状态筛选: 'open', 'closed', 'cancelled'"), limit: int = Query(100, ge=1, le=1000, description="返回记录数限制") ): diff --git a/backend/database/models.py b/backend/database/models.py index c042f57..31b562e 100644 --- a/backend/database/models.py +++ b/backend/database/models.py @@ -112,7 +112,7 @@ class Trade: ) @staticmethod - def get_all(start_date=None, end_date=None, symbol=None, status=None): + def get_all(start_date=None, end_date=None, symbol=None, status=None, trade_type=None, exit_reason=None): """获取交易记录""" query = "SELECT * FROM trades WHERE 1=1" params = [] @@ -129,6 +129,12 @@ class Trade: if status: query += " AND status = %s" params.append(status) + if trade_type: + query += " AND side = %s" + params.append(trade_type) + if exit_reason: + query += " AND exit_reason = %s" + params.append(exit_reason) query += " ORDER BY entry_time DESC" return db.execute_query(query, params) diff --git a/frontend/src/components/StatsDashboard.css b/frontend/src/components/StatsDashboard.css index 1ad6eb6..140db5c 100644 --- a/frontend/src/components/StatsDashboard.css +++ b/frontend/src/components/StatsDashboard.css @@ -30,12 +30,12 @@ gap: 1rem; } -@media (min-width: 768px) { +/* @media (min-width: 768px) { .dashboard-grid { grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 2rem; } -} +} */ .dashboard-card { background: #f8f9fa; @@ -128,6 +128,8 @@ border: 1px solid #e9ecef; } + + @media (min-width: 768px) { .trade-item { flex-direction: row; diff --git a/frontend/src/components/StatsDashboard.jsx b/frontend/src/components/StatsDashboard.jsx index 2ec6656..89b7bba 100644 --- a/frontend/src/components/StatsDashboard.jsx +++ b/frontend/src/components/StatsDashboard.jsx @@ -145,6 +145,10 @@ const StatsDashboard = () => {
数量: {parseFloat(trade.quantity || 0).toFixed(4)}
+
保证金: {margin.toFixed(2)} USDT
+ {trade.entry_time && ( +
开仓时间: {formatEntryTime(trade.entry_time)}
+ )}
入场价: {parseFloat(trade.entry_price || 0).toFixed(4)}
{trade.mark_price && (
标记价: {parseFloat(trade.mark_price).toFixed(4)}
@@ -152,10 +156,6 @@ const StatsDashboard = () => { {trade.leverage && (
杠杆: {trade.leverage}x
)} -
保证金: {margin.toFixed(2)} USDT
- {trade.entry_time && ( -
开仓时间: {formatEntryTime(trade.entry_time)}
- )}
= 0 ? 'positive' : 'negative'}`}> diff --git a/frontend/src/components/TradeList.jsx b/frontend/src/components/TradeList.jsx index bcafae8..9f82e55 100644 --- a/frontend/src/components/TradeList.jsx +++ b/frontend/src/components/TradeList.jsx @@ -14,6 +14,8 @@ const TradeList = () => { const [symbol, setSymbol] = useState('') const [status, setStatus] = useState('') const [useCustomDate, setUseCustomDate] = useState(false) + const [tradeType, setTradeType] = useState('') + const [exitReason, setExitReason] = useState('') useEffect(() => { loadData() @@ -37,6 +39,8 @@ const TradeList = () => { if (symbol) params.symbol = symbol if (status) params.status = status + if (tradeType) params.trade_type = tradeType + if (exitReason) params.exit_reason = exitReason const [tradesData, statsData] = await Promise.all([ api.getTrades(params), @@ -151,6 +155,33 @@ const TradeList = () => { style={{ width: '150px' }} />
+
+ + +
+
+ + +