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);
|
.sort((a, b) => b.count - a.count);
|
||||||
}, [ztDetail]);
|
}, [ztDetail]);
|
||||||
|
|
||||||
// 股票详情数据处理
|
// 股票详情数据处理 - 支持两种字段名:stocks 和 stock_infos
|
||||||
const stockList = useMemo(() => {
|
const stockList = useMemo(() => {
|
||||||
if (!ztDetail?.stock_infos) return [];
|
const stocksData = ztDetail?.stocks || ztDetail?.stock_infos;
|
||||||
return ztDetail.stock_infos.map(stock => ({
|
if (!stocksData) return [];
|
||||||
|
return stocksData.map(stock => ({
|
||||||
...stock,
|
...stock,
|
||||||
key: stock.scode,
|
key: stock.scode,
|
||||||
}));
|
}));
|
||||||
@@ -456,6 +457,51 @@ const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading
|
|||||||
return ztDetail.word_freq_data.slice(0, 12);
|
return ztDetail.word_freq_data.slice(0, 12);
|
||||||
}, [ztDetail]);
|
}, [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
|
// 获取六位股票代码(去掉后缀)- 纯函数,不是hook
|
||||||
const getSixDigitCode = (code) => {
|
const getSixDigitCode = (code) => {
|
||||||
if (!code) return code;
|
if (!code) return code;
|
||||||
@@ -1453,6 +1499,82 @@ const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading
|
|||||||
</Box>
|
</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 justify="space-between" align="center" px={1}>
|
||||||
<HStack spacing={3}>
|
<HStack spacing={3}>
|
||||||
|
|||||||
Reference in New Issue
Block a user