// src/views/TradingSimulation/components/TradingHistory.js - 交易历史组件 import React, { useState, useMemo } from 'react'; import { Box, Card, CardHeader, CardBody, Heading, Text, Button, Table, Thead, Tbody, Tr, Th, Td, Badge, HStack, VStack, Select, Input, InputGroup, InputLeftElement, Flex, Spacer, Icon, useColorModeValue, Alert, AlertIcon, AlertDescription, Tooltip, useToast } from '@chakra-ui/react'; import { FiSearch, FiFilter, FiClock, FiTrendingUp, FiTrendingDown } from 'react-icons/fi'; import { logger } from '../../../utils/logger'; export default function TradingHistory({ history, onCancelOrder }) { const [filterType, setFilterType] = useState('ALL'); // ALL, BUY, SELL const [filterStatus, setFilterStatus] = useState('ALL'); // ALL, FILLED, PENDING, CANCELLED const [searchTerm, setSearchTerm] = useState(''); const [sortBy, setSortBy] = useState('createdAt'); // createdAt, stockCode, amount const [sortOrder, setSortOrder] = useState('desc'); // desc, asc const toast = useToast(); const cardBg = useColorModeValue('white', 'gray.800'); const textColor = useColorModeValue('gray.700', 'white'); const secondaryColor = useColorModeValue('gray.500', 'gray.400'); // 格式化货币 const formatCurrency = (amount) => { return new Intl.NumberFormat('zh-CN', { style: 'currency', currency: 'CNY', minimumFractionDigits: 2 }).format(amount); }; // 格式化日期时间 const formatDateTime = (dateString) => { return new Date(dateString).toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }); }; // 过滤和排序历史记录 const filteredAndSortedHistory = useMemo(() => { let filtered = [...(history || [])]; // 按类型过滤 if (filterType !== 'ALL') { filtered = filtered.filter(trade => trade.type === filterType); } // 按状态过滤 if (filterStatus !== 'ALL') { filtered = filtered.filter(trade => trade.status === filterStatus); } // 按搜索词过滤 if (searchTerm) { filtered = filtered.filter(trade => trade.stockCode.includes(searchTerm) || trade.stockName.toLowerCase().includes(searchTerm.toLowerCase()) || trade.orderId.includes(searchTerm) ); } // 排序 filtered.sort((a, b) => { let aValue, bValue; switch (sortBy) { case 'stockCode': aValue = a.stockCode; bValue = b.stockCode; break; case 'amount': aValue = a.totalAmount; bValue = b.totalAmount; break; default: aValue = new Date(a.createdAt); bValue = new Date(b.createdAt); } if (sortOrder === 'desc') { return aValue > bValue ? -1 : aValue < bValue ? 1 : 0; } else { return aValue < bValue ? -1 : aValue > bValue ? 1 : 0; } }); return filtered; }, [history, filterType, filterStatus, searchTerm, sortBy, sortOrder]); // 获取状态样式 const getStatusBadge = (status) => { switch (status) { case 'FILLED': return 已成交; case 'PENDING': return 待成交; case 'CANCELLED': return 已撤销; default: return 未知; } }; // 获取交易类型样式 const getTypeBadge = (type) => { switch (type) { case 'BUY': return 买入; case 'SELL': return 卖出; default: return 未知; } }; // 撤销订单 const handleCancelOrder = async (orderId) => { try { await onCancelOrder(orderId); logger.info('TradingHistory', '撤单成功', { orderId }); toast({ title: '撤单成功', description: `订单 ${orderId} 已撤销`, status: 'success', duration: 3000, isClosable: true, }); } catch (error) { logger.error('TradingHistory', 'handleCancelOrder', error, { orderId }); toast({ title: '撤单失败', description: error.message, status: 'error', duration: 5000, isClosable: true, }); } }; // 计算统计数据 const stats = useMemo(() => { const filled = history?.filter(t => t.status === 'FILLED') || []; const totalTrades = filled.length; const buyTrades = filled.filter(t => t.type === 'BUY').length; const sellTrades = filled.filter(t => t.type === 'SELL').length; const totalVolume = filled.reduce((sum, t) => sum + t.totalAmount, 0); return { totalTrades, buyTrades, sellTrades, totalVolume }; }, [history]); if (!history || history.length === 0) { return ( 暂无交易记录 完成首笔交易后,历史记录将在这里显示 ); } return ( {/* 交易统计 */} 交易统计 {stats.totalTrades} 总交易次数 {stats.buyTrades} 买入次数 {stats.sellTrades} 卖出次数 {formatCurrency(stats.totalVolume)} 累计成交额 {/* 过滤和搜索 */} 搜索 setSearchTerm(e.target.value)} /> 交易类型 订单状态 排序方式 {/* 交易历史列表 */} 交易历史 {filteredAndSortedHistory.length} 条记录 {filteredAndSortedHistory.length === 0 ? ( 没有找到符合条件的交易记录 ) : ( {filteredAndSortedHistory.map((trade) => ( ))}
订单号 交易时间 股票 类型 数量 价格 成交金额 手续费 状态 操作
{trade.orderId.substring(0, 12)}... {formatDateTime(trade.createdAt)} {trade.stockCode} {trade.stockName} {getTypeBadge(trade.type)} {trade.quantity.toLocaleString()} ¥{(trade.price || 0).toFixed(2)} {formatCurrency(trade.totalAmount)} {formatCurrency(trade.commission)} {trade.stampTax && ( 印花税: {formatCurrency(trade.stampTax)} )} {getStatusBadge(trade.status)} {trade.status === 'PENDING' && ( )}
)}
); }