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:
zdl
2025-12-12 13:13:34 +08:00
parent e049429b09
commit 7c7c70c4d9
6 changed files with 170 additions and 166 deletions

View File

@@ -147,7 +147,8 @@ const SubTabContainer: React.FC<SubTabContainerProps> = memo(({
bg={theme.bg}
borderBottom="1px solid"
borderColor={theme.borderColor}
px={4}
pl={0}
pr={4}
py={2}
flexWrap="wrap"
gap={2}

View File

@@ -20,7 +20,8 @@ const TabNavigation: React.FC<TabNavigationProps> = ({
borderColor={themeColors.dividerColor}
borderTopLeftRadius={borderRadius}
borderTopRightRadius={borderRadius}
px={4}
pl={0}
pr={4}
py={2}
flexWrap="wrap"
gap={2}

View File

@@ -473,147 +473,65 @@ export const PINGAN_BANK_DATA = {
},
business_structure: [
{
business_name: '零售金融',
business_name: '舒泰清复方聚乙二醇电解质散IV',
business_level: 1,
revenue: 812300,
revenue: 17900,
revenue_unit: '万元',
financial_metrics: {
revenue_ratio: 50.1,
gross_margin: 42.5
revenue_ratio: 55.16,
gross_margin: 78.21
},
growth_metrics: {
revenue_growth: 11.2
revenue_growth: -8.20
},
report_period: '2024Q3'
report_period: '2024年报'
},
{
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_name: '苏肽生(注射用鼠神经生长因子)',
business_level: 1,
revenue: 685400,
revenue: 13400,
revenue_unit: '万元',
financial_metrics: {
revenue_ratio: 42.2,
gross_margin: 38.6
revenue_ratio: 41.21,
gross_margin: 89.11
},
growth_metrics: {
revenue_growth: 6.8
revenue_growth: -17.30
},
report_period: '2024Q3'
report_period: '2024年报'
},
{
business_name: '公司贷款',
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_name: '舒斯通(复方聚乙二醇(3350)电解质散)',
business_level: 1,
revenue: 125800,
revenue: 771,
revenue_unit: '万元',
financial_metrics: {
revenue_ratio: 7.7,
gross_margin: 28.2
revenue_ratio: 2.37
},
growth_metrics: {
revenue_growth: 3.5
report_period: '2024年报'
},
{
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: [
{
segment_name: '信用卡业务',
description: '国内领先的信用卡发卡银行流通卡量超7000万张',
key_metrics: { cards_issued: 7200, transaction_volume: 28500, market_share: 8.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 }
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年有望通过新产品上市实现业绩突破。'
}
]
},
@@ -1336,11 +1254,68 @@ export const generateCompanyData = (stockCode, stockName = '示例公司') => {
}
},
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: '其他业务', revenue: baseRevenue * 0.15, ratio: 15, growth: 5.8, report_period: '2024Q3' }
{
business_name: '舒泰清复方聚乙二醇电解质散IV',
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: {
value_chain_flows: [

View File

@@ -3,6 +3,7 @@
*
* 递归显示业务结构层级
* 使用位置:业务结构分析卡片
* 黑金主题风格
*/
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 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 revenue = business.revenue || business.financial_metrics?.revenue;
@@ -27,40 +36,39 @@ const BusinessTreeItem: React.FC<BusinessTreeItemProps> = ({ business, depth = 0
<Box
ml={depth * 6}
p={3}
bg={bgColor}
bg={THEME.bg}
borderLeft={depth > 0 ? '4px solid' : 'none'}
borderLeftColor="blue.400"
borderLeftColor={THEME.gold}
borderRadius="md"
mb={2}
_hover={{ shadow: 'md' }}
_hover={{ shadow: 'md', bg: 'gray.600' }}
transition="all 0.2s"
>
<HStack justify="space-between">
<VStack align="start" spacing={1}>
<HStack>
<Text fontWeight="bold" fontSize={depth === 0 ? 'md' : 'sm'}>
<Text fontWeight="bold" fontSize={depth === 0 ? 'md' : 'sm'} color={THEME.textPrimary}>
{business.business_name}
</Text>
{business.financial_metrics?.revenue_ratio &&
business.financial_metrics.revenue_ratio > 30 && (
<Badge colorScheme="purple" size="sm">
<Badge bg={THEME.gold} color="gray.900" size="sm">
</Badge>
)}
</HStack>
<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)}
</Tag>
<Tag size="sm" variant="subtle">
<Tag size="sm" bg="gray.600" color={THEME.textPrimary}>
: {formatPercentage(business.financial_metrics?.gross_margin)}
</Tag>
{business.growth_metrics?.revenue_growth !== undefined && (
<Tag
size="sm"
colorScheme={
business.growth_metrics.revenue_growth > 0 ? 'red' : 'green'
}
bg={business.growth_metrics.revenue_growth > 0 ? 'red.600' : 'green.600'}
color="white"
>
<TagLabel>
: {business.growth_metrics.revenue_growth > 0 ? '+' : ''}
@@ -71,10 +79,10 @@ const BusinessTreeItem: React.FC<BusinessTreeItemProps> = ({ business, depth = 0
</HStack>
</VStack>
<VStack align="end" spacing={0}>
<Text fontSize="lg" fontWeight="bold" color="blue.500">
<Text fontSize="lg" fontWeight="bold" color={THEME.gold}>
{getRevenueDisplay()}
</Text>
<Text fontSize="xs" color="gray.500">
<Text fontSize="xs" color={THEME.textSecondary}>
</Text>
</VStack>

View File

@@ -2,6 +2,7 @@
* 业务板块详情卡片
*
* 显示公司各业务板块的详细信息
* 黑金主题风格
*/
import React from 'react';
@@ -20,9 +21,19 @@ import {
Button,
} from '@chakra-ui/react';
import { FaIndustry, FaExpandAlt, FaCompressAlt } from 'react-icons/fa';
import { DisclaimerBox } from '../atoms';
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 {
businessSegments: BusinessSegment[];
expandedSegments: Record<number, boolean>;
@@ -34,31 +45,29 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
businessSegments,
expandedSegments,
onToggleSegment,
cardBg,
}) => {
if (!businessSegments || businessSegments.length === 0) return null;
return (
<Card bg={cardBg} shadow="md">
<Card bg={THEME.cardBg} shadow="md">
<CardHeader>
<HStack>
<Icon as={FaIndustry} color="indigo.500" />
<Heading size="sm"></Heading>
<Badge>{businessSegments.length} </Badge>
<Icon as={FaIndustry} color={THEME.gold} />
<Heading size="sm" color={THEME.textPrimary}></Heading>
<Badge bg={THEME.gold} color="gray.900">{businessSegments.length} </Badge>
</HStack>
</CardHeader>
<CardBody>
<DisclaimerBox />
<CardBody px={2}>
<SimpleGrid columns={{ base: 1, md: 2, lg: 3 }} spacing={4}>
{businessSegments.map((segment, idx) => {
const isExpanded = expandedSegments[idx];
return (
<Card key={idx} variant="outline">
<CardBody>
<Card key={idx} bg={THEME.innerCardBg}>
<CardBody px={2}>
<VStack align="stretch" spacing={3}>
<HStack justify="space-between">
<Text fontWeight="bold" fontSize="md">
<Text fontWeight="bold" fontSize="md" color={THEME.textPrimary}>
{segment.segment_name}
</Text>
<Button
@@ -68,18 +77,20 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
<Icon as={isExpanded ? FaCompressAlt : FaExpandAlt} />
}
onClick={() => onToggleSegment(idx)}
colorScheme="blue"
color={THEME.gold}
_hover={{ bg: 'gray.600' }}
>
{isExpanded ? '折叠' : '展开'}
</Button>
</HStack>
<Box>
<Text fontSize="xs" color="gray.500" mb={1}>
<Text fontSize="xs" color={THEME.textSecondary} mb={1}>
</Text>
<Text
fontSize="sm"
color={THEME.textPrimary}
noOfLines={isExpanded ? undefined : 3}
>
{segment.segment_description || '暂无描述'}
@@ -87,11 +98,12 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
</Box>
<Box>
<Text fontSize="xs" color="gray.500" mb={1}>
<Text fontSize="xs" color={THEME.textSecondary} mb={1}>
</Text>
<Text
fontSize="sm"
color={THEME.textPrimary}
noOfLines={isExpanded ? undefined : 2}
>
{segment.competitive_position || '暂无数据'}
@@ -99,13 +111,13 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
</Box>
<Box>
<Text fontSize="xs" color="gray.500" mb={1}>
<Text fontSize="xs" color={THEME.textSecondary} mb={1}>
</Text>
<Text
fontSize="sm"
noOfLines={isExpanded ? undefined : 2}
color="blue.600"
color={THEME.goldLight}
>
{segment.future_potential || '暂无数据'}
</Text>
@@ -113,10 +125,10 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
{isExpanded && segment.key_products && (
<Box>
<Text fontSize="xs" color="gray.500" mb={1}>
<Text fontSize="xs" color={THEME.textSecondary} mb={1}>
</Text>
<Text fontSize="sm" color="green.600">
<Text fontSize="sm" color="green.300">
{segment.key_products}
</Text>
</Box>
@@ -124,10 +136,10 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
{isExpanded && segment.market_share !== undefined && (
<Box>
<Text fontSize="xs" color="gray.500" mb={1}>
<Text fontSize="xs" color={THEME.textSecondary} mb={1}>
</Text>
<Badge colorScheme="purple" fontSize="sm">
<Badge bg="purple.600" color="white" fontSize="sm">
{segment.market_share}%
</Badge>
</Box>
@@ -135,10 +147,10 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
{isExpanded && segment.revenue_contribution !== undefined && (
<Box>
<Text fontSize="xs" color="gray.500" mb={1}>
<Text fontSize="xs" color={THEME.textSecondary} mb={1}>
</Text>
<Badge colorScheme="orange" fontSize="sm">
<Badge bg={THEME.gold} color="gray.900" fontSize="sm">
{segment.revenue_contribution}%
</Badge>
</Box>

View File

@@ -2,6 +2,7 @@
* 业务结构分析卡片
*
* 显示公司业务结构树形图
* 黑金主题风格
*/
import React from 'react';
@@ -16,9 +17,17 @@ import {
Icon,
} from '@chakra-ui/react';
import { FaChartPie } from 'react-icons/fa';
import { DisclaimerBox, BusinessTreeItem } from '../atoms';
import { BusinessTreeItem } from '../atoms';
import type { BusinessStructure } from '../types';
// 黑金主题配置
const THEME = {
cardBg: 'gray.800',
gold: '#D4AF37',
textPrimary: '#D4AF37',
border: 'rgba(212, 175, 55, 0.3)',
};
interface BusinessStructureCardProps {
businessStructure: BusinessStructure[];
cardBg?: string;
@@ -26,21 +35,19 @@ interface BusinessStructureCardProps {
const BusinessStructureCard: React.FC<BusinessStructureCardProps> = ({
businessStructure,
cardBg,
}) => {
if (!businessStructure || businessStructure.length === 0) return null;
return (
<Card bg={cardBg} shadow="md">
<Card bg={THEME.cardBg} shadow="md">
<CardHeader>
<HStack>
<Icon as={FaChartPie} color="purple.500" />
<Heading size="sm"></Heading>
<Badge>{businessStructure[0]?.report_period}</Badge>
<Icon as={FaChartPie} color={THEME.gold} />
<Heading size="sm" color={THEME.textPrimary}></Heading>
<Badge bg={THEME.gold} color="gray.900">{businessStructure[0]?.report_period}</Badge>
</HStack>
</CardHeader>
<CardBody>
<DisclaimerBox />
<CardBody px={0}>
<VStack spacing={3} align="stretch">
{businessStructure.map((business, idx) => (
<BusinessTreeItem