refactor(FinancialPanorama): 重构为 SubTabContainer 二级导航
- 主组件从 Chakra Tabs 迁移到 SubTabContainer - 新增 PeriodSelector 时间选择器组件 - IndustryRankingView 增加深色主题支持 - 拆分出 6 个独立 Tab 组件到 tabs/ 目录 - 类型定义优化,props 改为可选
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
/**
|
||||
* 财务全景组件
|
||||
* 重构后的主组件,使用模块化结构
|
||||
* 重构后的主组件,使用模块化结构和 SubTabContainer 二级导航
|
||||
*/
|
||||
|
||||
import React, { useState, ReactNode } from 'react';
|
||||
import React, { useState, useMemo, ReactNode } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Container,
|
||||
@@ -11,20 +11,12 @@ import {
|
||||
HStack,
|
||||
Card,
|
||||
CardBody,
|
||||
CardHeader,
|
||||
Heading,
|
||||
Text,
|
||||
Badge,
|
||||
Select,
|
||||
IconButton,
|
||||
Alert,
|
||||
AlertIcon,
|
||||
Skeleton,
|
||||
Tabs,
|
||||
TabList,
|
||||
TabPanels,
|
||||
Tab,
|
||||
TabPanel,
|
||||
Modal,
|
||||
ModalOverlay,
|
||||
ModalContent,
|
||||
@@ -40,25 +32,25 @@ import {
|
||||
Td,
|
||||
TableContainer,
|
||||
Divider,
|
||||
Tooltip,
|
||||
} from '@chakra-ui/react';
|
||||
import { RepeatIcon } from '@chakra-ui/icons';
|
||||
import { BarChart3, DollarSign, TrendingUp } from 'lucide-react';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import { formatUtils } from '@services/financialService';
|
||||
|
||||
// 通用组件
|
||||
import SubTabContainer, { type SubTabConfig } from '@components/SubTabContainer';
|
||||
|
||||
// 内部模块导入
|
||||
import { useFinancialData } from './hooks';
|
||||
import { COLORS } from './constants';
|
||||
import { calculateYoYChange, getCellBackground, getMetricChartOption } from './utils';
|
||||
import {
|
||||
StockInfoHeader,
|
||||
BalanceSheetTable,
|
||||
IncomeStatementTable,
|
||||
CashflowTable,
|
||||
FinancialMetricsTable,
|
||||
MainBusinessAnalysis,
|
||||
ComparisonAnalysis,
|
||||
} from './components';
|
||||
import { BalanceSheetTab, IncomeStatementTab, CashflowTab } from './tabs';
|
||||
import type { FinancialPanoramaProps } from './types';
|
||||
|
||||
/**
|
||||
@@ -73,29 +65,24 @@ const FinancialPanorama: React.FC<FinancialPanoramaProps> = ({ stockCode: propSt
|
||||
cashflow,
|
||||
financialMetrics,
|
||||
mainBusiness,
|
||||
forecast,
|
||||
industryRank,
|
||||
comparison,
|
||||
loading,
|
||||
error,
|
||||
refetch,
|
||||
currentStockCode,
|
||||
selectedPeriods,
|
||||
setSelectedPeriods,
|
||||
} = useFinancialData({ stockCode: propStockCode });
|
||||
|
||||
// UI 状态
|
||||
const [activeTab, setActiveTab] = useState(0);
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const [modalContent, setModalContent] = useState<ReactNode>(null);
|
||||
|
||||
// 颜色配置
|
||||
const { bgColor, hoverBg, positiveColor, negativeColor, borderColor } = COLORS;
|
||||
const { bgColor, hoverBg, positiveColor, negativeColor } = COLORS;
|
||||
|
||||
// 点击指标行显示图表
|
||||
const showMetricChart = (
|
||||
metricName: string,
|
||||
metricKey: string,
|
||||
_metricKey: string,
|
||||
data: Array<{ period: string; [key: string]: unknown }>,
|
||||
dataPath: string
|
||||
) => {
|
||||
@@ -204,6 +191,45 @@ const FinancialPanorama: React.FC<FinancialPanoramaProps> = ({ stockCode: propSt
|
||||
hoverBg,
|
||||
};
|
||||
|
||||
// Tab 配置 - 只保留三大财务报表
|
||||
const tabConfigs: SubTabConfig[] = useMemo(
|
||||
() => [
|
||||
{ key: 'balance', name: '资产负债表', icon: BarChart3, component: BalanceSheetTab },
|
||||
{ key: 'income', name: '利润表', icon: DollarSign, component: IncomeStatementTab },
|
||||
{ key: 'cashflow', name: '现金流量表', icon: TrendingUp, component: CashflowTab },
|
||||
],
|
||||
[]
|
||||
);
|
||||
|
||||
// 传递给 Tab 组件的 props
|
||||
const componentProps = useMemo(
|
||||
() => ({
|
||||
// 数据
|
||||
balanceSheet,
|
||||
incomeStatement,
|
||||
cashflow,
|
||||
// 工具函数
|
||||
showMetricChart,
|
||||
calculateYoYChange,
|
||||
getCellBackground,
|
||||
// 颜色配置
|
||||
positiveColor,
|
||||
negativeColor,
|
||||
bgColor,
|
||||
hoverBg,
|
||||
}),
|
||||
[
|
||||
balanceSheet,
|
||||
incomeStatement,
|
||||
cashflow,
|
||||
showMetricChart,
|
||||
positiveColor,
|
||||
negativeColor,
|
||||
bgColor,
|
||||
hoverBg,
|
||||
]
|
||||
);
|
||||
|
||||
return (
|
||||
<Container maxW="container.xl" py={5}>
|
||||
<VStack spacing={6} align="stretch">
|
||||
@@ -250,124 +276,35 @@ const FinancialPanorama: React.FC<FinancialPanoramaProps> = ({ stockCode: propSt
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 主要内容区域 */}
|
||||
{/* 财务指标速览 */}
|
||||
{!loading && stockInfo && (
|
||||
<Tabs
|
||||
index={activeTab}
|
||||
onChange={setActiveTab}
|
||||
variant="enclosed"
|
||||
colorScheme="blue"
|
||||
>
|
||||
<TabList>
|
||||
<Tab>财务概览</Tab>
|
||||
<Tab>资产负债表</Tab>
|
||||
<Tab>利润表</Tab>
|
||||
<Tab>现金流量表</Tab>
|
||||
<Tab>财务指标</Tab>
|
||||
<Tab>主营业务</Tab>
|
||||
</TabList>
|
||||
<FinancialMetricsTable data={financialMetrics} {...tableProps} />
|
||||
)}
|
||||
|
||||
<TabPanels>
|
||||
{/* 财务概览 */}
|
||||
<TabPanel>
|
||||
<VStack spacing={4} align="stretch">
|
||||
<ComparisonAnalysis comparison={comparison} />
|
||||
<FinancialMetricsTable data={financialMetrics} {...tableProps} />
|
||||
</VStack>
|
||||
</TabPanel>
|
||||
{/* 主营业务 */}
|
||||
{!loading && stockInfo && (
|
||||
<Card>
|
||||
<CardBody>
|
||||
<Text fontSize="lg" fontWeight="bold" mb={4}>
|
||||
主营业务
|
||||
</Text>
|
||||
<MainBusinessAnalysis mainBusiness={mainBusiness} />
|
||||
</CardBody>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* 资产负债表 */}
|
||||
<TabPanel>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<VStack align="stretch" spacing={2}>
|
||||
<HStack justify="space-between">
|
||||
<Heading size="md">资产负债表</Heading>
|
||||
<HStack spacing={2}>
|
||||
<Badge colorScheme="blue">
|
||||
显示最近{Math.min(balanceSheet.length, 8)}期
|
||||
</Badge>
|
||||
<Text fontSize="sm" color="gray.500">
|
||||
红涨绿跌 | 同比变化
|
||||
</Text>
|
||||
</HStack>
|
||||
</HStack>
|
||||
<Text fontSize="xs" color="gray.500">
|
||||
提示:表格可横向滚动查看更多数据,点击行查看历史趋势
|
||||
</Text>
|
||||
</VStack>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<BalanceSheetTable data={balanceSheet} {...tableProps} />
|
||||
</CardBody>
|
||||
</Card>
|
||||
</TabPanel>
|
||||
|
||||
{/* 利润表 */}
|
||||
<TabPanel>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<VStack align="stretch" spacing={2}>
|
||||
<HStack justify="space-between">
|
||||
<Heading size="md">利润表</Heading>
|
||||
<HStack spacing={2}>
|
||||
<Badge colorScheme="blue">
|
||||
显示最近{Math.min(incomeStatement.length, 8)}期
|
||||
</Badge>
|
||||
<Text fontSize="sm" color="gray.500">
|
||||
红涨绿跌 | 同比变化
|
||||
</Text>
|
||||
</HStack>
|
||||
</HStack>
|
||||
<Text fontSize="xs" color="gray.500">
|
||||
提示:Q1、中报、Q3、年报数据为累计值,同比显示与去年同期对比
|
||||
</Text>
|
||||
</VStack>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<IncomeStatementTable data={incomeStatement} {...tableProps} />
|
||||
</CardBody>
|
||||
</Card>
|
||||
</TabPanel>
|
||||
|
||||
{/* 现金流量表 */}
|
||||
<TabPanel>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<VStack align="stretch" spacing={2}>
|
||||
<HStack justify="space-between">
|
||||
<Heading size="md">现金流量表</Heading>
|
||||
<HStack spacing={2}>
|
||||
<Badge colorScheme="blue">
|
||||
显示最近{Math.min(cashflow.length, 8)}期
|
||||
</Badge>
|
||||
<Text fontSize="sm" color="gray.500">
|
||||
红涨绿跌 | 同比变化
|
||||
</Text>
|
||||
</HStack>
|
||||
</HStack>
|
||||
<Text fontSize="xs" color="gray.500">
|
||||
提示:现金流数据为累计值,正值红色表示现金流入,负值绿色表示现金流出
|
||||
</Text>
|
||||
</VStack>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<CashflowTable data={cashflow} {...tableProps} />
|
||||
</CardBody>
|
||||
</Card>
|
||||
</TabPanel>
|
||||
|
||||
{/* 财务指标 */}
|
||||
<TabPanel>
|
||||
<FinancialMetricsTable data={financialMetrics} {...tableProps} />
|
||||
</TabPanel>
|
||||
|
||||
{/* 主营业务 */}
|
||||
<TabPanel>
|
||||
<MainBusinessAnalysis mainBusiness={mainBusiness} />
|
||||
</TabPanel>
|
||||
</TabPanels>
|
||||
</Tabs>
|
||||
{/* 三大财务报表 - 使用 SubTabContainer 二级导航 */}
|
||||
{!loading && stockInfo && (
|
||||
<Card bg="gray.900" shadow="md" border="1px solid" borderColor="rgba(212, 175, 55, 0.3)">
|
||||
<CardBody p={0}>
|
||||
<SubTabContainer
|
||||
tabs={tabConfigs}
|
||||
componentProps={componentProps}
|
||||
themePreset="blackGold"
|
||||
isLazy
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* 错误提示 */}
|
||||
|
||||
Reference in New Issue
Block a user