事件中心的涨停原因里面和事件相关

This commit is contained in:
2026-01-10 19:05:14 +08:00
parent 6ae338eae8
commit 2eb876ebbf

View File

@@ -500,6 +500,9 @@ const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading
const [expandedReasons, setExpandedReasons] = useState({});
const [klineModalVisible, setKlineModalVisible] = useState(false);
const [selectedKlineStock, setSelectedKlineStock] = useState(null);
// 关联事件弹窗状态
const [relatedEventsModalVisible, setRelatedEventsModalVisible] = useState(false);
const [selectedRelatedEvents, setSelectedRelatedEvents] = useState({ sectorName: '', events: [] });
// 板块数据处理 - 必须在条件返回之前调用所有hooks
const sectorList = useMemo(() => {
@@ -1157,80 +1160,67 @@ const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading
return '#6B7280';
};
// 点击打开事件详情弹窗
const handleClick = (e) => {
e.stopPropagation();
setSelectedRelatedEvents({
sectorName: record.name,
events: sortedEvents,
count: record.count,
});
setRelatedEventsModalVisible(true);
};
return (
<VStack align="start" spacing={1}>
<Tooltip
title={
<Box maxW="300px">
<Text fontWeight="bold" mb={1}>{topEvent.title}</Text>
{topEvent.relevance_reason && (
<Text fontSize="12px" color="#ccc">{topEvent.relevance_reason}</Text>
)}
{topEvent.matched_concepts?.length > 0 && (
<Box mt={2}>
<Text fontSize="11px" color="#888" mb={1}>匹配概念</Text>
<HStack flexWrap="wrap" spacing={1}>
{topEvent.matched_concepts.slice(0, 5).map((c, i) => (
<Tag key={i} style={{ fontSize: '10px', margin: '1px', background: 'rgba(139, 92, 246, 0.2)', border: 'none', color: '#A78BFA' }}>
{c}
</Tag>
))}
</HStack>
</Box>
)}
</Box>
}
placement="left"
overlayStyle={{ maxWidth: 350 }}
<Box
cursor="pointer"
p={1.5}
borderRadius="md"
bg="rgba(96, 165, 250, 0.1)"
_hover={{ bg: 'rgba(96, 165, 250, 0.2)', transform: 'translateY(-1px)' }}
transition="all 0.2s"
maxW="260px"
onClick={handleClick}
>
<Box
cursor="pointer"
p={1.5}
borderRadius="md"
bg="rgba(96, 165, 250, 0.1)"
_hover={{ bg: 'rgba(96, 165, 250, 0.2)' }}
transition="background 0.2s"
maxW="260px"
>
<HStack spacing={1.5} align="start">
<FileText size={14} color="#60A5FA" style={{ flexShrink: 0, marginTop: 2 }} />
<VStack align="start" spacing={0.5} flex={1}>
<AntText
<HStack spacing={1.5} align="start">
<FileText size={14} color="#60A5FA" style={{ flexShrink: 0, marginTop: 2 }} />
<VStack align="start" spacing={0.5} flex={1}>
<AntText
style={{
color: '#E0E0E0',
fontSize: '12px',
lineHeight: '1.3',
display: '-webkit-box',
WebkitLineClamp: 2,
WebkitBoxOrient: 'vertical',
overflow: 'hidden',
}}
>
{topEvent.title}
</AntText>
<HStack spacing={2}>
<Tag
style={{
color: '#E0E0E0',
fontSize: '12px',
lineHeight: '1.3',
display: '-webkit-box',
WebkitLineClamp: 2,
WebkitBoxOrient: 'vertical',
overflow: 'hidden',
fontSize: '10px',
padding: '0 6px',
background: `${getRelevanceColor(topEvent.relevance_score || 0)}20`,
border: 'none',
color: getRelevanceColor(topEvent.relevance_score || 0),
borderRadius: '4px',
}}
>
{topEvent.title}
</AntText>
<HStack spacing={2}>
<Tag
style={{
fontSize: '10px',
padding: '0 6px',
background: `${getRelevanceColor(topEvent.relevance_score || 0)}20`,
border: 'none',
color: getRelevanceColor(topEvent.relevance_score || 0),
borderRadius: '4px',
}}
>
相关度 {topEvent.relevance_score || 0}
</Tag>
{events.length > 1 && (
<AntText style={{ fontSize: '10px', color: '#888' }}>
+{events.length - 1}
</AntText>
)}
</HStack>
</VStack>
</HStack>
</Box>
</Tooltip>
相关度 {topEvent.relevance_score || 0}
</Tag>
{events.length > 1 && (
<AntText style={{ fontSize: '10px', color: '#888' }}>
+{events.length - 1}
</AntText>
)}
</HStack>
</VStack>
</HStack>
</Box>
</VStack>
);
},
@@ -2457,6 +2447,165 @@ const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading
</ModalBody>
</ModalContent>
</Modal>
{/* 关联事件弹窗 - 涨停归因详情 */}
<Modal
isOpen={relatedEventsModalVisible}
onClose={() => {
setRelatedEventsModalVisible(false);
setSelectedRelatedEvents({ sectorName: '', events: [] });
}}
size="xl"
scrollBehavior="inside"
>
<ModalOverlay bg="blackAlpha.700" backdropFilter={GLASS_BLUR.sm} />
<ModalContent
maxW="700px"
maxH="80vh"
bg="linear-gradient(135deg, rgba(15,15,30,0.98) 0%, rgba(25,25,50,0.98) 100%)"
border="1px solid rgba(96,165,250,0.3)"
borderRadius="2xl"
>
<ModalHeader borderBottom="1px solid rgba(96,165,250,0.2)" py={4}>
<HStack spacing={3}>
<Box
p={2}
bg="rgba(96,165,250,0.15)"
borderRadius="lg"
border="1px solid rgba(96,165,250,0.3)"
>
<FileText size={18} color="#60A5FA" />
</Box>
<VStack align="start" spacing={0}>
<HStack spacing={2}>
<Text fontSize="lg" fontWeight="bold" color="#60A5FA">
{selectedRelatedEvents.sectorName} - 涨停归因
</Text>
</HStack>
<HStack spacing={3}>
<Text fontSize="xs" color="whiteAlpha.500">
涨停 <Text as="span" color="#EF4444" fontWeight="bold">{selectedRelatedEvents.count || 0}</Text>
</Text>
<Text fontSize="xs" color="whiteAlpha.500">
关联事件 <Text as="span" color="#60A5FA" fontWeight="bold">{selectedRelatedEvents.events?.length || 0}</Text>
</Text>
</HStack>
</VStack>
</HStack>
</ModalHeader>
<ModalCloseButton color="whiteAlpha.600" _hover={{ color: 'white' }} />
<ModalBody py={4} overflowY="auto">
{selectedRelatedEvents.events?.length > 0 ? (
<VStack spacing={3} align="stretch">
{selectedRelatedEvents.events.map((event, idx) => {
const getRelevanceColor = (score) => {
if (score >= 80) return '#10B981';
if (score >= 60) return '#F59E0B';
return '#6B7280';
};
const relevanceColor = getRelevanceColor(event.relevance_score || 0);
return (
<Box
key={event.event_id || idx}
p={4}
bg="rgba(30,30,50,0.8)"
borderRadius="xl"
border="1px solid rgba(255,255,255,0.06)"
cursor="pointer"
onClick={() => {
// 跳转到事件详情页
window.open(`/community?event_id=${event.event_id}`, '_blank');
}}
_hover={{
bg: 'rgba(40,40,70,0.9)',
borderColor: 'rgba(96,165,250,0.3)',
transform: 'translateY(-2px)',
}}
transition="all 0.2s"
>
<VStack align="stretch" spacing={3}>
{/* 标题 */}
<HStack justify="space-between" align="start">
<HStack spacing={2} flex={1}>
<FileText size={16} color="#60A5FA" style={{ flexShrink: 0 }} />
<Text fontSize="sm" fontWeight="600" color="#E0E0E0" noOfLines={2}>
{event.title}
</Text>
</HStack>
<Badge
bg={`${relevanceColor}20`}
color={relevanceColor}
fontSize="xs"
px={2}
py={0.5}
borderRadius="md"
>
相关度 {event.relevance_score || 0}
</Badge>
</HStack>
{/* 相关原因 */}
{event.relevance_reason && (
<Text fontSize="xs" color="whiteAlpha.600" lineHeight="1.6">
{event.relevance_reason}
</Text>
)}
{/* 匹配概念 */}
{event.matched_concepts?.length > 0 && (
<Box>
<Text fontSize="xs" color="whiteAlpha.400" mb={1.5}>
匹配概念
</Text>
<HStack spacing={1.5} flexWrap="wrap">
{event.matched_concepts.slice(0, 6).map((concept, i) => (
<Tag
key={i}
style={{
fontSize: '10px',
margin: '2px',
background: 'rgba(139, 92, 246, 0.15)',
border: 'none',
color: '#A78BFA',
borderRadius: '4px',
padding: '2px 8px',
}}
>
{concept}
</Tag>
))}
{event.matched_concepts.length > 6 && (
<Tag
style={{
fontSize: '10px',
margin: '2px',
background: 'rgba(255,255,255,0.1)',
border: 'none',
color: '#888',
borderRadius: '4px',
padding: '2px 8px',
}}
>
+{event.matched_concepts.length - 6}
</Tag>
)}
</HStack>
</Box>
)}
</VStack>
</Box>
);
})}
</VStack>
) : (
<Center h="200px">
<Text color="whiteAlpha.500">暂无关联事件</Text>
</Center>
)}
</ModalBody>
</ModalContent>
</Modal>
</>
);
};