- 迁移 klineDataCache.js 到 src/utils/stock/(被 StockChart 使用) - 迁移 InvestmentCalendar 到 src/components/InvestmentCalendar/(被 Navbar、Dashboard 使用) - 迁移 DynamicNewsDetail 到 src/components/EventDetailPanel/(被 EventDetail 使用) - 更新所有相关导入路径,使用路径别名 - 保持 Community 目录其余结构不变 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
117 lines
3.2 KiB
JavaScript
117 lines
3.2 KiB
JavaScript
/**
|
||
* EventDetail - 事件详情页面
|
||
* 使用 DynamicNewsDetailPanel 组件展示事件详情
|
||
*/
|
||
|
||
import React, { useState, useEffect } from 'react';
|
||
import { useParams, useSearchParams } from 'react-router-dom';
|
||
import {
|
||
Box,
|
||
Spinner,
|
||
Center,
|
||
} from '@chakra-ui/react';
|
||
import { decodeEventId } from '@/utils/idEncoder';
|
||
import { eventService } from '@/services/eventService';
|
||
import { DynamicNewsDetailPanel } from '@components/EventDetailPanel';
|
||
import { logger } from '@/utils/logger';
|
||
import ErrorPage from '@/components/ErrorPage';
|
||
|
||
const EventDetail = () => {
|
||
const { eventId: pathEventId } = useParams();
|
||
const [searchParams] = useSearchParams();
|
||
|
||
// 优先从查询参数获取加密 ID,兼容旧的路径参数
|
||
const encodedId = searchParams.get('id');
|
||
const eventId = encodedId ? decodeEventId(encodedId) : pathEventId;
|
||
|
||
// 状态
|
||
const [eventData, setEventData] = useState(null);
|
||
const [loading, setLoading] = useState(true);
|
||
const [error, setError] = useState(null);
|
||
|
||
// 加载事件基础数据
|
||
useEffect(() => {
|
||
const loadEventData = async () => {
|
||
if (!eventId) {
|
||
setError('无效的事件ID');
|
||
setLoading(false);
|
||
return;
|
||
}
|
||
|
||
try {
|
||
setLoading(true);
|
||
setError(null);
|
||
const response = await eventService.getEventDetail(eventId);
|
||
setEventData(response.data);
|
||
} catch (err) {
|
||
logger.error('EventDetail', 'loadEventData', err, { eventId });
|
||
setError(err.message || '加载事件数据失败');
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
loadEventData();
|
||
}, [eventId]);
|
||
|
||
// 加载状态
|
||
if (loading) {
|
||
return (
|
||
<Box minH="100vh" w="100%">
|
||
<Center py={20}>
|
||
<Spinner size="xl" color="blue.500" />
|
||
</Center>
|
||
</Box>
|
||
);
|
||
}
|
||
|
||
// 错误状态
|
||
if (error) {
|
||
return (
|
||
<ErrorPage
|
||
title="事件走丢了"
|
||
subtitle={encodedId ? `ID: ${encodedId}` : undefined}
|
||
description="抱歉,我们找不到您请求的事件,这可能是因为:"
|
||
detail={eventId}
|
||
detailLabel="事件ID"
|
||
reasons={[
|
||
{
|
||
icon: '🔍',
|
||
title: '事件ID输入错误',
|
||
description: '请检查URL中的事件ID是否正确',
|
||
},
|
||
{
|
||
icon: '🗑️',
|
||
title: '该事件已被删除或下架',
|
||
description: '该事件可能因过期或内容调整而被移除',
|
||
},
|
||
{
|
||
icon: '🔄',
|
||
title: '系统暂时无法访问该事件',
|
||
description: '请稍后重试或联系技术支持',
|
||
},
|
||
]}
|
||
techDetails={{
|
||
requestUrl: window.location.href,
|
||
errorType: '404 - Event Not Found',
|
||
errorMessage: error,
|
||
timestamp: new Date().toISOString(),
|
||
relatedId: eventId,
|
||
}}
|
||
showRetry
|
||
onRetry={() => window.location.reload()}
|
||
showBack
|
||
showHome
|
||
homePath="/community"
|
||
/>
|
||
);
|
||
}
|
||
|
||
// 主内容
|
||
return (
|
||
<Box maxW="7xl" mx="auto"><DynamicNewsDetailPanel event={eventData} showHeader={true} /></Box>
|
||
);
|
||
};
|
||
|
||
export default EventDetail;
|