// src/views/Community/components/EventDetailModal.js import React, { useState, useEffect } from 'react'; import { Modal, Spin, Descriptions, Tag, List, Badge, Empty, Input, Button, message } from 'antd'; import { eventService } from '../../../services/eventService'; import { logger } from '../../../utils/logger'; import moment from 'moment'; const EventDetailModal = ({ visible, event, onClose }) => { const [loading, setLoading] = useState(false); const [eventDetail, setEventDetail] = useState(null); const [commentText, setCommentText] = useState(''); const [submitting, setSubmitting] = useState(false); const [comments, setComments] = useState([]); const [commentsLoading, setCommentsLoading] = useState(false); const loadEventDetail = async () => { if (!event) return; setLoading(true); try { const response = await eventService.getEventDetail(event.id); if (response.success) { setEventDetail(response.data); } } catch (error) { logger.error('EventDetailModal', 'loadEventDetail', error, { eventId: event?.id }); } finally { setLoading(false); } }; const loadComments = async () => { if (!event) return; setCommentsLoading(true); try { // 使用统一的posts API获取评论 const result = await eventService.getPosts(event.id); if (result.success) { setComments(result.data || []); } } catch (error) { logger.error('EventDetailModal', 'loadComments', error, { eventId: event?.id }); } finally { setCommentsLoading(false); } }; useEffect(() => { if (visible && event) { loadEventDetail(); loadComments(); } }, [visible, event]); const getImportanceColor = (importance) => { const colors = { S: 'red', A: 'orange', B: 'blue', C: 'green' }; return colors[importance] || 'default'; }; const getRelationDesc = (relationDesc) => { // 处理空值 if (!relationDesc) return ''; // 如果是字符串,直接返回 if (typeof relationDesc === 'string') { return relationDesc; } // 如果是对象且包含data数组 if (typeof relationDesc === 'object' && relationDesc.data && Array.isArray(relationDesc.data)) { const firstItem = relationDesc.data[0]; if (firstItem) { // 优先使用 query_part,其次使用 sentences return firstItem.query_part || firstItem.sentences || ''; } } // 其他情况返回空字符串 return ''; }; const renderPriceTag = (value, label) => { if (value === null || value === undefined) return `${label}: --`; const color = value > 0 ? '#ff4d4f' : '#52c41a'; const prefix = value > 0 ? '+' : ''; return ( {label}: {prefix}{value.toFixed(2)}% ); }; const handleSubmitComment = async () => { if (!commentText.trim()) { message.warning('请输入评论内容'); return; } setSubmitting(true); try { // 使用统一的createPost API const result = await eventService.createPost(event.id, { content: commentText.trim(), content_type: 'text' }); if (result.success) { message.success('评论发布成功'); setCommentText(''); // 重新加载评论列表 loadComments(); } else { throw new Error(result.message || '评论失败'); } } catch (e) { message.error(e.message || '评论失败'); } finally { setSubmitting(false); } }; return ( {eventDetail && ( <> {moment(eventDetail.created_at).format('YYYY-MM-DD HH:mm:ss')} {eventDetail.creator?.username || 'Anonymous'} {eventDetail.view_count || 0} {renderPriceTag(eventDetail.related_avg_chg, '平均涨幅')} {renderPriceTag(eventDetail.related_max_chg, '最大涨幅')} {renderPriceTag(eventDetail.related_week_chg, '周涨幅')} {eventDetail.description}(AI合成) {eventDetail.keywords && eventDetail.keywords.length > 0 && (

相关概念

{eventDetail.keywords.map((keyword, index) => ( {keyword} ))}
)} {eventDetail.related_stocks && eventDetail.related_stocks.length > 0 && (

相关股票

( { const stockCode = stock.stock_code.split('.')[0]; window.open(`https://valuefrontier.cn/company?scode=${stockCode}`, '_blank'); }} > 股票详情 ]} > {stock.change !== null && ( 0 ? 'red' : 'green'}> {stock.change > 0 ? '+' : ''}{stock.change.toFixed(2)}% )} )} />
)} {/* 讨论区 */}

讨论区

{/* 评论列表 */}
{comments.length === 0 ? ( ) : ( ( {comment.author?.username || 'Anonymous'} {moment(comment.created_at).format('MM-DD HH:mm')}
} description={
{comment.content}
} /> )} /> )}
{/* 评论输入框(登录后可用,未登录后端会返回401) */}

发表评论

setCommentText(e.target.value)} maxLength={500} showCount />
)}
); }; export default EventDetailModal;