update pay function

This commit is contained in:
2025-11-23 09:01:00 +08:00
parent 173ddb985d
commit 04c13f3a6c
2 changed files with 456 additions and 1822 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -693,139 +693,235 @@ const ConceptCenter = () => {
init();
}, []);
// 概念卡片组件 - 优化
// 概念卡片组件 - 科幻毛玻璃
const ConceptCard = ({ concept, position = 0 }) => {
const changePercent = concept.price_info?.avg_change_pct;
const changeColor = getChangeColor(changePercent);
const hasChange = changePercent !== null && changePercent !== undefined;
// 生成随机涨幅数字背景
const generateNumbersBackground = () => {
const numbers = [];
for (let i = 0; i < 30; i++) {
const isPositive = Math.random() > 0.5;
const value = (Math.random() * 15).toFixed(2);
const sign = isPositive ? '+' : '-';
numbers.push(`${sign}${value}%`);
}
return numbers;
};
const backgroundNumbers = generateNumbersBackground();
return (
<Card
cursor="pointer"
onClick={() => handleConceptClick(concept.concept_id, concept.concept, concept, position)}
bg="white"
borderWidth="1px"
borderColor="gray.200"
borderColor="transparent"
overflow="hidden"
_hover={{
transform: 'translateY(-8px)',
boxShadow: 'xl',
borderColor: 'purple.300',
boxShadow: '0 20px 40px rgba(139, 92, 246, 0.3)',
borderColor: 'purple.400',
}}
transition="all 0.3s"
position="relative"
boxShadow="0 4px 12px rgba(0, 0, 0, 0.1)"
>
{/* 毛玻璃涨幅数字背景 */}
<Box position="relative" height="180px" overflow="hidden">
<Image
src={defaultImage}
alt={concept.concept}
height="100%"
width="100%"
objectFit="cover"
fallback={
<Box
height="100%"
bgGradient="linear(to-br, purple.100, pink.100)"
display="flex"
alignItems="center"
justifyContent="center"
>
<Icon as={FaTags} boxSize={12} color="purple.300" opacity={0.5} />
</Box>
}
/>
{/* 渐变背景层 */}
<Box
position="absolute"
top={0}
left={0}
right={0}
bottom={0}
bgGradient="linear(to-t, blackAlpha.700, transparent)"
bgGradient={
hasChange && changePercent > 0
? "linear(135deg, #667eea 0%, #764ba2 100%)"
: hasChange && changePercent < 0
? "linear(135deg, #f093fb 0%, #f5576c 100%)"
: "linear(135deg, #4facfe 0%, #00f2fe 100%)"
}
/>
{hasChange && (
<Badge
position="absolute"
top={3}
left={3}
bg={changeColor === 'red' ? 'red.500' : changeColor === 'green' ? 'green.500' : 'gray.500'}
color="white"
fontSize="sm"
px={2}
py={1}
borderRadius="full"
fontWeight="bold"
boxShadow="lg"
display="flex"
alignItems="center"
gap={1}
animation={Math.abs(changePercent) > 5 ? `${pulseAnimation} 2s infinite` : 'none'}
>
<Icon
as={changePercent > 0 ? FaArrowUp : changePercent < 0 ? FaArrowDown : null}
boxSize={3}
/>
{formatChangePercent(changePercent)}
</Badge>
)}
{/* 数字矩阵层 */}
<Box
position="absolute"
top={0}
left={0}
right={0}
bottom={0}
display="grid"
gridTemplateColumns="repeat(5, 1fr)"
gridTemplateRows="repeat(6, 1fr)"
gap={2}
p={3}
opacity={0.15}
>
{backgroundNumbers.map((num, idx) => (
<Flex
key={idx}
align="center"
justify="center"
fontSize="xs"
fontWeight="bold"
color="white"
transform={`rotate(${Math.random() * 20 - 10}deg)`}
>
{num}
</Flex>
))}
</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)"
/>
{/* 右上角股票数量徽章 */}
<Badge
position="absolute"
top={3}
right={3}
bgGradient="linear(to-r, purple.500, pink.500)"
bg="rgba(255, 255, 255, 0.2)"
backdropFilter="blur(10px)"
color="white"
fontSize="xs"
px={2}
px={3}
py={1}
borderRadius="full"
fontWeight="bold"
boxShadow="md"
boxShadow="0 4px 12px rgba(0, 0, 0, 0.2)"
border="1px solid"
borderColor="whiteAlpha.300"
>
{concept.stock_count || 0} 只股票
</Badge>
</Box>
<CardBody p={4}>
<VStack align="start" spacing={2}>
<Heading size="sm" color="gray.800" noOfLines={1}>
<VStack align="start" spacing={3}>
{/* 概念名称 */}
<Heading
size="sm"
color="gray.800"
noOfLines={1}
bgGradient="linear(to-r, purple.600, pink.600)"
bgClip="text"
fontWeight="bold"
>
{concept.concept}
</Heading>
{/* 描述信息 */}
<Text color="gray.600" fontSize="xs" noOfLines={2} minH="32px">
{concept.description || '暂无描述信息'}
</Text>
{/* 涨跌幅信息卡片 */}
{hasChange && concept.price_info?.trade_date && (
<HStack spacing={3} fontSize="xs" color="gray.500" w="100%">
<Text>交易日期: {new Date(concept.price_info.trade_date).toLocaleDateString('zh-CN')}</Text>
<Spacer />
<Text fontWeight="bold" color={`${changeColor}.600`}>
{formatChangePercent(changePercent)}
</Text>
</HStack>
<Box
w="100%"
p={2}
borderRadius="md"
bgGradient={
changePercent > 0
? "linear(to-r, rgba(139, 92, 246, 0.1), rgba(168, 85, 247, 0.05))"
: "linear(to-r, rgba(236, 72, 153, 0.1), rgba(251, 113, 133, 0.05))"
}
border="1px solid"
borderColor={changePercent > 0 ? "purple.200" : "pink.200"}
>
<Flex align="center" justify="space-between">
<HStack spacing={2}>
<Icon
as={FaCalendarAlt}
boxSize={3}
color={changePercent > 0 ? "purple.500" : "pink.500"}
/>
<Text fontSize="xs" color="gray.600">
{new Date(concept.price_info.trade_date).toLocaleDateString('zh-CN')}
</Text>
</HStack>
<HStack spacing={1}>
<Icon
as={changePercent > 0 ? FaArrowUp : FaArrowDown}
boxSize={3}
color={changePercent > 0 ? "red.500" : "green.500"}
/>
<Text
fontWeight="bold"
fontSize="sm"
color={changePercent > 0 ? "red.500" : "green.500"}
>
{formatChangePercent(changePercent)}
</Text>
</HStack>
</Flex>
</Box>
)}
{concept.stocks && concept.stocks.length > 0 && (
<Box
width="100%"
p={2}
bg="gray.50"
borderRadius="md"
p={3}
bg="linear-gradient(135deg, rgba(99, 102, 241, 0.05) 0%, rgba(168, 85, 247, 0.05) 100%)"
borderRadius="lg"
cursor="pointer"
onClick={(e) => handleViewStocks(e, concept)}
_hover={{ bg: 'gray.100' }}
transition="background 0.2s"
_hover={{
bg: 'linear-gradient(135deg, rgba(99, 102, 241, 0.1) 0%, rgba(168, 85, 247, 0.1) 100%)',
transform: 'translateX(2px)',
}}
transition="all 0.2s"
border="1px solid"
borderColor="purple.100"
>
<Flex align="center" justify="space-between">
<Box flex={1}>
<HStack spacing={2} mb={1}>
<Text fontSize="xs" color="gray.600" fontWeight="medium">
<HStack spacing={2} mb={2}>
<Icon as={FaChartLine} boxSize={3} color="purple.500" />
<Text fontSize="xs" color="purple.700" fontWeight="bold">
热门个股
</Text>
{!hasFeatureAccess('hot_stocks') && (
<Badge colorScheme="yellow" size="sm">
🔒需Pro
<Badge
colorScheme="yellow"
size="sm"
borderRadius="full"
px={2}
>
🔒Pro
</Badge>
)}
</HStack>
@@ -833,13 +929,20 @@ const ConceptCenter = () => {
{hasFeatureAccess('hot_stocks') ? (
<>
{concept.stocks.slice(0, 2).map((stock, idx) => (
<Tag key={idx} size="sm" colorScheme="purple" variant="subtle">
<Tag
key={idx}
size="sm"
bgGradient="linear(to-r, purple.500, pink.500)"
color="white"
borderRadius="full"
px={2}
>
<TagLabel fontSize="xs">{stock.stock_name}</TagLabel>
</Tag>
))}
{concept.stocks.length > 2 && (
<Text fontSize="xs" color="purple.600" fontWeight="medium">
+{concept.stocks.length - 2}更多
<Text fontSize="xs" color="purple.600" fontWeight="bold">
+{concept.stocks.length - 2}
</Text>
)}
</>
@@ -862,36 +965,41 @@ const ConceptCenter = () => {
</Box>
)}
<Divider />
<Divider borderColor="purple.100" />
<Flex width="100%" justify="space-between" align="center">
{formatHappenedTimes(concept.happened_times)}
<Button
size="sm"
leftIcon={<FaChartLine />} // 改成时间轴图标
colorScheme="purple" // 改成紫色主题
leftIcon={<FaHistory />}
bgGradient="linear(to-r, purple.500, pink.500)"
color="white"
variant="solid"
onClick={(e) => handleViewContent(e, concept.concept, concept.concept_id)} // 传入concept_id
onClick={(e) => handleViewContent(e, concept.concept, concept.concept_id)}
borderRadius="full"
px={4}
fontWeight="medium"
boxShadow="sm"
_hover={{ transform: 'scale(1.05)', boxShadow: 'md' }}
boxShadow="0 4px 12px rgba(139, 92, 246, 0.3)"
_hover={{
transform: 'scale(1.05)',
boxShadow: '0 6px 16px rgba(139, 92, 246, 0.4)',
}}
transition="all 0.2s"
>
历史时间轴 {/* 改按钮文字 */}
时间轴
</Button>
</Flex>
</VStack>
</CardBody>
{/* 顶部发光条 */}
<Box
position="absolute"
top={0}
left={0}
right={0}
height="3px"
height="2px"
bgGradient="linear(to-r, purple.400, pink.400, blue.400)"
opacity={0}
_groupHover={{ opacity: 1 }}
@@ -1078,216 +1186,241 @@ const ConceptCenter = () => {
</Card>
);
// 日期选择组件
// 日期选择组件 - 科幻风格
const DateSelector = () => (
<HStack spacing={4} p={4} bg="white" borderRadius="lg" shadow="sm">
<Icon as={FaCalendarAlt} color="purple.500" />
<Text fontWeight="medium" color="gray.700">交易日期</Text>
<Box
p={4}
bg="rgba(255, 255, 255, 0.8)"
backdropFilter="blur(10px)"
borderRadius="xl"
border="1px solid"
borderColor="purple.100"
boxShadow="0 4px 20px rgba(139, 92, 246, 0.1)"
>
<Flex
direction={{ base: 'column', lg: 'row' }}
align={{ base: 'stretch', lg: 'center' }}
gap={4}
>
<HStack spacing={3}>
<Icon as={FaCalendarAlt} color="purple.500" boxSize={5} />
<Text fontWeight="bold" color="purple.700">交易日期</Text>
</HStack>
<Input
type="date"
value={selectedDate ? selectedDate.toISOString().split('T')[0] : ''}
onChange={handleDateChange}
max={new Date().toISOString().split('T')[0]}
width="200px"
focusBorderColor="purple.500"
/>
<Input
type="date"
value={selectedDate ? selectedDate.toISOString().split('T')[0] : ''}
onChange={handleDateChange}
max={new Date().toISOString().split('T')[0]}
width={{ base: '100%', lg: '200px' }}
focusBorderColor="purple.500"
borderColor="purple.200"
borderRadius="lg"
fontWeight="medium"
/>
<ButtonGroup size="sm" variant="outline">
<Button onClick={() => handleQuickDateSelect(0)} colorScheme="purple">
今天
</Button>
<Button onClick={() => handleQuickDateSelect(1)} colorScheme="purple">
昨天
</Button>
<Button onClick={() => handleQuickDateSelect(7)} colorScheme="purple">
一周前
</Button>
<Button onClick={() => handleQuickDateSelect(30)} colorScheme="purple">
一月前
</Button>
</ButtonGroup>
<ButtonGroup size="sm" variant="outline" flexWrap="wrap">
<Button
onClick={() => handleQuickDateSelect(0)}
borderColor="purple.300"
color="purple.600"
borderRadius="full"
_hover={{
bg: 'purple.50',
borderColor: 'purple.400',
}}
>
今天
</Button>
<Button
onClick={() => handleQuickDateSelect(1)}
borderColor="purple.300"
color="purple.600"
borderRadius="full"
_hover={{
bg: 'purple.50',
borderColor: 'purple.400',
}}
>
昨天
</Button>
<Button
onClick={() => handleQuickDateSelect(7)}
borderColor="purple.300"
color="purple.600"
borderRadius="full"
_hover={{
bg: 'purple.50',
borderColor: 'purple.400',
}}
>
一周前
</Button>
<Button
onClick={() => handleQuickDateSelect(30)}
borderColor="purple.300"
color="purple.600"
borderRadius="full"
_hover={{
bg: 'purple.50',
borderColor: 'purple.400',
}}
>
一月前
</Button>
</ButtonGroup>
{latestTradeDate && (
<Tooltip label="数据库中最新的交易日期">
<HStack spacing={2} ml={4}>
<Icon as={InfoIcon} color="blue.500" />
<Text fontSize="sm" color="blue.600">
最新数据: {latestTradeDate.toLocaleDateString('zh-CN')}
</Text>
</HStack>
</Tooltip>
)}
</HStack>
{latestTradeDate && (
<Tooltip label="数据库中最新的交易日期">
<HStack
spacing={2}
bg="blue.50"
px={3}
py={1.5}
borderRadius="full"
border="1px solid"
borderColor="blue.200"
>
<Icon as={InfoIcon} color="blue.500" boxSize={3} />
<Text fontSize="sm" color="blue.600" fontWeight="medium">
最新: {latestTradeDate.toLocaleDateString('zh-CN')}
</Text>
</HStack>
</Tooltip>
)}
</Flex>
</Box>
);
return (
<Box minH="100vh" bg="gray.50">
<Box minH="100vh" bg="linear-gradient(180deg, #f8f9ff 0%, #f0f2ff 100%)">
{/* 导航栏已由 MainLayout 提供 */}
{/* Hero Section */}
{/* Hero Section - 精简版 */}
<Box
position="relative"
bgGradient="linear(135deg, #667eea 0%, #764ba2 100%)"
bgGradient="linear(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%)"
color="white"
overflow="hidden"
>
{/* 科幻网格背景 */}
<Box
position="absolute"
top="-50%"
left="-50%"
width="200%"
height="200%"
bgImage="radial-gradient(circle, rgba(255,255,255,0.1) 1px, transparent 1px)"
bgSize="50px 50px"
animation={`${floatAnimation} 20s ease-in-out infinite`}
top="0"
left="0"
right="0"
bottom="0"
bgImage="linear-gradient(rgba(99, 102, 241, 0.1) 1px, transparent 1px), linear-gradient(90deg, rgba(99, 102, 241, 0.1) 1px, transparent 1px)"
bgSize="40px 40px"
opacity={0.3}
/>
{/* 发光球体 */}
<Box
position="absolute"
top="10%"
top="20%"
right="10%"
width="300px"
height="300px"
width="200px"
height="200px"
borderRadius="full"
bgGradient="radial(purple.300, transparent)"
bgGradient="radial(circle, rgba(139, 92, 246, 0.4), transparent 70%)"
filter="blur(40px)"
opacity={0.6}
/>
<Box
position="absolute"
bottom="10%"
left="5%"
width="400px"
height="400px"
left="10%"
width="250px"
height="250px"
borderRadius="full"
bgGradient="radial(pink.300, transparent)"
filter="blur(60px)"
opacity={0.5}
bgGradient="radial(circle, rgba(59, 130, 246, 0.3), transparent 70%)"
filter="blur(50px)"
/>
<Container maxW="container.xl" position="relative" py={{ base: 12, md: 20 }}>
<VStack spacing={8}>
<VStack spacing={4} textAlign="center">
<HStack spacing={4} justify="center">
<Icon as={FaBrain} boxSize={16} color="yellow.300" />
<Container maxW="container.xl" position="relative" py={{ base: 8, md: 12 }}>
<VStack spacing={6}>
{/* 标题区域 */}
<VStack spacing={3} textAlign="center">
<HStack spacing={3} justify="center">
<Icon as={FaBrain} boxSize={10} color="cyan.300" filter="drop-shadow(0 0 10px rgba(6, 182, 212, 0.5))" />
</HStack>
<VStack spacing={2}>
<VStack spacing={1}>
<Heading
as="h1"
size="2xl"
fontSize={{ base: "3xl", md: "4xl" }}
fontWeight="black"
bgGradient="linear(to-r, white, yellow.200)"
bgGradient="linear(to-r, cyan.200, purple.200, pink.200)"
bgClip="text"
letterSpacing="tight"
lineHeight="shorter"
textShadow="0 0 30px rgba(147, 197, 253, 0.3)"
>
概念中心
</Heading>
<HStack spacing={2} justify="center">
<Icon as={FaClock} boxSize={4} color="yellow.200" />
<Text fontSize="sm" fontWeight="medium" opacity={0.95}>
约下午4点更新
<Icon as={FaClock} boxSize={3} color="cyan.200" />
<Text fontSize="xs" fontWeight="medium" opacity={0.8}>
数据约下午4点更新
</Text>
</HStack>
<Text fontSize="2xl" fontWeight="medium" opacity={0.95}>
大模型辅助的信息整理与呈现平台
</Text>
<Text fontSize="lg" opacity={0.8} maxW="3xl" lineHeight="tall">
以大模型协助汇聚与清洗多源信息结合自主训练的领域知识图谱
<br />
并由资深分析师进行人工整合与校准提供结构化参考信息
</Text>
</VStack>
<Text fontSize="md" opacity={0.7} maxW="2xl">
AI驱动的概念板块分析平台 · 实时追踪市场热点 · 智能挖掘投资机会
</Text>
</VStack>
<SimpleGrid columns={{ base: 2, md: 4 }} spacing={6} w="full" maxW="4xl">
<VStack
bg="whiteAlpha.100"
backdropFilter="blur(10px)"
p={6}
borderRadius="xl"
border="1px solid"
borderColor="whiteAlpha.300"
spacing={3}
>
<Icon as={BsLightningFill} boxSize={8} color="yellow.300" />
<Text fontWeight="bold" fontSize="lg">实时更新</Text>
<Text fontSize="sm" opacity={0.8} textAlign="center">
毫秒级数据同步
</Text>
</VStack>
<VStack
bg="whiteAlpha.100"
backdropFilter="blur(10px)"
p={6}
borderRadius="xl"
border="1px solid"
borderColor="whiteAlpha.300"
spacing={3}
>
<Icon as={FaRocket} boxSize={8} color="cyan.300" />
<Text fontWeight="bold" fontSize="lg">智能追踪</Text>
<Text fontSize="sm" opacity={0.8} textAlign="center">
算法智能追踪
</Text>
</VStack>
<VStack
bg="whiteAlpha.100"
backdropFilter="blur(10px)"
p={6}
borderRadius="xl"
border="1px solid"
borderColor="whiteAlpha.300"
spacing={3}
>
<Icon as={FaLightbulb} boxSize={8} color="orange.300" />
<Text fontWeight="bold" fontSize="lg">深度分析</Text>
<Text fontSize="sm" opacity={0.8} textAlign="center">
多维度数据挖掘
</Text>
</VStack>
<VStack
bg="whiteAlpha.100"
backdropFilter="blur(10px)"
p={6}
borderRadius="xl"
border="1px solid"
borderColor="whiteAlpha.300"
spacing={3}
>
<Icon as={FaShieldAlt} boxSize={8} color="green.300" />
<Text fontWeight="bold" fontSize="lg">专业可靠</Text>
<Text fontSize="sm" opacity={0.8} textAlign="center">
权威数据源保障
</Text>
</VStack>
</SimpleGrid>
<HStack spacing={8} divider={<Divider orientation="vertical" height="40px" borderColor="whiteAlpha.400" />}>
<VStack>
<Text fontSize="3xl" fontWeight="bold" color="yellow.300">500+</Text>
<Text fontSize="sm" opacity={0.8}>概念板块</Text>
</VStack>
<VStack>
<Text fontSize="3xl" fontWeight="bold" color="cyan.300">5000+</Text>
<Text fontSize="sm" opacity={0.8}>相关个股</Text>
</VStack>
<VStack>
<Text fontSize="3xl" fontWeight="bold" color="pink.300">24/7</Text>
<Text fontSize="sm" opacity={0.8}>全天候监控</Text>
</VStack>
{/* 核心数据展示 */}
<HStack
spacing={6}
divider={<Box w="1px" h="30px" bg="whiteAlpha.300" />}
bg="whiteAlpha.100"
backdropFilter="blur(10px)"
px={8}
py={3}
borderRadius="full"
border="1px solid"
borderColor="whiteAlpha.300"
boxShadow="0 8px 32px rgba(0, 0, 0, 0.3)"
>
<HStack spacing={2}>
<Icon as={FaTags} boxSize={4} color="cyan.300" />
<VStack spacing={0} align="start">
<Text fontSize="xl" fontWeight="bold" color="cyan.300">500+</Text>
<Text fontSize="xs" opacity={0.7}>概念板块</Text>
</VStack>
</HStack>
<HStack spacing={2}>
<Icon as={FaChartLine} boxSize={4} color="purple.300" />
<VStack spacing={0} align="start">
<Text fontSize="xl" fontWeight="bold" color="purple.300">5000+</Text>
<Text fontSize="xs" opacity={0.7}>相关个股</Text>
</VStack>
</HStack>
<HStack spacing={2}>
<Icon as={BsLightningFill} boxSize={4} color="yellow.300" />
<VStack spacing={0} align="start">
<Text fontSize="xl" fontWeight="bold" color="yellow.300">24/7</Text>
<Text fontSize="xs" opacity={0.7}>实时监控</Text>
</VStack>
</HStack>
</HStack>
{/* 搜索框 */}
<Box w="100%" maxW="3xl">
<VStack spacing={2}>
<Box w="100%" position="relative">
<HStack spacing={0} w="100%" boxShadow="2xl" borderRadius="full" overflow="hidden" bg="white">
<HStack
spacing={0}
w="100%"
boxShadow="0 8px 32px rgba(0, 0, 0, 0.4)"
borderRadius="full"
overflow="hidden"
bg="rgba(255, 255, 255, 0.95)"
backdropFilter="blur(10px)"
border="1px solid"
borderColor="whiteAlpha.400"
>
<InputGroup size="lg" flex={1}>
<InputLeftElement pointerEvents="none">
<SearchIcon color="gray.400" />
@@ -1330,7 +1463,8 @@ const ConceptCenter = () => {
bgGradient="linear(to-r, purple.500, pink.500)"
color="white"
_hover={{
bgGradient: 'linear(to-r, purple.600, pink.600)'
bgGradient: 'linear(to-r, purple.600, pink.600)',
boxShadow: '0 0 20px rgba(168, 85, 247, 0.4)'
}}
_active={{
bgGradient: 'linear(to-r, purple.700, pink.700)',
@@ -1349,7 +1483,7 @@ const ConceptCenter = () => {
</HStack>
</Box>
{searchQuery && sortBy === '_score' && (
<Text fontSize="xs" color="yellow.200" opacity={0.9}>
<Text fontSize="xs" color="cyan.200" opacity={0.9}>
正在搜索 "{searchQuery}"已自动切换到相关度排序
</Text>
)}
@@ -1370,7 +1504,14 @@ const ConceptCenter = () => {
{/* 左侧概念卡片区域 */}
<Box flex={1}>
<Card mb={8} shadow="sm">
<Card
mb={8}
bg="rgba(255, 255, 255, 0.8)"
backdropFilter="blur(10px)"
border="1px solid"
borderColor="purple.100"
boxShadow="0 4px 20px rgba(139, 92, 246, 0.1)"
>
<CardBody>
<Flex
direction={{ base: 'column', md: 'row' }}
@@ -1379,12 +1520,16 @@ const ConceptCenter = () => {
gap={4}
>
<HStack spacing={4} align="center">
<Text fontWeight="medium" color="gray.700">排序方式</Text>
<Icon as={FaTags} boxSize={4} color="purple.500" />
<Text fontWeight="bold" color="purple.700">排序方式</Text>
<Select
value={sortBy}
onChange={(e) => handleSortChange(e.target.value)}
width="200px"
focusBorderColor="purple.500"
borderColor="purple.200"
borderRadius="lg"
fontWeight="medium"
>
<option value="change_pct">涨跌幅</option>
<option value="_score">相关度</option>
@@ -1393,9 +1538,17 @@ const ConceptCenter = () => {
</Select>
{searchQuery && sortBy === '_score' && (
<Tooltip label="搜索时自动切换到相关度排序,以显示最匹配的结果。您也可以手动切换其他排序方式。">
<HStack spacing={1}>
<Icon as={InfoIcon} color="blue.500" boxSize={4} />
<Text fontSize="sm" color="blue.600">
<HStack
spacing={1}
bg="blue.50"
px={3}
py={1}
borderRadius="full"
border="1px solid"
borderColor="blue.200"
>
<Icon as={InfoIcon} color="blue.500" boxSize={3} />
<Text fontSize="xs" color="blue.600" fontWeight="medium">
智能排序
</Text>
</HStack>
@@ -1412,10 +1565,13 @@ const ConceptCenter = () => {
setViewMode('grid');
}
}}
bg={viewMode === 'grid' ? 'purple.500' : 'transparent'}
bg={viewMode === 'grid' ? 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' : 'transparent'}
color={viewMode === 'grid' ? 'white' : 'purple.500'}
borderColor="purple.500"
_hover={{ bg: viewMode === 'grid' ? 'purple.600' : 'purple.50' }}
_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',
}}
aria-label="网格视图"
/>
<IconButton
@@ -1426,10 +1582,13 @@ const ConceptCenter = () => {
setViewMode('list');
}
}}
bg={viewMode === 'list' ? 'purple.500' : 'transparent'}
bg={viewMode === 'list' ? 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' : 'transparent'}
color={viewMode === 'list' ? 'white' : 'purple.500'}
borderColor="purple.500"
_hover={{ bg: viewMode === 'list' ? 'purple.600' : 'purple.50' }}
_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',
}}
aria-label="列表视图"
/>
</ButtonGroup>
@@ -1474,18 +1633,39 @@ const ConceptCenter = () => {
)}
<Center mt={12}>
<HStack spacing={2}>
<HStack
spacing={3}
bg="rgba(255, 255, 255, 0.8)"
backdropFilter="blur(10px)"
px={6}
py={3}
borderRadius="full"
border="1px solid"
borderColor="purple.100"
boxShadow="0 4px 20px rgba(139, 92, 246, 0.15)"
>
<Button
size="sm"
onClick={() => handlePageChange(Math.max(1, currentPage - 1))}
isDisabled={currentPage === 1}
colorScheme="purple"
variant="outline"
bgGradient="linear(to-r, purple.500, pink.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)',
}}
_disabled={{
bg: 'gray.200',
color: 'gray.400',
cursor: 'not-allowed',
}}
>
上一页
</Button>
<HStack>
<HStack spacing={2}>
{[...Array(Math.min(5, totalPages))].map((_, i) => {
const pageNum = currentPage <= 3 ? i + 1 :
currentPage >= totalPages - 2 ? totalPages - 4 + i :
@@ -1496,8 +1676,16 @@ const ConceptCenter = () => {
key={pageNum}
size="sm"
onClick={() => handlePageChange(pageNum)}
colorScheme="purple"
variant={pageNum === currentPage ? 'solid' : 'outline'}
bg={pageNum === currentPage ? 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' : 'transparent'}
color={pageNum === currentPage ? 'white' : 'purple.600'}
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',
}}
>
{pageNum}
</Button>
@@ -1509,8 +1697,19 @@ const ConceptCenter = () => {
size="sm"
onClick={() => handlePageChange(Math.min(totalPages, currentPage + 1))}
isDisabled={currentPage === totalPages}
colorScheme="purple"
variant="outline"
bgGradient="linear(to-r, purple.500, pink.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)',
}}
_disabled={{
bg: 'gray.200',
color: 'gray.400',
cursor: 'not-allowed',
}}
>
下一页
</Button>