diff --git a/src/views/ValueForum/PredictionTopicDetail.js b/src/views/ValueForum/PredictionTopicDetail.js index 1b116970..60f3c512 100644 --- a/src/views/ValueForum/PredictionTopicDetail.js +++ b/src/views/ValueForum/PredictionTopicDetail.js @@ -3,7 +3,7 @@ * 展示预测市场的完整信息、交易、评论等 */ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useMemo } from 'react'; import { Box, Heading, @@ -20,17 +20,21 @@ import { useDisclosure, useToast, SimpleGrid, + Alert, + AlertIcon, } from '@chakra-ui/react'; import { TrendingUp, TrendingDown, Crown, Users, - Clock, Coins, ShoppingCart, ArrowLeftRight, CheckCircle2, + Lock, + Gavel, + Trophy, } from 'lucide-react'; import { useParams, useNavigate } from 'react-router-dom'; import { motion } from 'framer-motion'; @@ -41,6 +45,8 @@ import { LAYOUT_SIZE } from '@/layouts/config/layoutConfig'; import TradeModal from './components/TradeModal'; import PredictionCommentSection from './components/PredictionCommentSection'; import CommentInvestModal from './components/CommentInvestModal'; +import SettleTopicModal from './components/SettleTopicModal'; +import CountdownTimer, { useCountdown } from './components/CountdownTimer'; const MotionBox = motion(Box); @@ -70,6 +76,12 @@ const PredictionTopicDetail = () => { onClose: onInvestModalClose, } = useDisclosure(); + const { + isOpen: isSettleModalOpen, + onOpen: onSettleModalOpen, + onClose: onSettleModalClose, + } = useDisclosure(); + // 加载话题数据 useEffect(() => { const loadTopic = async () => { @@ -184,6 +196,47 @@ const PredictionTopicDetail = () => { } }; + // 使用倒计时 Hook + const timeLeft = useCountdown(topic?.deadline); + + // 计算实际状态(基于截止时间自动判断) + const effectiveStatus = useMemo(() => { + if (!topic) return 'active'; + // 如果已经是结算状态,保持不变 + if (topic.status === 'settled') return 'settled'; + // 如果已过截止时间,自动变为已截止 + if (timeLeft.expired && topic.status === 'active') return 'trading_closed'; + return topic.status; + }, [topic?.status, timeLeft.expired]); + + // 判断当前用户是否是作者 + const isAuthor = useMemo(() => { + if (!user || !topic) return false; + return user.id === topic.author_id || user.username === topic.author_name; + }, [user, topic]); + + // 判断是否可以结算(作者 + 已截止 + 未结算) + const canSettle = useMemo(() => { + return isAuthor && effectiveStatus === 'trading_closed'; + }, [isAuthor, effectiveStatus]); + + // 判断是否可以交易 + const canTrade = useMemo(() => { + return effectiveStatus === 'active' && !isAuthor; + }, [effectiveStatus, isAuthor]); + + // 结算成功回调 + const handleSettleSuccess = async () => { + try { + const topicResponse = await getTopicDetail(topicId); + if (topicResponse.success) { + setTopic(topicResponse.data); + } + } catch (error) { + console.error('刷新数据失败:', error); + } + }; + if (!topic) { return null; } @@ -207,20 +260,19 @@ const PredictionTopicDetail = () => { const yesPercent = totalShares > 0 ? (yesData.total_shares / totalShares) * 100 : 50; const noPercent = totalShares > 0 ? (noData.total_shares / totalShares) * 100 : 50; - // 格式化时间 - 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 getResultDisplay = () => { + if (topic.status !== 'settled' || !topic.result) return null; + const resultMap = { + yes: { label: '看涨方获胜', color: 'green', icon: TrendingUp }, + no: { label: '看跌方获胜', color: 'red', icon: TrendingDown }, + draw: { label: '平局', color: 'gray', icon: null }, + }; + return resultMap[topic.result]; }; + const resultDisplay = getResultDisplay(); + return ( {/* 头部:返回按钮 */} @@ -258,26 +310,73 @@ const PredictionTopicDetail = () => { borderBottom="1px solid" borderColor={forumColors.border.default} > - - - {topic.category} - + + + + {topic.category} + - - - - {formatTime(topic.deadline)} 截止 - + {/* 状态标识 */} + + + {effectiveStatus === 'active' ? '交易中' : + effectiveStatus === 'trading_closed' ? '等待结算' : '已结算'} + + + {/* 倒计时 */} + + {/* 结算结果展示 */} + {resultDisplay && ( + + + + 结算结果:{resultDisplay.label} + + + )} + { - {/* 交易按钮 */} - {topic.status === 'active' && ( + {/* 交易按钮 - 只在可交易时显示 */} + {canTrade && ( + + )} + + {/* 已结算状态提示 */} + {effectiveStatus === 'settled' && ( + + + + 话题已结算 + + + 奖池已分配给获胜方 + + + )} + + {/* 等待结算状态提示(非作者) */} + {effectiveStatus === 'trading_closed' && !isAuthor && ( + + + + 交易已截止 + + + 等待话题作者提交结算结果 + + + )} + {/* 用户余额 */} {user && userAccount && ( { topic={topic} onInvestSuccess={handleInvestSuccess} /> + + {/* 结算模态框 */} + ); }; diff --git a/src/views/ValueForum/components/CountdownTimer.js b/src/views/ValueForum/components/CountdownTimer.js new file mode 100644 index 00000000..e66ee0cb --- /dev/null +++ b/src/views/ValueForum/components/CountdownTimer.js @@ -0,0 +1,277 @@ +/** + * 倒计时组件 + * 实时显示距离截止时间的倒计时,参考 Polymarket 设计 + */ + +import React, { useState, useEffect, useMemo } from 'react'; +import { HStack, Text, Box, Icon, Badge } from '@chakra-ui/react'; +import { Clock, AlertTriangle, CheckCircle2, Lock } from 'lucide-react'; +import { forumColors } from '@theme/forumTheme'; + +/** + * 计算时间差 + * @param {string|Date} deadline - 截止时间 + * @returns {object} 时间差对象 + */ +const calculateTimeLeft = (deadline) => { + const now = new Date(); + const end = new Date(deadline); + const diff = end - now; + + if (diff <= 0) { + return { expired: true, days: 0, hours: 0, minutes: 0, seconds: 0, totalMs: 0 }; + } + + return { + expired: false, + days: Math.floor(diff / (1000 * 60 * 60 * 24)), + hours: Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)), + minutes: Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)), + seconds: Math.floor((diff % (1000 * 60)) / 1000), + totalMs: diff, + }; +}; + +/** + * 倒计时 Hook + */ +export const useCountdown = (deadline) => { + const [timeLeft, setTimeLeft] = useState(() => calculateTimeLeft(deadline)); + + useEffect(() => { + // 已过期则不需要更新 + if (timeLeft.expired) return; + + // 根据剩余时间决定更新频率 + const interval = timeLeft.totalMs < 60000 ? 1000 : 60000; // 小于1分钟时秒级更新 + + const timer = setInterval(() => { + const newTimeLeft = calculateTimeLeft(deadline); + setTimeLeft(newTimeLeft); + + if (newTimeLeft.expired) { + clearInterval(timer); + } + }, interval); + + return () => clearInterval(timer); + }, [deadline, timeLeft.expired, timeLeft.totalMs]); + + return timeLeft; +}; + +/** + * 格式化倒计时显示 + */ +const formatCountdown = (timeLeft) => { + if (timeLeft.expired) { + return '已截止'; + } + + if (timeLeft.days > 0) { + return `${timeLeft.days}天 ${timeLeft.hours}小时`; + } + + if (timeLeft.hours > 0) { + return `${timeLeft.hours}小时 ${timeLeft.minutes}分`; + } + + if (timeLeft.minutes > 0) { + return `${timeLeft.minutes}分 ${timeLeft.seconds}秒`; + } + + return `${timeLeft.seconds}秒`; +}; + +/** + * 获取倒计时状态和颜色 + */ +const getCountdownStatus = (timeLeft) => { + if (timeLeft.expired) { + return { + status: 'expired', + color: forumColors.text.secondary, + bgColor: forumColors.background.hover, + icon: Lock, + label: '已截止', + }; + } + + // 小于1小时 + if (timeLeft.days === 0 && timeLeft.hours === 0) { + return { + status: 'critical', + color: '#E53E3E', + bgColor: 'rgba(229, 62, 62, 0.1)', + icon: AlertTriangle, + label: '即将截止', + }; + } + + // 小于24小时 + if (timeLeft.days === 0) { + return { + status: 'warning', + color: '#DD6B20', + bgColor: 'rgba(221, 107, 32, 0.1)', + icon: Clock, + label: '今日截止', + }; + } + + // 小于3天 + if (timeLeft.days < 3) { + return { + status: 'soon', + color: '#D69E2E', + bgColor: 'rgba(214, 158, 46, 0.1)', + icon: Clock, + label: '即将截止', + }; + } + + return { + status: 'normal', + color: forumColors.text.secondary, + bgColor: 'transparent', + icon: Clock, + label: '交易中', + }; +}; + +/** + * 倒计时显示组件 + */ +const CountdownTimer = ({ + deadline, + status = 'active', // active, trading_closed, settled + size = 'md', // sm, md, lg + showIcon = true, + showLabel = false, + variant = 'inline', // inline, badge, card + onExpire, +}) => { + const timeLeft = useCountdown(deadline); + const countdownStatus = getCountdownStatus(timeLeft); + + // 当倒计时结束时触发回调 + useEffect(() => { + if (timeLeft.expired && onExpire) { + onExpire(); + } + }, [timeLeft.expired, onExpire]); + + // 如果话题已结算,显示结算状态 + if (status === 'settled') { + return ( + + + + 已结算 + + + ); + } + + // 如果话题已截止(手动设置的状态) + if (status === 'trading_closed') { + return ( + + + + 等待结算 + + + ); + } + + const sizeMap = { + sm: { fontSize: 'xs', iconSize: '12px', px: 2, py: 1 }, + md: { fontSize: 'sm', iconSize: '14px', px: 3, py: 1 }, + lg: { fontSize: 'md', iconSize: '16px', px: 4, py: 2 }, + }; + + const sizeConfig = sizeMap[size]; + + // Badge 变体 + if (variant === 'badge') { + return ( + + {showIcon && } + {showLabel && {countdownStatus.label}} + {formatCountdown(timeLeft)} + + ); + } + + // Card 变体 - 更详细的显示 + if (variant === 'card') { + return ( + + + + + + {timeLeft.expired ? '已截止' : '距离截止'} + + + + {formatCountdown(timeLeft)} + + + + {!timeLeft.expired && timeLeft.days === 0 && ( + + ⚠️ 交易即将关闭,请尽快完成交易 + + )} + + ); + } + + // 默认 inline 变体 + return ( + + {showIcon && ( + + )} + {showLabel && ( + + {countdownStatus.label}: + + )} + + {formatCountdown(timeLeft)} + + + ); +}; + +export default CountdownTimer; diff --git a/src/views/ValueForum/components/CreatePredictionModal.js b/src/views/ValueForum/components/CreatePredictionModal.js index 7313c4e1..2544347a 100644 --- a/src/views/ValueForum/components/CreatePredictionModal.js +++ b/src/views/ValueForum/components/CreatePredictionModal.js @@ -3,7 +3,7 @@ * 用户可以发起新的预测市场话题 */ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useMemo } from 'react'; import { Modal, ModalOverlay, @@ -26,8 +26,15 @@ import { Alert, AlertIcon, useToast, + RadioGroup, + Radio, + Tabs, + TabList, + Tab, + TabPanels, + TabPanel, } from '@chakra-ui/react'; -import { Zap, Calendar, DollarSign } from 'lucide-react'; +import { Zap, Calendar, DollarSign, Clock, AlertTriangle } from 'lucide-react'; import { forumColors } from '@theme/forumTheme'; import { createTopic, getUserAccount } from '@services/predictionMarketService.api'; import { CREDIT_CONFIG } from '@services/creditSystemService'; @@ -43,7 +50,10 @@ const CreatePredictionModal = ({ isOpen, onClose, onTopicCreated }) => { title: '', description: '', category: 'stock', + deadline_type: 'preset', // 'preset' 或 'custom' deadline_days: 7, + custom_date: '', + custom_time: '15:00', // 默认下午3点(A股收盘时间) }); const [isSubmitting, setIsSubmitting] = useState(false); @@ -70,6 +80,63 @@ const CreatePredictionModal = ({ isOpen, onClose, onTopicCreated }) => { setFormData((prev) => ({ ...prev, [field]: value })); }; + // 计算截止时间 + const calculatedDeadline = useMemo(() => { + if (formData.deadline_type === 'preset') { + const deadline = new Date(); + deadline.setDate(deadline.getDate() + parseInt(formData.deadline_days)); + deadline.setHours(15, 0, 0, 0); // 默认下午3点 + return deadline; + } else { + if (!formData.custom_date) return null; + const [hours, minutes] = formData.custom_time.split(':'); + const deadline = new Date(formData.custom_date); + deadline.setHours(parseInt(hours), parseInt(minutes), 0, 0); + return deadline; + } + }, [formData.deadline_type, formData.deadline_days, formData.custom_date, formData.custom_time]); + + // 格式化截止时间显示 + const formatDeadlineDisplay = (date) => { + if (!date) return '请选择日期'; + const now = new Date(); + const diff = date - now; + const days = Math.floor(diff / (1000 * 60 * 60 * 24)); + const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + + const dateStr = date.toLocaleDateString('zh-CN', { + year: 'numeric', + month: 'long', + day: 'numeric', + weekday: 'short', + }); + const timeStr = date.toLocaleTimeString('zh-CN', { + hour: '2-digit', + minute: '2-digit', + }); + + if (days > 0) { + return `${dateStr} ${timeStr}(${days}天${hours}小时后)`; + } else if (hours > 0) { + return `${dateStr} ${timeStr}(${hours}小时后)`; + } + return `${dateStr} ${timeStr}`; + }; + + // 获取最小日期(明天) + const getMinDate = () => { + const tomorrow = new Date(); + tomorrow.setDate(tomorrow.getDate() + 1); + return tomorrow.toISOString().split('T')[0]; + }; + + // 获取最大日期(90天后) + const getMaxDate = () => { + const maxDate = new Date(); + maxDate.setDate(maxDate.getDate() + 90); + return maxDate.toISOString().split('T')[0]; + }; + // 提交表单 const handleSubmit = async () => { try { @@ -105,9 +172,27 @@ const CreatePredictionModal = ({ isOpen, onClose, onTopicCreated }) => { return; } - // 计算截止时间 - const deadline = new Date(); - deadline.setDate(deadline.getDate() + parseInt(formData.deadline_days)); + // 验证截止时间 + if (!calculatedDeadline) { + toast({ + title: '请设置截止时间', + status: 'warning', + duration: 3000, + }); + return; + } + + // 检查截止时间是否在未来 + if (calculatedDeadline <= new Date()) { + toast({ + title: '截止时间必须在未来', + status: 'warning', + duration: 3000, + }); + return; + } + + const deadline = calculatedDeadline; // 调用 API 创建话题 const response = await createTopic({ @@ -130,7 +215,10 @@ const CreatePredictionModal = ({ isOpen, onClose, onTopicCreated }) => { title: '', description: '', category: 'stock', + deadline_type: 'preset', deadline_days: 7, + custom_date: '', + custom_time: '15:00', }); // 通知父组件 @@ -288,27 +376,175 @@ const CreatePredictionModal = ({ isOpen, onClose, onTopicCreated }) => { 交易截止时间 - handleChange('custom_date', e.target.value)} + min={getMinDate()} + max={getMaxDate()} + bg={forumColors.background.main} + border="1px solid" + borderColor={forumColors.border.default} + color={forumColors.text.primary} + _hover={{ borderColor: forumColors.border.light }} + _focus={{ + borderColor: forumColors.border.gold, + boxShadow: `0 0 0 1px ${forumColors.border.goldGlow}`, + }} + /> + + + + + 时间 + + handleChange('custom_time', e.target.value)} + bg={forumColors.background.main} + border="1px solid" + borderColor={forumColors.border.default} + color={forumColors.text.primary} + _hover={{ borderColor: forumColors.border.light }} + _focus={{ + borderColor: forumColors.border.gold, + boxShadow: `0 0 0 1px ${forumColors.border.goldGlow}`, + }} + /> + + + + + + + 建议选择 15:00(A股收盘时间)作为截止时间 + + + + + + + + {/* 截止时间预览 */} + - - - - - - + + + + 截止时间: + + + {formatDeadlineDisplay(calculatedDeadline)} + + + + - 截止后次日可提交结果进行结算 + 截止后交易自动锁定,由作者提交结果进行结算 diff --git a/src/views/ValueForum/components/PredictionTopicCard.js b/src/views/ValueForum/components/PredictionTopicCard.js index 561e186a..87078c74 100644 --- a/src/views/ValueForum/components/PredictionTopicCard.js +++ b/src/views/ValueForum/components/PredictionTopicCard.js @@ -3,7 +3,7 @@ * 展示预测市场的话题概览 */ -import React from 'react'; +import React, { useMemo } from 'react'; import { Box, Text, @@ -14,7 +14,6 @@ import { Flex, Avatar, Icon, - useColorModeValue, } from '@chakra-ui/react'; import { motion } from 'framer-motion'; import { @@ -22,18 +21,23 @@ import { TrendingDown, Crown, Users, - Clock, Coins, Zap, + Lock, + CheckCircle2, } from 'lucide-react'; import { useNavigate } from 'react-router-dom'; import { forumColors } from '@theme/forumTheme'; +import CountdownTimer, { useCountdown } from './CountdownTimer'; const MotionBox = motion(Box); const PredictionTopicCard = ({ topic }) => { const navigate = useNavigate(); + // 使用倒计时 Hook 获取实时状态 + const timeLeft = useCountdown(topic.deadline); + // 处理卡片点击 const handleCardClick = () => { navigate(`/value-forum/prediction/${topic.id}`); @@ -46,19 +50,14 @@ const PredictionTopicCard = ({ topic }) => { 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 effectiveStatus = useMemo(() => { + // 如果已经是结算状态,保持不变 + if (topic.status === 'settled') return 'settled'; + // 如果已过截止时间,自动变为已截止 + if (timeLeft.expired && topic.status === 'active') return 'trading_closed'; + return topic.status; + }, [topic.status, timeLeft.expired]); // 获取选项数据 const yesData = topic.positions?.yes || { total_shares: 0, current_price: 500, lord_id: null }; @@ -71,7 +70,7 @@ const PredictionTopicCard = ({ topic }) => { const yesPercent = totalShares > 0 ? (yesData.total_shares / totalShares) * 100 : 50; const noPercent = totalShares > 0 ? (noData.total_shares / totalShares) * 100 : 50; - // 状态颜色 + // 状态颜色(使用 effectiveStatus) const statusColorMap = { active: forumColors.success[500], trading_closed: forumColors.warning[500], @@ -80,10 +79,16 @@ const PredictionTopicCard = ({ topic }) => { const statusLabelMap = { active: '交易中', - trading_closed: '已截止', + trading_closed: '等待结算', settled: '已结算', }; + const statusIconMap = { + active: Zap, + trading_closed: Lock, + settled: CheckCircle2, + }; + return ( { > - - - 预测市场 + + + {statusLabelMap[effectiveStatus]} { fontSize="xs" fontWeight="bold" > - {statusLabelMap[topic.status]} + {effectiveStatus === 'active' ? '可交易' : effectiveStatus === 'trading_closed' ? '待结算' : '已完成'} @@ -270,7 +275,7 @@ const PredictionTopicCard = ({ topic }) => { {/* 奖池和数据 */} - + @@ -281,13 +286,16 @@ const PredictionTopicCard = ({ topic }) => { - {topic.stats?.unique_traders?.size || 0}人 + {topic.participants_count || topic.stats?.unique_traders?.size || 0}人 - - - {formatTime(topic.deadline)} - + {/* 使用新的倒计时组件 */} + {/* 底部:作者信息 */} diff --git a/src/views/ValueForum/components/SettleTopicModal.js b/src/views/ValueForum/components/SettleTopicModal.js new file mode 100644 index 00000000..edeb562b --- /dev/null +++ b/src/views/ValueForum/components/SettleTopicModal.js @@ -0,0 +1,332 @@ +/** + * 话题结算模态框 + * 允许话题创建者在截止后提交结算结果 + */ + +import React, { useState } from 'react'; +import { + Modal, + ModalOverlay, + ModalContent, + ModalHeader, + ModalBody, + ModalFooter, + ModalCloseButton, + Button, + VStack, + HStack, + Text, + Box, + Icon, + Alert, + AlertIcon, + useToast, + RadioGroup, + Radio, + Divider, +} from '@chakra-ui/react'; +import { CheckCircle2, TrendingUp, TrendingDown, Scale, AlertTriangle, Coins } from 'lucide-react'; +import { forumColors } from '@theme/forumTheme'; +import { settleTopic } from '@services/predictionMarketService.api'; +import { GLASS_BLUR } from '@/constants/glassConfig'; + +const SettleTopicModal = ({ isOpen, onClose, topic, onSettleSuccess }) => { + const toast = useToast(); + const [selectedResult, setSelectedResult] = useState(''); + const [isSubmitting, setIsSubmitting] = useState(false); + + // 获取选项数据 + const yesData = { + total_shares: topic?.yes_total_shares || 0, + current_price: topic?.yes_price || 500, + }; + const noData = { + total_shares: topic?.no_total_shares || 0, + current_price: topic?.no_price || 500, + }; + + 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 resultOptions = [ + { + value: 'yes', + label: '看涨方获胜 (Yes)', + icon: TrendingUp, + color: 'green', + description: `${yesData.total_shares} 份持仓将获得奖池分红`, + poolShare: yesData.total_shares > 0 ? topic?.total_pool : 0, + }, + { + value: 'no', + label: '看跌方获胜 (No)', + icon: TrendingDown, + color: 'red', + description: `${noData.total_shares} 份持仓将获得奖池分红`, + poolShare: noData.total_shares > 0 ? topic?.total_pool : 0, + }, + { + value: 'draw', + label: '平局 / 无效', + icon: Scale, + color: 'gray', + description: '所有参与者按持仓比例退回积分', + poolShare: 0, + }, + ]; + + const handleSubmit = async () => { + if (!selectedResult) { + toast({ + title: '请选择结算结果', + status: 'warning', + duration: 3000, + }); + return; + } + + try { + setIsSubmitting(true); + + const response = await settleTopic(topic.id, selectedResult); + + if (response.success) { + toast({ + title: '结算成功!', + description: `话题已结算,${resultOptions.find(o => o.value === selectedResult)?.label}`, + status: 'success', + duration: 5000, + }); + + if (onSettleSuccess) { + onSettleSuccess(response.data); + } + + onClose(); + } + } catch (error) { + console.error('结算失败:', error); + toast({ + title: '结算失败', + description: error.message || '请稍后重试', + status: 'error', + duration: 3000, + }); + } finally { + setIsSubmitting(false); + } + }; + + if (!topic) return null; + + return ( + + + + + + + 结算预测话题 + + + + + + + {/* 话题信息 */} + + + {topic.title} + + + {topic.description} + + + + {/* 市场数据摘要 */} + + + 看涨方 + + {yesPercent.toFixed(0)}% + + + {yesData.total_shares} 份 + + + + + + + 看跌方 + + {noPercent.toFixed(0)}% + + + {noData.total_shares} 份 + + + + + + + 奖池 + + + + {topic.total_pool} + + + 积分 + + + + {/* 警告提示 */} + + + + + 结算操作不可撤销 + + + 请确认预测结果后再提交,结算后将自动分配奖池给获胜方 + + + + + {/* 结算选项 */} + + + 选择结算结果 + + + + + {resultOptions.map((option) => ( + + + + + + + + + {option.label} + + + + {option.description} + + + + + {option.poolShare > 0 && ( + + + 奖池分配 + + + {option.poolShare} 积分 + + + )} + + + ))} + + + + + + + + + + + + + + + ); +}; + +export default SettleTopicModal;