From d9106bf9f759c49989711c0f3d9873b678961c44 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Fri, 12 Dec 2025 15:01:26 +0800 Subject: [PATCH] =?UTF-8?q?refactor(FinancialPanorama):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=95=B0=E6=8D=AE=E5=8A=A0=E8=BD=BD=20Hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit useFinancialData Hook 功能: - 9个财务API并行加载(Promise.all) - 股票信息、资产负债表、利润表、现金流量表 - 财务指标、主营业务、业绩预告 - 行业排名、期间对比 - 支持期数选择(4/8/12/16期) - 自动响应 stockCode 变化重新加载 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../FinancialPanorama/hooks/index.ts | 6 + .../hooks/useFinancialData.ts | 186 ++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 src/views/Company/components/FinancialPanorama/hooks/index.ts create mode 100644 src/views/Company/components/FinancialPanorama/hooks/useFinancialData.ts diff --git a/src/views/Company/components/FinancialPanorama/hooks/index.ts b/src/views/Company/components/FinancialPanorama/hooks/index.ts new file mode 100644 index 00000000..9593814a --- /dev/null +++ b/src/views/Company/components/FinancialPanorama/hooks/index.ts @@ -0,0 +1,6 @@ +/** + * Hooks 统一导出 + */ + +export { useFinancialData } from './useFinancialData'; +export type { default as UseFinancialDataReturn } from './useFinancialData'; diff --git a/src/views/Company/components/FinancialPanorama/hooks/useFinancialData.ts b/src/views/Company/components/FinancialPanorama/hooks/useFinancialData.ts new file mode 100644 index 00000000..cf954cc8 --- /dev/null +++ b/src/views/Company/components/FinancialPanorama/hooks/useFinancialData.ts @@ -0,0 +1,186 @@ +/** + * 财务数据加载 Hook + * 封装所有财务数据的加载逻辑 + */ + +import { useState, useEffect, useCallback } from 'react'; +import { useToast } from '@chakra-ui/react'; +import { logger } from '@utils/logger'; +import { financialService } from '@services/financialService'; +import type { + StockInfo, + BalanceSheetData, + IncomeStatementData, + CashflowData, + FinancialMetricsData, + MainBusinessData, + ForecastData, + IndustryRankData, + ComparisonData, +} from '../types'; + +interface UseFinancialDataOptions { + stockCode?: string; + periods?: number; +} + +interface UseFinancialDataReturn { + // 数据状态 + stockInfo: StockInfo | null; + balanceSheet: BalanceSheetData[]; + incomeStatement: IncomeStatementData[]; + cashflow: CashflowData[]; + financialMetrics: FinancialMetricsData[]; + mainBusiness: MainBusinessData | null; + forecast: ForecastData | null; + industryRank: IndustryRankData[]; + comparison: ComparisonData[]; + + // 加载状态 + loading: boolean; + error: string | null; + + // 操作方法 + refetch: () => Promise; + setStockCode: (code: string) => void; + setSelectedPeriods: (periods: number) => void; + + // 当前参数 + currentStockCode: string; + selectedPeriods: number; +} + +/** + * 财务数据加载 Hook + * @param options - 配置选项 + * @returns 财务数据和操作方法 + */ +export const useFinancialData = ( + options: UseFinancialDataOptions = {} +): UseFinancialDataReturn => { + const { stockCode: initialStockCode = '600000', periods: initialPeriods = 8 } = options; + + // 参数状态 + const [stockCode, setStockCode] = useState(initialStockCode); + const [selectedPeriods, setSelectedPeriods] = useState(initialPeriods); + + // 加载状态 + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + // 财务数据状态 + const [stockInfo, setStockInfo] = useState(null); + const [balanceSheet, setBalanceSheet] = useState([]); + const [incomeStatement, setIncomeStatement] = useState([]); + const [cashflow, setCashflow] = useState([]); + const [financialMetrics, setFinancialMetrics] = useState([]); + const [mainBusiness, setMainBusiness] = useState(null); + const [forecast, setForecast] = useState(null); + const [industryRank, setIndustryRank] = useState([]); + const [comparison, setComparison] = useState([]); + + const toast = useToast(); + + // 加载所有财务数据 + const loadFinancialData = useCallback(async () => { + if (!stockCode || stockCode.length !== 6) { + logger.warn('useFinancialData', '无效的股票代码', { stockCode }); + toast({ + title: '请输入有效的6位股票代码', + status: 'warning', + duration: 3000, + }); + return; + } + + logger.debug('useFinancialData', '开始加载财务数据', { stockCode, selectedPeriods }); + setLoading(true); + setError(null); + + try { + // 并行加载所有数据 + const [ + stockInfoRes, + balanceRes, + incomeRes, + cashflowRes, + metricsRes, + businessRes, + forecastRes, + rankRes, + comparisonRes, + ] = await Promise.all([ + financialService.getStockInfo(stockCode), + financialService.getBalanceSheet(stockCode, selectedPeriods), + financialService.getIncomeStatement(stockCode, selectedPeriods), + financialService.getCashflow(stockCode, selectedPeriods), + financialService.getFinancialMetrics(stockCode, selectedPeriods), + financialService.getMainBusiness(stockCode, 4), + financialService.getForecast(stockCode), + financialService.getIndustryRank(stockCode, 4), + financialService.getPeriodComparison(stockCode, selectedPeriods), + ]); + + // 设置数据 + if (stockInfoRes.success) setStockInfo(stockInfoRes.data); + if (balanceRes.success) setBalanceSheet(balanceRes.data); + if (incomeRes.success) setIncomeStatement(incomeRes.data); + if (cashflowRes.success) setCashflow(cashflowRes.data); + if (metricsRes.success) setFinancialMetrics(metricsRes.data); + if (businessRes.success) setMainBusiness(businessRes.data); + if (forecastRes.success) setForecast(forecastRes.data); + if (rankRes.success) setIndustryRank(rankRes.data); + if (comparisonRes.success) setComparison(comparisonRes.data); + + logger.info('useFinancialData', '财务数据加载成功', { stockCode }); + } catch (err) { + const errorMessage = err instanceof Error ? err.message : '未知错误'; + setError(errorMessage); + logger.error('useFinancialData', 'loadFinancialData', err, { stockCode, selectedPeriods }); + } finally { + setLoading(false); + } + }, [stockCode, selectedPeriods, toast]); + + // 监听 props 中的 stockCode 变化 + useEffect(() => { + if (initialStockCode && initialStockCode !== stockCode) { + setStockCode(initialStockCode); + } + }, [initialStockCode]); + + // 初始加载和参数变化时重新加载 + useEffect(() => { + if (stockCode) { + loadFinancialData(); + } + }, [stockCode, selectedPeriods, loadFinancialData]); + + return { + // 数据状态 + stockInfo, + balanceSheet, + incomeStatement, + cashflow, + financialMetrics, + mainBusiness, + forecast, + industryRank, + comparison, + + // 加载状态 + loading, + error, + + // 操作方法 + refetch: loadFinancialData, + setStockCode, + setSelectedPeriods, + + // 当前参数 + currentStockCode: stockCode, + selectedPeriods, + }; +}; + +export default useFinancialData;