更新Company页面的UI为FUI风格
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
// src/components/EventDetailPanel/RelatedConceptsSection/index.js
|
// src/components/EventDetailPanel/RelatedConceptsSection/index.js
|
||||||
// 相关概念区组件 - 折叠手风琴样式
|
// 相关概念区组件 - 便当盒网格布局
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import {
|
import {
|
||||||
@@ -10,94 +10,72 @@ import {
|
|||||||
Spinner,
|
Spinner,
|
||||||
Text,
|
Text,
|
||||||
Badge,
|
Badge,
|
||||||
VStack,
|
SimpleGrid,
|
||||||
HStack,
|
HStack,
|
||||||
Icon,
|
Tooltip,
|
||||||
Collapse,
|
|
||||||
useColorModeValue,
|
useColorModeValue,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { ChevronRightIcon, ChevronDownIcon } from '@chakra-ui/icons';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { logger } from '@utils/logger';
|
import { logger } from '@utils/logger';
|
||||||
import { getApiBase } from '@utils/apiConfig';
|
import { getApiBase } from '@utils/apiConfig';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单个概念项组件(手风琴项)
|
* 单个概念卡片组件(便当盒样式)
|
||||||
*/
|
*/
|
||||||
const ConceptItem = ({ concept, isExpanded, onToggle, onNavigate }) => {
|
const ConceptCard = ({ concept, onNavigate, isLocked, onLockedClick }) => {
|
||||||
const itemBg = useColorModeValue('white', 'gray.700');
|
// 深色主题固定颜色
|
||||||
const itemHoverBg = useColorModeValue('gray.50', 'gray.650');
|
const cardBg = 'rgba(252, 129, 129, 0.15)'; // 浅红色背景
|
||||||
const borderColor = useColorModeValue('gray.200', 'gray.600');
|
const cardHoverBg = 'rgba(252, 129, 129, 0.25)';
|
||||||
const conceptColor = useColorModeValue('blue.600', 'blue.300');
|
const borderColor = 'rgba(252, 129, 129, 0.3)';
|
||||||
const reasonBg = useColorModeValue('blue.50', 'gray.800');
|
const conceptColor = '#fc8181'; // 红色文字(与股票涨色一致)
|
||||||
const reasonColor = useColorModeValue('gray.700', 'gray.200');
|
|
||||||
const iconColor = useColorModeValue('gray.500', 'gray.400');
|
const handleClick = () => {
|
||||||
|
if (isLocked && onLockedClick) {
|
||||||
|
onLockedClick();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onNavigate(concept);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<Tooltip
|
||||||
|
label={concept.reason || concept.concept}
|
||||||
|
placement="top"
|
||||||
|
hasArrow
|
||||||
|
bg="gray.800"
|
||||||
|
color="white"
|
||||||
|
p={2}
|
||||||
|
borderRadius="md"
|
||||||
|
maxW="300px"
|
||||||
|
fontSize="xs"
|
||||||
|
>
|
||||||
<Box
|
<Box
|
||||||
|
bg={cardBg}
|
||||||
borderWidth="1px"
|
borderWidth="1px"
|
||||||
borderColor={borderColor}
|
borderColor={borderColor}
|
||||||
borderRadius="md"
|
borderRadius="lg"
|
||||||
overflow="hidden"
|
|
||||||
bg={itemBg}
|
|
||||||
>
|
|
||||||
{/* 概念标题行 - 可点击展开 */}
|
|
||||||
<Flex
|
|
||||||
px={3}
|
px={3}
|
||||||
py={2.5}
|
py={2}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
align="center"
|
onClick={handleClick}
|
||||||
justify="space-between"
|
_hover={{
|
||||||
_hover={{ bg: itemHoverBg }}
|
bg: cardHoverBg,
|
||||||
onClick={onToggle}
|
transform: 'translateY(-1px)',
|
||||||
transition="background 0.2s"
|
boxShadow: 'sm',
|
||||||
|
}}
|
||||||
|
transition="all 0.15s ease"
|
||||||
|
textAlign="center"
|
||||||
>
|
>
|
||||||
<HStack spacing={2} flex={1}>
|
|
||||||
<Icon
|
|
||||||
as={isExpanded ? ChevronDownIcon : ChevronRightIcon}
|
|
||||||
color={iconColor}
|
|
||||||
boxSize={4}
|
|
||||||
transition="transform 0.2s"
|
|
||||||
/>
|
|
||||||
<Text
|
<Text
|
||||||
fontSize="sm"
|
fontSize="sm"
|
||||||
fontWeight="medium"
|
fontWeight="semibold"
|
||||||
color={conceptColor}
|
color={conceptColor}
|
||||||
cursor="pointer"
|
noOfLines={1}
|
||||||
_hover={{ textDecoration: 'underline' }}
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
onNavigate(concept);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{concept.concept}
|
{concept.concept}
|
||||||
</Text>
|
</Text>
|
||||||
<Badge colorScheme="green" fontSize="xs" flexShrink={0}>
|
|
||||||
AI 分析
|
|
||||||
</Badge>
|
|
||||||
</HStack>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
{/* 关联原因 - 可折叠 */}
|
|
||||||
<Collapse in={isExpanded} animateOpacity>
|
|
||||||
<Box
|
|
||||||
px={4}
|
|
||||||
py={3}
|
|
||||||
bg={reasonBg}
|
|
||||||
borderTop="1px solid"
|
|
||||||
borderTopColor={borderColor}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
fontSize="sm"
|
|
||||||
color={reasonColor}
|
|
||||||
lineHeight="1.8"
|
|
||||||
whiteSpace="pre-wrap"
|
|
||||||
>
|
|
||||||
{concept.reason || '暂无关联原因说明'}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
</Collapse>
|
|
||||||
</Box>
|
</Box>
|
||||||
|
</Tooltip>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -120,16 +98,14 @@ const RelatedConceptsSection = ({
|
|||||||
const [concepts, setConcepts] = useState([]);
|
const [concepts, setConcepts] = useState([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
// 记录每个概念的展开状态
|
|
||||||
const [expandedItems, setExpandedItems] = useState({});
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
// 颜色配置
|
// 颜色配置 - 使用深色主题固定颜色
|
||||||
const sectionBg = useColorModeValue('gray.50', 'gray.750');
|
const sectionBg = 'transparent';
|
||||||
const headingColor = useColorModeValue('gray.700', 'gray.200');
|
const headingColor = '#e2e8f0';
|
||||||
const textColor = useColorModeValue('gray.600', 'gray.400');
|
const textColor = '#a0aec0';
|
||||||
const countBadgeBg = useColorModeValue('blue.100', 'blue.800');
|
const countBadgeBg = '#3182ce';
|
||||||
const countBadgeColor = useColorModeValue('blue.700', 'blue.200');
|
const countBadgeColor = '#ffffff';
|
||||||
|
|
||||||
// 获取相关概念
|
// 获取相关概念
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -162,10 +138,6 @@ const RelatedConceptsSection = ({
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if (data.success && Array.isArray(data.data)) {
|
if (data.success && Array.isArray(data.data)) {
|
||||||
setConcepts(data.data);
|
setConcepts(data.data);
|
||||||
// 默认展开第一个
|
|
||||||
if (data.data.length > 0) {
|
|
||||||
setExpandedItems({ 0: true });
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
setConcepts([]);
|
setConcepts([]);
|
||||||
}
|
}
|
||||||
@@ -182,18 +154,6 @@ const RelatedConceptsSection = ({
|
|||||||
fetchConcepts();
|
fetchConcepts();
|
||||||
}, [eventId]);
|
}, [eventId]);
|
||||||
|
|
||||||
// 切换某个概念的展开状态
|
|
||||||
const toggleItem = (index) => {
|
|
||||||
if (isLocked && onLockedClick) {
|
|
||||||
onLockedClick();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setExpandedItems(prev => ({
|
|
||||||
...prev,
|
|
||||||
[index]: !prev[index]
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
// 跳转到概念中心
|
// 跳转到概念中心
|
||||||
const handleNavigate = (concept) => {
|
const handleNavigate = (concept) => {
|
||||||
navigate(`/concepts?q=${encodeURIComponent(concept.concept)}`);
|
navigate(`/concepts?q=${encodeURIComponent(concept.concept)}`);
|
||||||
@@ -237,7 +197,7 @@ const RelatedConceptsSection = ({
|
|||||||
</HStack>
|
</HStack>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
{/* 概念列表 - 手风琴样式 */}
|
{/* 概念列表 - 便当盒网格布局 */}
|
||||||
{hasNoConcepts ? (
|
{hasNoConcepts ? (
|
||||||
<Box py={2}>
|
<Box py={2}>
|
||||||
{error ? (
|
{error ? (
|
||||||
@@ -247,17 +207,17 @@ const RelatedConceptsSection = ({
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
) : (
|
) : (
|
||||||
<VStack spacing={2} align="stretch">
|
<SimpleGrid columns={{ base: 2, sm: 3, md: 4 }} spacing={2}>
|
||||||
{concepts.map((concept, index) => (
|
{concepts.map((concept, index) => (
|
||||||
<ConceptItem
|
<ConceptCard
|
||||||
key={concept.id || index}
|
key={concept.id || index}
|
||||||
concept={concept}
|
concept={concept}
|
||||||
isExpanded={!!expandedItems[index]}
|
|
||||||
onToggle={() => toggleItem(index)}
|
|
||||||
onNavigate={handleNavigate}
|
onNavigate={handleNavigate}
|
||||||
|
isLocked={isLocked}
|
||||||
|
onLockedClick={onLockedClick}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</VStack>
|
</SimpleGrid>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user