import React, { useState, useEffect } from 'react'; import { useParams, useLocation } from 'react-router-dom'; import { Box, Container, VStack, HStack, Spinner, Alert, AlertIcon, AlertTitle, AlertDescription, Flex, useColorModeValue, Grid, GridItem, Icon, Text, Badge, Divider, useDisclosure, Button, Heading, Stat, StatLabel, StatNumber, StatHelpText, SimpleGrid, Tabs, TabList, TabPanels, Tab, TabPanel, Textarea, Avatar, IconButton, Input, Collapse, Center, useToast, Skeleton, } from '@chakra-ui/react'; import { FiLock } from 'react-icons/fi'; import { FiTrendingUp, FiActivity, FiMessageSquare, FiClock, FiBarChart2, FiLink, FiZap, FiGlobe, FiHeart, FiTrash2, FiChevronDown, FiChevronUp, } from 'react-icons/fi'; import { FaHeart, FaRegHeart, FaComment } from 'react-icons/fa'; import { format } from 'date-fns'; import { zhCN } from 'date-fns/locale'; // 导入新建的业务组件 import EventHeader from './components/EventHeader'; import RelatedConcepts from './components/RelatedConcepts'; import HistoricalEvents from './components/HistoricalEvents'; import RelatedStocks from './components/RelatedStocks'; // Navigation bar now provided by MainLayout // import HomeNavbar from '../../components/Navbars/HomeNavbar'; import SubscriptionUpgradeModal from '../../components/SubscriptionUpgradeModal'; import { useAuth } from '../../contexts/AuthContext'; import { useSubscription } from '../../hooks/useSubscription'; import TransmissionChainAnalysis from './components/TransmissionChainAnalysis'; // 导入你的 Flask API 服务 import { eventService } from '../../services/eventService'; import { debugEventService } from '../../utils/debugEventService'; import { logger } from '../../utils/logger'; import { useEventDetailEvents } from './hooks/useEventDetailEvents'; // 临时调试代码 - 生产环境测试后请删除 if (typeof window !== 'undefined') { logger.debug('EventDetail', '调试 eventService'); debugEventService(); } // 统计卡片组件 - 更简洁的设计 const StatCard = ({ icon, label, value, color }) => { const bg = useColorModeValue('white', 'gray.800'); const borderColor = useColorModeValue('gray.200', 'gray.700'); const iconColor = useColorModeValue(`${color}.500`, `${color}.300`); return ( {label} {value} ); }; // 帖子组件 const PostItem = ({ post, onRefresh, eventEvents }) => { const [showComments, setShowComments] = useState(false); const [comments, setComments] = useState([]); const [newComment, setNewComment] = useState(''); const [isLoading, setIsLoading] = useState(false); const [liked, setLiked] = useState(post.liked || false); const [likesCount, setLikesCount] = useState(post.likes_count || 0); const toast = useToast(); const { user } = useAuth(); const bg = useColorModeValue('white', 'gray.800'); const borderColor = useColorModeValue('gray.200', 'gray.700'); const loadComments = async () => { if (!showComments) { setShowComments(true); setIsLoading(true); try { const result = await eventService.getPostComments(post.id); if (result.success) { setComments(result.data); } } catch (error) { logger.error('PostItem', 'loadComments', error, { postId: post.id }); } finally { setIsLoading(false); } } else { setShowComments(false); } }; const handleLike = async () => { try { const result = await eventService.likePost(post.id); if (result.success) { const newLikedState = result.liked; setLiked(newLikedState); setLikesCount(result.likes_count); // 🎯 追踪评论点赞 if (eventEvents && eventEvents.trackCommentLiked) { eventEvents.trackCommentLiked(post.id, newLikedState); } } } catch (error) { toast({ title: '操作失败', status: 'error', duration: 2000, }); } }; const handleAddComment = async () => { if (!newComment.trim()) return; try { const result = await eventService.addPostComment(post.id, { content: newComment, }); if (result.success) { // 🎯 追踪添加评论 if (eventEvents && eventEvents.trackCommentAdded) { eventEvents.trackCommentAdded( result.data?.id || post.id, newComment.length ); } toast({ title: '评论发表成功', status: 'success', duration: 2000, }); setNewComment(''); // 重新加载评论 const commentsResult = await eventService.getPostComments(post.id); if (commentsResult.success) { setComments(commentsResult.data); } } } catch (error) { toast({ title: '评论失败', status: 'error', duration: 2000, }); } }; const handleDelete = async () => { if (window.confirm('确定要删除这个帖子吗?')) { try { const result = await eventService.deletePost(post.id); if (result.success) { // 🎯 追踪删除评论 if (eventEvents && eventEvents.trackCommentDeleted) { eventEvents.trackCommentDeleted(post.id); } toast({ title: '删除成功', status: 'success', duration: 2000, }); onRefresh(); } } catch (error) { toast({ title: '删除失败', status: 'error', duration: 2000, }); } } }; return ( {/* 帖子头部 */} {post.user?.username || '匿名用户'} {format(new Date(post.created_at), 'yyyy-MM-dd HH:mm', { locale: zhCN })} } variant="ghost" size="sm" onClick={handleDelete} /> {/* 帖子内容 */} {post.title && ( {post.title} )} {post.content} {/* 操作栏 */} {/* 评论区 */} {/* 评论输入 */}