update pay function
This commit is contained in:
@@ -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>;
|
||||
|
||||
// 预设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 },
|
||||
];
|
||||
|
||||
if (loading) {
|
||||
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`
|
||||
<Center h="100%">
|
||||
<VStack spacing={2}>
|
||||
<Spinner size="md" color="gold" thickness="3px" />
|
||||
<Text fontSize="xs" color="whiteAlpha.500">加载热门概念...</Text>
|
||||
</VStack>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
// 将概念分成三行
|
||||
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>
|
||||
|
||||
{/* 悬停提示 */}
|
||||
{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}
|
||||
<Text
|
||||
fontSize="xs"
|
||||
fontWeight="bold"
|
||||
color={colors.text}
|
||||
whiteSpace="nowrap"
|
||||
>
|
||||
<Text fontSize="xs" color={color} fontWeight="bold">
|
||||
{concept.change_pct > 0 ? '+' : ''}{concept.change_pct.toFixed(2)}%
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
</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 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">
|
||||
<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="xs" color="whiteAlpha.400">
|
||||
点击查看
|
||||
<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>
|
||||
|
||||
Reference in New Issue
Block a user