// src/views/Community/components/DynamicNewsDetail/DynamicNewsDetailPanel.js // 动态新闻详情面板主组件(组装所有子组件) import React, { useState, useMemo, useCallback } from 'react'; import { Card, CardBody, VStack, Text, useColorModeValue, useToast, } from '@chakra-ui/react'; import { getImportanceConfig } from '../../../../constants/importanceLevels'; import { eventService } from '../../../../services/eventService'; import EventHeaderInfo from './EventHeaderInfo'; import EventDescriptionSection from './EventDescriptionSection'; import RelatedConceptsSection from './RelatedConceptsSection'; import RelatedStocksSection from './RelatedStocksSection'; import CollapsibleSection from './CollapsibleSection'; import HistoricalEvents from '../../../EventDetail/components/HistoricalEvents'; import TransmissionChainAnalysis from '../../../EventDetail/components/TransmissionChainAnalysis'; /** * 动态新闻详情面板主组件 * @param {Object} props * @param {Object} props.event - 事件对象(包含详情数据) */ const DynamicNewsDetailPanel = ({ event }) => { const cardBg = useColorModeValue('white', 'gray.800'); const borderColor = useColorModeValue('gray.200', 'gray.700'); const textColor = useColorModeValue('gray.600', 'gray.400'); const toast = useToast(); // 折叠状态管理 const [isStocksOpen, setIsStocksOpen] = useState(true); const [isHistoricalOpen, setIsHistoricalOpen] = useState(false); const [isTransmissionOpen, setIsTransmissionOpen] = useState(false); // 关注状态管理 const [isFollowing, setIsFollowing] = useState(false); const [followerCount, setFollowerCount] = useState(0); // 自选股管理(使用 localStorage) const [watchlistSet, setWatchlistSet] = useState(() => { try { const saved = localStorage.getItem('stock_watchlist'); return saved ? new Set(JSON.parse(saved)) : new Set(); } catch { return new Set(); } }); // 生成模拟行情数据 const quotes = useMemo(() => { if (!event?.related_stocks) return {}; const quotesData = {}; event.related_stocks.forEach(stock => { // 优先使用 stock.daily_change,否则生成随机涨跌幅 const change = stock.daily_change ? parseFloat(stock.daily_change) : (Math.random() * 10 - 3); // -3% ~ +7% quotesData[stock.stock_code] = { change: change, price: 10 + Math.random() * 90 // 模拟价格 10-100 }; }); return quotesData; }, [event?.related_stocks]); // 切换关注状态 const handleToggleFollow = async () => { try { if (isFollowing) { // 取消关注 await eventService.unfollowEvent(event.id); setIsFollowing(false); setFollowerCount(prev => Math.max(0, prev - 1)); } else { // 添加关注 await eventService.followEvent(event.id); setIsFollowing(true); setFollowerCount(prev => prev + 1); } } catch (error) { console.error('切换关注状态失败:', error); } }; // 切换自选股 const handleWatchlistToggle = useCallback(async (stockCode, isInWatchlist) => { try { const newWatchlist = new Set(watchlistSet); if (isInWatchlist) { newWatchlist.delete(stockCode); toast({ title: '已移除自选股', status: 'info', duration: 2000, isClosable: true, }); } else { newWatchlist.add(stockCode); toast({ title: '已添加至自选股', status: 'success', duration: 2000, isClosable: true, }); } setWatchlistSet(newWatchlist); localStorage.setItem('stock_watchlist', JSON.stringify(Array.from(newWatchlist))); } catch (error) { console.error('切换自选股失败:', error); toast({ title: '操作失败', description: error.message, status: 'error', duration: 3000, isClosable: true, }); } }, [watchlistSet, toast]); // 空状态 if (!event) { return ( 请选择一个事件查看详情 ); } const importance = getImportanceConfig(event.importance); return ( {/* 头部信息区 */} {/* 事件描述 */} {/* 相关概念 */} {/* 相关股票(可折叠) */} setIsStocksOpen(!isStocksOpen)} onWatchlistToggle={handleWatchlistToggle} /> {/* 历史事件对比(可折叠) */} setIsHistoricalOpen(!isHistoricalOpen)} count={event.historical_events?.length || 0} > {/* 传导链分析(可折叠) */} setIsTransmissionOpen(!isTransmissionOpen)} > ); }; export default DynamicNewsDetailPanel;