update pay ui

This commit is contained in:
2025-12-05 15:55:32 +08:00
parent b60c196f9e
commit c54318c3c9
3 changed files with 308 additions and 284 deletions

View File

@@ -73,9 +73,10 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
const [useCustomRange, setUseCustomRange] = useState(false);
const toast = useToast();
const bg = useColorModeValue('white', 'gray.800');
const cardBg = useColorModeValue('gray.50', 'gray.700');
const borderColor = useColorModeValue('gray.200', 'gray.600');
// 深色主题颜色(固定使用深色模式)
const bg = 'rgba(15, 23, 42, 0.8)';
const cardBg = 'rgba(15, 23, 42, 0.6)';
const borderColor = 'whiteAlpha.100';
// 获取统计数据
const fetchStatsData = async (days = timeRange, startDate = null, endDate = null) => {
@@ -250,21 +251,21 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
return 'gray.500';
};
// 统计卡片组件 - 美化
// 统计卡片组件 - 深色主题
const StatsCard = ({ title, icon, color, data, renderItem, isLoading }) => (
<Box p={4}>
{isLoading ? (
<VStack spacing={3} align="stretch">
{[1, 2, 3, 4, 5].map((i) => (
<HStack key={i} justify="space-between" p={3} bg="gray.50" borderRadius="lg">
<HStack key={i} justify="space-between" p={3} bg="whiteAlpha.50" borderRadius="lg">
<HStack spacing={2} flex={1}>
<Skeleton height="20px" width="20px" borderRadius="full" />
<Skeleton height="20px" width="20px" borderRadius="full" startColor="whiteAlpha.100" endColor="whiteAlpha.200" />
<VStack align="start" spacing={1} flex={1}>
<Skeleton height="14px" width="80%" />
<Skeleton height="12px" width="60%" />
<Skeleton height="14px" width="80%" startColor="whiteAlpha.100" endColor="whiteAlpha.200" />
<Skeleton height="12px" width="60%" startColor="whiteAlpha.100" endColor="whiteAlpha.200" />
</VStack>
</HStack>
<Skeleton height="20px" width="50px" borderRadius="md" />
<Skeleton height="20px" width="50px" borderRadius="md" startColor="whiteAlpha.100" endColor="whiteAlpha.200" />
</HStack>
))}
</VStack>
@@ -275,15 +276,15 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
width: '4px',
},
'&::-webkit-scrollbar-track': {
background: '#f1f1f1',
background: 'rgba(255,255,255,0.05)',
borderRadius: '10px',
},
'&::-webkit-scrollbar-thumb': {
background: '#c1c1c1',
background: 'rgba(255,255,255,0.2)',
borderRadius: '10px',
},
'&::-webkit-scrollbar-thumb:hover': {
background: '#a8a8a8',
background: 'rgba(255,255,255,0.3)',
},
}}
>
@@ -309,14 +310,14 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
align="center"
p={3}
borderRadius="xl"
bg={index < 3 ? 'red.50' : 'gray.50'}
bg={index < 3 ? 'rgba(239, 68, 68, 0.15)' : 'whiteAlpha.50'}
border="1px solid"
borderColor={index < 3 ? 'red.100' : 'gray.200'}
borderColor={index < 3 ? 'red.500' : 'whiteAlpha.100'}
_hover={{
transform: 'translateY(-1px)',
shadow: 'md',
cursor: 'pointer',
bg: index < 3 ? 'red.100' : 'gray.100'
bg: index < 3 ? 'rgba(239, 68, 68, 0.25)' : 'whiteAlpha.100'
}}
transition="all 0.2s"
onClick={() => onConceptClick?.(null, item.name)}
@@ -324,8 +325,8 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
<HStack spacing={3} flex={1}>
<Box position="relative">
<Badge
colorScheme={index === 0 ? 'yellow' : index === 1 ? 'orange' : index === 2 ? 'red' : 'gray'}
variant="solid"
bg={index === 0 ? 'yellow.500' : index === 1 ? 'orange.500' : index === 2 ? 'red.500' : 'whiteAlpha.200'}
color="white"
borderRadius="full"
minW="24px"
h="24px"
@@ -344,16 +345,16 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
position="absolute"
top="-8px"
right="-8px"
color="yellow.500"
color="yellow.400"
boxSize={3}
/>
)}
</Box>
<VStack align="start" spacing={0} flex={1}>
<Text fontSize="sm" fontWeight="bold" noOfLines={1} color="gray.800">
<Text fontSize="sm" fontWeight="bold" noOfLines={1} color="white">
{item.name}
</Text>
<HStack spacing={2} fontSize="xs" color="gray.600">
<HStack spacing={2} fontSize="xs" color="whiteAlpha.600">
<HStack spacing={1}>
<Icon as={FaChartLine} boxSize={2.5} />
<Text>{item.stock_count}</Text>
@@ -367,8 +368,8 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
</VStack>
</HStack>
<Badge
colorScheme="red"
variant="solid"
bg="red.500"
color="white"
borderRadius="lg"
fontSize="xs"
fontWeight="bold"
@@ -392,22 +393,22 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
align="center"
p={3}
borderRadius="xl"
bg={index < 3 ? 'green.50' : 'gray.50'}
bg={index < 3 ? 'rgba(34, 197, 94, 0.15)' : 'whiteAlpha.50'}
border="1px solid"
borderColor={index < 3 ? 'green.100' : 'gray.200'}
borderColor={index < 3 ? 'green.500' : 'whiteAlpha.100'}
_hover={{
transform: 'translateY(-1px)',
shadow: 'md',
cursor: 'pointer',
bg: index < 3 ? 'green.100' : 'gray.100'
bg: index < 3 ? 'rgba(34, 197, 94, 0.25)' : 'whiteAlpha.100'
}}
transition="all 0.2s"
onClick={() => onConceptClick?.(null, item.name)}
>
<HStack spacing={3} flex={1}>
<Badge
colorScheme={index < 3 ? 'green' : 'gray'}
variant="solid"
bg={index < 3 ? 'green.500' : 'whiteAlpha.200'}
color="white"
borderRadius="full"
minW="24px"
h="24px"
@@ -421,10 +422,10 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
{index + 1}
</Badge>
<VStack align="start" spacing={0} flex={1}>
<Text fontSize="sm" fontWeight="bold" noOfLines={1} color="gray.800">
<Text fontSize="sm" fontWeight="bold" noOfLines={1} color="white">
{item.name}
</Text>
<HStack spacing={2} fontSize="xs" color="gray.600">
<HStack spacing={2} fontSize="xs" color="whiteAlpha.600">
<HStack spacing={1}>
<Icon as={FaChartLine} boxSize={2.5} />
<Text>{item.stock_count}</Text>
@@ -438,8 +439,8 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
</VStack>
</HStack>
<Badge
colorScheme="green"
variant="solid"
bg="green.500"
color="white"
borderRadius="lg"
fontSize="xs"
fontWeight="bold"
@@ -463,14 +464,14 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
align="center"
p={3}
borderRadius="xl"
bg={index < 3 ? 'orange.50' : 'gray.50'}
bg={index < 3 ? 'rgba(251, 146, 60, 0.15)' : 'whiteAlpha.50'}
border="1px solid"
borderColor={index < 3 ? 'orange.100' : 'gray.200'}
borderColor={index < 3 ? 'orange.500' : 'whiteAlpha.100'}
_hover={{
transform: 'translateY(-1px)',
shadow: 'md',
cursor: 'pointer',
bg: index < 3 ? 'orange.100' : 'gray.100'
bg: index < 3 ? 'rgba(251, 146, 60, 0.25)' : 'whiteAlpha.100'
}}
transition="all 0.2s"
onClick={() => onConceptClick?.(null, item.name)}
@@ -478,8 +479,8 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
<HStack spacing={3} flex={1}>
<Box position="relative">
<Badge
colorScheme={index === 0 ? 'orange' : index < 3 ? 'yellow' : 'gray'}
variant="solid"
bg={index === 0 ? 'orange.500' : index < 3 ? 'yellow.500' : 'whiteAlpha.200'}
color="white"
borderRadius="full"
minW="24px"
h="24px"
@@ -498,16 +499,16 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
position="absolute"
top="-8px"
right="-8px"
color="orange.500"
color="orange.400"
boxSize={3}
/>
)}
</Box>
<VStack align="start" spacing={0} flex={1}>
<Text fontSize="sm" fontWeight="bold" noOfLines={1} color="gray.800">
<Text fontSize="sm" fontWeight="bold" noOfLines={1} color="white">
{item.name}
</Text>
<HStack spacing={2} fontSize="xs" color="gray.600">
<HStack spacing={2} fontSize="xs" color="whiteAlpha.600">
<HStack spacing={1}>
<Icon as={FaNewspaper} boxSize={2.5} />
<Text>{item.news_count}</Text>
@@ -521,8 +522,8 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
</VStack>
</HStack>
<Badge
colorScheme="orange"
variant="solid"
bg="orange.500"
color="white"
borderRadius="lg"
fontSize="xs"
fontWeight="bold"
@@ -546,14 +547,14 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
align="center"
p={3}
borderRadius="xl"
bg={index < 3 ? 'purple.50' : 'gray.50'}
bg={index < 3 ? 'rgba(168, 85, 247, 0.15)' : 'whiteAlpha.50'}
border="1px solid"
borderColor={index < 3 ? 'purple.100' : 'gray.200'}
borderColor={index < 3 ? 'purple.500' : 'whiteAlpha.100'}
_hover={{
transform: 'translateY(-1px)',
shadow: 'md',
cursor: 'pointer',
bg: index < 3 ? 'purple.100' : 'gray.100'
bg: index < 3 ? 'rgba(168, 85, 247, 0.25)' : 'whiteAlpha.100'
}}
transition="all 0.2s"
onClick={() => onConceptClick?.(null, item.name)}
@@ -561,8 +562,8 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
<HStack spacing={3} flex={1}>
<Box position="relative">
<Badge
colorScheme={index < 3 ? 'purple' : 'gray'}
variant="solid"
bg={index < 3 ? 'purple.500' : 'whiteAlpha.200'}
color="white"
borderRadius="full"
minW="24px"
h="24px"
@@ -581,23 +582,23 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
position="absolute"
top="-8px"
right="-8px"
color="purple.500"
color="purple.400"
boxSize={3}
/>
)}
</Box>
<VStack align="start" spacing={0} flex={1}>
<Text fontSize="sm" fontWeight="bold" noOfLines={1} color="gray.800">
<Text fontSize="sm" fontWeight="bold" noOfLines={1} color="white">
{item.name}
</Text>
<Text fontSize="xs" color="gray.600">
<Text fontSize="xs" color="whiteAlpha.600">
均幅 {formatChange(item.avg_change)}
</Text>
</VStack>
</HStack>
<Badge
colorScheme="purple"
variant="solid"
bg="purple.500"
color="white"
borderRadius="lg"
fontSize="xs"
fontWeight="bold"
@@ -621,14 +622,14 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
align="center"
p={3}
borderRadius="xl"
bg={index < 3 ? 'cyan.50' : 'gray.50'}
bg={index < 3 ? 'rgba(34, 211, 238, 0.15)' : 'whiteAlpha.50'}
border="1px solid"
borderColor={index < 3 ? 'cyan.100' : 'gray.200'}
borderColor={index < 3 ? 'cyan.500' : 'whiteAlpha.100'}
_hover={{
transform: 'translateY(-1px)',
shadow: 'md',
cursor: 'pointer',
bg: index < 3 ? 'cyan.100' : 'gray.100'
bg: index < 3 ? 'rgba(34, 211, 238, 0.25)' : 'whiteAlpha.100'
}}
transition="all 0.2s"
onClick={() => onConceptClick?.(null, item.name)}
@@ -636,8 +637,8 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
<HStack spacing={3} flex={1}>
<Box position="relative">
<Badge
colorScheme={index === 0 ? 'cyan' : index < 3 ? 'blue' : 'gray'}
variant="solid"
bg={index === 0 ? 'cyan.500' : index < 3 ? 'blue.500' : 'whiteAlpha.200'}
color="white"
borderRadius="full"
minW="24px"
h="24px"
@@ -656,23 +657,23 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
position="absolute"
top="-8px"
right="-8px"
color="cyan.500"
color="cyan.400"
boxSize={3}
/>
)}
</Box>
<VStack align="start" spacing={0} flex={1}>
<Text fontSize="sm" fontWeight="bold" noOfLines={1} color="gray.800">
<Text fontSize="sm" fontWeight="bold" noOfLines={1} color="white">
{item.name}
</Text>
<Text fontSize="xs" color="gray.600">
<Text fontSize="xs" color="whiteAlpha.600">
累计 {formatChange(item.total_change)}
</Text>
</VStack>
</HStack>
<Badge
colorScheme="cyan"
variant="solid"
bg="cyan.500"
color="white"
borderRadius="lg"
fontSize="xs"
fontWeight="bold"
@@ -689,14 +690,17 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
return (
<Box>
{/* 顶部标题卡片 */}
{/* 顶部标题卡片 - 深色玻璃态 */}
<Box
bg="linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
bg="rgba(15, 23, 42, 0.8)"
backdropFilter="blur(20px)"
p={4}
borderRadius="xl"
mb={4}
position="relative"
overflow="hidden"
border="1px solid"
borderColor="whiteAlpha.100"
>
{/* 背景装饰 */}
<Box
@@ -706,8 +710,9 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
width="80px"
height="80px"
borderRadius="full"
bg="whiteAlpha.200"
filter="blur(10px)"
bg="purple.500"
opacity={0.2}
filter="blur(20px)"
/>
<Box
position="absolute"
@@ -716,15 +721,16 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
width="60px"
height="60px"
borderRadius="full"
bg="whiteAlpha.100"
filter="blur(8px)"
bg="cyan.500"
opacity={0.15}
filter="blur(15px)"
/>
<VStack align="start" spacing={3} position="relative" w="full">
<Flex justify="space-between" align="center" w="full">
<HStack spacing={2}>
<Box p={2} bg="whiteAlpha.200" borderRadius="lg">
<Icon as={FaChartLine} color="white" boxSize={4} />
<Box p={2} bg="whiteAlpha.100" borderRadius="lg" border="1px solid" borderColor="cyan.500">
<Icon as={FaChartLine} color="cyan.400" boxSize={4} />
</Box>
<VStack align="start" spacing={0}>
<Heading size="sm" color="white" fontWeight="bold">
@@ -868,8 +874,8 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
</VStack>
</Box>
{/* 主内容卡片 */}
<Box bg={bg} borderRadius="xl" border="1px" borderColor={borderColor} shadow="sm" overflow="hidden">
{/* 主内容卡片 - 深色玻璃态 */}
<Box bg={bg} backdropFilter="blur(20px)" borderRadius="xl" border="1px" borderColor={borderColor} overflow="hidden">
<Tabs
index={activeTab}
onChange={(index) => {
@@ -882,7 +888,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
size="sm"
>
<TabList
bg="gray.50"
bg="rgba(15, 23, 42, 0.6)"
borderBottom="1px"
borderColor={borderColor}
overflowX="auto"
@@ -902,6 +908,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
px={3}
py={3}
whiteSpace="nowrap"
color="whiteAlpha.700"
_selected={{
bg: `${tab.color}.500`,
color: 'white',
@@ -917,7 +924,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
bg: `${tab.color}.500`,
}
}}
_hover={{ bg: `${tab.color}.50` }}
_hover={{ bg: 'whiteAlpha.100', color: 'white' }}
transition="all 0.2s"
>
<HStack spacing={1}>