feat: 实现 Redux 全局状态管理事件关注功能
本次提交实现了滚动列表和事件详情的关注按钮状态同步: ✅ Redux 状态管理 - communityDataSlice.js: 添加 eventFollowStatus state - 新增 toggleEventFollow AsyncThunk(复用 EventList.js 逻辑) - 新增 setEventFollowStatus reducer 和 selectEventFollowStatus selector ✅ 组件集成 - DynamicNewsCard.js: 从 Redux 读取关注状态并传递给子组件 - EventScrollList.js: 接收并传递关注状态给事件卡片 - DynamicNewsDetailPanel.js: 移除本地 state,使用 Redux 状态 ✅ Mock API 支持 - event.js: 添加 POST /api/events/:eventId/follow 处理器 - 返回 { is_following, follower_count } 模拟数据 ✅ Bug 修复 - EventDetail/index.js: 添加 useRef 导入 - concept.js: 导出 generatePopularConcepts 函数 - event.js: 添加 /api/events/:eventId/concepts 处理器 功能: - 点击滚动列表的关注按钮,详情面板的关注状态自动同步 - 点击详情面板的关注按钮,滚动列表的关注状态自动同步 - 关注人数实时更新 - 状态在整个应用中保持一致 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
// 动态新闻详情面板主组件(组装所有子组件)
|
||||
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import {
|
||||
Card,
|
||||
CardBody,
|
||||
@@ -15,6 +16,7 @@ import {
|
||||
import { getImportanceConfig } from '../../../../constants/importanceLevels';
|
||||
import { eventService } from '../../../../services/eventService';
|
||||
import { useEventStocks } from '../StockDetailPanel/hooks/useEventStocks';
|
||||
import { toggleEventFollow, selectEventFollowStatus } from '../../../../store/slices/communityDataSlice';
|
||||
import EventHeaderInfo from './EventHeaderInfo';
|
||||
import EventDescriptionSection from './EventDescriptionSection';
|
||||
import RelatedConceptsSection from './RelatedConceptsSection';
|
||||
@@ -29,11 +31,17 @@ import TransmissionChainAnalysis from '../../../EventDetail/components/Transmiss
|
||||
* @param {Object} props.event - 事件对象(包含详情数据)
|
||||
*/
|
||||
const DynamicNewsDetailPanel = ({ event }) => {
|
||||
const dispatch = useDispatch();
|
||||
const cardBg = useColorModeValue('white', 'gray.800');
|
||||
const borderColor = useColorModeValue('gray.200', 'gray.700');
|
||||
const textColor = useColorModeValue('gray.600', 'gray.400');
|
||||
const toast = useToast();
|
||||
|
||||
// 从 Redux 读取关注状态
|
||||
const eventFollowStatus = useSelector(selectEventFollowStatus);
|
||||
const isFollowing = event?.id ? (eventFollowStatus[event.id]?.isFollowing || false) : false;
|
||||
const followerCount = event?.id ? (eventFollowStatus[event.id]?.followerCount || event.follower_count || 0) : 0;
|
||||
|
||||
// 使用 Hook 获取实时数据
|
||||
const {
|
||||
stocks,
|
||||
@@ -49,10 +57,6 @@ const DynamicNewsDetailPanel = ({ event }) => {
|
||||
const [isHistoricalOpen, setIsHistoricalOpen] = useState(true);
|
||||
const [isTransmissionOpen, setIsTransmissionOpen] = useState(false);
|
||||
|
||||
// 关注状态管理
|
||||
const [isFollowing, setIsFollowing] = useState(false);
|
||||
const [followerCount, setFollowerCount] = useState(0);
|
||||
|
||||
// 自选股管理(使用 localStorage)
|
||||
const [watchlistSet, setWatchlistSet] = useState(() => {
|
||||
try {
|
||||
@@ -64,23 +68,10 @@ const DynamicNewsDetailPanel = ({ event }) => {
|
||||
});
|
||||
|
||||
// 切换关注状态
|
||||
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 handleToggleFollow = useCallback(async () => {
|
||||
if (!event?.id) return;
|
||||
dispatch(toggleEventFollow(event.id));
|
||||
}, [dispatch, event?.id]);
|
||||
|
||||
// 切换自选股
|
||||
const handleWatchlistToggle = useCallback(async (stockCode, isInWatchlist) => {
|
||||
|
||||
Reference in New Issue
Block a user