update pay function

This commit is contained in:
2025-11-23 18:11:48 +08:00
parent 05a2f62a42
commit fe47d3dcc6
9 changed files with 3229 additions and 91 deletions

View File

@@ -0,0 +1,327 @@
/**
* 预测话题卡片组件
* 展示预测市场的话题概览
*/
import React from 'react';
import {
Box,
Text,
HStack,
VStack,
Badge,
Progress,
Flex,
Avatar,
Icon,
useColorModeValue,
} from '@chakra-ui/react';
import { motion } from 'framer-motion';
import {
TrendingUp,
TrendingDown,
Crown,
Users,
Clock,
DollarSign,
Zap,
} from 'lucide-react';
import { useNavigate } from 'react-router-dom';
import { forumColors } from '@theme/forumTheme';
const MotionBox = motion(Box);
const PredictionTopicCard = ({ topic }) => {
const navigate = useNavigate();
// 处理卡片点击
const handleCardClick = () => {
navigate(`/value-forum/prediction/${topic.id}`);
};
// 格式化数字
const formatNumber = (num) => {
if (num >= 10000) return `${(num / 10000).toFixed(1)}`;
if (num >= 1000) return `${(num / 1000).toFixed(1)}K`;
return num;
};
// 格式化时间
const formatTime = (dateString) => {
const date = new Date(dateString);
const now = new Date();
const diff = date - now;
const days = Math.floor(diff / 86400000);
const hours = Math.floor(diff / 3600000);
if (days > 0) return `${days}天后`;
if (hours > 0) return `${hours}小时后`;
return '即将截止';
};
// 获取选项数据
const yesData = topic.positions?.yes || { total_shares: 0, current_price: 500, lord_id: null };
const noData = topic.positions?.no || { total_shares: 0, current_price: 500, lord_id: null };
// 计算总份额
const totalShares = yesData.total_shares + noData.total_shares;
// 计算百分比
const yesPercent = totalShares > 0 ? (yesData.total_shares / totalShares) * 100 : 50;
const noPercent = totalShares > 0 ? (noData.total_shares / totalShares) * 100 : 50;
// 状态颜色
const statusColorMap = {
active: forumColors.success[500],
trading_closed: forumColors.warning[500],
settled: forumColors.text.secondary,
};
const statusLabelMap = {
active: '交易中',
trading_closed: '已截止',
settled: '已结算',
};
return (
<MotionBox
bg={forumColors.background.card}
borderRadius="xl"
overflow="hidden"
border="2px solid"
borderColor={forumColors.border.default}
cursor="pointer"
onClick={handleCardClick}
whileHover={{ y: -8, scale: 1.02 }}
transition={{ duration: 0.3 }}
_hover={{
borderColor: forumColors.border.gold,
boxShadow: forumColors.shadows.gold,
}}
>
{/* 头部:状态标识 */}
<Box
bg={forumColors.gradients.goldSubtle}
px="4"
py="2"
borderBottom="1px solid"
borderColor={forumColors.border.default}
>
<Flex justify="space-between" align="center">
<HStack spacing="2">
<Icon as={Zap} boxSize="16px" color={forumColors.primary[500]} />
<Text fontSize="xs" fontWeight="bold" color={forumColors.primary[500]}>
预测市场
</Text>
</HStack>
<Badge
bg={statusColorMap[topic.status]}
color="white"
px="3"
py="1"
borderRadius="full"
fontSize="xs"
fontWeight="bold"
>
{statusLabelMap[topic.status]}
</Badge>
</Flex>
</Box>
{/* 内容区域 */}
<VStack align="stretch" p="5" spacing="4">
{/* 话题标题 */}
<Text
fontSize="lg"
fontWeight="700"
color={forumColors.text.primary}
noOfLines={2}
lineHeight="1.4"
>
{topic.title}
</Text>
{/* 描述 */}
{topic.description && (
<Text
fontSize="sm"
color={forumColors.text.secondary}
noOfLines={2}
lineHeight="1.6"
>
{topic.description}
</Text>
)}
{/* 双向价格卡片 */}
<HStack spacing="3" w="full">
{/* Yes 方 */}
<Box
flex="1"
bg="linear-gradient(135deg, rgba(72, 187, 120, 0.1) 0%, rgba(72, 187, 120, 0.05) 100%)"
border="2px solid"
borderColor="green.400"
borderRadius="lg"
p="3"
position="relative"
overflow="hidden"
>
{/* 领主徽章 */}
{yesData.lord_id && (
<Icon
as={Crown}
position="absolute"
top="2"
right="2"
boxSize="16px"
color="yellow.400"
/>
)}
<VStack spacing="1" align="start">
<HStack spacing="1">
<Icon as={TrendingUp} boxSize="14px" color="green.500" />
<Text fontSize="xs" fontWeight="600" color="green.600">
看涨 / Yes
</Text>
</HStack>
<Text fontSize="2xl" fontWeight="bold" color="green.600">
{Math.round(yesData.current_price)}
<Text as="span" fontSize="xs" ml="1">
积分
</Text>
</Text>
<Text fontSize="xs" color={forumColors.text.secondary}>
{yesData.total_shares} · {yesPercent.toFixed(0)}%
</Text>
</VStack>
</Box>
{/* No 方 */}
<Box
flex="1"
bg="linear-gradient(135deg, rgba(245, 101, 101, 0.1) 0%, rgba(245, 101, 101, 0.05) 100%)"
border="2px solid"
borderColor="red.400"
borderRadius="lg"
p="3"
position="relative"
overflow="hidden"
>
{/* 领主徽章 */}
{noData.lord_id && (
<Icon
as={Crown}
position="absolute"
top="2"
right="2"
boxSize="16px"
color="yellow.400"
/>
)}
<VStack spacing="1" align="start">
<HStack spacing="1">
<Icon as={TrendingDown} boxSize="14px" color="red.500" />
<Text fontSize="xs" fontWeight="600" color="red.600">
看跌 / No
</Text>
</HStack>
<Text fontSize="2xl" fontWeight="bold" color="red.600">
{Math.round(noData.current_price)}
<Text as="span" fontSize="xs" ml="1">
积分
</Text>
</Text>
<Text fontSize="xs" color={forumColors.text.secondary}>
{noData.total_shares} · {noPercent.toFixed(0)}%
</Text>
</VStack>
</Box>
</HStack>
{/* 市场情绪进度条 */}
<Box>
<Flex justify="space-between" mb="1">
<Text fontSize="xs" color={forumColors.text.tertiary}>
市场情绪
</Text>
<Text fontSize="xs" color={forumColors.text.tertiary}>
{yesPercent.toFixed(0)}% vs {noPercent.toFixed(0)}%
</Text>
</Flex>
<Progress
value={yesPercent}
size="sm"
borderRadius="full"
bg="red.100"
sx={{
'& > div': {
bg: 'linear-gradient(90deg, #48BB78 0%, #38A169 100%)',
},
}}
/>
</Box>
{/* 奖池和数据 */}
<HStack spacing="4" fontSize="sm" color={forumColors.text.secondary}>
<HStack spacing="1">
<Icon as={DollarSign} boxSize="16px" color={forumColors.primary[500]} />
<Text fontWeight="600" color={forumColors.primary[500]}>
{formatNumber(topic.total_pool)}
</Text>
<Text fontSize="xs">奖池</Text>
</HStack>
<HStack spacing="1">
<Icon as={Users} boxSize="16px" />
<Text>{topic.stats?.unique_traders?.size || 0}</Text>
</HStack>
<HStack spacing="1">
<Icon as={Clock} boxSize="16px" />
<Text>{formatTime(topic.deadline)}</Text>
</HStack>
</HStack>
{/* 底部:作者信息 */}
<Flex justify="space-between" align="center" pt="2" borderTop="1px solid" borderColor={forumColors.border.default}>
<HStack spacing="2">
<Avatar
size="xs"
name={topic.author_name}
src={topic.author_avatar}
bg={forumColors.gradients.goldPrimary}
color={forumColors.background.main}
/>
<Text fontSize="xs" color={forumColors.text.tertiary}>
{topic.author_name}
</Text>
</HStack>
{/* 分类标签 */}
{topic.category && (
<Badge
bg={forumColors.background.hover}
color={forumColors.text.primary}
px="2"
py="1"
borderRadius="md"
fontSize="xs"
>
{topic.category}
</Badge>
)}
</Flex>
</VStack>
</MotionBox>
);
};
export default PredictionTopicCard;