From faf24462037eaa24a6bb5fc77ae5d6aaab074c1e Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Tue, 16 Dec 2025 20:17:08 +0800 Subject: [PATCH] =?UTF-8?q?feat(FinancialPanorama):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=20FinancialOverviewPanel=20=E4=B8=89=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 复用 MetricCard 组件构建三列布局 - 成长能力:利润增长、营收增长、预增标签 - 盈利与回报:ROE、净利率、毛利率 - 风险与运营:资产负债率、流动比率、研发费用率 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../components/FinancialOverviewPanel.tsx | 188 ++++++++++++++++++ .../FinancialPanorama/components/index.ts | 2 + 2 files changed, 190 insertions(+) create mode 100644 src/views/Company/components/FinancialPanorama/components/FinancialOverviewPanel.tsx diff --git a/src/views/Company/components/FinancialPanorama/components/FinancialOverviewPanel.tsx b/src/views/Company/components/FinancialPanorama/components/FinancialOverviewPanel.tsx new file mode 100644 index 00000000..27ba24da --- /dev/null +++ b/src/views/Company/components/FinancialPanorama/components/FinancialOverviewPanel.tsx @@ -0,0 +1,188 @@ +/** + * 财务全景面板组件 - 三列布局 + * 复用 MarketDataView 的 MetricCard 组件 + */ + +import React, { memo } from 'react'; +import { SimpleGrid, HStack, VStack, Text, Badge } from '@chakra-ui/react'; +import { TrendingUp, Coins, Shield, TrendingDown, Activity, PieChart } from 'lucide-react'; +import { formatUtils } from '@services/financialService'; + +// 复用 MarketDataView 的组件 +import MetricCard from '../../MarketDataView/components/StockSummaryCard/MetricCard'; +import { StatusTag } from '../../MarketDataView/components/StockSummaryCard/atoms'; +import { darkGoldTheme } from '../../MarketDataView/constants'; + +import type { StockInfo, FinancialMetricsData } from '../types'; + +export interface FinancialOverviewPanelProps { + stockInfo: StockInfo | null; + financialMetrics: FinancialMetricsData[]; +} + +/** + * 获取成长状态 + */ +const getGrowthStatus = (value: number | undefined): { text: string; color: string } => { + if (value === undefined || value === null) return { text: '-', color: darkGoldTheme.textMuted }; + if (value > 30) return { text: '高速增长', color: darkGoldTheme.green }; + if (value > 10) return { text: '稳健增长', color: darkGoldTheme.gold }; + if (value > 0) return { text: '低速增长', color: darkGoldTheme.orange }; + if (value > -10) return { text: '小幅下滑', color: darkGoldTheme.orange }; + return { text: '大幅下滑', color: darkGoldTheme.red }; +}; + +/** + * 获取 ROE 状态 + */ +const getROEStatus = (value: number | undefined): { text: string; color: string } => { + if (value === undefined || value === null) return { text: '-', color: darkGoldTheme.textMuted }; + if (value > 20) return { text: '优秀', color: darkGoldTheme.green }; + if (value > 15) return { text: '良好', color: darkGoldTheme.gold }; + if (value > 10) return { text: '一般', color: darkGoldTheme.orange }; + return { text: '较低', color: darkGoldTheme.red }; +}; + +/** + * 获取资产负债率状态 + */ +const getDebtStatus = (value: number | undefined): { text: string; color: string } => { + if (value === undefined || value === null) return { text: '-', color: darkGoldTheme.textMuted }; + if (value < 40) return { text: '安全', color: darkGoldTheme.green }; + if (value < 60) return { text: '适中', color: darkGoldTheme.gold }; + if (value < 70) return { text: '偏高', color: darkGoldTheme.orange }; + return { text: '风险', color: darkGoldTheme.red }; +}; + +/** + * 财务全景面板组件 + */ +export const FinancialOverviewPanel: React.FC = memo(({ + stockInfo, + financialMetrics, +}) => { + if (!stockInfo && (!financialMetrics || financialMetrics.length === 0)) { + return null; + } + + // 获取最新一期财务指标 + const latestMetrics = financialMetrics?.[0]; + + // 成长指标(来自 stockInfo) + const revenueGrowth = stockInfo?.growth_rates?.revenue_growth; + const profitGrowth = stockInfo?.growth_rates?.profit_growth; + const forecast = stockInfo?.latest_forecast; + + // 盈利指标(来自 financialMetrics) + const roe = latestMetrics?.profitability?.roe; + const netProfitMargin = latestMetrics?.profitability?.net_profit_margin; + const grossMargin = latestMetrics?.profitability?.gross_margin; + + // 风险与运营指标(来自 financialMetrics) + const assetLiabilityRatio = latestMetrics?.solvency?.asset_liability_ratio; + const currentRatio = latestMetrics?.solvency?.current_ratio; + const rdExpenseRatio = latestMetrics?.expense_ratios?.rd_expense_ratio; + + // 计算状态 + const growthStatus = getGrowthStatus(profitGrowth); + const roeStatus = getROEStatus(roe); + const debtStatus = getDebtStatus(assetLiabilityRatio); + + // 格式化涨跌显示 + const formatGrowth = (value: number | undefined) => { + if (value === undefined || value === null) return '-'; + const sign = value >= 0 ? '+' : ''; + return `${sign}${value.toFixed(2)}%`; + }; + + return ( + + {/* 卡片1: 成长能力 */} + } + rightIcon={} + mainLabel="利润增长" + mainValue={formatGrowth(profitGrowth)} + mainColor={profitGrowth !== undefined && profitGrowth >= 0 ? darkGoldTheme.green : darkGoldTheme.red} + subText={ + + + 营收增长 + = 0 ? darkGoldTheme.green : darkGoldTheme.red} + > + {formatGrowth(revenueGrowth)} + + + + {forecast && ( + + {forecast.forecast_type} {forecast.content} + + )} + + } + /> + + {/* 卡片2: 盈利与回报 */} + } + rightIcon={} + mainLabel="ROE" + mainValue={formatUtils.formatPercent(roe)} + mainColor={darkGoldTheme.orange} + subText={ + + + {roeStatus.text} + + + 净利率 {formatUtils.formatPercent(netProfitMargin)} + | + 毛利率 {formatUtils.formatPercent(grossMargin)} + + + } + /> + + {/* 卡片3: 风险与运营 */} + } + rightIcon={} + mainLabel="资产负债率" + mainValue={formatUtils.formatPercent(assetLiabilityRatio)} + mainColor={debtStatus.color} + subText={ + + + {debtStatus.text} + + + 流动比率 {currentRatio?.toFixed(2) ?? '-'} + | + 研发费用率 {formatUtils.formatPercent(rdExpenseRatio)} + + + } + /> + + ); +}); + +FinancialOverviewPanel.displayName = 'FinancialOverviewPanel'; + +export default FinancialOverviewPanel; diff --git a/src/views/Company/components/FinancialPanorama/components/index.ts b/src/views/Company/components/FinancialPanorama/components/index.ts index 334250d5..6bfaf227 100644 --- a/src/views/Company/components/FinancialPanorama/components/index.ts +++ b/src/views/Company/components/FinancialPanorama/components/index.ts @@ -3,6 +3,8 @@ */ export { PeriodSelector } from './PeriodSelector'; +export { FinancialOverviewPanel } from './FinancialOverviewPanel'; +// 保留旧组件导出(向后兼容) export { KeyMetricsOverview } from './KeyMetricsOverview'; export { StockInfoHeader } from './StockInfoHeader'; export { BalanceSheetTable } from './BalanceSheetTable';