community增加事件详情
This commit is contained in:
@@ -441,10 +441,11 @@ const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading
|
||||
.sort((a, b) => b.count - a.count);
|
||||
}, [ztDetail]);
|
||||
|
||||
// 股票详情数据处理
|
||||
// 股票详情数据处理 - 支持两种字段名:stocks 和 stock_infos
|
||||
const stockList = useMemo(() => {
|
||||
if (!ztDetail?.stock_infos) return [];
|
||||
return ztDetail.stock_infos.map(stock => ({
|
||||
const stocksData = ztDetail?.stocks || ztDetail?.stock_infos;
|
||||
if (!stocksData) return [];
|
||||
return stocksData.map(stock => ({
|
||||
...stock,
|
||||
key: stock.scode,
|
||||
}));
|
||||
@@ -456,6 +457,51 @@ const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading
|
||||
return ztDetail.word_freq_data.slice(0, 12);
|
||||
}, [ztDetail]);
|
||||
|
||||
// 涨停统计数据
|
||||
const ztStats = useMemo(() => {
|
||||
if (!stockList.length) return null;
|
||||
|
||||
// 连板分布统计
|
||||
const continuousStats = { '首板': 0, '2连板': 0, '3连板': 0, '4连板+': 0 };
|
||||
// 涨停时间分布统计
|
||||
const timeStats = { '秒板': 0, '早盘': 0, '盘中': 0, '尾盘': 0 };
|
||||
// 公告驱动统计
|
||||
let announcementCount = 0;
|
||||
|
||||
stockList.forEach(stock => {
|
||||
// 连板统计
|
||||
const days = stock.continuous_days || '首板';
|
||||
if (days === '首板' || days.includes('1')) {
|
||||
continuousStats['首板']++;
|
||||
} else {
|
||||
const match = days.match(/(\d+)/);
|
||||
const num = match ? parseInt(match[1]) : 1;
|
||||
if (num === 2) continuousStats['2连板']++;
|
||||
else if (num === 3) continuousStats['3连板']++;
|
||||
else if (num >= 4) continuousStats['4连板+']++;
|
||||
else continuousStats['首板']++;
|
||||
}
|
||||
|
||||
// 时间统计
|
||||
const time = stock.formatted_time || '15:00:00';
|
||||
if (time <= '09:30:00') timeStats['秒板']++;
|
||||
else if (time <= '10:00:00') timeStats['早盘']++;
|
||||
else if (time <= '14:00:00') timeStats['盘中']++;
|
||||
else timeStats['尾盘']++;
|
||||
|
||||
// 公告驱动
|
||||
if (stock.is_announcement) announcementCount++;
|
||||
});
|
||||
|
||||
return {
|
||||
total: stockList.length,
|
||||
continuousStats,
|
||||
timeStats,
|
||||
announcementCount,
|
||||
announcementRatio: stockList.length > 0 ? Math.round(announcementCount / stockList.length * 100) : 0
|
||||
};
|
||||
}, [stockList]);
|
||||
|
||||
// 获取六位股票代码(去掉后缀)- 纯函数,不是hook
|
||||
const getSixDigitCode = (code) => {
|
||||
if (!code) return code;
|
||||
@@ -1453,6 +1499,82 @@ const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* 涨停统计卡片 */}
|
||||
{ztStats && (
|
||||
<HStack spacing={4} flexWrap="wrap">
|
||||
{/* 连板分布 */}
|
||||
<Box
|
||||
flex="1"
|
||||
minW="200px"
|
||||
p={3}
|
||||
bg="rgba(255,255,255,0.03)"
|
||||
borderRadius="xl"
|
||||
border="1px solid rgba(255,255,255,0.08)"
|
||||
>
|
||||
<Text fontSize="xs" color="whiteAlpha.500" mb={2}>连板分布</Text>
|
||||
<HStack spacing={3} flexWrap="wrap">
|
||||
{Object.entries(ztStats.continuousStats).map(([key, value]) => (
|
||||
<VStack key={key} spacing={0} align="center">
|
||||
<Text
|
||||
fontSize="lg"
|
||||
fontWeight="bold"
|
||||
color={key === '4连板+' ? '#ff4d4f' : key === '3连板' ? '#fa541c' : key === '2连板' ? '#fa8c16' : '#52c41a'}
|
||||
>
|
||||
{value}
|
||||
</Text>
|
||||
<Text fontSize="10px" color="whiteAlpha.500">{key}</Text>
|
||||
</VStack>
|
||||
))}
|
||||
</HStack>
|
||||
</Box>
|
||||
|
||||
{/* 涨停时间分布 */}
|
||||
<Box
|
||||
flex="1"
|
||||
minW="200px"
|
||||
p={3}
|
||||
bg="rgba(255,255,255,0.03)"
|
||||
borderRadius="xl"
|
||||
border="1px solid rgba(255,255,255,0.08)"
|
||||
>
|
||||
<Text fontSize="xs" color="whiteAlpha.500" mb={2}>封板时间</Text>
|
||||
<HStack spacing={3} flexWrap="wrap">
|
||||
{Object.entries(ztStats.timeStats).map(([key, value]) => (
|
||||
<VStack key={key} spacing={0} align="center">
|
||||
<Text
|
||||
fontSize="lg"
|
||||
fontWeight="bold"
|
||||
color={key === '秒板' ? '#ff4d4f' : key === '早盘' ? '#fa8c16' : key === '盘中' ? '#52c41a' : '#888'}
|
||||
>
|
||||
{value}
|
||||
</Text>
|
||||
<Text fontSize="10px" color="whiteAlpha.500">{key}</Text>
|
||||
</VStack>
|
||||
))}
|
||||
</HStack>
|
||||
</Box>
|
||||
|
||||
{/* 公告驱动 */}
|
||||
<Box
|
||||
p={3}
|
||||
bg="rgba(255,255,255,0.03)"
|
||||
borderRadius="xl"
|
||||
border="1px solid rgba(255,255,255,0.08)"
|
||||
minW="120px"
|
||||
>
|
||||
<Text fontSize="xs" color="whiteAlpha.500" mb={2}>公告驱动</Text>
|
||||
<HStack spacing={2} align="baseline">
|
||||
<Text fontSize="xl" fontWeight="bold" color="#A855F7">
|
||||
{ztStats.announcementCount}
|
||||
</Text>
|
||||
<Text fontSize="xs" color="whiteAlpha.500">
|
||||
只 ({ztStats.announcementRatio}%)
|
||||
</Text>
|
||||
</HStack>
|
||||
</Box>
|
||||
</HStack>
|
||||
)}
|
||||
|
||||
{/* 视图切换按钮 - 更精致的样式 */}
|
||||
<HStack justify="space-between" align="center" px={1}>
|
||||
<HStack spacing={3}>
|
||||
|
||||
Reference in New Issue
Block a user