- 缩短菜单标题,解决显示不全问题 - 添加跟随系统语言选项,作为默认选项 - 移除语言切换时的页面刷新,实现无刷新切换 - 完成主要页面的多语言替换: * ConfigPage - 全局配置页面 * ResetPassword - 重置密码页面 * LeaderList - Leader 列表页面 * UserList - 用户列表页面 * Statistics - 统计信息页面 * OrderList - 订单列表页面 * TemplateList - 模板列表页面 * CopyTradingList - 跟单配置列表页面 - 添加简体中文、繁体中文和英文的完整翻译键 - 优化语言设置页面,支持跟随系统语言
163 lines
4.3 KiB
TypeScript
163 lines
4.3 KiB
TypeScript
import { useEffect, useState } from 'react'
|
|
import { Card, Table, Tag, message } from 'antd'
|
|
import { useTranslation } from 'react-i18next'
|
|
import { apiService } from '../services/api'
|
|
import type { CopyOrder } from '../types'
|
|
import { useMediaQuery } from 'react-responsive'
|
|
import { formatUSDC } from '../utils'
|
|
|
|
const OrderList: React.FC = () => {
|
|
const { t, i18n } = useTranslation()
|
|
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') || '获取订单列表失败')
|
|
}
|
|
} catch (error: any) {
|
|
message.error(error.message || t('orderList.fetchFailed') || '获取订单列表失败')
|
|
} 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',
|
|
dataIndex: 'leaderName',
|
|
key: 'leaderName',
|
|
render: (text: string, record: CopyOrder) => text || record.leaderAddress.slice(0, 10) + '...'
|
|
},
|
|
{
|
|
title: t('orderList.market') || '市场',
|
|
dataIndex: 'marketId',
|
|
key: 'marketId',
|
|
render: (marketId: string) => (
|
|
<span style={{ fontFamily: 'monospace', fontSize: '12px' }}>
|
|
{marketId.slice(0, 10)}...
|
|
</span>
|
|
)
|
|
},
|
|
{
|
|
title: t('orderList.category') || '分类',
|
|
dataIndex: 'category',
|
|
key: 'category',
|
|
render: (category: string) => (
|
|
<Tag color={category === 'sports' ? 'blue' : 'green'}>{category}</Tag>
|
|
)
|
|
},
|
|
{
|
|
title: t('orderList.side') || '方向',
|
|
dataIndex: 'side',
|
|
key: 'side',
|
|
render: (side: string) => (
|
|
<Tag color={getSideColor(side)}>{side}</Tag>
|
|
)
|
|
},
|
|
{
|
|
title: t('orderList.price') || '价格',
|
|
dataIndex: 'price',
|
|
key: 'price'
|
|
},
|
|
{
|
|
title: t('orderList.size') || '数量',
|
|
dataIndex: 'size',
|
|
key: 'size'
|
|
},
|
|
{
|
|
title: t('orderList.status') || '状态',
|
|
dataIndex: 'status',
|
|
key: 'status',
|
|
render: (status: string) => (
|
|
<Tag color={getStatusColor(status)}>{status}</Tag>
|
|
)
|
|
},
|
|
{
|
|
title: t('orderList.pnl') || '盈亏',
|
|
dataIndex: 'pnl',
|
|
key: 'pnl',
|
|
render: (pnl: string | undefined) => pnl ? (
|
|
<span style={{ color: pnl.startsWith('-') ? 'red' : 'green' }}>
|
|
{formatUSDC(pnl)} USDC
|
|
</span>
|
|
) : '-'
|
|
},
|
|
{
|
|
title: t('orderList.createdAt') || '创建时间',
|
|
dataIndex: 'createdAt',
|
|
key: 'createdAt',
|
|
render: (timestamp: number) => new Date(timestamp).toLocaleString(i18n.language || 'zh-CN')
|
|
}
|
|
]
|
|
|
|
return (
|
|
<div>
|
|
<div style={{ marginBottom: '16px' }}>
|
|
<h2>{t('orderList.title') || '订单管理'}</h2>
|
|
</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
|
|
|