Files
vf_react/src/views/Community/components/StockDetailPanel/hooks/useEventStocks.js
2025-11-05 08:29:44 +08:00

168 lines
5.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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
};
};