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