import { useEffect, useState } from 'react' import { useParams, useNavigate } from 'react-router-dom' import { Card, Table, Button, Tag, Select, Input, message, Divider, Spin } from 'antd' import { LeftOutlined } from '@ant-design/icons' import { apiService } from '../services/api' import { formatUSDC } from '../utils' import { useMediaQuery } from 'react-responsive' import { useTranslation } from 'react-i18next' import type { BuyOrderInfo, OrderTrackingRequest, OrderTrackingListResponse } from '../types' const { Option } = Select const CopyTradingBuyOrdersPage: React.FC = () => { const { t } = useTranslation() const { copyTradingId } = useParams<{ copyTradingId: string }>() const navigate = useNavigate() const isMobile = useMediaQuery({ maxWidth: 768 }) const [loading, setLoading] = useState(false) const [orders, setOrders] = useState([]) const [total, setTotal] = useState(0) const [page, setPage] = useState(1) const [limit, setLimit] = useState(20) const [filters, setFilters] = useState<{ marketId?: string side?: string status?: string }>({}) useEffect(() => { if (copyTradingId) { fetchOrders() } }, [copyTradingId, page, limit, filters]) const fetchOrders = async () => { if (!copyTradingId) return setLoading(true) try { const request: OrderTrackingRequest = { copyTradingId: parseInt(copyTradingId), type: 'buy', page, limit, ...filters } const response = await apiService.orderTracking.list(request) if (response.data.code === 0 && response.data.data) { const data = response.data.data as OrderTrackingListResponse setOrders((data.list || []) as BuyOrderInfo[]) setTotal(data.total || 0) } else { message.error(response.data.msg || '获取买入订单列表失败') } } catch (error: any) { message.error(error.message || '获取买入订单列表失败') } finally { setLoading(false) } } const getStatusTag = (status: string) => { const statusMap: Record = { filled: { color: 'processing', text: '已完成' }, partially_matched: { color: 'warning', text: '部分匹配' }, fully_matched: { color: 'success', text: '完全匹配' } } const config = statusMap[status] || { color: 'default', text: status } return {config.text} } const columns = [ { title: '订单ID', dataIndex: 'orderId', key: 'orderId', width: isMobile ? 100 : 150, render: (text: string) => ( {isMobile ? `${text.slice(0, 6)}...${text.slice(-4)}` : `${text.slice(0, 8)}...${text.slice(-6)}` } ) }, { title: 'Leader 交易ID', dataIndex: 'leaderTradeId', key: 'leaderTradeId', width: isMobile ? 100 : 150, render: (text: string) => ( {isMobile ? `${text.slice(0, 6)}...${text.slice(-4)}` : `${text.slice(0, 8)}...${text.slice(-6)}` } ) }, { title: '市场', dataIndex: 'marketId', key: 'marketId', width: isMobile ? 100 : 150, render: (text: string) => ( {isMobile ? `${text.slice(0, 6)}...${text.slice(-4)}` : `${text.slice(0, 8)}...${text.slice(-6)}` } ) }, { title: '方向', dataIndex: 'side', key: 'side', width: isMobile ? 60 : 80, render: (side: string) => { // 将0/1转换为YES/NO const displaySide = side === '0' ? 'YES' : side === '1' ? 'NO' : side return {displaySide} } }, { title: '买入数量', dataIndex: 'quantity', key: 'quantity', width: isMobile ? 80 : 100, render: (value: string) => ( {formatUSDC(value)} ) }, { title: '买入价格', dataIndex: 'price', key: 'price', width: isMobile ? 80 : 100, render: (value: string) => ( {formatUSDC(value)} ) }, { title: '买入金额', key: 'amount', width: isMobile ? 100 : 120, render: (_: any, record: BuyOrderInfo) => { const amount = (parseFloat(record.quantity) * parseFloat(record.price)).toString() return ( {isMobile ? formatUSDC(amount) : `${formatUSDC(amount)} USDC`} ) } }, { title: '已匹配', dataIndex: 'matchedQuantity', key: 'matchedQuantity', width: isMobile ? 70 : 90, render: (value: string) => ( {formatUSDC(value)} ) }, { title: '剩余', dataIndex: 'remainingQuantity', key: 'remainingQuantity', width: isMobile ? 70 : 90, render: (value: string) => ( {formatUSDC(value)} ) }, { title: '状态', dataIndex: 'status', key: 'status', width: isMobile ? 80 : 100, render: (status: string) => getStatusTag(status) }, { title: '创建时间', dataIndex: 'createdAt', key: 'createdAt', width: isMobile ? 120 : 160, render: (timestamp: number) => ( {isMobile ? new Date(timestamp).toLocaleDateString('zh-CN') : new Date(timestamp).toLocaleString('zh-CN') } ) } ] return (

买入订单列表

setFilters({ ...filters, marketId: e.target.value || undefined })} />
{isMobile ? ( // 移动端卡片布局
{loading ? (
) : orders.length === 0 ? (
暂无买入订单
) : (
{orders.map((order) => { const date = new Date(order.createdAt) const formattedDate = date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }) const amount = (parseFloat(order.quantity) * parseFloat(order.price)).toString() const displaySide = order.side === '0' ? 'YES' : order.side === '1' ? 'NO' : order.side return ( {/* 订单ID和状态 */}
{order.orderId.slice(0, 8)}...{order.orderId.slice(-6)}
{displaySide} {getStatusTag(order.status)}
{/* 买入信息 */}
买入信息
数量: {formatUSDC(order.quantity)} | 价格: {formatUSDC(order.price)}
金额: {formatUSDC(amount)} USDC
{/* 匹配信息 */}
匹配信息
已匹配: {formatUSDC(order.matchedQuantity)} | 剩余: {formatUSDC(order.remainingQuantity)}
{/* Leader 交易ID */}
Leader 交易ID
{order.leaderTradeId.slice(0, 8)}...{order.leaderTradeId.slice(-6)}
{/* 市场ID */}
市场ID
{order.marketId.slice(0, 8)}...{order.marketId.slice(-6)}
{/* 创建时间 */}
创建时间: {formattedDate}
) })}
)}
) : ( // 桌面端表格布局 `共 ${total} 条`, onChange: (newPage, newLimit) => { setPage(newPage) setLimit(newLimit) } }} /> )} ) } export default CopyTradingBuyOrdersPage