Files
PolyHermes/frontend/src/pages/OrderList.tsx
T

163 lines
4.3 KiB
TypeScript
Raw Normal View History

2025-11-21 04:32:08 +08:00
import { useEffect, useState } from 'react'
2025-11-26 22:26:50 +08:00
import { Card, Table, Tag, message } from 'antd'
import { useTranslation } from 'react-i18next'
2025-11-21 04:32:08 +08:00
import { apiService } from '../services/api'
import type { CopyOrder } from '../types'
import { useMediaQuery } from 'react-responsive'
import { formatUSDC } from '../utils'
2025-11-21 04:32:08 +08:00
const OrderList: React.FC = () => {
const { t, i18n } = useTranslation()
2025-11-21 04:32:08 +08:00
const isMobile = useMediaQuery({ maxWidth: 768 })
const [orders, setOrders] = useState<CopyOrder[]>([])
const [loading, setLoading] = useState(false)
const [pagination, setPagination] = useState({
current: 1,
pageSize: 20,
total: 0
})
useEffect(() => {
fetchOrders()
}, [pagination.current, pagination.pageSize])
const fetchOrders = async () => {
setLoading(true)
try {
const response = await apiService.orders.list({
page: pagination.current,
limit: pagination.pageSize
})
if (response.data.code === 0 && response.data.data) {
setOrders(response.data.data.list || [])
setPagination(prev => ({
...prev,
total: response.data.data?.total || 0
}))
} else {
message.error(response.data.msg || t('orderList.fetchFailed') || '获取订单列表失败')
2025-11-21 04:32:08 +08:00
}
} catch (error: any) {
message.error(error.message || t('orderList.fetchFailed') || '获取订单列表失败')
2025-11-21 04:32:08 +08:00
} finally {
setLoading(false)
}
}
const getStatusColor = (status: string) => {
switch (status) {
case 'filled':
return 'success'
case 'cancelled':
return 'default'
case 'failed':
return 'error'
default:
return 'processing'
}
}
const getSideColor = (side: string) => {
return side === 'BUY' ? 'green' : 'red'
}
const columns = [
{
title: t('orderList.leader') || 'Leader',
2025-11-21 04:32:08 +08:00
dataIndex: 'leaderName',
key: 'leaderName',
render: (text: string, record: CopyOrder) => text || record.leaderAddress.slice(0, 10) + '...'
},
{
title: t('orderList.market') || '市场',
2025-11-21 04:32:08 +08:00
dataIndex: 'marketId',
key: 'marketId',
render: (marketId: string) => (
<span style={{ fontFamily: 'monospace', fontSize: '12px' }}>
{marketId.slice(0, 10)}...
</span>
)
},
{
title: t('orderList.category') || '分类',
2025-11-21 04:32:08 +08:00
dataIndex: 'category',
key: 'category',
render: (category: string) => (
<Tag color={category === 'sports' ? 'blue' : 'green'}>{category}</Tag>
)
},
{
title: t('orderList.side') || '方向',
2025-11-21 04:32:08 +08:00
dataIndex: 'side',
key: 'side',
render: (side: string) => (
<Tag color={getSideColor(side)}>{side}</Tag>
)
},
{
title: t('orderList.price') || '价格',
2025-11-21 04:32:08 +08:00
dataIndex: 'price',
key: 'price'
},
{
title: t('orderList.size') || '数量',
2025-11-21 04:32:08 +08:00
dataIndex: 'size',
key: 'size'
},
{
title: t('orderList.status') || '状态',
2025-11-21 04:32:08 +08:00
dataIndex: 'status',
key: 'status',
render: (status: string) => (
<Tag color={getStatusColor(status)}>{status}</Tag>
)
},
{
title: t('orderList.pnl') || '盈亏',
2025-11-21 04:32:08 +08:00
dataIndex: 'pnl',
key: 'pnl',
render: (pnl: string | undefined) => pnl ? (
<span style={{ color: pnl.startsWith('-') ? 'red' : 'green' }}>
{formatUSDC(pnl)} USDC
2025-11-21 04:32:08 +08:00
</span>
) : '-'
},
{
title: t('orderList.createdAt') || '创建时间',
2025-11-21 04:32:08 +08:00
dataIndex: 'createdAt',
key: 'createdAt',
render: (timestamp: number) => new Date(timestamp).toLocaleString(i18n.language || 'zh-CN')
2025-11-21 04:32:08 +08:00
}
]
return (
<div>
<div style={{ marginBottom: '16px' }}>
<h2>{t('orderList.title') || '订单管理'}</h2>
2025-11-21 04:32:08 +08:00
</div>
<Card>
<Table
dataSource={orders}
columns={columns}
rowKey="id"
loading={loading}
pagination={{
current: pagination.current,
pageSize: pagination.pageSize,
total: pagination.total,
showSizeChanger: !isMobile,
onChange: (page, pageSize) => {
setPagination(prev => ({ ...prev, current: page, pageSize }))
}
}}
scroll={isMobile ? { x: 800 } : undefined}
/>
</Card>
</div>
)
}
export default OrderList