update pay function
This commit is contained in:
386
src/views/ValueForum/components/CreatePredictionModal.js
Normal file
386
src/views/ValueForum/components/CreatePredictionModal.js
Normal file
@@ -0,0 +1,386 @@
|
||||
/**
|
||||
* 创建预测话题模态框
|
||||
* 用户可以发起新的预测市场话题
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Modal,
|
||||
ModalOverlay,
|
||||
ModalContent,
|
||||
ModalHeader,
|
||||
ModalBody,
|
||||
ModalFooter,
|
||||
ModalCloseButton,
|
||||
Button,
|
||||
VStack,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
Input,
|
||||
Textarea,
|
||||
Select,
|
||||
HStack,
|
||||
Text,
|
||||
Box,
|
||||
Icon,
|
||||
Alert,
|
||||
AlertIcon,
|
||||
useToast,
|
||||
} from '@chakra-ui/react';
|
||||
import { Zap, Calendar, DollarSign } from 'lucide-react';
|
||||
import { forumColors } from '@theme/forumTheme';
|
||||
import { createTopic } from '@services/predictionMarketService';
|
||||
import { getUserAccount, CREDIT_CONFIG } from '@services/creditSystemService';
|
||||
import { useAuth } from '@contexts/AuthContext';
|
||||
|
||||
const CreatePredictionModal = ({ isOpen, onClose, onTopicCreated }) => {
|
||||
const toast = useToast();
|
||||
const { user } = useAuth();
|
||||
|
||||
// 表单状态
|
||||
const [formData, setFormData] = useState({
|
||||
title: '',
|
||||
description: '',
|
||||
category: 'stock',
|
||||
deadline_days: 7,
|
||||
});
|
||||
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// 获取用户余额
|
||||
const userAccount = user ? getUserAccount(user.id) : null;
|
||||
|
||||
// 处理表单变化
|
||||
const handleChange = (field, value) => {
|
||||
setFormData((prev) => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
|
||||
// 验证
|
||||
if (!formData.title.trim()) {
|
||||
toast({
|
||||
title: '请填写话题标题',
|
||||
status: 'warning',
|
||||
duration: 3000,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!formData.description.trim()) {
|
||||
toast({
|
||||
title: '请填写话题描述',
|
||||
status: 'warning',
|
||||
duration: 3000,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查余额
|
||||
if (userAccount.balance < CREDIT_CONFIG.CREATE_TOPIC_COST) {
|
||||
toast({
|
||||
title: '积分不足',
|
||||
description: `创建话题需要${CREDIT_CONFIG.CREATE_TOPIC_COST}积分`,
|
||||
status: 'error',
|
||||
duration: 3000,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算截止时间
|
||||
const deadline = new Date();
|
||||
deadline.setDate(deadline.getDate() + parseInt(formData.deadline_days));
|
||||
|
||||
const settlement_date = new Date(deadline);
|
||||
settlement_date.setDate(settlement_date.getDate() + 1);
|
||||
|
||||
// 创建话题
|
||||
const newTopic = createTopic({
|
||||
author_id: user.id,
|
||||
author_name: user.name || user.username,
|
||||
author_avatar: user.avatar,
|
||||
title: formData.title,
|
||||
description: formData.description,
|
||||
category: formData.category,
|
||||
deadline: deadline.toISOString(),
|
||||
settlement_date: settlement_date.toISOString(),
|
||||
});
|
||||
|
||||
toast({
|
||||
title: '创建成功!',
|
||||
description: `话题已发布,扣除${CREDIT_CONFIG.CREATE_TOPIC_COST}积分`,
|
||||
status: 'success',
|
||||
duration: 3000,
|
||||
});
|
||||
|
||||
// 重置表单
|
||||
setFormData({
|
||||
title: '',
|
||||
description: '',
|
||||
category: 'stock',
|
||||
deadline_days: 7,
|
||||
});
|
||||
|
||||
// 通知父组件
|
||||
if (onTopicCreated) {
|
||||
onTopicCreated(newTopic);
|
||||
}
|
||||
|
||||
onClose();
|
||||
} catch (error) {
|
||||
console.error('创建话题失败:', error);
|
||||
toast({
|
||||
title: '创建失败',
|
||||
description: error.message,
|
||||
status: 'error',
|
||||
duration: 3000,
|
||||
});
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={onClose} size="xl" isCentered>
|
||||
<ModalOverlay backdropFilter="blur(4px)" />
|
||||
<ModalContent
|
||||
bg={forumColors.background.card}
|
||||
borderRadius="xl"
|
||||
border="1px solid"
|
||||
borderColor={forumColors.border.default}
|
||||
>
|
||||
<ModalHeader
|
||||
bg={forumColors.gradients.goldSubtle}
|
||||
borderTopRadius="xl"
|
||||
borderBottom="1px solid"
|
||||
borderColor={forumColors.border.default}
|
||||
>
|
||||
<HStack spacing="2">
|
||||
<Icon as={Zap} boxSize="20px" color={forumColors.primary[500]} />
|
||||
<Text color={forumColors.text.primary}>发起预测话题</Text>
|
||||
</HStack>
|
||||
</ModalHeader>
|
||||
<ModalCloseButton color={forumColors.text.primary} />
|
||||
|
||||
<ModalBody py="6">
|
||||
<VStack spacing="5" align="stretch">
|
||||
{/* 提示信息 */}
|
||||
<Alert
|
||||
status="info"
|
||||
bg={forumColors.background.hover}
|
||||
borderRadius="lg"
|
||||
border="1px solid"
|
||||
borderColor={forumColors.border.default}
|
||||
>
|
||||
<AlertIcon color={forumColors.primary[500]} />
|
||||
<VStack align="start" spacing="1" flex="1">
|
||||
<Text fontSize="sm" color={forumColors.text.primary} fontWeight="600">
|
||||
创建预测话题
|
||||
</Text>
|
||||
<Text fontSize="xs" color={forumColors.text.secondary}>
|
||||
• 创建费用:{CREDIT_CONFIG.CREATE_TOPIC_COST}积分(进入奖池)
|
||||
</Text>
|
||||
<Text fontSize="xs" color={forumColors.text.secondary}>
|
||||
• 作者不能参与自己发起的话题
|
||||
</Text>
|
||||
<Text fontSize="xs" color={forumColors.text.secondary}>
|
||||
• 截止后由作者提交结果进行结算
|
||||
</Text>
|
||||
</VStack>
|
||||
</Alert>
|
||||
|
||||
{/* 话题标题 */}
|
||||
<FormControl isRequired>
|
||||
<FormLabel fontSize="sm" color={forumColors.text.primary}>
|
||||
话题标题
|
||||
</FormLabel>
|
||||
<Input
|
||||
placeholder="例如:贵州茅台下周会涨吗?"
|
||||
value={formData.title}
|
||||
onChange={(e) => handleChange('title', e.target.value)}
|
||||
bg={forumColors.background.main}
|
||||
border="1px solid"
|
||||
borderColor={forumColors.border.default}
|
||||
color={forumColors.text.primary}
|
||||
_placeholder={{ color: forumColors.text.tertiary }}
|
||||
_hover={{ borderColor: forumColors.border.light }}
|
||||
_focus={{
|
||||
borderColor: forumColors.border.gold,
|
||||
boxShadow: `0 0 0 1px ${forumColors.border.goldGlow}`,
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
{/* 话题描述 */}
|
||||
<FormControl isRequired>
|
||||
<FormLabel fontSize="sm" color={forumColors.text.primary}>
|
||||
话题描述
|
||||
</FormLabel>
|
||||
<Textarea
|
||||
placeholder="详细描述预测的内容、判断标准、数据来源等..."
|
||||
value={formData.description}
|
||||
onChange={(e) => handleChange('description', e.target.value)}
|
||||
rows={4}
|
||||
bg={forumColors.background.main}
|
||||
border="1px solid"
|
||||
borderColor={forumColors.border.default}
|
||||
color={forumColors.text.primary}
|
||||
_placeholder={{ color: forumColors.text.tertiary }}
|
||||
_hover={{ borderColor: forumColors.border.light }}
|
||||
_focus={{
|
||||
borderColor: forumColors.border.gold,
|
||||
boxShadow: `0 0 0 1px ${forumColors.border.goldGlow}`,
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
{/* 分类 */}
|
||||
<FormControl>
|
||||
<FormLabel fontSize="sm" color={forumColors.text.primary}>
|
||||
分类
|
||||
</FormLabel>
|
||||
<Select
|
||||
value={formData.category}
|
||||
onChange={(e) => handleChange('category', 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}`,
|
||||
}}
|
||||
>
|
||||
<option value="stock">股票行情</option>
|
||||
<option value="index">指数走势</option>
|
||||
<option value="concept">概念板块</option>
|
||||
<option value="policy">政策影响</option>
|
||||
<option value="event">事件预测</option>
|
||||
<option value="other">其他</option>
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
{/* 截止时间 */}
|
||||
<FormControl>
|
||||
<FormLabel fontSize="sm" color={forumColors.text.primary}>
|
||||
<HStack spacing="2">
|
||||
<Icon as={Calendar} boxSize="16px" />
|
||||
<Text>交易截止时间</Text>
|
||||
</HStack>
|
||||
</FormLabel>
|
||||
<Select
|
||||
value={formData.deadline_days}
|
||||
onChange={(e) => handleChange('deadline_days', 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}`,
|
||||
}}
|
||||
>
|
||||
<option value="1">1天后</option>
|
||||
<option value="3">3天后</option>
|
||||
<option value="7">7天后(推荐)</option>
|
||||
<option value="14">14天后</option>
|
||||
<option value="30">30天后</option>
|
||||
</Select>
|
||||
<Text fontSize="xs" color={forumColors.text.tertiary} mt="2">
|
||||
截止后次日可提交结果进行结算
|
||||
</Text>
|
||||
</FormControl>
|
||||
|
||||
{/* 费用说明 */}
|
||||
<Box
|
||||
bg={forumColors.gradients.goldSubtle}
|
||||
border="1px solid"
|
||||
borderColor={forumColors.border.gold}
|
||||
borderRadius="lg"
|
||||
p="4"
|
||||
>
|
||||
<HStack justify="space-between">
|
||||
<VStack align="start" spacing="1">
|
||||
<Text fontSize="sm" fontWeight="600" color={forumColors.text.primary}>
|
||||
创建费用
|
||||
</Text>
|
||||
<Text fontSize="xs" color={forumColors.text.secondary}>
|
||||
将进入奖池,奖励给获胜者
|
||||
</Text>
|
||||
</VStack>
|
||||
|
||||
<HStack spacing="1">
|
||||
<Icon as={DollarSign} boxSize="20px" color={forumColors.primary[500]} />
|
||||
<Text fontSize="2xl" fontWeight="bold" color={forumColors.primary[500]}>
|
||||
{CREDIT_CONFIG.CREATE_TOPIC_COST}
|
||||
</Text>
|
||||
<Text fontSize="sm" color={forumColors.text.secondary}>
|
||||
积分
|
||||
</Text>
|
||||
</HStack>
|
||||
</HStack>
|
||||
|
||||
<Box mt="3" pt="3" borderTop="1px solid" borderColor={forumColors.border.default}>
|
||||
<HStack justify="space-between" fontSize="sm">
|
||||
<Text color={forumColors.text.secondary}>你的余额:</Text>
|
||||
<Text fontWeight="600" color={forumColors.text.primary}>
|
||||
{userAccount?.balance || 0} 积分
|
||||
</Text>
|
||||
</HStack>
|
||||
<HStack justify="space-between" fontSize="sm" mt="1">
|
||||
<Text color={forumColors.text.secondary}>创建后:</Text>
|
||||
<Text
|
||||
fontWeight="600"
|
||||
color={
|
||||
(userAccount?.balance || 0) >= CREDIT_CONFIG.CREATE_TOPIC_COST
|
||||
? forumColors.success[500]
|
||||
: forumColors.error[500]
|
||||
}
|
||||
>
|
||||
{(userAccount?.balance || 0) - CREDIT_CONFIG.CREATE_TOPIC_COST} 积分
|
||||
</Text>
|
||||
</HStack>
|
||||
</Box>
|
||||
</Box>
|
||||
</VStack>
|
||||
</ModalBody>
|
||||
|
||||
<ModalFooter borderTop="1px solid" borderColor={forumColors.border.default}>
|
||||
<HStack spacing="3">
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={onClose}
|
||||
color={forumColors.text.secondary}
|
||||
_hover={{ bg: forumColors.background.hover }}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
bg={forumColors.gradients.goldPrimary}
|
||||
color={forumColors.background.main}
|
||||
fontWeight="bold"
|
||||
onClick={handleSubmit}
|
||||
isLoading={isSubmitting}
|
||||
loadingText="创建中..."
|
||||
isDisabled={(userAccount?.balance || 0) < CREDIT_CONFIG.CREATE_TOPIC_COST}
|
||||
_hover={{
|
||||
opacity: 0.9,
|
||||
transform: 'translateY(-2px)',
|
||||
}}
|
||||
_active={{ transform: 'translateY(0)' }}
|
||||
>
|
||||
发布话题
|
||||
</Button>
|
||||
</HStack>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default CreatePredictionModal;
|
||||
Reference in New Issue
Block a user