fix(FinancialPanorama): 优化期数切换和数据加载
- Tab 切换时检查期数是否一致,不一致则重新加载 - 股票切换时立即清空旧数据,确保显示骨架屏 - 表格右上角显示当前期数 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -345,6 +345,12 @@ const UnifiedFinancialTableInner: React.FC<UnifiedFinancialTableProps> = ({
|
|||||||
return (
|
return (
|
||||||
<Box className={TABLE_CLASS_NAME}>
|
<Box className={TABLE_CLASS_NAME}>
|
||||||
<style>{extendedTableStyles}</style>
|
<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}>
|
<ConfigProvider theme={BLACK_GOLD_TABLE_THEME}>
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ interface UseFinancialDataReturn {
|
|||||||
setStockCode: (code: string) => void;
|
setStockCode: (code: string) => void;
|
||||||
setSelectedPeriods: (periods: number) => void;
|
setSelectedPeriods: (periods: number) => void;
|
||||||
setActiveTab: (tabKey: DataTypeKey) => void;
|
setActiveTab: (tabKey: DataTypeKey) => void;
|
||||||
|
handleTabChange: (tabKey: DataTypeKey) => void; // Tab 切换时自动检查期数
|
||||||
|
|
||||||
// 当前参数
|
// 当前参数
|
||||||
currentStockCode: string;
|
currentStockCode: string;
|
||||||
@@ -140,22 +141,34 @@ export const useFinancialData = (
|
|||||||
switch (dataType) {
|
switch (dataType) {
|
||||||
case 'balance': {
|
case 'balance': {
|
||||||
const res = await financialService.getBalanceSheet(stockCode, periods, options);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case 'income': {
|
case 'income': {
|
||||||
const res = await financialService.getIncomeStatement(stockCode, periods, options);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case 'cashflow': {
|
case 'cashflow': {
|
||||||
const res = await financialService.getCashflow(stockCode, periods, options);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case 'metrics': {
|
case 'metrics': {
|
||||||
const res = await financialService.getFinancialMetrics(stockCode, periods, options);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,6 +218,17 @@ export const useFinancialData = (
|
|||||||
setSelectedPeriodsState(periods);
|
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)
|
// 加载核心财务数据(初始加载:stockInfo + metrics + comparison)
|
||||||
const loadCoreFinancialData = useCallback(async () => {
|
const loadCoreFinancialData = useCallback(async () => {
|
||||||
if (!stockCode || stockCode.length !== 6) {
|
if (!stockCode || stockCode.length !== 6) {
|
||||||
@@ -243,7 +267,10 @@ export const useFinancialData = (
|
|||||||
|
|
||||||
// 设置数据
|
// 设置数据
|
||||||
if (stockInfoRes.success) setStockInfo(stockInfoRes.data);
|
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 (comparisonRes.success) setComparison(comparisonRes.data);
|
||||||
if (businessRes.success) setMainBusiness(businessRes.data);
|
if (businessRes.success) setMainBusiness(businessRes.data);
|
||||||
|
|
||||||
@@ -277,6 +304,23 @@ export const useFinancialData = (
|
|||||||
// 初始加载(仅股票代码变化时全量加载)
|
// 初始加载(仅股票代码变化时全量加载)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (stockCode) {
|
if (stockCode) {
|
||||||
|
// 立即清空所有旧数据,触发骨架屏
|
||||||
|
setStockInfo(null);
|
||||||
|
setBalanceSheet([]);
|
||||||
|
setIncomeStatement([]);
|
||||||
|
setCashflow([]);
|
||||||
|
setFinancialMetrics([]);
|
||||||
|
setMainBusiness(null);
|
||||||
|
setComparison([]);
|
||||||
|
|
||||||
|
// 重置期数记录
|
||||||
|
dataPeriodsRef.current = {
|
||||||
|
balance: 0,
|
||||||
|
income: 0,
|
||||||
|
cashflow: 0,
|
||||||
|
metrics: 0,
|
||||||
|
};
|
||||||
|
|
||||||
loadAllFinancialData();
|
loadAllFinancialData();
|
||||||
isInitialLoad.current = false;
|
isInitialLoad.current = false;
|
||||||
}
|
}
|
||||||
@@ -319,6 +363,7 @@ export const useFinancialData = (
|
|||||||
setStockCode,
|
setStockCode,
|
||||||
setSelectedPeriods,
|
setSelectedPeriods,
|
||||||
setActiveTab,
|
setActiveTab,
|
||||||
|
handleTabChange,
|
||||||
|
|
||||||
// 当前参数
|
// 当前参数
|
||||||
currentStockCode: stockCode,
|
currentStockCode: stockCode,
|
||||||
|
|||||||
@@ -90,15 +90,15 @@ const FinancialPanorama: React.FC<FinancialPanoramaProps> = ({ stockCode: propSt
|
|||||||
refetchByTab,
|
refetchByTab,
|
||||||
selectedPeriods,
|
selectedPeriods,
|
||||||
setSelectedPeriods,
|
setSelectedPeriods,
|
||||||
setActiveTab,
|
handleTabChange: handleTabChangeWithPeriodCheck,
|
||||||
activeTab,
|
activeTab,
|
||||||
} = useFinancialData({ stockCode: propStockCode });
|
} = useFinancialData({ stockCode: propStockCode });
|
||||||
|
|
||||||
// 处理 Tab 切换
|
// 处理 Tab 切换(使用 hook 提供的带期数检查的函数)
|
||||||
const handleTabChange = useCallback((index: number, tabKey: string) => {
|
const handleTabChange = useCallback((index: number, tabKey: string) => {
|
||||||
const dataTypeKey = TAB_KEY_MAP[index] || (tabKey as DataTypeKey);
|
const dataTypeKey = TAB_KEY_MAP[index] || (tabKey as DataTypeKey);
|
||||||
setActiveTab(dataTypeKey);
|
handleTabChangeWithPeriodCheck(dataTypeKey);
|
||||||
}, [setActiveTab]);
|
}, [handleTabChangeWithPeriodCheck]);
|
||||||
|
|
||||||
// 处理刷新 - 只刷新当前 Tab
|
// 处理刷新 - 只刷新当前 Tab
|
||||||
const handleRefresh = useCallback(() => {
|
const handleRefresh = useCallback(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user