feat: 继续重构 Community 子组件和 EventDetail 子组件
This commit is contained in:
@@ -15,6 +15,7 @@ import EventDiscussionModal from './EventDiscussionModal';
|
||||
import { useSubscription } from '../../../hooks/useSubscription';
|
||||
import SubscriptionUpgradeModal from '../../../components/SubscriptionUpgradeModal';
|
||||
import moment from 'moment';
|
||||
import { logger } from '../../../utils/logger';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
const { TabPane } = Tabs;
|
||||
@@ -58,24 +59,24 @@ const shouldRefreshData = (cacheKey) => {
|
||||
// 获取K线数据(带缓存和防重复请求)
|
||||
const fetchKlineData = async (stockCode, eventTime) => {
|
||||
const cacheKey = getCacheKey(stockCode, eventTime);
|
||||
|
||||
|
||||
// 1. 检查缓存
|
||||
if (klineDataCache.has(cacheKey)) {
|
||||
// 检查是否需要刷新
|
||||
if (!shouldRefreshData(cacheKey)) {
|
||||
console.log(`使用缓存数据: ${cacheKey}`);
|
||||
logger.debug('StockDetailPanel', '使用缓存数据', { cacheKey });
|
||||
return klineDataCache.get(cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 2. 检查是否有正在进行的请求
|
||||
if (pendingRequests.has(cacheKey)) {
|
||||
console.log(`等待进行中的请求: ${cacheKey}`);
|
||||
logger.debug('StockDetailPanel', '等待进行中的请求', { cacheKey });
|
||||
return pendingRequests.get(cacheKey);
|
||||
}
|
||||
|
||||
|
||||
// 3. 发起新请求
|
||||
console.log(`发起新请求: ${cacheKey}`);
|
||||
logger.debug('StockDetailPanel', '发起新K线数据请求', { cacheKey });
|
||||
const normalizedEventTime = eventTime ? moment(eventTime).format('YYYY-MM-DD HH:mm') : undefined;
|
||||
const requestPromise = stockService
|
||||
.getKlineData(stockCode, 'minute', normalizedEventTime)
|
||||
@@ -86,11 +87,14 @@ const fetchKlineData = async (stockCode, eventTime) => {
|
||||
lastRequestTime.set(cacheKey, Date.now());
|
||||
// 清除pending状态
|
||||
pendingRequests.delete(cacheKey);
|
||||
console.log(`请求完成并缓存: ${cacheKey}`);
|
||||
logger.debug('StockDetailPanel', 'K线数据请求完成并缓存', {
|
||||
cacheKey,
|
||||
dataPoints: data.length
|
||||
});
|
||||
return data;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(`获取${stockCode}的K线数据失败:`, error);
|
||||
logger.error('StockDetailPanel', 'fetchKlineData', error, { stockCode, cacheKey });
|
||||
// 清除pending状态
|
||||
pendingRequests.delete(cacheKey);
|
||||
// 如果有旧缓存,返回旧数据
|
||||
@@ -99,10 +103,10 @@ const fetchKlineData = async (stockCode, eventTime) => {
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
|
||||
// 保存pending请求
|
||||
pendingRequests.set(cacheKey, requestPromise);
|
||||
|
||||
|
||||
return requestPromise;
|
||||
};
|
||||
|
||||
@@ -284,7 +288,11 @@ const StockDetailModal = ({ stock, onClose, fixed, eventTime }) => {
|
||||
};
|
||||
|
||||
function StockDetailPanel({ visible, event, onClose }) {
|
||||
console.log('StockDetailPanel 组件已加载,visible:', visible, 'event:', event?.id);
|
||||
logger.debug('StockDetailPanel', '组件加载', {
|
||||
visible,
|
||||
eventId: event?.id,
|
||||
eventTitle: event?.title
|
||||
});
|
||||
|
||||
// 权限控制
|
||||
const { hasFeatureAccess, getRequiredLevel, getUpgradeRecommendation } = useSubscription();
|
||||
@@ -362,7 +370,10 @@ function StockDetailPanel({ visible, event, onClose }) {
|
||||
const codes = relatedStocks.map(s => s.stock_code);
|
||||
stockService.getQuotes(codes, event?.created_at)
|
||||
.then(quotes => setStockQuotes(quotes))
|
||||
.catch(error => console.error('更新行情失败:', error));
|
||||
.catch(error => logger.error('StockDetailPanel', 'updateQuotes', error, {
|
||||
stockCodes: codes,
|
||||
eventTime: event?.created_at
|
||||
}));
|
||||
};
|
||||
|
||||
updateQuotes();
|
||||
@@ -391,9 +402,12 @@ function StockDetailPanel({ visible, event, onClose }) {
|
||||
if (data.success && data.data) {
|
||||
const watchlistSet = new Set(data.data.map(item => item.stock_code));
|
||||
setWatchlistStocks(watchlistSet);
|
||||
logger.debug('StockDetailPanel', '自选股列表加载成功', {
|
||||
count: watchlistSet.size
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载自选股列表失败:', error);
|
||||
logger.error('StockDetailPanel', 'loadWatchlist', error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
@@ -452,7 +466,10 @@ function StockDetailPanel({ visible, event, onClose }) {
|
||||
|
||||
// 初始化数据加载
|
||||
useEffect(() => {
|
||||
console.log('[StockDetailPanel] useEffect 触发, visible:', visible, 'event:', event?.id);
|
||||
logger.debug('StockDetailPanel', 'useEffect 触发', {
|
||||
visible,
|
||||
eventId: event?.id
|
||||
});
|
||||
if (visible && event) {
|
||||
setActiveTab('stocks');
|
||||
loadAllData();
|
||||
@@ -461,27 +478,40 @@ function StockDetailPanel({ visible, event, onClose }) {
|
||||
|
||||
// 加载所有数据的函数
|
||||
const loadAllData = useCallback(() => {
|
||||
console.log('[StockDetailPanel] loadAllData 被调用, event:', event?.id);
|
||||
logger.debug('StockDetailPanel', 'loadAllData 被调用', {
|
||||
eventId: event?.id
|
||||
});
|
||||
if (!event) return;
|
||||
|
||||
// 加载自选股列表
|
||||
loadWatchlist();
|
||||
|
||||
|
||||
// 加载相关标的
|
||||
setLoading(true);
|
||||
eventService.getRelatedStocks(event.id)
|
||||
.then(res => {
|
||||
console.log('[前端] 接收到事件相关股票数据:', res);
|
||||
logger.debug('StockDetailPanel', '接收到事件相关股票数据', {
|
||||
eventId: event.id,
|
||||
success: res.success,
|
||||
stockCount: res.data?.length || 0
|
||||
});
|
||||
if (res.success) {
|
||||
console.log('[前端] 股票数据数组:', res.data);
|
||||
console.log('[前端] 第一只股票:', res.data[0]);
|
||||
console.log('[前端] 第一只股票的 relation_desc:', res.data[0]?.relation_desc);
|
||||
if (res.data && res.data[0]) {
|
||||
logger.debug('StockDetailPanel', '第一只股票数据', {
|
||||
stockCode: res.data[0].stock_code,
|
||||
stockName: res.data[0].stock_name,
|
||||
hasRelationDesc: !!res.data[0].relation_desc
|
||||
});
|
||||
}
|
||||
setRelatedStocks(res.data);
|
||||
if (res.data.length > 0) {
|
||||
const codes = res.data.map(s => s.stock_code);
|
||||
stockService.getQuotes(codes, event.created_at)
|
||||
.then(quotes => setStockQuotes(quotes))
|
||||
.catch(error => console.error('加载行情失败:', error));
|
||||
.catch(error => logger.error('StockDetailPanel', 'getQuotes', error, {
|
||||
stockCodes: codes,
|
||||
eventTime: event.created_at
|
||||
}));
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -593,7 +623,10 @@ function StockDetailPanel({ visible, event, onClose }) {
|
||||
key: 'relation_desc',
|
||||
width: 300,
|
||||
render: (relationDesc, record) => {
|
||||
console.log('[表格渲染] 股票:', record.stock_code, 'relation_desc:', relationDesc);
|
||||
logger.debug('StockDetailPanel', '表格渲染 - 股票关联描述', {
|
||||
stockCode: record.stock_code,
|
||||
hasRelationDesc: !!relationDesc
|
||||
});
|
||||
|
||||
// 处理 relation_desc 的两种格式
|
||||
let text = '';
|
||||
@@ -611,7 +644,10 @@ function StockDetailPanel({ visible, event, onClose }) {
|
||||
.filter(s => s)
|
||||
.join(';') || '--';
|
||||
} else {
|
||||
console.warn('[表格渲染] 未知的 relation_desc 格式:', relationDesc);
|
||||
logger.warn('StockDetailPanel', '未知的 relation_desc 格式', {
|
||||
stockCode: record.stock_code,
|
||||
relationDescType: typeof relationDesc
|
||||
});
|
||||
return '--';
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user