update pay ui

This commit is contained in:
2025-12-05 15:14:50 +08:00
parent 525e9d16f7
commit e85a6a14d1
2 changed files with 308 additions and 207 deletions

View File

@@ -16,13 +16,14 @@ import {
Flex, Flex,
Tooltip, Tooltip,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ChevronRightIcon, CloseIcon } from '@chakra-ui/icons'; import { ChevronRightIcon } from '@chakra-ui/icons';
import { FaLayerGroup, FaFilter, FaTimes, FaHome } from 'react-icons/fa'; import { FaFilter, FaTimes, FaHome } from 'react-icons/fa';
const BreadcrumbNav = ({ const BreadcrumbNav = ({
filter, filter,
onClearFilter, onClearFilter,
onNavigate, onNavigate,
isDarkMode = false,
}) => { }) => {
// 如果没有筛选条件,不显示 // 如果没有筛选条件,不显示
if (!filter || (!filter.lv1 && !filter.lv2 && !filter.lv3)) { if (!filter || (!filter.lv1 && !filter.lv2 && !filter.lv3)) {
@@ -56,14 +57,71 @@ const BreadcrumbNav = ({
}); });
} }
// 深色主题样式
const darkStyles = {
container: {
bg: 'rgba(15, 23, 42, 0.8)',
backdropFilter: 'blur(20px)',
borderColor: 'whiteAlpha.100',
},
filterBadge: {
bg: 'purple.500',
color: 'white',
},
homeBadge: {
bg: 'whiteAlpha.100',
color: 'white',
_hover: { bg: 'whiteAlpha.200' },
},
chevron: { color: 'whiteAlpha.400' },
crumbBadge: (level, isLast) => ({
bg: level === 'lv1' ? 'purple.500' : level === 'lv2' ? 'blue.500' : 'cyan.500',
color: 'white',
}),
clearBtn: {
color: 'red.300',
_hover: { bg: 'whiteAlpha.100' },
},
hintText: { color: 'whiteAlpha.500' },
linkText: { color: 'purple.300' },
};
// 浅色主题样式
const lightStyles = {
container: {
bg: 'linear-gradient(135deg, rgba(99, 102, 241, 0.1) 0%, rgba(168, 85, 247, 0.1) 100%)',
borderColor: 'purple.200',
},
filterBadge: {
bg: 'purple.500',
color: 'white',
},
homeBadge: {
colorScheme: 'gray',
_hover: { bg: 'gray.200' },
},
chevron: { color: 'gray.400' },
crumbBadge: (level, isLast) => ({
colorScheme: level === 'lv1' ? 'purple' : level === 'lv2' ? 'blue' : 'cyan',
}),
clearBtn: {
colorScheme: 'red',
},
hintText: { color: 'gray.500' },
linkText: { color: 'purple.600' },
};
const styles = isDarkMode ? darkStyles : lightStyles;
return ( return (
<Box <Box
bg="linear-gradient(135deg, rgba(99, 102, 241, 0.1) 0%, rgba(168, 85, 247, 0.1) 100%)" bg={styles.container.bg}
backdropFilter={isDarkMode ? styles.container.backdropFilter : undefined}
borderRadius="xl" borderRadius="xl"
p={{ base: 3, md: 4 }} p={{ base: 3, md: 4 }}
mb={4} mb={4}
border="1px solid" border="1px solid"
borderColor="purple.200" borderColor={styles.container.borderColor}
> >
<Flex <Flex
align="center" align="center"
@@ -75,8 +133,8 @@ const BreadcrumbNav = ({
{/* 筛选图标 */} {/* 筛选图标 */}
<HStack <HStack
spacing={2} spacing={2}
bg="purple.500" bg={styles.filterBadge.bg}
color="white" color={styles.filterBadge.color}
px={3} px={3}
py={1} py={1}
borderRadius="full" borderRadius="full"
@@ -90,15 +148,15 @@ const BreadcrumbNav = ({
{/* 首页入口 */} {/* 首页入口 */}
<Tooltip label="返回全部概念" placement="top"> <Tooltip label="返回全部概念" placement="top">
<Badge <Badge
colorScheme="gray" {...(isDarkMode ? {} : { colorScheme: 'gray' })}
bg={isDarkMode ? styles.homeBadge.bg : undefined}
color={isDarkMode ? styles.homeBadge.color : undefined}
px={3} px={3}
py={1} py={1}
borderRadius="full" borderRadius="full"
cursor="pointer" cursor="pointer"
onClick={onClearFilter} onClick={onClearFilter}
_hover={{ _hover={styles.homeBadge._hover}
bg: 'gray.200',
}}
display="flex" display="flex"
alignItems="center" alignItems="center"
gap={1} gap={1}
@@ -111,12 +169,11 @@ const BreadcrumbNav = ({
{/* 面包屑路径 */} {/* 面包屑路径 */}
{breadcrumbs.map((crumb, index) => ( {breadcrumbs.map((crumb, index) => (
<React.Fragment key={crumb.level}> <React.Fragment key={crumb.level}>
<Icon as={ChevronRightIcon} color="gray.400" boxSize={4} /> <Icon as={ChevronRightIcon} color={styles.chevron.color} boxSize={4} />
<Badge <Badge
colorScheme={ {...(isDarkMode ? {} : { colorScheme: styles.crumbBadge(crumb.level, index === breadcrumbs.length - 1).colorScheme })}
crumb.level === 'lv1' ? 'purple' : bg={isDarkMode ? styles.crumbBadge(crumb.level, index === breadcrumbs.length - 1).bg : undefined}
crumb.level === 'lv2' ? 'blue' : 'cyan' color={isDarkMode ? styles.crumbBadge(crumb.level, index === breadcrumbs.length - 1).color : undefined}
}
px={3} px={3}
py={1} py={1}
borderRadius="full" borderRadius="full"
@@ -140,21 +197,23 @@ const BreadcrumbNav = ({
<IconButton <IconButton
size="sm" size="sm"
icon={<FaTimes />} icon={<FaTimes />}
colorScheme="red" {...(isDarkMode ? {} : { colorScheme: 'red' })}
color={isDarkMode ? styles.clearBtn.color : undefined}
variant="ghost" variant="ghost"
borderRadius="full" borderRadius="full"
onClick={onClearFilter} onClick={onClearFilter}
aria-label="清除筛选" aria-label="清除筛选"
_hover={isDarkMode ? styles.clearBtn._hover : undefined}
/> />
</Tooltip> </Tooltip>
</Flex> </Flex>
{/* 筛选提示 */} {/* 筛选提示 */}
<Text fontSize="xs" color="gray.500" mt={2}> <Text fontSize="xs" color={styles.hintText.color} mt={2}>
当前显示{breadcrumbs.map(b => b.label).join(' > ')}分类下的概念 当前显示{breadcrumbs.map(b => b.label).join(' > ')}分类下的概念
<Text <Text
as="span" as="span"
color="purple.600" color={styles.linkText.color}
cursor="pointer" cursor="pointer"
fontWeight="medium" fontWeight="medium"
onClick={onClearFilter} onClick={onClearFilter}

View File

@@ -635,15 +635,19 @@ const ConceptCenter = () => {
init(); init();
}, []); }, []);
// 概念卡片组件 - 科幻毛玻璃版 // 获取股票名称兼容新旧API格式
const getStockName = (stock) => stock.name || stock.stock_name || '未知';
const getStockCode = (stock) => stock.code || stock.stock_code || '';
// 概念卡片组件 - 深色毛玻璃版HeroUI风格
const ConceptCard = ({ concept, position = 0 }) => { const ConceptCard = ({ concept, position = 0 }) => {
const changePercent = concept.price_info?.avg_change_pct; const changePercent = concept.price_info?.avg_change_pct;
const changeColor = getChangeColor(changePercent); const changeColor = getChangeColor(changePercent);
const hasChange = changePercent !== null && changePercent !== undefined; const hasChange = changePercent !== null && changePercent !== undefined;
// H5 端使用更紧凑的尺寸 // H5 端使用更紧凑的尺寸
const isMobile = useBreakpointValue({ base: true, md: false }); const isMobile = useBreakpointValue({ base: true, md: false });
const coverHeight = useBreakpointValue({ base: '100px', md: '180px' }); const coverHeight = useBreakpointValue({ base: '100px', md: '160px' });
const logoSize = useBreakpointValue({ base: '60px', md: '120px' }); const logoSize = useBreakpointValue({ base: '60px', md: '100px' });
// 生成随机涨幅数字背景 // 生成随机涨幅数字背景
const generateNumbersBackground = () => { const generateNumbersBackground = () => {
@@ -663,22 +667,24 @@ const ConceptCenter = () => {
<Card <Card
cursor="pointer" cursor="pointer"
onClick={() => handleConceptClick(concept.concept_id, concept.concept, concept, position)} onClick={() => handleConceptClick(concept.concept_id, concept.concept, concept, position)}
bg="white" bg="rgba(15, 23, 42, 0.8)"
backdropFilter="blur(20px)"
borderWidth="1px" borderWidth="1px"
borderColor="transparent" borderColor="whiteAlpha.100"
overflow="hidden" overflow="hidden"
_hover={{ _hover={{
transform: 'translateY(-8px)', transform: 'translateY(-6px)',
boxShadow: '0 20px 40px rgba(139, 92, 246, 0.3)', boxShadow: '0 20px 40px rgba(139, 92, 246, 0.25)',
borderColor: 'purple.400', borderColor: 'purple.500',
}} }}
transition="all 0.3s" transition="all 0.3s cubic-bezier(0.4, 0, 0.2, 1)"
position="relative" position="relative"
boxShadow="0 4px 12px rgba(0, 0, 0, 0.1)" boxShadow="0 4px 20px rgba(0, 0, 0, 0.3)"
borderRadius="2xl"
> >
{/* 毛玻璃涨幅数字背景 */} {/* 毛玻璃涨幅数字背景 */}
<Box position="relative" height={coverHeight} overflow="hidden"> <Box position="relative" height={coverHeight} overflow="hidden">
{/* 渐变背景层 */} {/* 渐变背景层 - 涨红跌绿 */}
<Box <Box
position="absolute" position="absolute"
top={0} top={0}
@@ -687,10 +693,10 @@ const ConceptCenter = () => {
bottom={0} bottom={0}
bgGradient={ bgGradient={
hasChange && changePercent > 0 hasChange && changePercent > 0
? "linear(135deg, #667eea 0%, #764ba2 100%)" ? "linear(135deg, rgba(153, 27, 27, 0.6) 0%, rgba(239, 68, 68, 0.4) 100%)"
: hasChange && changePercent < 0 : hasChange && changePercent < 0
? "linear(135deg, #f093fb 0%, #f5576c 100%)" ? "linear(135deg, rgba(20, 83, 45, 0.6) 0%, rgba(34, 197, 94, 0.4) 100%)"
: "linear(135deg, #4facfe 0%, #00f2fe 100%)" : "linear(135deg, rgba(71, 85, 105, 0.6) 0%, rgba(100, 116, 139, 0.4) 100%)"
} }
/> />
@@ -706,7 +712,7 @@ const ConceptCenter = () => {
gridTemplateRows="repeat(6, 1fr)" gridTemplateRows="repeat(6, 1fr)"
gap={2} gap={2}
p={3} p={3}
opacity={0.15} opacity={0.1}
> >
{backgroundNumbers.map((num, idx) => ( {backgroundNumbers.map((num, idx) => (
<Flex <Flex
@@ -731,7 +737,7 @@ const ConceptCenter = () => {
transform="translate(-50%, -50%)" transform="translate(-50%, -50%)"
width={logoSize} width={logoSize}
height={logoSize} height={logoSize}
opacity={0.15} opacity={0.1}
> >
<Image <Image
src={`${process.env.PUBLIC_URL}/LOGO_badge.png`} src={`${process.env.PUBLIC_URL}/LOGO_badge.png`}
@@ -742,35 +748,15 @@ const ConceptCenter = () => {
/> />
</Box> </Box>
{/* 毛玻璃层 */} {/* 高光效果 */}
<Box <Box
position="absolute" position="absolute"
top={0} top={0}
left={0} left={0}
right={0} right={0}
bottom={0} height="50%"
backdropFilter="blur(8px)" bg="linear-gradient(180deg, rgba(255,255,255,0.08) 0%, transparent 100%)"
bg="rgba(255, 255, 255, 0.05)" pointerEvents="none"
/>
{/* 渐变遮罩 */}
<Box
position="absolute"
top={0}
left={0}
right={0}
bottom={0}
bgGradient="linear(to-t, rgba(0,0,0,0.6), transparent)"
/>
{/* 发光边框效果 */}
<Box
position="absolute"
top={0}
left={0}
right={0}
height="2px"
bgGradient="linear(to-r, transparent, rgba(255,255,255,0.5), transparent)"
/> />
{/* 左上角涨跌幅 Badge */} {/* 左上角涨跌幅 Badge */}
@@ -779,14 +765,14 @@ const ConceptCenter = () => {
position="absolute" position="absolute"
top={3} top={3}
left={3} left={3}
bg={changeColor === 'red' ? 'red.500' : changeColor === 'green' ? 'green.500' : 'gray.500'} bg={changeColor === 'red' ? 'rgba(239, 68, 68, 0.9)' : changeColor === 'green' ? 'rgba(34, 197, 94, 0.9)' : 'rgba(100, 116, 139, 0.9)'}
color="white" color="white"
fontSize="sm" fontSize="sm"
px={3} px={3}
py={1} py={1}
borderRadius="full" borderRadius="full"
fontWeight="bold" fontWeight="bold"
boxShadow="0 4px 12px rgba(0, 0, 0, 0.3)" boxShadow={`0 4px 12px rgba(${changeColor === 'red' ? '239, 68, 68' : changeColor === 'green' ? '34, 197, 94' : '100, 116, 139'}, 0.4)`}
display="flex" display="flex"
alignItems="center" alignItems="center"
gap={1} gap={1}
@@ -805,38 +791,36 @@ const ConceptCenter = () => {
position="absolute" position="absolute"
top={3} top={3}
right={3} right={3}
bg="rgba(255, 255, 255, 0.2)" bg="rgba(0, 0, 0, 0.4)"
backdropFilter="blur(10px)" backdropFilter="blur(10px)"
color="white" color="white"
fontSize="xs" fontSize="xs"
px={3} px={3}
py={1} py={1}
borderRadius="full" borderRadius="full"
fontWeight="bold" fontWeight="medium"
boxShadow="0 4px 12px rgba(0, 0, 0, 0.2)"
border="1px solid" border="1px solid"
borderColor="whiteAlpha.300" borderColor="whiteAlpha.200"
> >
{concept.stock_count || 0} 只股票 {concept.stock_count || 0} 只股票
</Badge> </Badge>
</Box> </Box>
<CardBody p={{ base: 3, md: 4 }}> <CardBody p={{ base: 3, md: 4 }} bg="transparent">
<VStack align="start" spacing={{ base: 1, md: 2 }}> <VStack align="start" spacing={{ base: 1, md: 2 }}>
{/* 概念名称 */} {/* 概念名称 */}
<Heading <Heading
size={{ base: 'xs', md: 'sm' }} size={{ base: 'xs', md: 'sm' }}
color="gray.800" color="white"
noOfLines={1} noOfLines={1}
bgGradient="linear(to-r, purple.600, pink.600)"
bgClip="text"
fontWeight="bold" fontWeight="bold"
letterSpacing="0.02em"
> >
{concept.concept} {concept.concept}
</Heading> </Heading>
{/* 描述信息 - H5端显示1行 */} {/* 描述信息 - H5端显示1行 */}
<Text color="gray.600" fontSize="xs" noOfLines={isMobile ? 1 : 2} minH={{ base: '16px', md: '32px' }}> <Text color="whiteAlpha.600" fontSize="xs" noOfLines={isMobile ? 1 : 2} minH={{ base: '16px', md: '32px' }}>
{concept.description || '暂无描述信息'} {concept.description || '暂无描述信息'}
</Text> </Text>
@@ -844,31 +828,34 @@ const ConceptCenter = () => {
<Box <Box
width="100%" width="100%"
p={{ base: 2, md: 3 }} p={{ base: 2, md: 3 }}
bg="linear-gradient(135deg, rgba(99, 102, 241, 0.05) 0%, rgba(168, 85, 247, 0.05) 100%)" bg="whiteAlpha.50"
borderRadius="lg" backdropFilter="blur(10px)"
borderRadius="xl"
cursor="pointer" cursor="pointer"
onClick={(e) => handleViewStocks(e, concept)} onClick={(e) => handleViewStocks(e, concept)}
_hover={{ _hover={{
bg: 'linear-gradient(135deg, rgba(99, 102, 241, 0.1) 0%, rgba(168, 85, 247, 0.1) 100%)', bg: 'whiteAlpha.100',
transform: 'translateX(2px)', transform: 'translateX(2px)',
}} }}
transition="all 0.2s" transition="all 0.2s"
border="1px solid" border="1px solid"
borderColor="purple.100" borderColor="whiteAlpha.100"
> >
<Flex align="center" justify="space-between"> <Flex align="center" justify="space-between">
<Box flex={1}> <Box flex={1}>
<HStack spacing={2} mb={{ base: 1, md: 2 }}> <HStack spacing={2} mb={{ base: 1, md: 2 }}>
<Icon as={FaChartLine} boxSize={3} color="purple.500" /> <Icon as={FaChartLine} boxSize={3} color="purple.300" />
<Text fontSize="xs" color="purple.700" fontWeight="bold"> <Text fontSize="xs" color="purple.200" fontWeight="bold">
热门个股 热门个股
</Text> </Text>
{!hasFeatureAccess('hot_stocks') && ( {!hasFeatureAccess('hot_stocks') && (
<Badge <Badge
colorScheme="yellow" bg="yellow.500"
color="gray.900"
size="sm" size="sm"
borderRadius="full" borderRadius="full"
px={2} px={2}
fontSize="xs"
> >
🔒Pro 🔒Pro
</Badge> </Badge>
@@ -881,24 +868,24 @@ const ConceptCenter = () => {
<Tag <Tag
key={idx} key={idx}
size="sm" size="sm"
bgGradient="linear(to-r, purple.500, pink.500)" bg="purple.500"
color="white" color="white"
borderRadius="full" borderRadius="full"
px={2} px={2}
> >
<TagLabel fontSize="xs">{stock.stock_name}</TagLabel> <TagLabel fontSize="xs">{getStockName(stock)}</TagLabel>
</Tag> </Tag>
))} ))}
{concept.stocks.length > 2 && ( {concept.stocks.length > 2 && (
<Text fontSize="xs" color="purple.600" fontWeight="bold"> <Text fontSize="xs" color="purple.300" fontWeight="bold">
+{concept.stocks.length - 2} +{concept.stocks.length - 2}
</Text> </Text>
)} )}
</> </>
) : ( ) : (
<HStack spacing={1}> <HStack spacing={1}>
<Icon as={FaLock} boxSize="10px" color="yellow.600" /> <Icon as={FaLock} boxSize="10px" color="yellow.400" />
<Text fontSize="xs" color="yellow.600" fontWeight="medium"> <Text fontSize="xs" color="yellow.400" fontWeight="medium">
升级查看{concept.stocks.length}只个股 升级查看{concept.stocks.length}只个股
</Text> </Text>
</HStack> </HStack>
@@ -907,32 +894,41 @@ const ConceptCenter = () => {
</Box> </Box>
<Icon <Icon
as={hasFeatureAccess('hot_stocks') ? ChevronRightIcon : FaLock} as={hasFeatureAccess('hot_stocks') ? ChevronRightIcon : FaLock}
color={hasFeatureAccess('hot_stocks') ? 'purple.500' : 'yellow.600'} color={hasFeatureAccess('hot_stocks') ? 'purple.300' : 'yellow.400'}
boxSize={4} boxSize={4}
/> />
</Flex> </Flex>
</Box> </Box>
)} )}
<Divider borderColor="purple.100" my={{ base: 1, md: 0 }} /> <Divider borderColor="whiteAlpha.100" my={{ base: 1, md: 0 }} />
<Flex width="100%" justify="space-between" align="center"> <Flex width="100%" justify="space-between" align="center">
{formatAddedDate(concept)} {/* 添加日期 - 深色主题适配 */}
{concept.created_at || concept.added_date || concept.happened_times?.[0] ? (
<HStack spacing={2}>
<Icon as={CalendarIcon} boxSize={3} color="cyan.400" />
<Text fontSize="xs" color="whiteAlpha.600" fontWeight="medium">
添加于 {new Date(concept.created_at || concept.added_date || concept.happened_times?.[0]).toLocaleDateString('zh-CN')}
</Text>
</HStack>
) : <Box />}
<Button <Button
size={{ base: 'xs', md: 'sm' }} size={{ base: 'xs', md: 'sm' }}
leftIcon={<FaHistory />} leftIcon={<FaHistory />}
bgGradient="linear(to-r, purple.500, pink.500)" bg="purple.500"
color="white" color="white"
variant="solid" variant="solid"
onClick={(e) => handleViewContent(e, concept.concept, concept.concept_id)} onClick={(e) => handleViewContent(e, concept.concept, concept.concept_id)}
borderRadius="full" borderRadius="full"
px={{ base: 2, md: 4 }} px={{ base: 2, md: 4 }}
fontWeight="medium" fontWeight="medium"
boxShadow="0 4px 12px rgba(139, 92, 246, 0.3)" boxShadow="0 4px 12px rgba(139, 92, 246, 0.4)"
_hover={{ _hover={{
bg: 'purple.400',
transform: 'scale(1.05)', transform: 'scale(1.05)',
boxShadow: '0 6px 16px rgba(139, 92, 246, 0.4)', boxShadow: '0 6px 16px rgba(139, 92, 246, 0.5)',
}} }}
transition="all 0.2s" transition="all 0.2s"
> >
@@ -949,7 +945,7 @@ const ConceptCenter = () => {
left={0} left={0}
right={0} right={0}
height="2px" height="2px"
bgGradient="linear(to-r, purple.400, pink.400, blue.400)" bgGradient="linear(to-r, purple.500, pink.500, cyan.500)"
opacity={0} opacity={0}
_groupHover={{ opacity: 1 }} _groupHover={{ opacity: 1 }}
transition="opacity 0.3s" transition="opacity 0.3s"
@@ -958,7 +954,7 @@ const ConceptCenter = () => {
); );
}; };
// 概念列表项组件 - 列表视图 // 概念列表项组件 - 列表视图(深色主题版)
const ConceptListItem = ({ concept, position = 0 }) => { const ConceptListItem = ({ concept, position = 0 }) => {
const changePercent = concept.price_info?.avg_change_pct; const changePercent = concept.price_info?.avg_change_pct;
const changeColor = getChangeColor(changePercent); const changeColor = getChangeColor(changePercent);
@@ -968,38 +964,49 @@ const ConceptCenter = () => {
<Card <Card
cursor="pointer" cursor="pointer"
onClick={() => handleConceptClick(concept.concept_id, concept.concept, concept, position)} onClick={() => handleConceptClick(concept.concept_id, concept.concept, concept, position)}
bg="white" bg="rgba(15, 23, 42, 0.8)"
backdropFilter="blur(20px)"
borderWidth="1px" borderWidth="1px"
borderColor="gray.200" borderColor="whiteAlpha.100"
overflow="hidden" overflow="hidden"
borderRadius="2xl"
_hover={{ _hover={{
transform: 'translateX(4px)', transform: 'translateX(4px)',
boxShadow: 'lg', boxShadow: '0 8px 32px rgba(139, 92, 246, 0.25)',
borderColor: 'purple.300', borderColor: 'purple.500',
}} }}
transition="all 0.3s" transition="all 0.3s cubic-bezier(0.4, 0, 0.2, 1)"
> >
<CardBody p={6}> <CardBody p={{ base: 4, md: 6 }}>
<Flex align="center" gap={6}> <Flex align="center" gap={{ base: 3, md: 6 }} flexWrap={{ base: 'wrap', md: 'nowrap' }}>
{/* 左侧图标区域 */} {/* 左侧图标区域 */}
<Box <Box
width="80px" width={{ base: '60px', md: '80px' }}
height="80px" height={{ base: '60px', md: '80px' }}
borderRadius="xl" borderRadius="xl"
bgGradient="linear(to-br, purple.100, pink.100)" bg={hasChange
? changePercent > 0
? "linear-gradient(135deg, rgba(153, 27, 27, 0.6) 0%, rgba(239, 68, 68, 0.4) 100%)"
: changePercent < 0
? "linear-gradient(135deg, rgba(20, 83, 45, 0.6) 0%, rgba(34, 197, 94, 0.4) 100%)"
: "linear-gradient(135deg, rgba(71, 85, 105, 0.6) 0%, rgba(100, 116, 139, 0.4) 100%)"
: "linear-gradient(135deg, rgba(99, 102, 241, 0.4) 0%, rgba(168, 85, 247, 0.3) 100%)"
}
display="flex" display="flex"
alignItems="center" alignItems="center"
justifyContent="center" justifyContent="center"
position="relative" position="relative"
flexShrink={0} flexShrink={0}
border="1px solid"
borderColor="whiteAlpha.100"
> >
<Icon as={FaTags} boxSize={8} color="purple.400" /> <Icon as={FaTags} boxSize={{ base: 6, md: 8 }} color="white" opacity={0.8} />
{hasChange && ( {hasChange && (
<Badge <Badge
position="absolute" position="absolute"
top={-2} top={-2}
right={-2} right={-2}
bg={changeColor === 'red' ? 'red.500' : changeColor === 'green' ? 'green.500' : 'gray.500'} bg={changeColor === 'red' ? 'rgba(239, 68, 68, 0.9)' : changeColor === 'green' ? 'rgba(34, 197, 94, 0.9)' : 'rgba(100, 116, 139, 0.9)'}
color="white" color="white"
fontSize="xs" fontSize="xs"
px={2} px={2}
@@ -1007,6 +1014,7 @@ const ConceptCenter = () => {
borderRadius="full" borderRadius="full"
fontWeight="bold" fontWeight="bold"
minW="auto" minW="auto"
boxShadow={`0 2px 8px rgba(${changeColor === 'red' ? '239, 68, 68' : changeColor === 'green' ? '34, 197, 94' : '100, 116, 139'}, 0.4)`}
> >
<Icon <Icon
as={changePercent > 0 ? FaArrowUp : changePercent < 0 ? FaArrowDown : null} as={changePercent > 0 ? FaArrowUp : changePercent < 0 ? FaArrowDown : null}
@@ -1020,47 +1028,58 @@ const ConceptCenter = () => {
{/* 中间内容区域 */} {/* 中间内容区域 */}
<Box flex={1}> <Box flex={1}>
<VStack align="start" spacing={3}> <VStack align="start" spacing={{ base: 2, md: 3 }}>
<Heading size="md" color="gray.800" noOfLines={1}> <Heading size={{ base: 'sm', md: 'md' }} color="white" noOfLines={1}>
{concept.concept} {concept.concept}
</Heading> </Heading>
<Text color="gray.600" fontSize="sm" noOfLines={2}> <Text color="whiteAlpha.600" fontSize="sm" noOfLines={2}>
{concept.description || '该概念板块涵盖相关技术、产业链和市场应用等多个维度的投资机会'} {concept.description || '该概念板块涵盖相关技术、产业链和市场应用等多个维度的投资机会'}
</Text> </Text>
<HStack spacing={4} flexWrap="wrap"> <HStack spacing={4} flexWrap="wrap">
<HStack spacing={1}> <HStack spacing={1}>
<Icon as={FaChartLine} boxSize={4} color="purple.500" /> <Icon as={FaChartLine} boxSize={4} color="purple.300" />
<Text fontSize="sm" fontWeight="medium" color="gray.700"> <Text fontSize="sm" fontWeight="medium" color="whiteAlpha.800">
{concept.stock_count || 0} 只股票 {concept.stock_count || 0} 只股票
</Text> </Text>
</HStack> </HStack>
{hasChange && concept.price_info?.trade_date && ( {hasChange && concept.price_info?.trade_date && (
<HStack spacing={1}> <HStack spacing={1}>
<Icon as={FaCalendarAlt} boxSize={4} color="blue.500" /> <Icon as={FaCalendarAlt} boxSize={4} color="cyan.400" />
<Text fontSize="sm" color="gray.600"> <Text fontSize="sm" color="whiteAlpha.600">
{new Date(concept.price_info.trade_date).toLocaleDateString('zh-CN')} {new Date(concept.price_info.trade_date).toLocaleDateString('zh-CN')}
</Text> </Text>
</HStack> </HStack>
)} )}
{formatAddedDate(concept)} {/* 添加日期 - 深色主题 */}
{(concept.created_at || concept.added_date || concept.happened_times?.[0]) && (
<HStack spacing={1}>
<Icon as={CalendarIcon} boxSize={4} color="cyan.400" />
<Text fontSize="sm" color="whiteAlpha.600">
添加于 {new Date(concept.created_at || concept.added_date || concept.happened_times?.[0]).toLocaleDateString('zh-CN')}
</Text>
</HStack>
)}
</HStack> </HStack>
</VStack> </VStack>
</Box> </Box>
{/* 右侧操作区域 */} {/* 右侧操作区域 */}
<VStack spacing={3} align="end" flexShrink={0}> <VStack spacing={3} align="end" flexShrink={0} display={{ base: 'none', md: 'flex' }}>
<HStack spacing={3}> <HStack spacing={3}>
<Button <Button
size="sm" size="sm"
leftIcon={<ViewIcon />} leftIcon={<ViewIcon />}
colorScheme="blue" bg="whiteAlpha.100"
variant="outline" color="white"
border="1px solid"
borderColor="whiteAlpha.200"
onClick={(e) => handleViewStocks(e, concept)} onClick={(e) => handleViewStocks(e, concept)}
borderRadius="full" borderRadius="full"
_hover={{ bg: 'whiteAlpha.200', borderColor: 'whiteAlpha.300' }}
> >
查看个股 查看个股
</Button> </Button>
@@ -1068,10 +1087,12 @@ const ConceptCenter = () => {
<Button <Button
size="sm" size="sm"
leftIcon={<FaChartLine />} leftIcon={<FaChartLine />}
colorScheme="purple" bg="purple.500"
variant="solid" color="white"
onClick={(e) => handleViewContent(e, concept.concept, concept.concept_id)} onClick={(e) => handleViewContent(e, concept.concept, concept.concept_id)}
borderRadius="full" borderRadius="full"
boxShadow="0 4px 12px rgba(139, 92, 246, 0.4)"
_hover={{ bg: 'purple.400', boxShadow: '0 6px 16px rgba(139, 92, 246, 0.5)' }}
> >
历史时间轴 历史时间轴
</Button> </Button>
@@ -1080,9 +1101,9 @@ const ConceptCenter = () => {
{concept.stocks && concept.stocks.length > 0 && ( {concept.stocks && concept.stocks.length > 0 && (
<Box> <Box>
<HStack spacing={1} mb={2}> <HStack spacing={1} mb={2}>
<Text fontSize="xs" color="gray.500">热门个股</Text> <Text fontSize="xs" color="whiteAlpha.500">热门个股</Text>
{!hasFeatureAccess('hot_stocks') && ( {!hasFeatureAccess('hot_stocks') && (
<Badge colorScheme="yellow" size="sm"> <Badge bg="yellow.500" color="gray.900" size="sm" fontSize="xs">
🔒需Pro 🔒需Pro
</Badge> </Badge>
)} )}
@@ -1092,14 +1113,14 @@ const ConceptCenter = () => {
<> <>
{concept.stocks.slice(0, 3).map((stock, idx) => ( {concept.stocks.slice(0, 3).map((stock, idx) => (
<WrapItem key={idx}> <WrapItem key={idx}>
<Tag size="sm" colorScheme="purple" variant="subtle"> <Tag size="sm" bg="purple.500" color="white" borderRadius="full">
<TagLabel fontSize="xs">{stock.stock_name}</TagLabel> <TagLabel fontSize="xs">{getStockName(stock)}</TagLabel>
</Tag> </Tag>
</WrapItem> </WrapItem>
))} ))}
{concept.stocks.length > 3 && ( {concept.stocks.length > 3 && (
<WrapItem> <WrapItem>
<Text fontSize="xs" color="purple.600" fontWeight="medium"> <Text fontSize="xs" color="purple.300" fontWeight="medium">
+{concept.stocks.length - 3}更多 +{concept.stocks.length - 3}更多
</Text> </Text>
</WrapItem> </WrapItem>
@@ -1108,8 +1129,8 @@ const ConceptCenter = () => {
) : ( ) : (
<WrapItem> <WrapItem>
<HStack spacing={1}> <HStack spacing={1}>
<Icon as={FaLock} boxSize="8px" color="yellow.600" /> <Icon as={FaLock} boxSize="8px" color="yellow.400" />
<Text fontSize="xs" color="yellow.600" fontWeight="medium"> <Text fontSize="xs" color="yellow.400" fontWeight="medium">
升级查看{concept.stocks.length} 升级查看{concept.stocks.length}
</Text> </Text>
</HStack> </HStack>
@@ -1125,26 +1146,26 @@ const ConceptCenter = () => {
); );
}; };
// 骨架屏组件 // 骨架屏组件 - 深色主题
const SkeletonCard = () => ( const SkeletonCard = () => (
<Card bg="white" borderWidth="1px" borderColor="gray.200"> <Card bg="rgba(15, 23, 42, 0.8)" borderWidth="1px" borderColor="whiteAlpha.100" borderRadius="2xl">
<Skeleton height="200px" /> <Skeleton height="160px" startColor="whiteAlpha.100" endColor="whiteAlpha.200" />
<CardBody> <CardBody>
<SkeletonText mt={4} noOfLines={4} spacing={4} /> <SkeletonText mt={4} noOfLines={4} spacing={4} startColor="whiteAlpha.100" endColor="whiteAlpha.200" />
</CardBody> </CardBody>
</Card> </Card>
); );
// 日期选择组件 - 科幻风格 // 日期选择组件 - 深色主题
const DateSelector = () => ( const DateSelector = () => (
<Box <Box
p={4} p={4}
bg="rgba(255, 255, 255, 0.8)" bg="rgba(15, 23, 42, 0.8)"
backdropFilter="blur(10px)" backdropFilter="blur(20px)"
borderRadius="xl" borderRadius="2xl"
border="1px solid" border="1px solid"
borderColor="purple.100" borderColor="whiteAlpha.100"
boxShadow="0 4px 20px rgba(139, 92, 246, 0.1)" boxShadow="0 4px 20px rgba(0, 0, 0, 0.3)"
> >
<Flex <Flex
direction={{ base: 'column', lg: 'row' }} direction={{ base: 'column', lg: 'row' }}
@@ -1165,17 +1186,18 @@ const ConceptCenter = () => {
}} }}
latestTradeDate={latestTradeDate} latestTradeDate={latestTradeDate}
label="交易日期" label="交易日期"
isDarkMode={true}
/> />
{/* 快捷按钮保留在页面内 */} {/* 快捷按钮 - 深色主题 */}
<ButtonGroup size="sm" variant="outline" flexWrap="wrap"> <ButtonGroup size="sm" variant="outline" flexWrap="wrap">
<Button <Button
onClick={() => handleQuickDateSelect(0)} onClick={() => handleQuickDateSelect(0)}
borderColor="purple.300" borderColor="whiteAlpha.300"
color="purple.600" color="white"
borderRadius="full" borderRadius="full"
_hover={{ _hover={{
bg: 'purple.50', bg: 'whiteAlpha.100',
borderColor: 'purple.400', borderColor: 'purple.400',
}} }}
> >
@@ -1183,11 +1205,11 @@ const ConceptCenter = () => {
</Button> </Button>
<Button <Button
onClick={() => handleQuickDateSelect(1)} onClick={() => handleQuickDateSelect(1)}
borderColor="purple.300" borderColor="whiteAlpha.300"
color="purple.600" color="white"
borderRadius="full" borderRadius="full"
_hover={{ _hover={{
bg: 'purple.50', bg: 'whiteAlpha.100',
borderColor: 'purple.400', borderColor: 'purple.400',
}} }}
> >
@@ -1195,11 +1217,11 @@ const ConceptCenter = () => {
</Button> </Button>
<Button <Button
onClick={() => handleQuickDateSelect(7)} onClick={() => handleQuickDateSelect(7)}
borderColor="purple.300" borderColor="whiteAlpha.300"
color="purple.600" color="white"
borderRadius="full" borderRadius="full"
_hover={{ _hover={{
bg: 'purple.50', bg: 'whiteAlpha.100',
borderColor: 'purple.400', borderColor: 'purple.400',
}} }}
> >
@@ -1207,11 +1229,11 @@ const ConceptCenter = () => {
</Button> </Button>
<Button <Button
onClick={() => handleQuickDateSelect(30)} onClick={() => handleQuickDateSelect(30)}
borderColor="purple.300" borderColor="whiteAlpha.300"
color="purple.600" color="white"
borderRadius="full" borderRadius="full"
_hover={{ _hover={{
bg: 'purple.50', bg: 'whiteAlpha.100',
borderColor: 'purple.400', borderColor: 'purple.400',
}} }}
> >
@@ -1223,7 +1245,7 @@ const ConceptCenter = () => {
); );
return ( return (
<Box minH="100vh" bg="linear-gradient(180deg, #f8f9ff 0%, #f0f2ff 100%)"> <Box minH="100vh" bg="linear-gradient(to-b, gray.900, slate.900, gray.900)">
{/* 导航栏已由 MainLayout 提供 */} {/* 导航栏已由 MainLayout 提供 */}
{/* Hero Section - 精简版 */} {/* Hero Section - 精简版 */}
@@ -1434,7 +1456,7 @@ const ConceptCenter = () => {
</Container> </Container>
</Box> </Box>
{/* 主内容区域 */} {/* 主内容区域 - 深色主题 */}
<Container maxW="container.xl" py={10}> <Container maxW="container.xl" py={10}>
<Box mb={6}> <Box mb={6}>
<DateSelector /> <DateSelector />
@@ -1447,11 +1469,12 @@ const ConceptCenter = () => {
<Card <Card
mb={8} mb={8}
bg="rgba(255, 255, 255, 0.8)" bg="rgba(15, 23, 42, 0.8)"
backdropFilter="blur(10px)" backdropFilter="blur(20px)"
border="1px solid" border="1px solid"
borderColor="purple.100" borderColor="whiteAlpha.100"
boxShadow="0 4px 20px rgba(139, 92, 246, 0.1)" boxShadow="0 4px 20px rgba(0, 0, 0, 0.3)"
borderRadius="2xl"
> >
<CardBody> <CardBody>
<Flex <Flex
@@ -1461,16 +1484,25 @@ const ConceptCenter = () => {
gap={4} gap={4}
> >
<HStack spacing={4} align="center"> <HStack spacing={4} align="center">
<Icon as={FaTags} boxSize={4} color="purple.500" /> <Icon as={FaTags} boxSize={4} color="purple.300" />
<Text fontWeight="bold" color="purple.700">排序方式</Text> <Text fontWeight="bold" color="white">排序方式</Text>
<Select <Select
value={sortBy} value={sortBy}
onChange={(e) => handleSortChange(e.target.value)} onChange={(e) => handleSortChange(e.target.value)}
width="200px" width="200px"
focusBorderColor="purple.500" focusBorderColor="purple.400"
borderColor="purple.200" borderColor="whiteAlpha.300"
borderRadius="lg" borderRadius="lg"
fontWeight="medium" fontWeight="medium"
color="white"
bg="whiteAlpha.50"
_hover={{ borderColor: 'purple.400' }}
sx={{
option: {
bg: 'gray.800',
color: 'white',
},
}}
> >
<option value="change_pct">涨跌幅</option> <option value="change_pct">涨跌幅</option>
<option value="_score">相关度</option> <option value="_score">相关度</option>
@@ -1482,15 +1514,14 @@ const ConceptCenter = () => {
<Tooltip label="搜索时自动切换到相关度排序,以显示最匹配的结果。您也可以手动切换其他排序方式。"> <Tooltip label="搜索时自动切换到相关度排序,以显示最匹配的结果。您也可以手动切换其他排序方式。">
<HStack <HStack
spacing={1} spacing={1}
bg="blue.50" bg="blue.500"
px={3} px={3}
py={1} py={1}
borderRadius="full" borderRadius="full"
border="1px solid" boxShadow="0 0 10px rgba(59, 130, 246, 0.4)"
borderColor="blue.200"
> >
<Icon as={InfoIcon} color="blue.500" boxSize={3} /> <Icon as={InfoIcon} color="white" boxSize={3} />
<Text fontSize="xs" color="blue.600" fontWeight="medium"> <Text fontSize="xs" color="white" fontWeight="medium">
智能排序 智能排序
</Text> </Text>
</HStack> </HStack>
@@ -1508,12 +1539,12 @@ const ConceptCenter = () => {
setViewMode('hierarchy'); setViewMode('hierarchy');
} }
}} }}
bg={viewMode === 'hierarchy' ? 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' : 'transparent'} bg={viewMode === 'hierarchy' ? 'purple.500' : 'transparent'}
color={viewMode === 'hierarchy' ? 'white' : 'purple.500'} color={viewMode === 'hierarchy' ? 'white' : 'whiteAlpha.700'}
borderColor="purple.500" borderColor="whiteAlpha.300"
_hover={{ _hover={{
bg: viewMode === 'hierarchy' ? 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' : 'purple.50', bg: viewMode === 'hierarchy' ? 'purple.400' : 'whiteAlpha.100',
boxShadow: viewMode === 'hierarchy' ? '0 0 10px rgba(139, 92, 246, 0.3)' : 'none', boxShadow: viewMode === 'hierarchy' ? '0 0 10px rgba(139, 92, 246, 0.4)' : 'none',
}} }}
aria-label="层级图" aria-label="层级图"
/> />
@@ -1527,12 +1558,12 @@ const ConceptCenter = () => {
setViewMode('grid'); setViewMode('grid');
} }
}} }}
bg={viewMode === 'grid' ? 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' : 'transparent'} bg={viewMode === 'grid' ? 'purple.500' : 'transparent'}
color={viewMode === 'grid' ? 'white' : 'purple.500'} color={viewMode === 'grid' ? 'white' : 'whiteAlpha.700'}
borderColor="purple.500" borderColor="whiteAlpha.300"
_hover={{ _hover={{
bg: viewMode === 'grid' ? 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' : 'purple.50', bg: viewMode === 'grid' ? 'purple.400' : 'whiteAlpha.100',
boxShadow: viewMode === 'grid' ? '0 0 10px rgba(139, 92, 246, 0.3)' : 'none', boxShadow: viewMode === 'grid' ? '0 0 10px rgba(139, 92, 246, 0.4)' : 'none',
}} }}
aria-label="网格视图" aria-label="网格视图"
/> />
@@ -1546,12 +1577,12 @@ const ConceptCenter = () => {
setViewMode('list'); setViewMode('list');
} }
}} }}
bg={viewMode === 'list' ? 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' : 'transparent'} bg={viewMode === 'list' ? 'purple.500' : 'transparent'}
color={viewMode === 'list' ? 'white' : 'purple.500'} color={viewMode === 'list' ? 'white' : 'whiteAlpha.700'}
borderColor="purple.500" borderColor="whiteAlpha.300"
_hover={{ _hover={{
bg: viewMode === 'list' ? 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' : 'purple.50', bg: viewMode === 'list' ? 'purple.400' : 'whiteAlpha.100',
boxShadow: viewMode === 'list' ? '0 0 10px rgba(139, 92, 246, 0.3)' : 'none', boxShadow: viewMode === 'list' ? '0 0 10px rgba(139, 92, 246, 0.4)' : 'none',
}} }}
aria-label="列表视图" aria-label="列表视图"
/> />
@@ -1566,15 +1597,16 @@ const ConceptCenter = () => {
filter={hierarchyFilter} filter={hierarchyFilter}
onClearFilter={handleClearHierarchyFilter} onClearFilter={handleClearHierarchyFilter}
onNavigate={handleNavigateHierarchy} onNavigate={handleNavigateHierarchy}
isDarkMode={true}
/> />
{selectedDate && viewMode !== 'hierarchy' && ( {selectedDate && viewMode !== 'hierarchy' && (
<Box mb={4} p={3} bg="blue.50" borderRadius="md" borderLeft="4px solid" borderColor="blue.500"> <Box mb={4} p={3} bg="rgba(59, 130, 246, 0.2)" borderRadius="xl" borderLeft="4px solid" borderColor="blue.400">
<HStack> <HStack>
<Icon as={InfoIcon} color="blue.500" /> <Icon as={InfoIcon} color="blue.300" />
<Text fontSize="sm" color="blue.700"> <Text fontSize="sm" color="whiteAlpha.800">
当前显示 <strong>{selectedDate.toLocaleDateString('zh-CN')}</strong> 当前显示 <Text as="strong" color="cyan.300">{selectedDate.toLocaleDateString('zh-CN')}</Text>
{searchQuery && <span>搜索词<strong>"{searchQuery}"</strong></span>} {searchQuery && <span>搜索词<Text as="strong" color="cyan.300">"{searchQuery}"</Text></span>}
</Text> </Text>
</HStack> </HStack>
</Box> </Box>
@@ -1614,30 +1646,30 @@ const ConceptCenter = () => {
<Center mt={12}> <Center mt={12}>
<HStack <HStack
spacing={3} spacing={3}
bg="rgba(255, 255, 255, 0.8)" bg="rgba(15, 23, 42, 0.8)"
backdropFilter="blur(10px)" backdropFilter="blur(20px)"
px={6} px={6}
py={3} py={3}
borderRadius="full" borderRadius="full"
border="1px solid" border="1px solid"
borderColor="purple.100" borderColor="whiteAlpha.100"
boxShadow="0 4px 20px rgba(139, 92, 246, 0.15)" boxShadow="0 4px 20px rgba(0, 0, 0, 0.3)"
> >
<Button <Button
size="sm" size="sm"
onClick={() => handlePageChange(Math.max(1, currentPage - 1))} onClick={() => handlePageChange(Math.max(1, currentPage - 1))}
isDisabled={currentPage === 1} isDisabled={currentPage === 1}
bgGradient="linear(to-r, purple.500, pink.500)" bg="purple.500"
color="white" color="white"
variant="solid" variant="solid"
borderRadius="full" borderRadius="full"
_hover={{ _hover={{
bgGradient: 'linear(to-r, purple.600, pink.600)', bg: 'purple.400',
boxShadow: '0 0 15px rgba(139, 92, 246, 0.4)', boxShadow: '0 0 15px rgba(139, 92, 246, 0.5)',
}} }}
_disabled={{ _disabled={{
bg: 'gray.200', bg: 'whiteAlpha.100',
color: 'gray.400', color: 'whiteAlpha.400',
cursor: 'not-allowed', cursor: 'not-allowed',
}} }}
> >
@@ -1655,15 +1687,15 @@ const ConceptCenter = () => {
key={pageNum} key={pageNum}
size="sm" size="sm"
onClick={() => handlePageChange(pageNum)} onClick={() => handlePageChange(pageNum)}
bg={pageNum === currentPage ? 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' : 'transparent'} bg={pageNum === currentPage ? 'purple.500' : 'transparent'}
color={pageNum === currentPage ? 'white' : 'purple.600'} color={pageNum === currentPage ? 'white' : 'whiteAlpha.700'}
variant={pageNum === currentPage ? 'solid' : 'ghost'} variant={pageNum === currentPage ? 'solid' : 'ghost'}
borderRadius="full" borderRadius="full"
minW="40px" minW="40px"
fontWeight="bold" fontWeight="bold"
_hover={{ _hover={{
bg: pageNum === currentPage ? 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' : 'purple.50', bg: pageNum === currentPage ? 'purple.400' : 'whiteAlpha.100',
boxShadow: pageNum === currentPage ? '0 0 10px rgba(139, 92, 246, 0.3)' : 'none', boxShadow: pageNum === currentPage ? '0 0 10px rgba(139, 92, 246, 0.4)' : 'none',
}} }}
> >
{pageNum} {pageNum}
@@ -1676,17 +1708,17 @@ const ConceptCenter = () => {
size="sm" size="sm"
onClick={() => handlePageChange(Math.min(totalPages, currentPage + 1))} onClick={() => handlePageChange(Math.min(totalPages, currentPage + 1))}
isDisabled={currentPage === totalPages} isDisabled={currentPage === totalPages}
bgGradient="linear(to-r, purple.500, pink.500)" bg="purple.500"
color="white" color="white"
variant="solid" variant="solid"
borderRadius="full" borderRadius="full"
_hover={{ _hover={{
bgGradient: 'linear(to-r, purple.600, pink.600)', bg: 'purple.400',
boxShadow: '0 0 15px rgba(139, 92, 246, 0.4)', boxShadow: '0 0 15px rgba(139, 92, 246, 0.5)',
}} }}
_disabled={{ _disabled={{
bg: 'gray.200', bg: 'whiteAlpha.100',
color: 'gray.400', color: 'whiteAlpha.400',
cursor: 'not-allowed', cursor: 'not-allowed',
}} }}
> >
@@ -1698,10 +1730,10 @@ const ConceptCenter = () => {
) : viewMode !== 'hierarchy' ? ( ) : viewMode !== 'hierarchy' ? (
<Center h="400px"> <Center h="400px">
<VStack spacing={6}> <VStack spacing={6}>
<Icon as={FaTags} boxSize={20} color="gray.300" /> <Icon as={FaTags} boxSize={20} color="whiteAlpha.300" />
<VStack spacing={2}> <VStack spacing={2}>
<Text fontSize="xl" color="gray.600" fontWeight="medium">暂无概念数据</Text> <Text fontSize="xl" color="white" fontWeight="medium">暂无概念数据</Text>
<Text color="gray.500"> <Text color="whiteAlpha.600">
{hierarchyFilter?.lv1 {hierarchyFilter?.lv1
? `${[hierarchyFilter.lv1, hierarchyFilter.lv2, hierarchyFilter.lv3].filter(Boolean).join(' > ')}」分类下暂无数据` ? `${[hierarchyFilter.lv1, hierarchyFilter.lv2, hierarchyFilter.lv3].filter(Boolean).join(' > ')}」分类下暂无数据`
: '请尝试其他搜索关键词或选择其他日期' : '请尝试其他搜索关键词或选择其他日期'
@@ -1710,9 +1742,10 @@ const ConceptCenter = () => {
{hierarchyFilter?.lv1 && ( {hierarchyFilter?.lv1 && (
<Button <Button
size="sm" size="sm"
colorScheme="purple" bg="purple.500"
variant="outline" color="white"
onClick={handleClearHierarchyFilter} onClick={handleClearHierarchyFilter}
_hover={{ bg: 'purple.400' }}
> >
清除筛选 清除筛选
</Button> </Button>
@@ -1730,27 +1763,36 @@ const ConceptCenter = () => {
<ConceptStatsPanel <ConceptStatsPanel
apiBaseUrl={API_BASE_URL} apiBaseUrl={API_BASE_URL}
onConceptClick={handleConceptClick} onConceptClick={handleConceptClick}
isDarkMode={true}
/> />
) : ( ) : (
<Card> <Card
bg="rgba(15, 23, 42, 0.8)"
backdropFilter="blur(20px)"
border="1px solid"
borderColor="whiteAlpha.100"
borderRadius="2xl"
>
<CardBody p={6}> <CardBody p={6}>
<VStack spacing={4} textAlign="center"> <VStack spacing={4} textAlign="center">
<Icon as={FaChartLine} boxSize={12} color="gray.300" /> <Icon as={FaChartLine} boxSize={12} color="whiteAlpha.300" />
<VStack spacing={2}> <VStack spacing={2}>
<Heading size="md" color="gray.600"> <Heading size="md" color="white">
概念统计中心 概念统计中心
</Heading> </Heading>
<Text fontSize="sm" color="gray.500"> <Text fontSize="sm" color="whiteAlpha.600">
此功能需要Pro版订阅才能使用 此功能需要Pro版订阅才能使用
</Text> </Text>
</VStack> </VStack>
<Button <Button
colorScheme="blue" bg="blue.500"
color="white"
leftIcon={<Icon as={FaRocket} />} leftIcon={<Icon as={FaRocket} />}
onClick={() => { onClick={() => {
setUpgradeFeature('pro'); setUpgradeFeature('pro');
setUpgradeModalOpen(true); setUpgradeModalOpen(true);
}} }}
_hover={{ bg: 'blue.400', boxShadow: '0 0 15px rgba(59, 130, 246, 0.5)' }}
> >
升级到Pro版 升级到Pro版
</Button> </Button>