This commit is contained in:
薇薇安 2026-01-23 14:30:50 +08:00
parent 63f1ea05f0
commit f9ce156e9a
2 changed files with 204 additions and 5 deletions

View File

@ -208,6 +208,31 @@
background: #5a6268;
}
.btn-export {
padding: 0.75rem 1.5rem;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 0.9rem;
font-weight: 500;
transition: all 0.3s;
touch-action: manipulation;
min-height: 44px;
background: #28a745;
color: white;
}
@media (min-width: 768px) {
.btn-export {
padding: 0.5rem 1.5rem;
min-height: auto;
}
}
.btn-export:hover {
background: #218838;
}
.no-data {
text-align: center;
padding: 3rem;
@ -257,11 +282,36 @@
color: #e74c3c;
}
.table-wrapper {
width: 100%;
overflow-x: auto;
margin-top: 1rem;
-webkit-overflow-scrolling: touch;
}
.table-wrapper::-webkit-scrollbar {
height: 8px;
}
.table-wrapper::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
.table-wrapper::-webkit-scrollbar-thumb {
background: #888;
border-radius: 4px;
}
.table-wrapper::-webkit-scrollbar-thumb:hover {
background: #555;
}
.trades-table {
width: 100%;
border-collapse: collapse;
margin-top: 1rem;
display: none;
min-width: 1200px; /* 确保表格有最小宽度,避免列被压缩 */
}
@media (min-width: 768px) {
@ -273,16 +323,100 @@
.trades-table th {
background-color: #34495e;
color: white;
padding: 1rem;
padding: 0.75rem 0.5rem;
text-align: left;
font-weight: 500;
font-size: 0.9rem;
font-size: 0.85rem;
white-space: nowrap;
position: sticky;
top: 0;
z-index: 10;
}
.trades-table td {
padding: 0.75rem 1rem;
padding: 0.6rem 0.5rem;
border-bottom: 1px solid #eee;
font-size: 0.9rem;
font-size: 0.85rem;
white-space: nowrap;
}
/* 优化特定列的宽度 */
.trades-table th:nth-child(1),
.trades-table td:nth-child(1) {
min-width: 60px;
max-width: 80px;
}
.trades-table th:nth-child(2),
.trades-table td:nth-child(2) {
min-width: 90px;
}
.trades-table th:nth-child(3),
.trades-table td:nth-child(3) {
min-width: 60px;
}
.trades-table th:nth-child(4),
.trades-table td:nth-child(4) {
min-width: 90px;
}
.trades-table th:nth-child(5),
.trades-table td:nth-child(5) {
min-width: 90px;
}
.trades-table th:nth-child(6),
.trades-table td:nth-child(6) {
min-width: 90px;
}
.trades-table th:nth-child(7),
.trades-table td:nth-child(7) {
min-width: 90px;
}
.trades-table th:nth-child(8),
.trades-table td:nth-child(8) {
min-width: 90px;
}
.trades-table th:nth-child(9),
.trades-table td:nth-child(9) {
min-width: 100px;
}
.trades-table th:nth-child(10),
.trades-table td:nth-child(10) {
min-width: 100px;
}
.trades-table th:nth-child(11),
.trades-table td:nth-child(11) {
min-width: 80px;
}
.trades-table th:nth-child(12),
.trades-table td:nth-child(12) {
min-width: 100px;
}
.trades-table th:nth-child(13),
.trades-table td:nth-child(13) {
min-width: 200px;
white-space: normal;
word-break: break-all;
}
.trades-table th:nth-child(14),
.trades-table td:nth-child(14) {
min-width: 140px;
}
.trades-table th:nth-child(15),
.trades-table td:nth-child(15) {
min-width: 140px;
}
.trades-table tr:hover {

View File

@ -81,6 +81,65 @@ const TradeList = () => {
setUseCustomDate(false)
}
//
const handleExport = () => {
if (trades.length === 0) {
alert('暂无数据可导出')
return
}
//
const exportData = trades.map(trade => {
const notional = trade.notional_usdt !== undefined && trade.notional_usdt !== null
? parseFloat(trade.notional_usdt)
: (trade.entry_value_usdt !== undefined && trade.entry_value_usdt !== null
? parseFloat(trade.entry_value_usdt)
: (parseFloat(trade.quantity || 0) * parseFloat(trade.entry_price || 0)))
const leverage = parseFloat(trade.leverage || 10)
const margin = trade.margin_usdt !== undefined && trade.margin_usdt !== null
? parseFloat(trade.margin_usdt)
: (leverage > 0 ? notional / leverage : 0)
const pnl = parseFloat(trade.pnl || 0)
const pnlPercent = margin > 0 ? (pnl / margin) * 100 : 0
return {
交易ID: trade.id,
交易对: trade.symbol,
方向: trade.side,
数量: parseFloat(trade.quantity || 0),
名义价值: notional,
保证金: margin,
杠杆: leverage,
入场价: parseFloat(trade.entry_price || 0),
出场价: trade.exit_price ? parseFloat(trade.exit_price) : null,
盈亏: pnl,
盈亏比例: pnlPercent,
状态: trade.status === 'open' ? '持仓中' : trade.status === 'closed' ? '已平仓' : '已取消',
平仓类型: trade.exit_reason_display || '-',
开仓订单号: trade.entry_order_id || '-',
平仓订单号: trade.exit_order_id || '-',
入场时间: trade.entry_time,
平仓时间: trade.exit_time || null,
}
})
//
const timestamp = new Date().toISOString().slice(0, 19).replace(/:/g, '-')
const filename = `交易记录_${timestamp}.json`
//
const dataStr = JSON.stringify(exportData, null, 2)
const dataBlob = new Blob([dataStr], { type: 'application/json' })
const url = URL.createObjectURL(dataBlob)
const link = document.createElement('a')
link.href = url
link.download = filename
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
URL.revokeObjectURL(url)
}
if (loading) return <div className="loading">加载中...</div>
return (
@ -228,6 +287,11 @@ const TradeList = () => {
<button className="btn-secondary" onClick={handleReset}>
重置
</button>
{trades.length > 0 && (
<button className="btn-export" onClick={handleExport} title="导出当前显示的订单数据">
导出数据 ({trades.length})
</button>
)}
</div>
</div>
@ -471,6 +535,7 @@ const TradeList = () => {
})}
</tbody>
</table>
</div>
{/* 移动端卡片 */}
<div className="trades-cards">