update pay ui
This commit is contained in:
@@ -25,9 +25,13 @@ const RelatedStocksSection = ({
|
||||
watchlistSet = new Set(),
|
||||
onWatchlistToggle
|
||||
}) => {
|
||||
// K线数据状态:{ [stockCode]: data[] }
|
||||
const [klineDataMap, setKlineDataMap] = useState({});
|
||||
const [klineLoading, setKlineLoading] = useState(false);
|
||||
// 分时图数据状态:{ [stockCode]: data[] }
|
||||
const [timelineDataMap, setTimelineDataMap] = useState({});
|
||||
const [timelineLoading, setTimelineLoading] = useState(false);
|
||||
|
||||
// 日K线数据状态:{ [stockCode]: data[] }
|
||||
const [dailyDataMap, setDailyDataMap] = useState({});
|
||||
const [dailyLoading, setDailyLoading] = useState(false);
|
||||
|
||||
// 稳定的事件时间
|
||||
const stableEventTime = useMemo(() => {
|
||||
@@ -40,67 +44,113 @@ const RelatedStocksSection = ({
|
||||
return stocks.map(s => s.stock_code).sort().join(',');
|
||||
}, [stocks]);
|
||||
|
||||
// 计算是否应该显示 loading
|
||||
const shouldShowLoading = useMemo(() => {
|
||||
// 计算分时图是否应该显示 loading
|
||||
const shouldShowTimelineLoading = useMemo(() => {
|
||||
if (!stocks || stocks.length === 0) return false;
|
||||
const currentDataKeys = Object.keys(klineDataMap).sort().join(',');
|
||||
const currentDataKeys = Object.keys(timelineDataMap).sort().join(',');
|
||||
if (stocksKey !== currentDataKeys) {
|
||||
return true;
|
||||
}
|
||||
return klineLoading;
|
||||
}, [stocks, stocksKey, klineDataMap, klineLoading]);
|
||||
return timelineLoading;
|
||||
}, [stocks, stocksKey, timelineDataMap, timelineLoading]);
|
||||
|
||||
// 批量加载K线数据
|
||||
// 计算日K线是否应该显示 loading
|
||||
const shouldShowDailyLoading = useMemo(() => {
|
||||
if (!stocks || stocks.length === 0) return false;
|
||||
const currentDataKeys = Object.keys(dailyDataMap).sort().join(',');
|
||||
if (stocksKey !== currentDataKeys) {
|
||||
return true;
|
||||
}
|
||||
return dailyLoading;
|
||||
}, [stocks, stocksKey, dailyDataMap, dailyLoading]);
|
||||
|
||||
// 批量加载分时图数据
|
||||
useEffect(() => {
|
||||
if (!stocks || stocks.length === 0) {
|
||||
setKlineDataMap({});
|
||||
setKlineLoading(false);
|
||||
setTimelineDataMap({});
|
||||
setTimelineLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 立即设置 loading 状态
|
||||
setKlineLoading(true);
|
||||
|
||||
setTimelineLoading(true);
|
||||
const stockCodes = stocks.map(s => s.stock_code);
|
||||
|
||||
// 先检查缓存
|
||||
// 检查缓存
|
||||
const cachedData = {};
|
||||
const uncachedCodes = [];
|
||||
stockCodes.forEach(code => {
|
||||
const cacheKey = getCacheKey(code, stableEventTime, 'timeline');
|
||||
const cached = klineDataCache.get(cacheKey);
|
||||
if (cached !== undefined) {
|
||||
cachedData[code] = cached;
|
||||
} else {
|
||||
uncachedCodes.push(code);
|
||||
}
|
||||
});
|
||||
|
||||
// 如果全部缓存命中,直接使用
|
||||
if (uncachedCodes.length === 0) {
|
||||
setKlineDataMap(cachedData);
|
||||
setKlineLoading(false);
|
||||
logger.debug('RelatedStocksSection', 'K线数据全部来自缓存', { stockCount: stockCodes.length });
|
||||
if (Object.keys(cachedData).length === stockCodes.length) {
|
||||
setTimelineDataMap(cachedData);
|
||||
setTimelineLoading(false);
|
||||
logger.debug('RelatedStocksSection', '分时图数据全部来自缓存', { stockCount: stockCodes.length });
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug('RelatedStocksSection', '批量加载K线数据', {
|
||||
logger.debug('RelatedStocksSection', '批量加载分时图数据', {
|
||||
totalCount: stockCodes.length,
|
||||
cachedCount: Object.keys(cachedData).length,
|
||||
uncachedCount: uncachedCodes.length,
|
||||
eventTime: stableEventTime
|
||||
});
|
||||
|
||||
// 批量请求
|
||||
fetchBatchKlineData(stockCodes, stableEventTime, 'timeline')
|
||||
.then((batchData) => {
|
||||
setKlineDataMap({ ...cachedData, ...batchData });
|
||||
setKlineLoading(false);
|
||||
setTimelineDataMap({ ...cachedData, ...batchData });
|
||||
setTimelineLoading(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error('RelatedStocksSection', '批量加载K线数据失败', error);
|
||||
setKlineDataMap(cachedData);
|
||||
setKlineLoading(false);
|
||||
logger.error('RelatedStocksSection', '批量加载分时图数据失败', error);
|
||||
setTimelineDataMap(cachedData);
|
||||
setTimelineLoading(false);
|
||||
});
|
||||
}, [stocksKey, stableEventTime]);
|
||||
|
||||
// 批量加载日K线数据
|
||||
useEffect(() => {
|
||||
if (!stocks || stocks.length === 0) {
|
||||
setDailyDataMap({});
|
||||
setDailyLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setDailyLoading(true);
|
||||
const stockCodes = stocks.map(s => s.stock_code);
|
||||
|
||||
// 检查缓存
|
||||
const cachedData = {};
|
||||
stockCodes.forEach(code => {
|
||||
const cacheKey = getCacheKey(code, stableEventTime, 'daily');
|
||||
const cached = klineDataCache.get(cacheKey);
|
||||
if (cached !== undefined) {
|
||||
cachedData[code] = cached;
|
||||
}
|
||||
});
|
||||
|
||||
if (Object.keys(cachedData).length === stockCodes.length) {
|
||||
setDailyDataMap(cachedData);
|
||||
setDailyLoading(false);
|
||||
logger.debug('RelatedStocksSection', '日K线数据全部来自缓存', { stockCount: stockCodes.length });
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug('RelatedStocksSection', '批量加载日K线数据', {
|
||||
totalCount: stockCodes.length,
|
||||
eventTime: stableEventTime
|
||||
});
|
||||
|
||||
fetchBatchKlineData(stockCodes, stableEventTime, 'daily')
|
||||
.then((batchData) => {
|
||||
setDailyDataMap({ ...cachedData, ...batchData });
|
||||
setDailyLoading(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error('RelatedStocksSection', '批量加载日K线数据失败', error);
|
||||
setDailyDataMap(cachedData);
|
||||
setDailyLoading(false);
|
||||
});
|
||||
}, [stocksKey, stableEventTime]);
|
||||
|
||||
@@ -119,8 +169,10 @@ const RelatedStocksSection = ({
|
||||
eventTime={eventTime}
|
||||
isInWatchlist={watchlistSet.has(stock.stock_code)}
|
||||
onWatchlistToggle={onWatchlistToggle}
|
||||
klineData={klineDataMap[stock.stock_code]}
|
||||
klineLoading={shouldShowLoading && !klineDataMap[stock.stock_code]}
|
||||
timelineData={timelineDataMap[stock.stock_code]}
|
||||
timelineLoading={shouldShowTimelineLoading && !timelineDataMap[stock.stock_code]}
|
||||
dailyData={dailyDataMap[stock.stock_code]}
|
||||
dailyLoading={shouldShowDailyLoading && !dailyDataMap[stock.stock_code]}
|
||||
/>
|
||||
))}
|
||||
</VStack>
|
||||
|
||||
Reference in New Issue
Block a user