fix(FinancialPanorama): 优化期数切换和数据加载

- Tab 切换时检查期数是否一致,不一致则重新加载
- 股票切换时立即清空旧数据,确保显示骨架屏
- 表格右上角显示当前期数

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-12-19 16:16:12 +08:00
parent d394c25d7e
commit 0ad0287f7b
3 changed files with 60 additions and 9 deletions

View File

@@ -345,6 +345,12 @@ const UnifiedFinancialTableInner: React.FC<UnifiedFinancialTableProps> = ({
return (
<Box className={TABLE_CLASS_NAME}>
<style>{extendedTableStyles}</style>
{/* 右上角显示期数标签 */}
<HStack justify="flex-end" mb={1}>
<Text fontSize="2xs" color="gray.500">
{displayData.length}
</Text>
</HStack>
<ConfigProvider theme={BLACK_GOLD_TABLE_THEME}>
<Table
columns={columns}

View File

@@ -62,6 +62,7 @@ interface UseFinancialDataReturn {
setStockCode: (code: string) => void;
setSelectedPeriods: (periods: number) => void;
setActiveTab: (tabKey: DataTypeKey) => void;
handleTabChange: (tabKey: DataTypeKey) => void; // Tab 切换时自动检查期数
// 当前参数
currentStockCode: string;
@@ -140,22 +141,34 @@ export const useFinancialData = (
switch (dataType) {
case 'balance': {
const res = await financialService.getBalanceSheet(stockCode, periods, options);
if (res.success) setBalanceSheet(res.data);
if (res.success) {
setBalanceSheet(res.data);
dataPeriodsRef.current.balance = periods;
}
break;
}
case 'income': {
const res = await financialService.getIncomeStatement(stockCode, periods, options);
if (res.success) setIncomeStatement(res.data);
if (res.success) {
setIncomeStatement(res.data);
dataPeriodsRef.current.income = periods;
}
break;
}
case 'cashflow': {
const res = await financialService.getCashflow(stockCode, periods, options);
if (res.success) setCashflow(res.data);
if (res.success) {
setCashflow(res.data);
dataPeriodsRef.current.cashflow = periods;
}
break;
}
case 'metrics': {
const res = await financialService.getFinancialMetrics(stockCode, periods, options);
if (res.success) setFinancialMetrics(res.data);
if (res.success) {
setFinancialMetrics(res.data);
dataPeriodsRef.current.metrics = periods;
}
break;
}
}
@@ -205,6 +218,17 @@ export const useFinancialData = (
setSelectedPeriodsState(periods);
}, []);
// Tab 切换处理:检查期数是否需要重新加载
const handleTabChange = useCallback((tabKey: DataTypeKey) => {
setActiveTab(tabKey);
const dataType = getDataTypeForTab(tabKey);
// 如果该 Tab 数据的期数与当前选择的期数不一致,重新加载
// 注refetchByTab 使用传入的 tabKey不依赖 activeTab 状态,无需延迟
if (dataPeriodsRef.current[dataType] !== selectedPeriods) {
refetchByTab(tabKey);
}
}, [selectedPeriods, refetchByTab]);
// 加载核心财务数据初始加载stockInfo + metrics + comparison
const loadCoreFinancialData = useCallback(async () => {
if (!stockCode || stockCode.length !== 6) {
@@ -243,7 +267,10 @@ export const useFinancialData = (
// 设置数据
if (stockInfoRes.success) setStockInfo(stockInfoRes.data);
if (metricsRes.success) setFinancialMetrics(metricsRes.data);
if (metricsRes.success) {
setFinancialMetrics(metricsRes.data);
dataPeriodsRef.current.metrics = selectedPeriods;
}
if (comparisonRes.success) setComparison(comparisonRes.data);
if (businessRes.success) setMainBusiness(businessRes.data);
@@ -277,6 +304,23 @@ export const useFinancialData = (
// 初始加载(仅股票代码变化时全量加载)
useEffect(() => {
if (stockCode) {
// 立即清空所有旧数据,触发骨架屏
setStockInfo(null);
setBalanceSheet([]);
setIncomeStatement([]);
setCashflow([]);
setFinancialMetrics([]);
setMainBusiness(null);
setComparison([]);
// 重置期数记录
dataPeriodsRef.current = {
balance: 0,
income: 0,
cashflow: 0,
metrics: 0,
};
loadAllFinancialData();
isInitialLoad.current = false;
}
@@ -319,6 +363,7 @@ export const useFinancialData = (
setStockCode,
setSelectedPeriods,
setActiveTab,
handleTabChange,
// 当前参数
currentStockCode: stockCode,

View File

@@ -90,15 +90,15 @@ const FinancialPanorama: React.FC<FinancialPanoramaProps> = ({ stockCode: propSt
refetchByTab,
selectedPeriods,
setSelectedPeriods,
setActiveTab,
handleTabChange: handleTabChangeWithPeriodCheck,
activeTab,
} = useFinancialData({ stockCode: propStockCode });
// 处理 Tab 切换
// 处理 Tab 切换(使用 hook 提供的带期数检查的函数)
const handleTabChange = useCallback((index: number, tabKey: string) => {
const dataTypeKey = TAB_KEY_MAP[index] || (tabKey as DataTypeKey);
setActiveTab(dataTypeKey);
}, [setActiveTab]);
handleTabChangeWithPeriodCheck(dataTypeKey);
}, [handleTabChangeWithPeriodCheck]);
// 处理刷新 - 只刷新当前 Tab
const handleRefresh = useCallback(() => {