diff --git a/src/views/Company/components/FinancialPanorama/index.tsx b/src/views/Company/components/FinancialPanorama/index.tsx index 7fdcf6a4..a9a7f349 100644 --- a/src/views/Company/components/FinancialPanorama/index.tsx +++ b/src/views/Company/components/FinancialPanorama/index.tsx @@ -3,7 +3,7 @@ * 重构后的主组件,使用模块化结构和 SubTabContainer 二级导航 */ -import React, { useState, useMemo, useCallback, ReactNode } from 'react'; +import React, { useState, useMemo, useCallback } from 'react'; import { Box, Container, @@ -13,21 +13,7 @@ import { Text, Alert, AlertIcon, - Modal, - ModalOverlay, - ModalContent, - ModalHeader, - ModalBody, - ModalCloseButton, useDisclosure, - Table, - Thead, - Tbody, - Tr, - Th, - Td, - TableContainer, - Divider, } from '@chakra-ui/react'; import { BarChart3, @@ -41,8 +27,6 @@ import { Receipt, Banknote, } from 'lucide-react'; -import ReactECharts from 'echarts-for-react'; -import { formatUtils } from '@services/financialService'; // 通用组件 import SubTabContainer, { type SubTabConfig } from '@components/SubTabContainer'; @@ -51,8 +35,14 @@ import LoadingState from '../LoadingState'; // 内部模块导入 import { useFinancialData, type DataTypeKey } from './hooks'; import { COLORS } from './constants'; -import { calculateYoYChange, getCellBackground, getMetricChartOption } from './utils'; -import { PeriodSelector, FinancialOverviewPanel, MainBusinessAnalysis, ComparisonAnalysis } from './components'; +import { calculateYoYChange, getCellBackground } from './utils'; +import { + PeriodSelector, + FinancialOverviewPanel, + MainBusinessAnalysis, + ComparisonAnalysis, + MetricChartModal, +} from './components'; import { BalanceSheetTab, IncomeStatementTab, @@ -117,111 +107,22 @@ const FinancialPanorama: React.FC = ({ stockCode: propSt // UI 状态 const { isOpen, onOpen, onClose } = useDisclosure(); - const [modalContent, setModalContent] = useState(null); + const [modalProps, setModalProps] = useState<{ + metricName: string; + data: Array<{ period: string; [key: string]: unknown }>; + dataPath: string; + }>({ metricName: '', data: [], dataPath: '' }); - // 颜色配置 - const { bgColor, hoverBg, positiveColor, negativeColor } = COLORS; - - // 点击指标行显示图表(使用 useCallback 避免不必要的重渲染) + // 点击指标行显示图表 const showMetricChart = useCallback(( metricName: string, _metricKey: string, data: Array<{ period: string; [key: string]: unknown }>, dataPath: string ) => { - const chartData = data - .map((item) => { - const value = dataPath.split('.').reduce((obj: unknown, key: string) => { - if (obj && typeof obj === 'object') { - return (obj as Record)[key]; - } - return undefined; - }, item) as number | undefined; - return { - period: formatUtils.getReportType(item.period), - date: item.period, - value: value ?? 0, - }; - }) - .reverse(); - - const option = getMetricChartOption(metricName, chartData); - - setModalContent( - - - - - - - - - - - - - - - {chartData.map((item, idx) => { - // 计算环比 - const qoq = - idx > 0 - ? ((item.value - chartData[idx - 1].value) / - Math.abs(chartData[idx - 1].value)) * - 100 - : null; - - // 计算同比 - const currentDate = new Date(item.date); - const lastYearItem = chartData.find((d) => { - const date = new Date(d.date); - return ( - date.getFullYear() === currentDate.getFullYear() - 1 && - date.getMonth() === currentDate.getMonth() - ); - }); - const yoy = lastYearItem - ? ((item.value - lastYearItem.value) / Math.abs(lastYearItem.value)) * 100 - : null; - - return ( - - - - - - - ); - })} - -
报告期数值同比环比
{item.period}{formatUtils.formatLargeNumber(item.value)} 0 - ? positiveColor - : yoy !== null && yoy < 0 - ? negativeColor - : 'gray.500' - } - > - {yoy !== null ? `${yoy.toFixed(2)}%` : '-'} - 0 - ? positiveColor - : qoq !== null && qoq < 0 - ? negativeColor - : 'gray.500' - } - > - {qoq !== null ? `${qoq.toFixed(2)}%` : '-'} -
-
-
- ); + setModalProps({ metricName, data, dataPath }); onOpen(); - }, [onOpen, positiveColor, negativeColor]); + }, [onOpen]); // Tab 配置 - 财务指标分类 + 三大财务报表 const tabConfigs: SubTabConfig[] = useMemo( @@ -242,7 +143,7 @@ const FinancialPanorama: React.FC = ({ stockCode: propSt [] ); - // 传递给 Tab 组件的 props + // 传递给 Tab 组件的 props(颜色使用常量,不需要在依赖数组中) const componentProps = useMemo( () => ({ // 数据 @@ -257,11 +158,8 @@ const FinancialPanorama: React.FC = ({ stockCode: propSt showMetricChart, calculateYoYChange, getCellBackground, - // 颜色配置 - positiveColor, - negativeColor, - bgColor, - hoverBg, + // 颜色配置(使用常量) + ...COLORS, }), [ balanceSheet, @@ -271,10 +169,6 @@ const FinancialPanorama: React.FC = ({ stockCode: propSt loading, loadingTab, showMetricChart, - positiveColor, - negativeColor, - bgColor, - hoverBg, ] ); @@ -335,15 +229,14 @@ const FinancialPanorama: React.FC = ({ stockCode: propSt )} - {/* 弹出模态框 */} - - - - 指标详情 - - {modalContent} - - + {/* 指标图表弹窗 */} + );