// src/views/Community/components/StockDetailPanel/hooks/useEventStocks.js import { useSelector, useDispatch, shallowEqual } from 'react-redux'; import { useEffect, useCallback, useMemo } from 'react'; import { fetchEventStocks, fetchStockQuotes, fetchEventDetail, fetchHistoricalEvents, fetchChainAnalysis, fetchExpectationScore } from '../../../../../store/slices/stockSlice'; import { logger } from '../../../../../utils/logger'; /** * 事件股票数据 Hook * 封装事件相关的所有数据加载逻辑 * * @param {string} eventId - 事件ID * @param {string} eventTime - 事件时间 * @param {Object} options - 配置选项 * @param {boolean} options.autoLoad - 是否自动加载数据(默认true) * @returns {Object} 事件数据和加载状态 */ export const useEventStocks = (eventId, eventTime, { autoLoad = true } = {}) => { const dispatch = useDispatch(); // 从 Redux 获取数据 const stocks = useSelector(state => eventId ? (state.stock.eventStocksCache[eventId] || []) : [], shallowEqual // 防止不必要的引用变化 ); const quotes = useSelector(state => state.stock.quotes, shallowEqual); const eventDetail = useSelector(state => eventId ? state.stock.eventDetailsCache[eventId] : null ); const historicalEvents = useSelector(state => eventId ? (state.stock.historicalEventsCache[eventId] || []) : [], shallowEqual // 防止不必要的引用变化 ); const chainAnalysis = useSelector(state => eventId ? state.stock.chainAnalysisCache[eventId] : null ); const expectationScore = useSelector(state => eventId ? state.stock.expectationScores[eventId] : null ); // 加载状态 const loading = useSelector(state => state.stock.loading, shallowEqual); // 拆分加载函数 - 相关股票数据 const loadStocksData = useCallback(() => { if (!eventId) return; logger.debug('useEventStocks', '加载股票数据', { eventId }); dispatch(fetchEventStocks({ eventId })); }, [dispatch, eventId]); // 拆分加载函数 - 历史事件数据 const loadHistoricalData = useCallback(() => { if (!eventId) return; logger.debug('useEventStocks', '加载历史事件数据', { eventId }); dispatch(fetchHistoricalEvents({ eventId })); dispatch(fetchExpectationScore({ eventId })); }, [dispatch, eventId]); // 拆分加载函数 - 传导链分析数据 const loadChainAnalysis = useCallback(() => { if (!eventId) return; logger.debug('useEventStocks', '加载传导链数据', { eventId }); dispatch(fetchChainAnalysis({ eventId })); }, [dispatch, eventId]); // 加载所有数据(保留用于兼容性) const loadAllData = useCallback(() => { if (!eventId) { logger.warn('useEventStocks', 'eventId 为空,跳过数据加载'); return; } logger.debug('useEventStocks', '开始加载事件所有数据', { eventId }); // 并发加载所有数据 dispatch(fetchEventDetail({ eventId })); loadStocksData(); loadHistoricalData(); loadChainAnalysis(); }, [dispatch, eventId, loadStocksData, loadHistoricalData, loadChainAnalysis]); // 强制刷新所有数据 const refreshAllData = useCallback(() => { if (!eventId) return; logger.debug('useEventStocks', '强制刷新事件数据', { eventId }); dispatch(fetchEventStocks({ eventId, forceRefresh: true })); dispatch(fetchEventDetail({ eventId, forceRefresh: true })); dispatch(fetchHistoricalEvents({ eventId, forceRefresh: true })); dispatch(fetchChainAnalysis({ eventId, forceRefresh: true })); dispatch(fetchExpectationScore({ eventId })); }, [dispatch, eventId]); // 只刷新行情数据 const refreshQuotes = useCallback(() => { if (stocks.length === 0) return; const codes = stocks.map(s => s.stock_code); logger.debug('useEventStocks', '刷新行情数据', { stockCount: codes.length, eventTime }); dispatch(fetchStockQuotes({ codes, eventTime })); }, [dispatch, stocks, eventTime]); // 自动加载事件数据(可通过 autoLoad 参数控制) useEffect(() => { if (eventId && autoLoad) { logger.debug('useEventStocks', '自动加载已启用,加载所有数据', { eventId, autoLoad }); loadAllData(); } else if (eventId && !autoLoad) { logger.debug('useEventStocks', '自动加载已禁用,等待手动触发', { eventId, autoLoad }); // 禁用自动加载时,不加载任何数据 } }, [eventId, autoLoad, loadAllData]); // 添加 loadAllData 依赖 // 自动加载行情数据 useEffect(() => { if (stocks.length > 0) { refreshQuotes(); } }, [stocks.length, eventId]); // 注意:这里不依赖 refreshQuotes,避免重复请求 // 计算股票行情合并数据 const stocksWithQuotes = useMemo(() => { return stocks.map(stock => ({ ...stock, quote: quotes[stock.stock_code] || null })); }, [stocks, quotes]); return { // 数据 stocks, stocksWithQuotes, quotes, eventDetail, historicalEvents, chainAnalysis, expectationScore, // 加载状态 loading: { stocks: loading.stocks, quotes: loading.quotes, eventDetail: loading.eventDetail, historicalEvents: loading.historicalEvents, chainAnalysis: loading.chainAnalysis }, // 方法 loadAllData, loadStocksData, // 新增:加载股票数据 loadHistoricalData, // 新增:加载历史事件数据 loadChainAnalysis, // 新增:加载传导链数据(重命名避免冲突) refreshAllData, refreshQuotes }; };