heropanel修改
This commit is contained in:
@@ -64,121 +64,113 @@ const getChgColor = (val) => {
|
||||
* 获取胜率颜色(>50%红色,<50%绿色)
|
||||
*/
|
||||
const getRateColor = (rate) => {
|
||||
if (rate >= 50) return '#FF4D4F'; // 红色(上涨多)
|
||||
return '#52C41A'; // 绿色(下跌多)
|
||||
if (rate >= 50) return '#F31260'; // HeroUI 红色
|
||||
return '#17C964'; // HeroUI 绿色
|
||||
};
|
||||
|
||||
/**
|
||||
* 半圆仪表盘组件 - 使用 SVG 实现渐变弧线
|
||||
* 渐变色:左侧绿色 -> 中间黄色 -> 右侧红色
|
||||
* HeroUI 风格圆环仪表盘
|
||||
*/
|
||||
const SemiCircleGauge = ({ rate, label, size = 'normal' }) => {
|
||||
const CircularGauge = ({ rate, label, icon }) => {
|
||||
const validRate = Math.min(100, Math.max(0, rate || 0));
|
||||
// 角度:0% = -90deg (左), 50% = 0deg (上), 100% = 90deg (右)
|
||||
const needleAngle = (validRate / 100) * 180 - 90;
|
||||
|
||||
const gaugeColor = getRateColor(validRate);
|
||||
const isSmall = size === 'small';
|
||||
const svgSize = isSmall ? 80 : 100;
|
||||
const strokeWidth = isSmall ? 6 : 8;
|
||||
const radius = (svgSize - strokeWidth) / 2;
|
||||
const needleLength = isSmall ? 28 : 35;
|
||||
const gradientId = `gauge-gradient-${label.replace(/\s/g, '-')}`;
|
||||
|
||||
// 计算半圆弧的路径(从左到右)
|
||||
const arcPath = `M ${strokeWidth / 2} ${svgSize / 2} A ${radius} ${radius} 0 0 1 ${svgSize - strokeWidth / 2} ${svgSize / 2}`;
|
||||
const circumference = 2 * Math.PI * 42; // 半径42
|
||||
const strokeDashoffset = circumference - (validRate / 100) * circumference;
|
||||
|
||||
return (
|
||||
<Box position="relative" w={`${svgSize}px`} h={`${svgSize / 2 + 18}px`}>
|
||||
{/* SVG 半圆弧 */}
|
||||
<svg
|
||||
width={svgSize}
|
||||
height={svgSize / 2 + 2}
|
||||
style={{ position: 'absolute', top: 0, left: 0 }}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id={gradientId} x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stopColor="#52C41A" />
|
||||
<stop offset="50%" stopColor="#FADB14" />
|
||||
<stop offset="100%" stopColor="#FF4D4F" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
d={arcPath}
|
||||
fill="none"
|
||||
stroke={`url(#${gradientId})`}
|
||||
strokeWidth={strokeWidth}
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
</svg>
|
||||
<Box
|
||||
bg="rgba(255,255,255,0.03)"
|
||||
backdropFilter="blur(20px)"
|
||||
borderRadius="2xl"
|
||||
p={4}
|
||||
border="1px solid"
|
||||
borderColor="rgba(255,255,255,0.08)"
|
||||
position="relative"
|
||||
overflow="hidden"
|
||||
flex="1"
|
||||
_before={{
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
background: `radial-gradient(circle at 30% 20%, ${gaugeColor}15 0%, transparent 50%)`,
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
>
|
||||
{/* 圆环仪表盘 */}
|
||||
<Center>
|
||||
<Box position="relative" w="100px" h="100px">
|
||||
<svg width="100" height="100" style={{ transform: 'rotate(-90deg)' }}>
|
||||
{/* 背景圆环 */}
|
||||
<circle
|
||||
cx="50"
|
||||
cy="50"
|
||||
r="42"
|
||||
fill="none"
|
||||
stroke="rgba(255,255,255,0.08)"
|
||||
strokeWidth="8"
|
||||
/>
|
||||
{/* 渐变定义 */}
|
||||
<defs>
|
||||
<linearGradient id={`gauge-grad-${label}`} x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stopColor={gaugeColor} stopOpacity="0.6" />
|
||||
<stop offset="100%" stopColor={gaugeColor} />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
{/* 进度圆环 */}
|
||||
<circle
|
||||
cx="50"
|
||||
cy="50"
|
||||
r="42"
|
||||
fill="none"
|
||||
stroke={`url(#gauge-grad-${label})`}
|
||||
strokeWidth="8"
|
||||
strokeLinecap="round"
|
||||
strokeDasharray={circumference}
|
||||
strokeDashoffset={strokeDashoffset}
|
||||
style={{
|
||||
transition: 'stroke-dashoffset 0.8s ease-out',
|
||||
filter: `drop-shadow(0 0 8px ${gaugeColor}60)`,
|
||||
}}
|
||||
/>
|
||||
</svg>
|
||||
{/* 中心数值 */}
|
||||
<VStack
|
||||
position="absolute"
|
||||
top="50%"
|
||||
left="50%"
|
||||
transform="translate(-50%, -50%)"
|
||||
spacing={0}
|
||||
>
|
||||
<Text
|
||||
fontSize="2xl"
|
||||
fontWeight="bold"
|
||||
color={gaugeColor}
|
||||
lineHeight="1"
|
||||
textShadow={`0 0 20px ${gaugeColor}40`}
|
||||
>
|
||||
{validRate.toFixed(1)}
|
||||
</Text>
|
||||
<Text fontSize="xs" color="whiteAlpha.600">%</Text>
|
||||
</VStack>
|
||||
</Box>
|
||||
</Center>
|
||||
|
||||
{/* 指针 */}
|
||||
<Box
|
||||
position="absolute"
|
||||
bottom="18px"
|
||||
left="50%"
|
||||
w="2px"
|
||||
h={`${needleLength}px`}
|
||||
bg={gaugeColor}
|
||||
borderRadius="full"
|
||||
transformOrigin="bottom center"
|
||||
transform={`translateX(-50%) rotate(${needleAngle}deg)`}
|
||||
boxShadow={`0 0 6px ${gaugeColor}`}
|
||||
transition="transform 0.5s ease-out"
|
||||
/>
|
||||
|
||||
{/* 指针中心点 */}
|
||||
<Box
|
||||
position="absolute"
|
||||
bottom="15px"
|
||||
left="50%"
|
||||
transform="translateX(-50%)"
|
||||
w="6px"
|
||||
h="6px"
|
||||
bg={gaugeColor}
|
||||
borderRadius="full"
|
||||
boxShadow={`0 0 4px ${gaugeColor}`}
|
||||
/>
|
||||
|
||||
{/* 刻度标记 */}
|
||||
<Text
|
||||
position="absolute"
|
||||
bottom="18px"
|
||||
left="2px"
|
||||
fontSize="2xs"
|
||||
color="gray.600"
|
||||
>
|
||||
0
|
||||
</Text>
|
||||
<Text
|
||||
position="absolute"
|
||||
bottom="18px"
|
||||
right="2px"
|
||||
fontSize="2xs"
|
||||
color="gray.600"
|
||||
>
|
||||
100
|
||||
</Text>
|
||||
|
||||
{/* 数值和标签 */}
|
||||
<VStack
|
||||
position="absolute"
|
||||
bottom="0"
|
||||
left="50%"
|
||||
transform="translateX(-50%)"
|
||||
spacing={0}
|
||||
>
|
||||
<Text fontSize={isSmall ? 'sm' : 'md'} fontWeight="bold" color={gaugeColor} lineHeight="1">
|
||||
{validRate.toFixed(1)}%
|
||||
{/* 标签 */}
|
||||
<HStack justify="center" mt={2} spacing={2}>
|
||||
<Box color={gaugeColor} fontSize="sm">{icon}</Box>
|
||||
<Text fontSize="sm" color="whiteAlpha.800" fontWeight="medium">
|
||||
{label}
|
||||
</Text>
|
||||
<Text fontSize="2xs" color="gray.500">{label}</Text>
|
||||
</VStack>
|
||||
</HStack>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 胜率对比组件 - 双仪表盘
|
||||
* HeroUI 风格胜率对比面板
|
||||
*/
|
||||
const WinRateGauge = ({ eventRate, marketRate, marketStats }) => {
|
||||
const eventRateVal = eventRate || 0;
|
||||
@@ -186,60 +178,122 @@ const WinRateGauge = ({ eventRate, marketRate, marketStats }) => {
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{/* 双仪表盘对比 */}
|
||||
<HStack spacing={2} justify="center" mb={1}>
|
||||
<VStack spacing={0}>
|
||||
<SemiCircleGauge rate={eventRateVal} label="事件胜率" size="small" />
|
||||
</VStack>
|
||||
<Box w="1px" h="50px" bg="rgba(255,215,0,0.2)" />
|
||||
<VStack spacing={0}>
|
||||
<SemiCircleGauge rate={marketRateVal} label="大盘上涨率" size="small" />
|
||||
</VStack>
|
||||
{/* 双仪表盘对比 - HeroUI 毛玻璃卡片 */}
|
||||
<HStack spacing={4} mb={4}>
|
||||
<CircularGauge
|
||||
rate={eventRateVal}
|
||||
label="事件胜率"
|
||||
icon={<TrophyOutlined />}
|
||||
/>
|
||||
<CircularGauge
|
||||
rate={marketRateVal}
|
||||
label="大盘上涨率"
|
||||
icon={<RiseOutlined />}
|
||||
/>
|
||||
</HStack>
|
||||
|
||||
{/* 市场统计 */}
|
||||
{marketStats && (
|
||||
<HStack justify="center" spacing={3} mt={1}>
|
||||
<HStack spacing={1}>
|
||||
<Box w="6px" h="6px" borderRadius="full" bg="#FF4D4F" />
|
||||
<Text fontSize="2xs" color="#FF4D4F">{marketStats.risingCount}涨</Text>
|
||||
{/* 市场统计 - 毛玻璃条 */}
|
||||
{marketStats && marketStats.totalCount > 0 && (
|
||||
<Box
|
||||
bg="rgba(255,255,255,0.03)"
|
||||
backdropFilter="blur(10px)"
|
||||
borderRadius="xl"
|
||||
p={3}
|
||||
border="1px solid rgba(255,255,255,0.06)"
|
||||
>
|
||||
<HStack justify="space-between" mb={2}>
|
||||
<Text fontSize="xs" color="whiteAlpha.500">沪深两市实时</Text>
|
||||
<Text fontSize="xs" color="whiteAlpha.400">{marketStats.totalCount} 只</Text>
|
||||
</HStack>
|
||||
<HStack spacing={1}>
|
||||
<Box w="6px" h="6px" borderRadius="full" bg="gray.400" />
|
||||
<Text fontSize="2xs" color="gray.400">{marketStats.flatCount}平</Text>
|
||||
{/* 进度条 */}
|
||||
<Box position="relative" h="6px" borderRadius="full" overflow="hidden" bg="rgba(255,255,255,0.05)">
|
||||
<Box
|
||||
position="absolute"
|
||||
left="0"
|
||||
top="0"
|
||||
h="100%"
|
||||
w={`${(marketStats.risingCount / marketStats.totalCount) * 100}%`}
|
||||
bg="linear-gradient(90deg, #F31260, #FF6B9D)"
|
||||
borderRadius="full"
|
||||
/>
|
||||
<Box
|
||||
position="absolute"
|
||||
left={`${(marketStats.risingCount / marketStats.totalCount) * 100}%`}
|
||||
top="0"
|
||||
h="100%"
|
||||
w={`${(marketStats.flatCount / marketStats.totalCount) * 100}%`}
|
||||
bg="rgba(255,255,255,0.3)"
|
||||
/>
|
||||
</Box>
|
||||
{/* 数字统计 */}
|
||||
<HStack justify="space-between" mt={2}>
|
||||
<HStack spacing={1}>
|
||||
<Box w="8px" h="8px" borderRadius="full" bg="#F31260" boxShadow="0 0 8px #F3126060" />
|
||||
<Text fontSize="sm" color="#FF6B9D" fontWeight="bold">{marketStats.risingCount}</Text>
|
||||
<Text fontSize="xs" color="whiteAlpha.500">涨</Text>
|
||||
</HStack>
|
||||
<HStack spacing={1}>
|
||||
<Box w="8px" h="8px" borderRadius="full" bg="whiteAlpha.400" />
|
||||
<Text fontSize="sm" color="whiteAlpha.700" fontWeight="bold">{marketStats.flatCount}</Text>
|
||||
<Text fontSize="xs" color="whiteAlpha.500">平</Text>
|
||||
</HStack>
|
||||
<HStack spacing={1}>
|
||||
<Box w="8px" h="8px" borderRadius="full" bg="#17C964" boxShadow="0 0 8px #17C96460" />
|
||||
<Text fontSize="sm" color="#17C964" fontWeight="bold">{marketStats.fallingCount}</Text>
|
||||
<Text fontSize="xs" color="whiteAlpha.500">跌</Text>
|
||||
</HStack>
|
||||
</HStack>
|
||||
<HStack spacing={1}>
|
||||
<Box w="6px" h="6px" borderRadius="full" bg="#52C41A" />
|
||||
<Text fontSize="2xs" color="#52C41A">{marketStats.fallingCount}跌</Text>
|
||||
</HStack>
|
||||
</HStack>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 紧凑数据卡片
|
||||
* HeroUI 风格紧凑数据卡片
|
||||
*/
|
||||
const CompactStatCard = ({ label, value, icon, color = '#FFD700', subText }) => (
|
||||
const CompactStatCard = ({ label, value, icon, color = '#7C3AED', subText }) => (
|
||||
<Box
|
||||
bg="rgba(0,0,0,0.25)"
|
||||
borderRadius="md"
|
||||
p={2}
|
||||
bg="rgba(255,255,255,0.03)"
|
||||
backdropFilter="blur(10px)"
|
||||
borderRadius="xl"
|
||||
p={3}
|
||||
border="1px solid"
|
||||
borderColor="rgba(255,215,0,0.12)"
|
||||
_hover={{ borderColor: 'rgba(255,215,0,0.25)' }}
|
||||
transition="all 0.2s"
|
||||
borderColor="rgba(255,255,255,0.06)"
|
||||
_hover={{
|
||||
borderColor: 'rgba(255,255,255,0.12)',
|
||||
bg: 'rgba(255,255,255,0.05)',
|
||||
transform: 'translateY(-2px)',
|
||||
}}
|
||||
transition="all 0.3s ease"
|
||||
position="relative"
|
||||
overflow="hidden"
|
||||
_before={{
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0,
|
||||
w: '60px',
|
||||
h: '60px',
|
||||
background: `radial-gradient(circle, ${color}15 0%, transparent 70%)`,
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
>
|
||||
<HStack spacing={1.5} mb={0.5}>
|
||||
<Box color={color} fontSize="xs">
|
||||
<HStack spacing={2} mb={1}>
|
||||
<Box
|
||||
color={color}
|
||||
fontSize="sm"
|
||||
p={1.5}
|
||||
borderRadius="lg"
|
||||
bg={`${color}15`}
|
||||
>
|
||||
{icon}
|
||||
</Box>
|
||||
<Text fontSize="2xs" color="gray.500" fontWeight="medium">
|
||||
<Text fontSize="xs" color="whiteAlpha.600" fontWeight="medium">
|
||||
{label}
|
||||
</Text>
|
||||
</HStack>
|
||||
<Text fontSize="md" fontWeight="bold" color={color} lineHeight="1.2">
|
||||
<Text fontSize="lg" fontWeight="bold" color={color} lineHeight="1.2" textShadow={`0 0 20px ${color}30`}>
|
||||
{value}
|
||||
</Text>
|
||||
{subText && (
|
||||
@@ -424,90 +478,137 @@ const EventDailyStats = () => {
|
||||
|
||||
return (
|
||||
<Box
|
||||
bg="linear-gradient(180deg, rgba(25, 32, 55, 0.95) 0%, rgba(17, 24, 39, 0.98) 100%)"
|
||||
borderRadius="xl"
|
||||
p={3}
|
||||
bg="linear-gradient(135deg, rgba(10, 10, 20, 0.9) 0%, rgba(20, 20, 40, 0.95) 50%, rgba(15, 15, 30, 0.9) 100%)"
|
||||
backdropFilter="blur(20px)"
|
||||
borderRadius="2xl"
|
||||
p={4}
|
||||
border="1px solid"
|
||||
borderColor="rgba(255, 215, 0, 0.15)"
|
||||
borderColor="rgba(255, 255, 255, 0.08)"
|
||||
position="relative"
|
||||
overflow="hidden"
|
||||
h="100%"
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
boxShadow="0 8px 32px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255,255,255,0.05)"
|
||||
>
|
||||
{/* 背景装饰 */}
|
||||
{/* 背景光效 */}
|
||||
<Box
|
||||
position="absolute"
|
||||
top="-30%"
|
||||
right="-20%"
|
||||
w="150px"
|
||||
h="150px"
|
||||
bg="radial-gradient(circle, rgba(255,215,0,0.06) 0%, transparent 70%)"
|
||||
top="-100px"
|
||||
right="-100px"
|
||||
w="300px"
|
||||
h="300px"
|
||||
bg="radial-gradient(circle, rgba(124, 58, 237, 0.15) 0%, transparent 60%)"
|
||||
pointerEvents="none"
|
||||
filter="blur(40px)"
|
||||
/>
|
||||
<Box
|
||||
position="absolute"
|
||||
bottom="-80px"
|
||||
left="-80px"
|
||||
w="250px"
|
||||
h="250px"
|
||||
bg="radial-gradient(circle, rgba(6, 182, 212, 0.1) 0%, transparent 60%)"
|
||||
pointerEvents="none"
|
||||
filter="blur(40px)"
|
||||
/>
|
||||
|
||||
{/* 标题行 */}
|
||||
<Flex justify="space-between" align="center" mb={2}>
|
||||
<HStack spacing={2}>
|
||||
<Flex justify="space-between" align="center" mb={4}>
|
||||
<HStack spacing={3}>
|
||||
<Box
|
||||
w="3px"
|
||||
h="16px"
|
||||
bg="linear-gradient(180deg, #FFD700, #FFA500)"
|
||||
w="4px"
|
||||
h="20px"
|
||||
bg="linear-gradient(180deg, #7C3AED, #06B6D4)"
|
||||
borderRadius="full"
|
||||
boxShadow="0 0 10px rgba(124, 58, 237, 0.5)"
|
||||
/>
|
||||
<Text fontSize="sm" fontWeight="bold" color="white" letterSpacing="wide">
|
||||
<Text fontSize="md" fontWeight="bold" color="white" letterSpacing="wide">
|
||||
{isToday ? '今日统计' : '历史统计'}
|
||||
</Text>
|
||||
{isToday && (
|
||||
<Badge colorScheme="yellow" variant="subtle" fontSize="2xs" px={1.5}>
|
||||
实时
|
||||
</Badge>
|
||||
)}
|
||||
</HStack>
|
||||
<HStack spacing={1}>
|
||||
{/* 今天按钮 - 仅在查看历史时显示 */}
|
||||
{!isToday && (
|
||||
<Box
|
||||
px={2}
|
||||
py={0.5}
|
||||
bg="rgba(255,215,0,0.15)"
|
||||
border="1px solid rgba(255,215,0,0.3)"
|
||||
borderRadius="md"
|
||||
cursor="pointer"
|
||||
_hover={{ bg: 'rgba(255,215,0,0.25)' }}
|
||||
onClick={() => setSelectedDate('')}
|
||||
bg="rgba(23, 201, 100, 0.15)"
|
||||
border="1px solid rgba(23, 201, 100, 0.3)"
|
||||
borderRadius="full"
|
||||
>
|
||||
<Text fontSize="xs" color="#FFD700" fontWeight="bold">今天</Text>
|
||||
<HStack spacing={1}>
|
||||
<Box
|
||||
w="6px"
|
||||
h="6px"
|
||||
borderRadius="full"
|
||||
bg="#17C964"
|
||||
animation="pulse 2s infinite"
|
||||
boxShadow="0 0 8px #17C964"
|
||||
/>
|
||||
<Text fontSize="xs" color="#17C964" fontWeight="medium">实时</Text>
|
||||
</HStack>
|
||||
</Box>
|
||||
)}
|
||||
<CalendarOutlined style={{ color: '#FFD700', fontSize: '12px' }} />
|
||||
<Input
|
||||
type="date"
|
||||
size="xs"
|
||||
value={selectedDate}
|
||||
onChange={handleDateChange}
|
||||
max={new Date().toISOString().split('T')[0]}
|
||||
bg="rgba(0,0,0,0.3)"
|
||||
border="1px solid rgba(255,215,0,0.2)"
|
||||
borderRadius="md"
|
||||
color="white"
|
||||
fontSize="xs"
|
||||
w="110px"
|
||||
h="24px"
|
||||
_hover={{ borderColor: 'rgba(255,215,0,0.4)' }}
|
||||
_focus={{ borderColor: '#FFD700', boxShadow: 'none' }}
|
||||
css={{
|
||||
'&::-webkit-calendar-picker-indicator': {
|
||||
filter: 'invert(1)',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</HStack>
|
||||
<HStack spacing={2}>
|
||||
{/* 今天按钮 - 仅在查看历史时显示 */}
|
||||
{!isToday && (
|
||||
<Box
|
||||
px={3}
|
||||
py={1}
|
||||
bg="rgba(124, 58, 237, 0.15)"
|
||||
border="1px solid rgba(124, 58, 237, 0.3)"
|
||||
borderRadius="lg"
|
||||
cursor="pointer"
|
||||
_hover={{ bg: 'rgba(124, 58, 237, 0.25)', transform: 'scale(1.02)' }}
|
||||
transition="all 0.2s"
|
||||
onClick={() => setSelectedDate('')}
|
||||
>
|
||||
<Text fontSize="xs" color="#A78BFA" fontWeight="bold">返回今天</Text>
|
||||
</Box>
|
||||
)}
|
||||
<Box
|
||||
as="label"
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
gap={2}
|
||||
px={3}
|
||||
py={1.5}
|
||||
bg="rgba(255,255,255,0.03)"
|
||||
border="1px solid rgba(255,255,255,0.08)"
|
||||
borderRadius="lg"
|
||||
cursor="pointer"
|
||||
_hover={{ bg: 'rgba(255,255,255,0.06)', borderColor: 'rgba(255,255,255,0.12)' }}
|
||||
transition="all 0.2s"
|
||||
>
|
||||
<CalendarOutlined style={{ color: 'rgba(255,255,255,0.6)', fontSize: '14px' }} />
|
||||
<Input
|
||||
type="date"
|
||||
size="xs"
|
||||
value={selectedDate}
|
||||
onChange={handleDateChange}
|
||||
max={new Date().toISOString().split('T')[0]}
|
||||
bg="transparent"
|
||||
border="none"
|
||||
color="whiteAlpha.800"
|
||||
fontSize="xs"
|
||||
w="100px"
|
||||
h="20px"
|
||||
p={0}
|
||||
_hover={{ border: 'none' }}
|
||||
_focus={{ border: 'none', boxShadow: 'none' }}
|
||||
css={{
|
||||
'&::-webkit-calendar-picker-indicator': {
|
||||
filter: 'invert(0.8)',
|
||||
cursor: 'pointer',
|
||||
opacity: 0.6,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</HStack>
|
||||
</Flex>
|
||||
|
||||
{/* 内容区域 - 使用 flex: 1 填充剩余空间 */}
|
||||
<VStack spacing={2} align="stretch" flex="1">
|
||||
<VStack spacing={4} align="stretch" flex="1">
|
||||
{/* 胜率对比仪表盘 */}
|
||||
<WinRateGauge
|
||||
eventRate={summary?.positiveRate || 0}
|
||||
|
||||
@@ -2537,41 +2537,77 @@ const CombinedCalendar = () => {
|
||||
};
|
||||
|
||||
/**
|
||||
* 右侧 Tab 面板 - 连板情绪监测 / 综合日历
|
||||
* 右侧 Tab 面板 - HeroUI 风格毛玻璃
|
||||
*/
|
||||
const RightPanelTabs = () => {
|
||||
const [activeTab, setActiveTab] = useState('comet');
|
||||
// 默认显示日历
|
||||
const [activeTab, setActiveTab] = useState('calendar');
|
||||
|
||||
return (
|
||||
<Box
|
||||
bg="linear-gradient(180deg, rgba(25, 32, 55, 0.95) 0%, rgba(17, 24, 39, 0.98) 100%)"
|
||||
borderRadius="xl"
|
||||
bg="linear-gradient(135deg, rgba(10, 10, 20, 0.9) 0%, rgba(20, 20, 40, 0.95) 50%, rgba(15, 15, 30, 0.9) 100%)"
|
||||
backdropFilter="blur(20px)"
|
||||
borderRadius="2xl"
|
||||
border="1px solid"
|
||||
borderColor="rgba(255, 215, 0, 0.15)"
|
||||
borderColor="rgba(255, 255, 255, 0.08)"
|
||||
h="100%"
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
overflow="hidden"
|
||||
boxShadow="0 8px 32px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255,255,255,0.05)"
|
||||
position="relative"
|
||||
>
|
||||
{/* 背景光效 */}
|
||||
<Box
|
||||
position="absolute"
|
||||
top="-50px"
|
||||
left="-50px"
|
||||
w="200px"
|
||||
h="200px"
|
||||
bg="radial-gradient(circle, rgba(6, 182, 212, 0.1) 0%, transparent 60%)"
|
||||
pointerEvents="none"
|
||||
filter="blur(40px)"
|
||||
/>
|
||||
|
||||
{/* Tab 切换头 */}
|
||||
<HStack
|
||||
px={4}
|
||||
py={2}
|
||||
borderBottom="1px solid rgba(255,215,0,0.1)"
|
||||
py={3}
|
||||
borderBottom="1px solid rgba(255,255,255,0.06)"
|
||||
bg="rgba(0,0,0,0.2)"
|
||||
spacing={0}
|
||||
spacing={2}
|
||||
>
|
||||
<Box
|
||||
px={4}
|
||||
py={2}
|
||||
cursor="pointer"
|
||||
borderRadius="md"
|
||||
bg={activeTab === 'comet' ? 'rgba(255,215,0,0.15)' : 'transparent'}
|
||||
color={activeTab === 'comet' ? '#FFD700' : 'gray.400'}
|
||||
borderRadius="xl"
|
||||
bg={activeTab === 'calendar' ? 'rgba(124, 58, 237, 0.2)' : 'transparent'}
|
||||
color={activeTab === 'calendar' ? '#A78BFA' : 'whiteAlpha.500'}
|
||||
fontWeight={activeTab === 'calendar' ? 'bold' : 'normal'}
|
||||
fontSize="sm"
|
||||
transition="all 0.3s ease"
|
||||
border={activeTab === 'calendar' ? '1px solid rgba(124, 58, 237, 0.3)' : '1px solid transparent'}
|
||||
_hover={{ color: '#A78BFA', bg: 'rgba(124, 58, 237, 0.1)' }}
|
||||
onClick={() => setActiveTab('calendar')}
|
||||
>
|
||||
<HStack spacing={2}>
|
||||
<CalendarOutlined />
|
||||
<Text>涨停与未来日历</Text>
|
||||
</HStack>
|
||||
</Box>
|
||||
<Box
|
||||
px={4}
|
||||
py={2}
|
||||
cursor="pointer"
|
||||
borderRadius="xl"
|
||||
bg={activeTab === 'comet' ? 'rgba(6, 182, 212, 0.2)' : 'transparent'}
|
||||
color={activeTab === 'comet' ? '#22D3EE' : 'whiteAlpha.500'}
|
||||
fontWeight={activeTab === 'comet' ? 'bold' : 'normal'}
|
||||
fontSize="sm"
|
||||
transition="all 0.2s"
|
||||
_hover={{ color: '#FFD700', bg: 'rgba(255,215,0,0.08)' }}
|
||||
transition="all 0.3s ease"
|
||||
border={activeTab === 'comet' ? '1px solid rgba(6, 182, 212, 0.3)' : '1px solid transparent'}
|
||||
_hover={{ color: '#22D3EE', bg: 'rgba(6, 182, 212, 0.1)' }}
|
||||
onClick={() => setActiveTab('comet')}
|
||||
>
|
||||
<HStack spacing={2}>
|
||||
@@ -2579,32 +2615,18 @@ const RightPanelTabs = () => {
|
||||
<Text>连板情绪监测</Text>
|
||||
</HStack>
|
||||
</Box>
|
||||
<Box
|
||||
px={4}
|
||||
py={2}
|
||||
cursor="pointer"
|
||||
borderRadius="md"
|
||||
bg={activeTab === 'calendar' ? 'rgba(255,215,0,0.15)' : 'transparent'}
|
||||
color={activeTab === 'calendar' ? '#FFD700' : 'gray.400'}
|
||||
fontWeight={activeTab === 'calendar' ? 'bold' : 'normal'}
|
||||
fontSize="sm"
|
||||
transition="all 0.2s"
|
||||
_hover={{ color: '#FFD700', bg: 'rgba(255,215,0,0.08)' }}
|
||||
onClick={() => setActiveTab('calendar')}
|
||||
>
|
||||
<HStack spacing={2}>
|
||||
<CalendarOutlined />
|
||||
<Text>事件日历</Text>
|
||||
</HStack>
|
||||
</Box>
|
||||
</HStack>
|
||||
|
||||
{/* Tab 内容区域 */}
|
||||
<Box flex="1" minH={0} p={3}>
|
||||
{/* Tab 内容区域 - 固定高度确保一致 */}
|
||||
<Box flex="1" minH="650px" p={3} overflow="hidden">
|
||||
{activeTab === 'comet' ? (
|
||||
<ThemeCometChart />
|
||||
<Box h="100%">
|
||||
<ThemeCometChart />
|
||||
</Box>
|
||||
) : (
|
||||
<CombinedCalendar />
|
||||
<Box h="100%">
|
||||
<CombinedCalendar />
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user