This commit is contained in:
薇薇安 2026-01-15 23:00:28 +08:00
parent 9513f94760
commit 3a07c55281
2 changed files with 149 additions and 54 deletions

View File

@ -243,79 +243,156 @@ const TradeList = () => {
<th>交易对</th> <th>交易对</th>
<th>方向</th> <th>方向</th>
<th>数量</th> <th>数量</th>
<th>保证金</th>
<th>入场价</th> <th>入场价</th>
<th>出场价</th> <th>出场价</th>
<th>盈亏</th> <th>盈亏</th>
<th>盈亏比例</th>
<th>状态</th> <th>状态</th>
<th>平仓类型</th> <th>平仓类型</th>
<th>时间</th> <th>时间</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{trades.map(trade => ( {trades.map(trade => {
<tr key={trade.id}> // entry_value_usdtleverage使/
<td>{trade.symbol}</td> const entryValue = trade.entry_value_usdt !== undefined
<td className={trade.side === 'BUY' ? 'buy' : 'sell'}>{trade.side}</td> ? parseFloat(trade.entry_value_usdt)
<td>{parseFloat(trade.quantity).toFixed(4)}</td> : (parseFloat(trade.quantity || 0) * parseFloat(trade.entry_price || 0))
<td>{parseFloat(trade.entry_price).toFixed(4)}</td> const leverage = parseFloat(trade.leverage || 10)
<td>{trade.exit_price ? parseFloat(trade.exit_price).toFixed(4) : '-'}</td> const margin = leverage > 0 ? entryValue / leverage : 0
<td className={parseFloat(trade.pnl) >= 0 ? 'positive' : 'negative'}>
{parseFloat(trade.pnl).toFixed(2)} USDT // /
</td> const pnl = parseFloat(trade.pnl || 0)
<td> const pnlPercent = margin > 0 ? (pnl / margin) * 100 : 0
<span className={`status ${trade.status}`}>{trade.status === 'open' ? '持仓中' : trade.status === 'closed' ? '已平仓' : '已取消'}</span>
</td> //
<td>{trade.exit_reason_display || '-'}</td> const formatTime = (timeStr) => {
<td>{new Date(trade.entry_time).toLocaleString('zh-CN')}</td> if (!timeStr) return '-'
</tr> try {
))} const date = new Date(timeStr)
if (isNaN(date.getTime())) return timeStr
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
timeZone: 'Asia/Shanghai'
})
} catch (e) {
return timeStr
}
}
return (
<tr key={trade.id}>
<td>{trade.symbol}</td>
<td className={trade.side === 'BUY' ? 'buy' : 'sell'}>{trade.side}</td>
<td>{parseFloat(trade.quantity).toFixed(4)}</td>
<td>{margin.toFixed(2)} USDT</td>
<td>{parseFloat(trade.entry_price).toFixed(4)}</td>
<td>{trade.exit_price ? parseFloat(trade.exit_price).toFixed(4) : '-'}</td>
<td className={pnl >= 0 ? 'positive' : 'negative'}>
{pnl.toFixed(2)} USDT
</td>
<td className={pnlPercent >= 0 ? 'positive' : 'negative'}>
{pnlPercent >= 0 ? '+' : ''}{pnlPercent.toFixed(2)}%
</td>
<td>
<span className={`status ${trade.status}`}>{trade.status === 'open' ? '持仓中' : trade.status === 'closed' ? '已平仓' : '已取消'}</span>
</td>
<td>{trade.exit_reason_display || '-'}</td>
<td>{formatTime(trade.entry_time)}</td>
</tr>
)
})}
</tbody> </tbody>
</table> </table>
{/* 移动端卡片 */} {/* 移动端卡片 */}
<div className="trades-cards"> <div className="trades-cards">
{trades.map(trade => ( {trades.map(trade => {
<div key={trade.id} className="trade-card"> //
<div className="trade-card-header"> const entryValue = trade.entry_value_usdt !== undefined
<span className="trade-card-symbol">{trade.symbol}</span> ? parseFloat(trade.entry_value_usdt)
<span className={`trade-card-side ${trade.side === 'BUY' ? 'buy' : 'sell'} status ${trade.status}`}> : (parseFloat(trade.quantity || 0) * parseFloat(trade.entry_price || 0))
{trade.side === 'BUY' ? '买入' : '卖出'} · {trade.status === 'open' ? '持仓中' : trade.status === 'closed' ? '已平仓' : '已取消'} const leverage = parseFloat(trade.leverage || 10)
</span> const margin = leverage > 0 ? entryValue / leverage : 0
</div> const pnl = parseFloat(trade.pnl || 0)
<div className="trade-card-body"> const pnlPercent = margin > 0 ? (pnl / margin) * 100 : 0
<div className="trade-card-field">
<span className="trade-card-label">数量</span> //
<span className="trade-card-value">{parseFloat(trade.quantity).toFixed(4)}</span> const formatTime = (timeStr) => {
</div> if (!timeStr) return '-'
<div className="trade-card-field"> try {
<span className="trade-card-label">入场价</span> const date = new Date(timeStr)
<span className="trade-card-value">{parseFloat(trade.entry_price).toFixed(4)}</span> if (isNaN(date.getTime())) return timeStr
</div> return date.toLocaleString('zh-CN', {
<div className="trade-card-field"> month: '2-digit',
<span className="trade-card-label">出场价</span> day: '2-digit',
<span className="trade-card-value">{trade.exit_price ? parseFloat(trade.exit_price).toFixed(4) : '-'}</span> hour: '2-digit',
</div> minute: '2-digit',
<div className="trade-card-field"> timeZone: 'Asia/Shanghai'
<span className="trade-card-label">盈亏</span> })
<span className={`trade-card-value ${parseFloat(trade.pnl) >= 0 ? 'positive' : 'negative'}`}> } catch (e) {
{parseFloat(trade.pnl).toFixed(2)} USDT return timeStr
}
}
return (
<div key={trade.id} className="trade-card">
<div className="trade-card-header">
<span className="trade-card-symbol">{trade.symbol}</span>
<span className={`trade-card-side ${trade.side === 'BUY' ? 'buy' : 'sell'} status ${trade.status}`}>
{trade.side === 'BUY' ? '买入' : '卖出'} · {trade.status === 'open' ? '持仓中' : trade.status === 'closed' ? '已平仓' : '已取消'}
</span> </span>
</div> </div>
{trade.exit_reason_display && ( <div className="trade-card-body">
<div className="trade-card-field"> <div className="trade-card-field">
<span className="trade-card-label">平仓类型</span> <span className="trade-card-label">数量</span>
<span className="trade-card-value">{trade.exit_reason_display}</span> <span className="trade-card-value">{parseFloat(trade.quantity).toFixed(4)}</span>
</div> </div>
)} <div className="trade-card-field">
<span className="trade-card-label">保证金</span>
<span className="trade-card-value">{margin.toFixed(2)} USDT</span>
</div>
<div className="trade-card-field">
<span className="trade-card-label">入场价</span>
<span className="trade-card-value">{parseFloat(trade.entry_price).toFixed(4)}</span>
</div>
<div className="trade-card-field">
<span className="trade-card-label">出场价</span>
<span className="trade-card-value">{trade.exit_price ? parseFloat(trade.exit_price).toFixed(4) : '-'}</span>
</div>
<div className="trade-card-field">
<span className="trade-card-label">盈亏</span>
<span className={`trade-card-value ${pnl >= 0 ? 'positive' : 'negative'}`}>
{pnl.toFixed(2)} USDT
</span>
</div>
<div className="trade-card-field">
<span className="trade-card-label">盈亏比例</span>
<span className={`trade-card-value ${pnlPercent >= 0 ? 'positive' : 'negative'}`}>
{pnlPercent >= 0 ? '+' : ''}{pnlPercent.toFixed(2)}%
</span>
</div>
{trade.exit_reason_display && (
<div className="trade-card-field">
<span className="trade-card-label">平仓类型</span>
<span className="trade-card-value">{trade.exit_reason_display}</span>
</div>
)}
</div>
<div className="trade-card-footer">
<span>{formatTime(trade.entry_time)}</span>
{trade.exit_time && (
<span>平仓: {formatTime(trade.exit_time)}</span>
)}
</div>
</div> </div>
<div className="trade-card-footer"> )
<span>{new Date(trade.entry_time).toLocaleString('zh-CN', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' })}</span> })}
{trade.exit_time && (
<span>平仓: {new Date(trade.exit_time).toLocaleString('zh-CN', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' })}</span>
)}
</div>
</div>
))}
</div> </div>
</> </>
)} )}

View File

@ -104,6 +104,24 @@ function RecommendationsViewer() {
}; };
const formatTime = (timeStr) => { const formatTime = (timeStr) => {
if (!timeStr) return '-'
try {
const date = new Date(timeStr)
if (isNaN(date.getTime())) return timeStr
// 使
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
timeZone: 'Asia/Shanghai' // 使
})
} catch (e) {
return timeStr
}
}
if (!timeStr) return '-'; if (!timeStr) return '-';
try { try {
const date = new Date(timeStr); const date = new Date(timeStr);