fix: 个股中心页面日期数据源统一
- fetchTopConcepts: 始终设置 selectedDate 和 availableDates - fetchHeatmapData: 移除 setSelectedDate - fetchMarketStats: 移除 setSelectedDate 和 setAvailableDates - 新增 src/data/tradingDays.json: 交易日历数据(从 tdays.csv 转换) - availableDates 基于交易日历生成,确保日期列表完整且包含最新日期 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
1
src/data/tradingDays.json
Normal file
1
src/data/tradingDays.json
Normal file
File diff suppressed because one or more lines are too long
@@ -59,7 +59,11 @@ import { FaChartLine, FaFire, FaRocket, FaBrain, FaCalendarAlt, FaChevronRight,
|
|||||||
import { BsGraphUp, BsLightningFill } from 'react-icons/bs';
|
import { BsGraphUp, BsLightningFill } from 'react-icons/bs';
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import { logger } from '../../utils/logger';
|
import { logger } from '../../utils/logger';
|
||||||
|
import tradingDays from '../../data/tradingDays.json';
|
||||||
import { useStockOverviewEvents } from './hooks/useStockOverviewEvents';
|
import { useStockOverviewEvents } from './hooks/useStockOverviewEvents';
|
||||||
|
|
||||||
|
// 交易日 Set,用于快速查找
|
||||||
|
const tradingDaysSet = new Set(tradingDays);
|
||||||
// Navigation bar now provided by MainLayout
|
// Navigation bar now provided by MainLayout
|
||||||
// import HomeNavbar from '../../components/Navbars/HomeNavbar';
|
// import HomeNavbar from '../../components/Navbars/HomeNavbar';
|
||||||
|
|
||||||
@@ -173,7 +177,27 @@ const StockOverview = () => {
|
|||||||
|
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
setTopConcepts(data.data);
|
setTopConcepts(data.data);
|
||||||
if (!selectedDate) setSelectedDate(data.trade_date);
|
// 使用概念接口的日期作为统一数据源(数据最新)
|
||||||
|
setSelectedDate(data.trade_date);
|
||||||
|
// 基于交易日历生成可选日期列表
|
||||||
|
if (data.trade_date && tradingDays.length > 0) {
|
||||||
|
// 找到当前日期或最近的交易日
|
||||||
|
let targetDate = data.trade_date;
|
||||||
|
if (!tradingDaysSet.has(data.trade_date)) {
|
||||||
|
for (let i = tradingDays.length - 1; i >= 0; i--) {
|
||||||
|
if (tradingDays[i] <= data.trade_date) {
|
||||||
|
targetDate = tradingDays[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const idx = tradingDays.indexOf(targetDate);
|
||||||
|
if (idx !== -1) {
|
||||||
|
const startIdx = Math.max(0, idx - 19);
|
||||||
|
const dates = tradingDays.slice(startIdx, idx + 1).reverse();
|
||||||
|
setAvailableDates(dates);
|
||||||
|
}
|
||||||
|
}
|
||||||
logger.debug('StockOverview', '热门概念加载成功', {
|
logger.debug('StockOverview', '热门概念加载成功', {
|
||||||
count: data.data?.length || 0,
|
count: data.data?.length || 0,
|
||||||
date: data.trade_date
|
date: data.trade_date
|
||||||
@@ -204,7 +228,7 @@ const StockOverview = () => {
|
|||||||
falling_count: data.statistics.falling_count
|
falling_count: data.statistics.falling_count
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
if (!selectedDate) setSelectedDate(data.trade_date);
|
// 日期由 fetchTopConcepts 统一设置,这里不再设置
|
||||||
logger.debug('StockOverview', '热力图数据加载成功', {
|
logger.debug('StockOverview', '热力图数据加载成功', {
|
||||||
count: data.data?.length || 0,
|
count: data.data?.length || 0,
|
||||||
date: data.trade_date
|
date: data.trade_date
|
||||||
@@ -235,11 +259,9 @@ const StockOverview = () => {
|
|||||||
date: data.trade_date
|
date: data.trade_date
|
||||||
};
|
};
|
||||||
setMarketStats(newStats);
|
setMarketStats(newStats);
|
||||||
setAvailableDates(data.available_dates || []);
|
// 日期和可选日期列表由 fetchTopConcepts 统一设置,这里不再设置
|
||||||
if (!selectedDate) setSelectedDate(data.trade_date);
|
|
||||||
logger.debug('StockOverview', '市场统计数据加载成功', {
|
logger.debug('StockOverview', '市场统计数据加载成功', {
|
||||||
date: data.trade_date,
|
date: data.trade_date
|
||||||
availableDatesCount: data.available_dates?.length || 0
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 🎯 追踪市场统计数据查看
|
// 🎯 追踪市场统计数据查看
|
||||||
@@ -975,36 +997,36 @@ const StockOverview = () => {
|
|||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
<Box w="100%">
|
<Box w="100%">
|
||||||
<Text fontSize="xs" color="gray.500" mb={2}>
|
<Text fontSize="xs" color="gray.500" mb={2}>
|
||||||
包含 {concept.stock_count} 只个股
|
包含 {concept.stock_count} 只个股
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
{concept.stocks && concept.stocks.length > 0 && (
|
|
||||||
<Flex flexWrap="wrap" gap={2}>
|
|
||||||
{concept.stocks.map((stock, idx) => (
|
|
||||||
<Tag
|
|
||||||
key={idx}
|
|
||||||
size="sm"
|
|
||||||
colorScheme="purple"
|
|
||||||
variant="subtle"
|
|
||||||
cursor="pointer"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
// 🎯 追踪概念下的股票标签点击
|
{concept.stocks && concept.stocks.length > 0 && (
|
||||||
trackConceptStockClicked({
|
<Flex flexWrap="wrap" gap={2}>
|
||||||
code: stock.stock_code,
|
{concept.stocks.map((stock, idx) => (
|
||||||
name: stock.stock_name
|
<Tag
|
||||||
}, concept.concept_name);
|
key={idx}
|
||||||
|
size="sm"
|
||||||
|
colorScheme="purple"
|
||||||
|
variant="subtle"
|
||||||
|
cursor="pointer"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
navigate(`/company?scode=${stock.stock_code}`);
|
// 🎯 追踪概念下的股票标签点击
|
||||||
}}
|
trackConceptStockClicked({
|
||||||
>
|
code: stock.stock_code,
|
||||||
<TagLabel>{stock.stock_name}</TagLabel>
|
name: stock.stock_name
|
||||||
</Tag>
|
}, concept.concept_name);
|
||||||
))}
|
|
||||||
</Flex>
|
navigate(`/company?scode=${stock.stock_code}`);
|
||||||
)}
|
}}
|
||||||
|
>
|
||||||
|
<TagLabel>{stock.stock_name}</TagLabel>
|
||||||
|
</Tag>
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<HStack spacing={2} w="100%">
|
<HStack spacing={2} w="100%">
|
||||||
|
|||||||
Reference in New Issue
Block a user