feat: 新增实时要闻·动态追踪与市场复盘功能,优化导航体验

新增功能:
- 实时要闻·动态追踪横向滚动卡片(DynamicNewsCard)
- 动态新闻事件卡片组件(DynamicNewsEventCard)
- 市场复盘卡片组件(MarketReviewCard)
- 股票涨跌幅指标组件(StockChangeIndicators)
- 交易时间工具函数(tradingTimeUtils)
- Mock API 支持动态新闻数据生成

UI 优化:
- EventFollowButton 改用 react-icons 星星图标,实现真正的空心/实心效果
- 关注按钮添加半透明白色背景(whiteAlpha.500),悬停效果更明显
- 事件卡片标题添加右侧留白,防止关注按钮遮挡文字

性能优化:
- 禁用 Router v7_startTransition 特性,解决路由切换延迟 2 秒问题
- 调整导航菜单点击顺序(先跳转后关闭),提升响应速度

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-10-31 14:11:03 +08:00
parent 5d8ad5e442
commit c372832f1f
11 changed files with 1211 additions and 23 deletions

View File

@@ -1,5 +1,5 @@
// src/views/Community/index.js
import React, { useState, useEffect, useRef, useCallback } from 'react';
import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import { fetchPopularKeywords, fetchHotEvents } from '../../store/slices/communityDataSlice';
@@ -11,6 +11,8 @@ import {
// 导入组件
import EventTimelineCard from './components/EventTimelineCard';
import DynamicNewsCard from './components/DynamicNewsCard';
import MarketReviewCard from './components/MarketReviewCard';
import HotEventsSection from './components/HotEventsSection';
import EventModals from './components/EventModals';
@@ -19,6 +21,13 @@ import { useEventData } from './hooks/useEventData';
import { useEventFilters } from './hooks/useEventFilters';
import { useCommunityEvents } from './hooks/useCommunityEvents';
// 导入时间工具函数
import {
getCurrentTradingTimeRange,
getMarketReviewTimeRange,
filterEventsByTimeRange
} from '../../utils/tradingTimeUtils';
import { logger } from '../../utils/logger';
import { useNotification } from '../../contexts/NotificationContext';
import { usePostHogTrack } from '../../hooks/usePostHogRedux';
@@ -48,6 +57,10 @@ const Community = () => {
const [selectedEvent, setSelectedEvent] = useState(null);
const [selectedEventForStock, setSelectedEventForStock] = useState(null);
// 动态新闻数据状态
const [dynamicNewsEvents, setDynamicNewsEvents] = useState([]);
const [dynamicNewsLoading, setDynamicNewsLoading] = useState(true);
// 🎯 初始化Community埋点Hook
const communityEvents = useCommunityEvents({ navigate });
@@ -60,12 +73,64 @@ const Community = () => {
const { events, pagination, loading, lastUpdateTime } = useEventData(filters);
// 计算市场复盘的时间范围和过滤后的事件
const marketReviewData = useMemo(() => {
const timeRange = getMarketReviewTimeRange();
const filteredEvents = filterEventsByTimeRange(events, timeRange.startTime, timeRange.endTime);
logger.debug('Community', '市场复盘时间范围', {
description: timeRange.description,
rangeType: timeRange.rangeType,
eventCount: filteredEvents.length
});
return {
events: filteredEvents,
timeRange
};
}, [events]);
// 加载热门关键词和热点事件使用Redux内部有缓存判断
useEffect(() => {
dispatch(fetchPopularKeywords());
dispatch(fetchHotEvents());
}, [dispatch]);
// 加载动态新闻数据
useEffect(() => {
const fetchDynamicNews = async () => {
setDynamicNewsLoading(true);
try {
const timeRange = getCurrentTradingTimeRange();
const response = await fetch(
`/api/events/dynamic-news?start_time=${timeRange.startTime.toISOString()}&end_time=${timeRange.endTime.toISOString()}&count=30`,
{ credentials: 'include' }
);
const data = await response.json();
if (data.success && data.data) {
setDynamicNewsEvents(data.data);
logger.info('Community', '动态新闻加载成功', {
count: data.data.length,
timeRange: timeRange.description
});
} else {
logger.warn('Community', '动态新闻加载失败', data);
setDynamicNewsEvents([]);
}
} catch (error) {
logger.error('Community', '动态新闻加载异常', error);
setDynamicNewsEvents([]);
} finally {
setDynamicNewsLoading(false);
}
};
fetchDynamicNews();
// 每5分钟刷新一次动态新闻
const interval = setInterval(fetchDynamicNews, 5 * 60 * 1000);
return () => clearInterval(interval);
}, []);
// 🎯 PostHog 追踪:页面浏览
// useEffect(() => {
// track(RETENTION_EVENTS.COMMUNITY_PAGE_VIEWED, {
@@ -120,7 +185,28 @@ const Community = () => {
{/* 热点事件区域 */}
<HotEventsSection events={hotEvents} />
{/* 实时事件 */}
{/* 实时要闻·动态追踪 - 横向滚动 */}
<DynamicNewsCard
mt={6}
events={dynamicNewsEvents}
loading={dynamicNewsLoading}
lastUpdateTime={lastUpdateTime}
onEventClick={handleEventClick}
onViewDetail={handleViewDetail}
/>
{/* 市场复盘 - 左右布局 */}
<MarketReviewCard
mt={6}
events={marketReviewData.events}
loading={loading}
lastUpdateTime={lastUpdateTime}
onEventClick={handleEventClick}
onViewDetail={handleViewDetail}
onToggleFollow={() => {}}
/>
{/* 实时事件 - 原纵向列表 */}
<EventTimelineCard
ref={eventTimelineRef}
mt={6}