update pay function

This commit is contained in:
2025-11-30 23:58:06 +08:00
parent a72978c200
commit ff9c68295b

View File

@@ -192,115 +192,186 @@ const CompactIndexCard = ({ indexCode, indexName }) => {
};
/**
* 概念漂浮动画 - 稀疏美观版
* 流动式热门概念组件 - HeroUI 风格
* 特点:
* 1. 三行横向滚动,每行方向不同
* 2. 卡片式设计,带渐变边框
* 3. 悬停时暂停滚动,放大效果
* 4. 流光动画效果
*/
const ConceptFloat = () => {
const FlowingConcepts = () => {
const [concepts, setConcepts] = useState([]);
const [loading, setLoading] = useState(true);
const [hoveredIdx, setHoveredIdx] = useState(null);
const containerRef = useRef(null);
const [isPaused, setIsPaused] = useState(false);
useEffect(() => {
const load = async () => {
const data = await fetchPopularConcepts();
// 只取前12个更稀疏
setConcepts(data.slice(0, 12));
setConcepts(data.slice(0, 30)); // 取30个概念
setLoading(false);
};
load();
}, []);
const getColor = (pct) => {
if (pct > 5) return '#ff1744';
if (pct > 2) return '#ff5252';
if (pct > 0) return '#ff8a80';
if (pct === 0) return '#FFD700';
if (pct > -2) return '#69f0ae';
if (pct > -5) return '#00e676';
return '#00c853';
if (pct > 5) return { bg: 'rgba(255,23,68,0.15)', border: '#ff1744', text: '#ff1744', glow: 'rgba(255,23,68,0.4)' };
if (pct > 2) return { bg: 'rgba(255,82,82,0.12)', border: '#ff5252', text: '#ff5252', glow: 'rgba(255,82,82,0.3)' };
if (pct > 0) return { bg: 'rgba(255,138,128,0.1)', border: '#ff8a80', text: '#ff8a80', glow: 'rgba(255,138,128,0.25)' };
if (pct === 0) return { bg: 'rgba(255,215,0,0.1)', border: '#FFD700', text: '#FFD700', glow: 'rgba(255,215,0,0.25)' };
if (pct > -2) return { bg: 'rgba(105,240,174,0.1)', border: '#69f0ae', text: '#69f0ae', glow: 'rgba(105,240,174,0.25)' };
if (pct > -5) return { bg: 'rgba(0,230,118,0.12)', border: '#00e676', text: '#00e676', glow: 'rgba(0,230,118,0.3)' };
return { bg: 'rgba(0,200,83,0.15)', border: '#00c853', text: '#00c853', glow: 'rgba(0,200,83,0.4)' };
};
const handleClick = (name) => {
window.open(`https://valuefrontier.cn/htmls/${name}.html`, '_blank');
};
if (loading) return <Center h="100%"><Spinner size="sm" color="gold" /></Center>;
if (loading) {
return (
<Center h="100%">
<VStack spacing={2}>
<Spinner size="md" color="gold" thickness="3px" />
<Text fontSize="xs" color="whiteAlpha.500">加载热门概念...</Text>
</VStack>
</Center>
);
}
// 预设12个位置均匀分布且不重叠
const positions = [
{ x: 15, y: 20 }, { x: 50, y: 15 }, { x: 85, y: 25 },
{ x: 25, y: 50 }, { x: 60, y: 45 }, { x: 80, y: 55 },
{ x: 10, y: 75 }, { x: 40, y: 80 }, { x: 70, y: 75 },
{ x: 20, y: 35 }, { x: 55, y: 65 }, { x: 90, y: 40 },
];
// 将概念分成三行
const row1 = concepts.slice(0, 10);
const row2 = concepts.slice(10, 20);
const row3 = concepts.slice(20, 30);
// 渲染单个概念卡片
const renderConceptCard = (concept, globalIdx) => {
const colors = getColor(concept.change_pct);
const isActive = hoveredIdx === globalIdx;
return (
<Box
key={globalIdx}
flexShrink={0}
px={3}
py={2}
mx={2}
bg={isActive ? colors.bg : 'rgba(255,255,255,0.03)'}
border="1px solid"
borderColor={isActive ? colors.border : 'rgba(255,255,255,0.08)'}
borderRadius="xl"
cursor="pointer"
transition="all 0.3s cubic-bezier(0.4, 0, 0.2, 1)"
transform={isActive ? 'scale(1.1) translateY(-4px)' : 'scale(1)'}
boxShadow={isActive
? `0 8px 32px ${colors.glow}, 0 0 0 1px ${colors.border}40, inset 0 1px 0 rgba(255,255,255,0.1)`
: '0 2px 8px rgba(0,0,0,0.2)'
}
onClick={() => handleClick(concept.name)}
onMouseEnter={() => {
setHoveredIdx(globalIdx);
setIsPaused(true);
}}
onMouseLeave={() => {
setHoveredIdx(null);
setIsPaused(false);
}}
position="relative"
overflow="hidden"
_before={isActive ? {
content: '""',
position: 'absolute',
top: 0,
left: '-100%',
width: '200%',
height: '100%',
background: `linear-gradient(90deg, transparent, ${colors.glow}, transparent)`,
animation: 'shimmer 1.5s infinite',
} : {}}
>
<HStack spacing={2}>
<Text
fontSize="sm"
fontWeight={isActive ? 'bold' : 'semibold'}
color={isActive ? colors.text : 'whiteAlpha.900'}
whiteSpace="nowrap"
textShadow={isActive ? `0 0 10px ${colors.glow}` : 'none'}
>
{concept.name}
</Text>
<Text
fontSize="xs"
fontWeight="bold"
color={colors.text}
whiteSpace="nowrap"
>
{concept.change_pct > 0 ? '+' : ''}{concept.change_pct.toFixed(2)}%
</Text>
</HStack>
</Box>
);
};
// 渲染滚动行
const renderScrollRow = (items, direction, startIdx, duration) => {
const animationName = direction === 'left' ? 'scrollLeft' : 'scrollRight';
return (
<Box
overflow="hidden"
position="relative"
py={1}
_before={{
content: '""',
position: 'absolute',
left: 0,
top: 0,
bottom: 0,
width: '60px',
background: 'linear-gradient(90deg, rgba(10,10,20,1) 0%, transparent 100%)',
zIndex: 2,
pointerEvents: 'none',
}}
_after={{
content: '""',
position: 'absolute',
right: 0,
top: 0,
bottom: 0,
width: '60px',
background: 'linear-gradient(90deg, transparent 0%, rgba(10,10,20,1) 100%)',
zIndex: 2,
pointerEvents: 'none',
}}
>
<Flex
animation={isPaused ? 'none' : `${animationName} ${duration}s linear infinite`}
sx={{
[`@keyframes ${animationName}`]: direction === 'left' ? {
'0%': { transform: 'translateX(0)' },
'100%': { transform: 'translateX(-50%)' },
} : {
'0%': { transform: 'translateX(-50%)' },
'100%': { transform: 'translateX(0)' },
},
}}
>
{/* 复制两份实现无缝滚动 */}
{[...items, ...items].map((concept, idx) =>
renderConceptCard(concept, startIdx + (idx % items.length))
)}
</Flex>
</Box>
);
};
return (
<Box
ref={containerRef}
position="relative"
h="100%"
w="100%"
overflow="hidden"
>
{/* 概念标签 */}
{concepts.map((concept, idx) => {
const pos = positions[idx] || { x: 50, y: 50 };
const color = getColor(concept.change_pct);
const isActive = hoveredIdx === idx;
const size = 11 + (idx % 3) * 2; // 11-15px
return (
<Box
key={idx}
position="absolute"
left={`${pos.x}%`}
top={`${pos.y}%`}
transform={`translate(-50%, -50%) scale(${isActive ? 1.3 : 1})`}
opacity={isActive ? 1 : 0.85}
zIndex={isActive ? 100 : 10}
cursor="pointer"
transition="all 0.3s ease"
onMouseEnter={() => setHoveredIdx(idx)}
onMouseLeave={() => setHoveredIdx(null)}
onClick={() => handleClick(concept.name)}
animation={`floatSlow ${5 + (idx % 3)}s ease-in-out infinite ${idx * 0.3}s`}
>
<Text
fontSize={`${size}px`}
fontWeight={isActive ? 'bold' : 'medium'}
color={color}
textShadow={isActive
? `0 0 15px ${color}, 0 0 30px ${color}50`
: `0 0 8px ${color}40`
}
whiteSpace="nowrap"
>
{concept.name}
</Text>
{/* 悬停提示 */}
{isActive && (
<Box
position="absolute"
top="-28px"
left="50%"
transform="translateX(-50%)"
bg="rgba(0,0,0,0.9)"
border="1px solid"
borderColor={color}
borderRadius="md"
px={2}
py={1}
whiteSpace="nowrap"
>
<Text fontSize="xs" color={color} fontWeight="bold">
{concept.change_pct > 0 ? '+' : ''}{concept.change_pct.toFixed(2)}%
</Text>
</Box>
)}
</Box>
);
})}
<Box h="100%" w="100%" py={2}>
<VStack spacing={2} h="100%" justify="center">
{renderScrollRow(row1, 'left', 0, 35)}
{renderScrollRow(row2, 'right', 10, 40)}
{renderScrollRow(row3, 'left', 20, 32)}
</VStack>
</Box>
);
};
@@ -556,35 +627,69 @@ const HeroPanel = () => {
</Box>
</Flex>
{/* 右侧:热门概念 */}
{/* 右侧:热门概念 - 流动式设计 */}
<Box
flex={{ lg: '1' }}
minH={{ base: '150px', lg: '100px' }}
bg="rgba(0,0,0,0.2)"
borderRadius="xl"
border="1px solid rgba(255,215,0,0.1)"
minH={{ base: '180px', lg: '160px' }}
bg="linear-gradient(135deg, rgba(0,0,0,0.4) 0%, rgba(20,20,40,0.3) 50%, rgba(0,0,0,0.4) 100%)"
borderRadius="2xl"
border="1px solid"
borderColor="rgba(255,215,0,0.15)"
overflow="hidden"
position="relative"
boxShadow="inset 0 2px 20px rgba(0,0,0,0.3), 0 4px 30px rgba(0,0,0,0.2)"
_before={{
content: '""',
position: 'absolute',
top: 0,
left: 0,
right: 0,
height: '1px',
background: 'linear-gradient(90deg, transparent, rgba(255,215,0,0.3), transparent)',
}}
>
{/* 标题 */}
<HStack
{/* 标题栏 - 更精致的设计 */}
<Flex
position="absolute"
top={2}
left={3}
top={0}
left={0}
right={0}
px={4}
py={2}
bg="rgba(0,0,0,0.3)"
backdropFilter="blur(10px)"
borderBottom="1px solid rgba(255,255,255,0.05)"
justify="space-between"
align="center"
zIndex={10}
spacing={2}
>
<Icon as={TrendingUp} color="gold" boxSize={3.5} />
<Text fontSize="xs" fontWeight="bold" color="gold">
热门概念
</Text>
<Text fontSize="xs" color="whiteAlpha.400">
点击查看
</Text>
</HStack>
<HStack spacing={2}>
<Box
p={1.5}
bg="rgba(255,215,0,0.15)"
borderRadius="lg"
border="1px solid rgba(255,215,0,0.2)"
>
<Icon as={TrendingUp} color="gold" boxSize={4} />
</Box>
<VStack align="start" spacing={0}>
<Text fontSize="sm" fontWeight="bold" color="gold">
热门概念
</Text>
<Text fontSize="10px" color="whiteAlpha.500">
实时涨跌排行
</Text>
</VStack>
</HStack>
<HStack spacing={1} px={2} py={1} bg="rgba(255,255,255,0.05)" borderRadius="full">
<Box w="6px" h="6px" borderRadius="full" bg="gold" animation="pulse 2s infinite" />
<Text fontSize="10px" color="whiteAlpha.600">点击查看详情</Text>
</HStack>
</Flex>
<Box pt={7} h="100%">
<ConceptFloat />
{/* 流动式概念展示 */}
<Box pt="52px" h="100%">
<FlowingConcepts />
</Box>
</Box>
</Flex>