feat: 任务 1: 集成 TradingSimulation 追踪事件任务 2: 传递 tradingEvents 到子组件
This commit is contained in:
@@ -64,20 +64,38 @@ const calculateChange = (currentPrice, avgPrice) => {
|
||||
return { change, changePercent };
|
||||
};
|
||||
|
||||
export default function PositionsList({ positions, account, onSellStock }) {
|
||||
export default function PositionsList({ positions, account, onSellStock, tradingEvents }) {
|
||||
const [selectedPosition, setSelectedPosition] = useState(null);
|
||||
const [sellQuantity, setSellQuantity] = useState(0);
|
||||
const [orderType, setOrderType] = useState('MARKET');
|
||||
const [limitPrice, setLimitPrice] = useState('');
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const [hasTracked, setHasTracked] = React.useState(false);
|
||||
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const toast = useToast();
|
||||
|
||||
|
||||
const cardBg = useColorModeValue('white', 'gray.800');
|
||||
const textColor = useColorModeValue('gray.700', 'white');
|
||||
const secondaryColor = useColorModeValue('gray.500', 'gray.400');
|
||||
|
||||
// 🎯 追踪持仓查看 - 组件加载时触发一次
|
||||
React.useEffect(() => {
|
||||
if (!hasTracked && positions && positions.length > 0 && tradingEvents && tradingEvents.trackSimulationHoldingsViewed) {
|
||||
const totalMarketValue = positions.reduce((sum, pos) => sum + (pos.marketValue || pos.quantity * pos.currentPrice || 0), 0);
|
||||
const totalCost = positions.reduce((sum, pos) => sum + (pos.totalCost || pos.quantity * pos.avgPrice || 0), 0);
|
||||
const totalProfit = positions.reduce((sum, pos) => sum + (pos.profit || 0), 0);
|
||||
|
||||
tradingEvents.trackSimulationHoldingsViewed({
|
||||
count: positions.length,
|
||||
totalValue: totalMarketValue,
|
||||
totalCost,
|
||||
profitLoss: totalProfit,
|
||||
});
|
||||
setHasTracked(true);
|
||||
}
|
||||
}, [positions, tradingEvents, hasTracked]);
|
||||
|
||||
// 格式化货币
|
||||
const formatCurrency = (amount) => {
|
||||
return new Intl.NumberFormat('zh-CN', {
|
||||
@@ -102,6 +120,17 @@ export default function PositionsList({ positions, account, onSellStock }) {
|
||||
setSelectedPosition(position);
|
||||
setSellQuantity(position.availableQuantity); // 默认全部可卖数量
|
||||
setLimitPrice(position.currentPrice?.toString() || position.avgPrice.toString());
|
||||
|
||||
// 🎯 追踪卖出按钮点击
|
||||
if (tradingEvents && tradingEvents.trackSellButtonClicked) {
|
||||
tradingEvents.trackSellButtonClicked({
|
||||
stockCode: position.stockCode,
|
||||
stockName: position.stockName,
|
||||
quantity: position.quantity,
|
||||
profitLoss: position.profit || 0,
|
||||
}, 'holdings');
|
||||
}
|
||||
|
||||
onOpen();
|
||||
};
|
||||
|
||||
@@ -110,6 +139,8 @@ export default function PositionsList({ positions, account, onSellStock }) {
|
||||
if (!selectedPosition || sellQuantity <= 0) return;
|
||||
|
||||
setIsLoading(true);
|
||||
const price = orderType === 'LIMIT' ? parseFloat(limitPrice) : selectedPosition.currentPrice || selectedPosition.avgPrice;
|
||||
|
||||
try {
|
||||
const result = await onSellStock(
|
||||
selectedPosition.stockCode,
|
||||
@@ -126,6 +157,20 @@ export default function PositionsList({ positions, account, onSellStock }) {
|
||||
orderType,
|
||||
orderId: result.orderId
|
||||
});
|
||||
|
||||
// 🎯 追踪卖出成功
|
||||
if (tradingEvents && tradingEvents.trackSimulationOrderPlaced) {
|
||||
tradingEvents.trackSimulationOrderPlaced({
|
||||
stockCode: selectedPosition.stockCode,
|
||||
stockName: selectedPosition.stockName,
|
||||
direction: 'sell',
|
||||
quantity: sellQuantity,
|
||||
price,
|
||||
orderType,
|
||||
success: true,
|
||||
});
|
||||
}
|
||||
|
||||
toast({
|
||||
title: '卖出成功',
|
||||
description: `已卖出 ${selectedPosition.stockName} ${sellQuantity} 股`,
|
||||
@@ -142,6 +187,21 @@ export default function PositionsList({ positions, account, onSellStock }) {
|
||||
quantity: sellQuantity,
|
||||
orderType
|
||||
});
|
||||
|
||||
// 🎯 追踪卖出失败
|
||||
if (tradingEvents && tradingEvents.trackSimulationOrderPlaced) {
|
||||
tradingEvents.trackSimulationOrderPlaced({
|
||||
stockCode: selectedPosition.stockCode,
|
||||
stockName: selectedPosition.stockName,
|
||||
direction: 'sell',
|
||||
quantity: sellQuantity,
|
||||
price,
|
||||
orderType,
|
||||
success: false,
|
||||
errorMessage: error.message,
|
||||
});
|
||||
}
|
||||
|
||||
toast({
|
||||
title: '卖出失败',
|
||||
description: error.message,
|
||||
|
||||
Reference in New Issue
Block a user