a
This commit is contained in:
parent
63f1ea05f0
commit
f9ce156e9a
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user