style: 移除 Tab 导航和卡片内部左右 padding
- TabNavigation/SubTabContainer: 移除左侧 padding (pl=0) - BusinessStructureCard/BusinessSegmentsCard: 移除 CardBody 左右 padding - BusinessTreeItem: 黑金主题样式优化 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -147,7 +147,8 @@ const SubTabContainer: React.FC<SubTabContainerProps> = memo(({
|
|||||||
bg={theme.bg}
|
bg={theme.bg}
|
||||||
borderBottom="1px solid"
|
borderBottom="1px solid"
|
||||||
borderColor={theme.borderColor}
|
borderColor={theme.borderColor}
|
||||||
px={4}
|
pl={0}
|
||||||
|
pr={4}
|
||||||
py={2}
|
py={2}
|
||||||
flexWrap="wrap"
|
flexWrap="wrap"
|
||||||
gap={2}
|
gap={2}
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ const TabNavigation: React.FC<TabNavigationProps> = ({
|
|||||||
borderColor={themeColors.dividerColor}
|
borderColor={themeColors.dividerColor}
|
||||||
borderTopLeftRadius={borderRadius}
|
borderTopLeftRadius={borderRadius}
|
||||||
borderTopRightRadius={borderRadius}
|
borderTopRightRadius={borderRadius}
|
||||||
px={4}
|
pl={0}
|
||||||
|
pr={4}
|
||||||
py={2}
|
py={2}
|
||||||
flexWrap="wrap"
|
flexWrap="wrap"
|
||||||
gap={2}
|
gap={2}
|
||||||
|
|||||||
@@ -473,147 +473,65 @@ export const PINGAN_BANK_DATA = {
|
|||||||
},
|
},
|
||||||
business_structure: [
|
business_structure: [
|
||||||
{
|
{
|
||||||
business_name: '零售金融',
|
business_name: '舒泰清(复方聚乙二醇电解质散IV)',
|
||||||
business_level: 1,
|
business_level: 1,
|
||||||
revenue: 812300,
|
revenue: 17900,
|
||||||
revenue_unit: '万元',
|
revenue_unit: '万元',
|
||||||
financial_metrics: {
|
financial_metrics: {
|
||||||
revenue_ratio: 50.1,
|
revenue_ratio: 55.16,
|
||||||
gross_margin: 42.5
|
gross_margin: 78.21
|
||||||
},
|
},
|
||||||
growth_metrics: {
|
growth_metrics: {
|
||||||
revenue_growth: 11.2
|
revenue_growth: -8.20
|
||||||
},
|
},
|
||||||
report_period: '2024Q3'
|
report_period: '2024年报'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
business_name: '信用卡业务',
|
business_name: '苏肽生(注射用鼠神经生长因子)',
|
||||||
business_level: 2,
|
|
||||||
revenue: 325000,
|
|
||||||
revenue_unit: '万元',
|
|
||||||
financial_metrics: {
|
|
||||||
revenue_ratio: 20.1,
|
|
||||||
gross_margin: 38.2
|
|
||||||
},
|
|
||||||
growth_metrics: {
|
|
||||||
revenue_growth: 15.8
|
|
||||||
},
|
|
||||||
report_period: '2024Q3'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
business_name: '财富管理',
|
|
||||||
business_level: 2,
|
|
||||||
revenue: 280500,
|
|
||||||
revenue_unit: '万元',
|
|
||||||
financial_metrics: {
|
|
||||||
revenue_ratio: 17.3,
|
|
||||||
gross_margin: 52.1
|
|
||||||
},
|
|
||||||
growth_metrics: {
|
|
||||||
revenue_growth: 22.5
|
|
||||||
},
|
|
||||||
report_period: '2024Q3'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
business_name: '消费信贷',
|
|
||||||
business_level: 2,
|
|
||||||
revenue: 206800,
|
|
||||||
revenue_unit: '万元',
|
|
||||||
financial_metrics: {
|
|
||||||
revenue_ratio: 12.7,
|
|
||||||
gross_margin: 35.8
|
|
||||||
},
|
|
||||||
growth_metrics: {
|
|
||||||
revenue_growth: 8.6
|
|
||||||
},
|
|
||||||
report_period: '2024Q3'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
business_name: '对公金融',
|
|
||||||
business_level: 1,
|
business_level: 1,
|
||||||
revenue: 685400,
|
revenue: 13400,
|
||||||
revenue_unit: '万元',
|
revenue_unit: '万元',
|
||||||
financial_metrics: {
|
financial_metrics: {
|
||||||
revenue_ratio: 42.2,
|
revenue_ratio: 41.21,
|
||||||
gross_margin: 38.6
|
gross_margin: 89.11
|
||||||
},
|
},
|
||||||
growth_metrics: {
|
growth_metrics: {
|
||||||
revenue_growth: 6.8
|
revenue_growth: -17.30
|
||||||
},
|
},
|
||||||
report_period: '2024Q3'
|
report_period: '2024年报'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
business_name: '公司贷款',
|
business_name: '舒斯通(复方聚乙二醇(3350)电解质散)',
|
||||||
business_level: 2,
|
|
||||||
revenue: 412000,
|
|
||||||
revenue_unit: '万元',
|
|
||||||
financial_metrics: {
|
|
||||||
revenue_ratio: 25.4,
|
|
||||||
gross_margin: 36.2
|
|
||||||
},
|
|
||||||
growth_metrics: {
|
|
||||||
revenue_growth: 5.2
|
|
||||||
},
|
|
||||||
report_period: '2024Q3'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
business_name: '供应链金融',
|
|
||||||
business_level: 2,
|
|
||||||
revenue: 185600,
|
|
||||||
revenue_unit: '万元',
|
|
||||||
financial_metrics: {
|
|
||||||
revenue_ratio: 11.4,
|
|
||||||
gross_margin: 41.5
|
|
||||||
},
|
|
||||||
growth_metrics: {
|
|
||||||
revenue_growth: 18.3
|
|
||||||
},
|
|
||||||
report_period: '2024Q3'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
business_name: '投资银行',
|
|
||||||
business_level: 2,
|
|
||||||
revenue: 87800,
|
|
||||||
revenue_unit: '万元',
|
|
||||||
financial_metrics: {
|
|
||||||
revenue_ratio: 5.4,
|
|
||||||
gross_margin: 45.2
|
|
||||||
},
|
|
||||||
growth_metrics: {
|
|
||||||
revenue_growth: -2.3
|
|
||||||
},
|
|
||||||
report_period: '2024Q3'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
business_name: '资金同业',
|
|
||||||
business_level: 1,
|
business_level: 1,
|
||||||
revenue: 125800,
|
revenue: 771,
|
||||||
revenue_unit: '万元',
|
revenue_unit: '万元',
|
||||||
financial_metrics: {
|
financial_metrics: {
|
||||||
revenue_ratio: 7.7,
|
revenue_ratio: 2.37
|
||||||
gross_margin: 28.2
|
|
||||||
},
|
},
|
||||||
growth_metrics: {
|
report_period: '2024年报'
|
||||||
revenue_growth: 3.5
|
},
|
||||||
|
{
|
||||||
|
business_name: '阿司匹林肠溶片',
|
||||||
|
business_level: 1,
|
||||||
|
revenue: 396,
|
||||||
|
revenue_unit: '万元',
|
||||||
|
financial_metrics: {
|
||||||
|
revenue_ratio: 1.22
|
||||||
},
|
},
|
||||||
report_period: '2024Q3'
|
report_period: '2024年报'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
business_name: '研发业务',
|
||||||
|
business_level: 1,
|
||||||
|
report_period: '2024年报'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
business_segments: [
|
business_segments: [
|
||||||
{
|
{
|
||||||
segment_name: '信用卡业务',
|
segment_name: '已上市药品营销',
|
||||||
description: '国内领先的信用卡发卡银行,流通卡量超7000万张',
|
segment_description: '舒泰神已上市药品营销业务主要包括舒泰清(复方聚乙二醇电解质散IV)和苏肽生(注射用鼠神经生长因子)两大核心产品。2024年实现营业收入3.25亿元,其中舒泰清贡献1.79亿元(55.16%),苏肽生贡献1.34亿元(41.21%)。尽管面临市场竞争压力,产品毛利率保持高位,综合毛利率达80.83%,其中苏肽生毛利率高达89.11%。',
|
||||||
key_metrics: { cards_issued: 7200, transaction_volume: 28500, market_share: 8.5 }
|
competitive_position: '舒泰清为《中国消化内镜诊疗肠道准备指南》和《慢性便秘诊治指南》一线用药,苏肽生是国内首个国药准字鼠神经生长因子产品。公司医保目录产品舒斯通已落地,并布局舒亦清、舒常轻等系列产品形成梯队,构建了一定市场竞争优势。然而,2024年集采中同类(III型)产品中选,对舒泰清(IV型)形成潜在价格压力。',
|
||||||
},
|
future_potential: '公司正在构建系列化产品线应对市场变化,研发投入保持高强度(1.62亿元,占营收49.97%)。在研管线中,STSP-0601血友病药物获FDA孤儿药资格,BDB-001被纳入突破性治疗品种,创新药研发持续推进。国家政策支持创新药发展,行业环境向好,同时国际化布局已有初步进展,未来3-5年有望通过新产品上市实现业绩突破。'
|
||||||
{
|
|
||||||
segment_name: '财富管理',
|
|
||||||
description: '私人银行及财富管理业务快速发展,AUM突破4万亿',
|
|
||||||
key_metrics: { aum: 42000, private_banking_customers: 125000, wealth_customers: 1200000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
segment_name: '供应链金融',
|
|
||||||
description: '依托科技平台打造智慧供应链金融生态',
|
|
||||||
key_metrics: { platform_customers: 35000, financing_balance: 5600, digitization_rate: 95 }
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -1336,11 +1254,68 @@ export const generateCompanyData = (stockCode, stockName = '示例公司') => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
business_structure: [
|
business_structure: [
|
||||||
{ business_name: '核心产品', revenue: baseRevenue * 0.6, ratio: 60, growth: 12.5, report_period: '2024Q3' },
|
{
|
||||||
{ business_name: '增值服务', revenue: baseRevenue * 0.25, ratio: 25, growth: 18.2, report_period: '2024Q3' },
|
business_name: '舒泰清(复方聚乙二醇电解质散IV)',
|
||||||
{ business_name: '其他业务', revenue: baseRevenue * 0.15, ratio: 15, growth: 5.8, report_period: '2024Q3' }
|
business_level: 1,
|
||||||
|
revenue: 17900,
|
||||||
|
revenue_unit: '万元',
|
||||||
|
financial_metrics: {
|
||||||
|
revenue_ratio: 55.16,
|
||||||
|
gross_margin: 78.21
|
||||||
|
},
|
||||||
|
growth_metrics: {
|
||||||
|
revenue_growth: -8.20
|
||||||
|
},
|
||||||
|
report_period: '2024年报'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
business_name: '苏肽生(注射用鼠神经生长因子)',
|
||||||
|
business_level: 1,
|
||||||
|
revenue: 13400,
|
||||||
|
revenue_unit: '万元',
|
||||||
|
financial_metrics: {
|
||||||
|
revenue_ratio: 41.21,
|
||||||
|
gross_margin: 89.11
|
||||||
|
},
|
||||||
|
growth_metrics: {
|
||||||
|
revenue_growth: -17.30
|
||||||
|
},
|
||||||
|
report_period: '2024年报'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
business_name: '舒斯通(复方聚乙二醇(3350)电解质散)',
|
||||||
|
business_level: 1,
|
||||||
|
revenue: 771,
|
||||||
|
revenue_unit: '万元',
|
||||||
|
financial_metrics: {
|
||||||
|
revenue_ratio: 2.37
|
||||||
|
},
|
||||||
|
report_period: '2024年报'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
business_name: '阿司匹林肠溶片',
|
||||||
|
business_level: 1,
|
||||||
|
revenue: 396,
|
||||||
|
revenue_unit: '万元',
|
||||||
|
financial_metrics: {
|
||||||
|
revenue_ratio: 1.22
|
||||||
|
},
|
||||||
|
report_period: '2024年报'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
business_name: '研发业务',
|
||||||
|
business_level: 1,
|
||||||
|
report_period: '2024年报'
|
||||||
|
}
|
||||||
],
|
],
|
||||||
business_segments: []
|
business_segments: [
|
||||||
|
{
|
||||||
|
segment_name: '已上市药品营销',
|
||||||
|
segment_description: '舒泰神已上市药品营销业务主要包括舒泰清(复方聚乙二醇电解质散IV)和苏肽生(注射用鼠神经生长因子)两大核心产品。2024年实现营业收入3.25亿元,其中舒泰清贡献1.79亿元(55.16%),苏肽生贡献1.34亿元(41.21%)。尽管面临市场竞争压力,产品毛利率保持高位,综合毛利率达80.83%,其中苏肽生毛利率高达89.11%。',
|
||||||
|
competitive_position: '舒泰清为《中国消化内镜诊疗肠道准备指南》和《慢性便秘诊治指南》一线用药,苏肽生是国内首个国药准字鼠神经生长因子产品。公司医保目录产品舒斯通已落地,并布局舒亦清、舒常轻等系列产品形成梯队,构建了一定市场竞争优势。然而,2024年集采中同类(III型)产品中选,对舒泰清(IV型)形成潜在价格压力。',
|
||||||
|
future_potential: '公司正在构建系列化产品线应对市场变化,研发投入保持高强度(1.62亿元,占营收49.97%)。在研管线中,STSP-0601血友病药物获FDA孤儿药资格,BDB-001被纳入突破性治疗品种,创新药研发持续推进。国家政策支持创新药发展,行业环境向好,同时国际化布局已有初步进展,未来3-5年有望通过新产品上市实现业绩突破。'
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
valueChainAnalysis: {
|
valueChainAnalysis: {
|
||||||
value_chain_flows: [
|
value_chain_flows: [
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* 递归显示业务结构层级
|
* 递归显示业务结构层级
|
||||||
* 使用位置:业务结构分析卡片
|
* 使用位置:业务结构分析卡片
|
||||||
|
* 黑金主题风格
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@@ -10,9 +11,17 @@ import { Box, HStack, VStack, Text, Badge, Tag, TagLabel } from '@chakra-ui/reac
|
|||||||
import { formatPercentage, formatBusinessRevenue } from '@utils/priceFormatters';
|
import { formatPercentage, formatBusinessRevenue } from '@utils/priceFormatters';
|
||||||
import type { BusinessTreeItemProps } from '../types';
|
import type { BusinessTreeItemProps } from '../types';
|
||||||
|
|
||||||
const BusinessTreeItem: React.FC<BusinessTreeItemProps> = ({ business, depth = 0 }) => {
|
// 黑金主题配置
|
||||||
const bgColor = 'gray.50';
|
const THEME = {
|
||||||
|
bg: 'gray.700',
|
||||||
|
gold: '#D4AF37',
|
||||||
|
goldLight: '#F0D78C',
|
||||||
|
textPrimary: '#D4AF37',
|
||||||
|
textSecondary: 'gray.400',
|
||||||
|
border: 'rgba(212, 175, 55, 0.5)',
|
||||||
|
};
|
||||||
|
|
||||||
|
const BusinessTreeItem: React.FC<BusinessTreeItemProps> = ({ business, depth = 0 }) => {
|
||||||
// 获取营收显示
|
// 获取营收显示
|
||||||
const getRevenueDisplay = (): string => {
|
const getRevenueDisplay = (): string => {
|
||||||
const revenue = business.revenue || business.financial_metrics?.revenue;
|
const revenue = business.revenue || business.financial_metrics?.revenue;
|
||||||
@@ -27,40 +36,39 @@ const BusinessTreeItem: React.FC<BusinessTreeItemProps> = ({ business, depth = 0
|
|||||||
<Box
|
<Box
|
||||||
ml={depth * 6}
|
ml={depth * 6}
|
||||||
p={3}
|
p={3}
|
||||||
bg={bgColor}
|
bg={THEME.bg}
|
||||||
borderLeft={depth > 0 ? '4px solid' : 'none'}
|
borderLeft={depth > 0 ? '4px solid' : 'none'}
|
||||||
borderLeftColor="blue.400"
|
borderLeftColor={THEME.gold}
|
||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
mb={2}
|
mb={2}
|
||||||
_hover={{ shadow: 'md' }}
|
_hover={{ shadow: 'md', bg: 'gray.600' }}
|
||||||
transition="all 0.2s"
|
transition="all 0.2s"
|
||||||
>
|
>
|
||||||
<HStack justify="space-between">
|
<HStack justify="space-between">
|
||||||
<VStack align="start" spacing={1}>
|
<VStack align="start" spacing={1}>
|
||||||
<HStack>
|
<HStack>
|
||||||
<Text fontWeight="bold" fontSize={depth === 0 ? 'md' : 'sm'}>
|
<Text fontWeight="bold" fontSize={depth === 0 ? 'md' : 'sm'} color={THEME.textPrimary}>
|
||||||
{business.business_name}
|
{business.business_name}
|
||||||
</Text>
|
</Text>
|
||||||
{business.financial_metrics?.revenue_ratio &&
|
{business.financial_metrics?.revenue_ratio &&
|
||||||
business.financial_metrics.revenue_ratio > 30 && (
|
business.financial_metrics.revenue_ratio > 30 && (
|
||||||
<Badge colorScheme="purple" size="sm">
|
<Badge bg={THEME.gold} color="gray.900" size="sm">
|
||||||
核心业务
|
核心业务
|
||||||
</Badge>
|
</Badge>
|
||||||
)}
|
)}
|
||||||
</HStack>
|
</HStack>
|
||||||
<HStack spacing={4} flexWrap="wrap">
|
<HStack spacing={4} flexWrap="wrap">
|
||||||
<Tag size="sm" variant="subtle">
|
<Tag size="sm" bg="gray.600" color={THEME.textPrimary}>
|
||||||
营收占比: {formatPercentage(business.financial_metrics?.revenue_ratio)}
|
营收占比: {formatPercentage(business.financial_metrics?.revenue_ratio)}
|
||||||
</Tag>
|
</Tag>
|
||||||
<Tag size="sm" variant="subtle">
|
<Tag size="sm" bg="gray.600" color={THEME.textPrimary}>
|
||||||
毛利率: {formatPercentage(business.financial_metrics?.gross_margin)}
|
毛利率: {formatPercentage(business.financial_metrics?.gross_margin)}
|
||||||
</Tag>
|
</Tag>
|
||||||
{business.growth_metrics?.revenue_growth !== undefined && (
|
{business.growth_metrics?.revenue_growth !== undefined && (
|
||||||
<Tag
|
<Tag
|
||||||
size="sm"
|
size="sm"
|
||||||
colorScheme={
|
bg={business.growth_metrics.revenue_growth > 0 ? 'red.600' : 'green.600'}
|
||||||
business.growth_metrics.revenue_growth > 0 ? 'red' : 'green'
|
color="white"
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<TagLabel>
|
<TagLabel>
|
||||||
增长: {business.growth_metrics.revenue_growth > 0 ? '+' : ''}
|
增长: {business.growth_metrics.revenue_growth > 0 ? '+' : ''}
|
||||||
@@ -71,10 +79,10 @@ const BusinessTreeItem: React.FC<BusinessTreeItemProps> = ({ business, depth = 0
|
|||||||
</HStack>
|
</HStack>
|
||||||
</VStack>
|
</VStack>
|
||||||
<VStack align="end" spacing={0}>
|
<VStack align="end" spacing={0}>
|
||||||
<Text fontSize="lg" fontWeight="bold" color="blue.500">
|
<Text fontSize="lg" fontWeight="bold" color={THEME.gold}>
|
||||||
{getRevenueDisplay()}
|
{getRevenueDisplay()}
|
||||||
</Text>
|
</Text>
|
||||||
<Text fontSize="xs" color="gray.500">
|
<Text fontSize="xs" color={THEME.textSecondary}>
|
||||||
营业收入
|
营业收入
|
||||||
</Text>
|
</Text>
|
||||||
</VStack>
|
</VStack>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
* 业务板块详情卡片
|
* 业务板块详情卡片
|
||||||
*
|
*
|
||||||
* 显示公司各业务板块的详细信息
|
* 显示公司各业务板块的详细信息
|
||||||
|
* 黑金主题风格
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@@ -20,9 +21,19 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { FaIndustry, FaExpandAlt, FaCompressAlt } from 'react-icons/fa';
|
import { FaIndustry, FaExpandAlt, FaCompressAlt } from 'react-icons/fa';
|
||||||
import { DisclaimerBox } from '../atoms';
|
|
||||||
import type { BusinessSegment } from '../types';
|
import type { BusinessSegment } from '../types';
|
||||||
|
|
||||||
|
// 黑金主题配置
|
||||||
|
const THEME = {
|
||||||
|
cardBg: 'gray.800',
|
||||||
|
innerCardBg: 'gray.700',
|
||||||
|
gold: '#D4AF37',
|
||||||
|
goldLight: '#F0D78C',
|
||||||
|
textPrimary: '#D4AF37',
|
||||||
|
textSecondary: 'gray.400',
|
||||||
|
border: 'rgba(212, 175, 55, 0.3)',
|
||||||
|
};
|
||||||
|
|
||||||
interface BusinessSegmentsCardProps {
|
interface BusinessSegmentsCardProps {
|
||||||
businessSegments: BusinessSegment[];
|
businessSegments: BusinessSegment[];
|
||||||
expandedSegments: Record<number, boolean>;
|
expandedSegments: Record<number, boolean>;
|
||||||
@@ -34,31 +45,29 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
|
|||||||
businessSegments,
|
businessSegments,
|
||||||
expandedSegments,
|
expandedSegments,
|
||||||
onToggleSegment,
|
onToggleSegment,
|
||||||
cardBg,
|
|
||||||
}) => {
|
}) => {
|
||||||
if (!businessSegments || businessSegments.length === 0) return null;
|
if (!businessSegments || businessSegments.length === 0) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card bg={cardBg} shadow="md">
|
<Card bg={THEME.cardBg} shadow="md">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<HStack>
|
<HStack>
|
||||||
<Icon as={FaIndustry} color="indigo.500" />
|
<Icon as={FaIndustry} color={THEME.gold} />
|
||||||
<Heading size="sm">业务板块详情</Heading>
|
<Heading size="sm" color={THEME.textPrimary}>业务板块详情</Heading>
|
||||||
<Badge>{businessSegments.length} 个板块</Badge>
|
<Badge bg={THEME.gold} color="gray.900">{businessSegments.length} 个板块</Badge>
|
||||||
</HStack>
|
</HStack>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardBody>
|
<CardBody px={2}>
|
||||||
<DisclaimerBox />
|
|
||||||
<SimpleGrid columns={{ base: 1, md: 2, lg: 3 }} spacing={4}>
|
<SimpleGrid columns={{ base: 1, md: 2, lg: 3 }} spacing={4}>
|
||||||
{businessSegments.map((segment, idx) => {
|
{businessSegments.map((segment, idx) => {
|
||||||
const isExpanded = expandedSegments[idx];
|
const isExpanded = expandedSegments[idx];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card key={idx} variant="outline">
|
<Card key={idx} bg={THEME.innerCardBg}>
|
||||||
<CardBody>
|
<CardBody px={2}>
|
||||||
<VStack align="stretch" spacing={3}>
|
<VStack align="stretch" spacing={3}>
|
||||||
<HStack justify="space-between">
|
<HStack justify="space-between">
|
||||||
<Text fontWeight="bold" fontSize="md">
|
<Text fontWeight="bold" fontSize="md" color={THEME.textPrimary}>
|
||||||
{segment.segment_name}
|
{segment.segment_name}
|
||||||
</Text>
|
</Text>
|
||||||
<Button
|
<Button
|
||||||
@@ -68,18 +77,20 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
|
|||||||
<Icon as={isExpanded ? FaCompressAlt : FaExpandAlt} />
|
<Icon as={isExpanded ? FaCompressAlt : FaExpandAlt} />
|
||||||
}
|
}
|
||||||
onClick={() => onToggleSegment(idx)}
|
onClick={() => onToggleSegment(idx)}
|
||||||
colorScheme="blue"
|
color={THEME.gold}
|
||||||
|
_hover={{ bg: 'gray.600' }}
|
||||||
>
|
>
|
||||||
{isExpanded ? '折叠' : '展开'}
|
{isExpanded ? '折叠' : '展开'}
|
||||||
</Button>
|
</Button>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
<Text fontSize="xs" color="gray.500" mb={1}>
|
<Text fontSize="xs" color={THEME.textSecondary} mb={1}>
|
||||||
业务描述
|
业务描述
|
||||||
</Text>
|
</Text>
|
||||||
<Text
|
<Text
|
||||||
fontSize="sm"
|
fontSize="sm"
|
||||||
|
color={THEME.textPrimary}
|
||||||
noOfLines={isExpanded ? undefined : 3}
|
noOfLines={isExpanded ? undefined : 3}
|
||||||
>
|
>
|
||||||
{segment.segment_description || '暂无描述'}
|
{segment.segment_description || '暂无描述'}
|
||||||
@@ -87,11 +98,12 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
<Text fontSize="xs" color="gray.500" mb={1}>
|
<Text fontSize="xs" color={THEME.textSecondary} mb={1}>
|
||||||
竞争地位
|
竞争地位
|
||||||
</Text>
|
</Text>
|
||||||
<Text
|
<Text
|
||||||
fontSize="sm"
|
fontSize="sm"
|
||||||
|
color={THEME.textPrimary}
|
||||||
noOfLines={isExpanded ? undefined : 2}
|
noOfLines={isExpanded ? undefined : 2}
|
||||||
>
|
>
|
||||||
{segment.competitive_position || '暂无数据'}
|
{segment.competitive_position || '暂无数据'}
|
||||||
@@ -99,13 +111,13 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
<Text fontSize="xs" color="gray.500" mb={1}>
|
<Text fontSize="xs" color={THEME.textSecondary} mb={1}>
|
||||||
未来潜力
|
未来潜力
|
||||||
</Text>
|
</Text>
|
||||||
<Text
|
<Text
|
||||||
fontSize="sm"
|
fontSize="sm"
|
||||||
noOfLines={isExpanded ? undefined : 2}
|
noOfLines={isExpanded ? undefined : 2}
|
||||||
color="blue.600"
|
color={THEME.goldLight}
|
||||||
>
|
>
|
||||||
{segment.future_potential || '暂无数据'}
|
{segment.future_potential || '暂无数据'}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -113,10 +125,10 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
|
|||||||
|
|
||||||
{isExpanded && segment.key_products && (
|
{isExpanded && segment.key_products && (
|
||||||
<Box>
|
<Box>
|
||||||
<Text fontSize="xs" color="gray.500" mb={1}>
|
<Text fontSize="xs" color={THEME.textSecondary} mb={1}>
|
||||||
主要产品
|
主要产品
|
||||||
</Text>
|
</Text>
|
||||||
<Text fontSize="sm" color="green.600">
|
<Text fontSize="sm" color="green.300">
|
||||||
{segment.key_products}
|
{segment.key_products}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -124,10 +136,10 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
|
|||||||
|
|
||||||
{isExpanded && segment.market_share !== undefined && (
|
{isExpanded && segment.market_share !== undefined && (
|
||||||
<Box>
|
<Box>
|
||||||
<Text fontSize="xs" color="gray.500" mb={1}>
|
<Text fontSize="xs" color={THEME.textSecondary} mb={1}>
|
||||||
市场份额
|
市场份额
|
||||||
</Text>
|
</Text>
|
||||||
<Badge colorScheme="purple" fontSize="sm">
|
<Badge bg="purple.600" color="white" fontSize="sm">
|
||||||
{segment.market_share}%
|
{segment.market_share}%
|
||||||
</Badge>
|
</Badge>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -135,10 +147,10 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
|
|||||||
|
|
||||||
{isExpanded && segment.revenue_contribution !== undefined && (
|
{isExpanded && segment.revenue_contribution !== undefined && (
|
||||||
<Box>
|
<Box>
|
||||||
<Text fontSize="xs" color="gray.500" mb={1}>
|
<Text fontSize="xs" color={THEME.textSecondary} mb={1}>
|
||||||
营收贡献
|
营收贡献
|
||||||
</Text>
|
</Text>
|
||||||
<Badge colorScheme="orange" fontSize="sm">
|
<Badge bg={THEME.gold} color="gray.900" fontSize="sm">
|
||||||
{segment.revenue_contribution}%
|
{segment.revenue_contribution}%
|
||||||
</Badge>
|
</Badge>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
* 业务结构分析卡片
|
* 业务结构分析卡片
|
||||||
*
|
*
|
||||||
* 显示公司业务结构树形图
|
* 显示公司业务结构树形图
|
||||||
|
* 黑金主题风格
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@@ -16,9 +17,17 @@ import {
|
|||||||
Icon,
|
Icon,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { FaChartPie } from 'react-icons/fa';
|
import { FaChartPie } from 'react-icons/fa';
|
||||||
import { DisclaimerBox, BusinessTreeItem } from '../atoms';
|
import { BusinessTreeItem } from '../atoms';
|
||||||
import type { BusinessStructure } from '../types';
|
import type { BusinessStructure } from '../types';
|
||||||
|
|
||||||
|
// 黑金主题配置
|
||||||
|
const THEME = {
|
||||||
|
cardBg: 'gray.800',
|
||||||
|
gold: '#D4AF37',
|
||||||
|
textPrimary: '#D4AF37',
|
||||||
|
border: 'rgba(212, 175, 55, 0.3)',
|
||||||
|
};
|
||||||
|
|
||||||
interface BusinessStructureCardProps {
|
interface BusinessStructureCardProps {
|
||||||
businessStructure: BusinessStructure[];
|
businessStructure: BusinessStructure[];
|
||||||
cardBg?: string;
|
cardBg?: string;
|
||||||
@@ -26,21 +35,19 @@ interface BusinessStructureCardProps {
|
|||||||
|
|
||||||
const BusinessStructureCard: React.FC<BusinessStructureCardProps> = ({
|
const BusinessStructureCard: React.FC<BusinessStructureCardProps> = ({
|
||||||
businessStructure,
|
businessStructure,
|
||||||
cardBg,
|
|
||||||
}) => {
|
}) => {
|
||||||
if (!businessStructure || businessStructure.length === 0) return null;
|
if (!businessStructure || businessStructure.length === 0) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card bg={cardBg} shadow="md">
|
<Card bg={THEME.cardBg} shadow="md">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<HStack>
|
<HStack>
|
||||||
<Icon as={FaChartPie} color="purple.500" />
|
<Icon as={FaChartPie} color={THEME.gold} />
|
||||||
<Heading size="sm">业务结构分析</Heading>
|
<Heading size="sm" color={THEME.textPrimary}>业务结构分析</Heading>
|
||||||
<Badge>{businessStructure[0]?.report_period}</Badge>
|
<Badge bg={THEME.gold} color="gray.900">{businessStructure[0]?.report_period}</Badge>
|
||||||
</HStack>
|
</HStack>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardBody>
|
<CardBody px={0}>
|
||||||
<DisclaimerBox />
|
|
||||||
<VStack spacing={3} align="stretch">
|
<VStack spacing={3} align="stretch">
|
||||||
{businessStructure.map((business, idx) => (
|
{businessStructure.map((business, idx) => (
|
||||||
<BusinessTreeItem
|
<BusinessTreeItem
|
||||||
|
|||||||
Reference in New Issue
Block a user