diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard.tsx deleted file mode 100644 index 7138179c..00000000 --- a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard.tsx +++ /dev/null @@ -1,94 +0,0 @@ -/** - * 核心定位卡片 - * - * 显示公司的核心定位、投资亮点和商业模式 - */ - -import React from 'react'; -import { - Card, - CardBody, - CardHeader, - VStack, - HStack, - Text, - Heading, - Alert, - AlertIcon, - Grid, - GridItem, - Box, - Icon, -} from '@chakra-ui/react'; -import { FaLightbulb } from 'react-icons/fa'; -import { DisclaimerBox } from '../atoms'; -import type { QualitativeAnalysis } from '../types'; - -interface CorePositioningCardProps { - qualitativeAnalysis: QualitativeAnalysis; - cardBg?: string; -} - -const CorePositioningCard: React.FC = ({ - qualitativeAnalysis, - cardBg, -}) => { - const blueBg = 'blue.50'; - const greenBg = 'green.50'; - - return ( - - - - - 核心定位 - - - - - - {qualitativeAnalysis.core_positioning?.one_line_intro && ( - - - - {qualitativeAnalysis.core_positioning.one_line_intro} - - - )} - - - - - - 投资亮点 - - - - {qualitativeAnalysis.core_positioning?.investment_highlights || - '暂无数据'} - - - - - - - - - 商业模式 - - - - {qualitativeAnalysis.core_positioning?.business_model_desc || - '暂无数据'} - - - - - - - - - ); -}; - -export default CorePositioningCard; diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/atoms/HighlightCard.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/atoms/HighlightCard.tsx new file mode 100644 index 00000000..e4a0b75d --- /dev/null +++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/atoms/HighlightCard.tsx @@ -0,0 +1,54 @@ +/** + * 投资亮点卡片组件 + */ + +import React, { memo } from 'react'; +import { Box, HStack, VStack, Icon, Text } from '@chakra-ui/react'; +import { FaUsers } from 'react-icons/fa'; +import { THEME, ICON_MAP, HIGHLIGHT_HOVER_STYLES } from '../theme'; +import type { InvestmentHighlightItem } from '../../../types'; + +interface HighlightCardProps { + highlight: InvestmentHighlightItem; +} + +export const HighlightCard = memo(({ highlight }) => { + const IconComponent = ICON_MAP[highlight.icon] || FaUsers; + + return ( + + + + + + + + {highlight.title} + + + {highlight.description} + + + + + ); +}); + +HighlightCard.displayName = 'HighlightCard'; diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/atoms/ModelBlock.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/atoms/ModelBlock.tsx new file mode 100644 index 00000000..60495a6b --- /dev/null +++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/atoms/ModelBlock.tsx @@ -0,0 +1,47 @@ +/** + * 商业模式板块组件 + */ + +import React, { memo } from 'react'; +import { Box, VStack, HStack, Text, Tag, Divider } from '@chakra-ui/react'; +import { THEME } from '../theme'; +import type { BusinessModelSection } from '../../../types'; + +interface ModelBlockProps { + section: BusinessModelSection; + isLast?: boolean; +} + +export const ModelBlock = memo(({ section, isLast }) => ( + + + + {section.title} + + + {section.description} + + {section.tags && section.tags.length > 0 && ( + + {section.tags.map((tag, idx) => ( + + {tag} + + ))} + + )} + + {!isLast && } + +)); + +ModelBlock.displayName = 'ModelBlock'; diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/atoms/SectionHeader.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/atoms/SectionHeader.tsx new file mode 100644 index 00000000..6a1c5267 --- /dev/null +++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/atoms/SectionHeader.tsx @@ -0,0 +1,27 @@ +/** + * 区域标题组件 + */ + +import React, { memo } from 'react'; +import { HStack, Icon, Text } from '@chakra-ui/react'; +import type { IconType } from 'react-icons'; +import { THEME } from '../theme'; + +interface SectionHeaderProps { + icon: IconType; + title: string; + color?: string; +} + +export const SectionHeader = memo( + ({ icon, title, color = THEME.dark.titleColor }) => ( + + + + {title} + + + ) +); + +SectionHeader.displayName = 'SectionHeader'; diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/atoms/index.ts b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/atoms/index.ts new file mode 100644 index 00000000..47e08ba9 --- /dev/null +++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/atoms/index.ts @@ -0,0 +1,7 @@ +/** + * CorePositioningCard 原子组件统一导出 + */ + +export { SectionHeader } from './SectionHeader'; +export { HighlightCard } from './HighlightCard'; +export { ModelBlock } from './ModelBlock'; diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/index.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/index.tsx new file mode 100644 index 00000000..07301161 --- /dev/null +++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/index.tsx @@ -0,0 +1,204 @@ +/** + * 核心定位卡片 + * + * 显示公司的核心定位、投资亮点和商业模式 + * 黑金主题设计 + */ + +import React, { memo, useMemo } from 'react'; +import { + Card, + CardBody, + VStack, + Text, + Box, + Grid, + GridItem, +} from '@chakra-ui/react'; +import { FaCrown, FaStar, FaBriefcase } from 'react-icons/fa'; +import type { + QualitativeAnalysis, + InvestmentHighlightItem, +} from '../../types'; +import { + THEME, + CARD_STYLES, + GRID_COLUMNS, + BORDER_RIGHT_RESPONSIVE, +} from './theme'; +import { SectionHeader, HighlightCard, ModelBlock } from './atoms'; + +// ==================== 主组件 ==================== + +interface CorePositioningCardProps { + qualitativeAnalysis: QualitativeAnalysis; + cardBg?: string; +} + +const CorePositioningCard: React.FC = memo( + ({ qualitativeAnalysis }) => { + const corePositioning = qualitativeAnalysis.core_positioning; + + // 判断是否有结构化数据 + const hasStructuredData = useMemo( + () => + !!( + corePositioning?.features?.length || + (Array.isArray(corePositioning?.investment_highlights) && + corePositioning.investment_highlights.length > 0) || + corePositioning?.business_model_sections?.length + ), + [corePositioning] + ); + + // 如果没有结构化数据,使用旧的文本格式渲染 + if (!hasStructuredData) { + return ( + + + + + {corePositioning?.one_line_intro && ( + + + {corePositioning.one_line_intro} + + + )} + + + + + + {corePositioning?.investment_highlights_text || + (typeof corePositioning?.investment_highlights === 'string' + ? corePositioning.investment_highlights + : '暂无数据')} + + + + + + + + {corePositioning?.business_model_desc || '暂无数据'} + + + + + + + + ); + } + + // 结构化数据渲染 - 缓存数组计算 + const highlights = useMemo( + () => + (Array.isArray(corePositioning?.investment_highlights) + ? corePositioning.investment_highlights + : []) as InvestmentHighlightItem[], + [corePositioning?.investment_highlights] + ); + + const businessSections = useMemo( + () => corePositioning?.business_model_sections || [], + [corePositioning?.business_model_sections] + ); + + return ( + + + + {/* 核心定位区域(深色背景) */} + + + + {/* 一句话介绍 */} + {corePositioning?.one_line_intro && ( + + + {corePositioning.one_line_intro} + + + )} + + + {/* 投资亮点 + 商业模式区域 */} + + {/* 投资亮点区域 */} + + + + {highlights.length > 0 ? ( + highlights.map((highlight, idx) => ( + + )) + ) : ( + + 暂无数据 + + )} + + + + {/* 商业模式区域 */} + + + + {businessSections.length > 0 ? ( + businessSections.map((section, idx) => ( + + )) + ) : ( + + 暂无数据 + + )} + + + + + + + ); + } +); + +CorePositioningCard.displayName = 'CorePositioningCard'; + +export default CorePositioningCard; diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/theme.ts b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/theme.ts new file mode 100644 index 00000000..a640f522 --- /dev/null +++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard/theme.ts @@ -0,0 +1,83 @@ +/** + * CorePositioningCard 主题和样式常量 + */ + +import { + FaUniversity, + FaFire, + FaUsers, + FaChartLine, + FaMicrochip, + FaShieldAlt, +} from 'react-icons/fa'; +import type { IconType } from 'react-icons'; + +// ==================== 主题常量 ==================== + +export const THEME = { + // 深色背景区域(核心定位) + dark: { + bg: '#1A202C', + cardBg: '#252D3A', + border: '#C9A961', + borderGradient: 'linear-gradient(90deg, #C9A961, #8B7355)', + titleColor: '#C9A961', + textColor: '#E2E8F0', + subtextColor: '#A0AEC0', + }, + // 浅色背景区域(投资亮点/商业模式) + light: { + bg: '#1E2530', + cardBg: '#252D3A', + titleColor: '#C9A961', + textColor: '#E2E8F0', + subtextColor: '#A0AEC0', + tagBg: 'rgba(201, 169, 97, 0.15)', + tagColor: '#C9A961', + }, +} as const; + +// ==================== 图标映射 ==================== + +export const ICON_MAP: Record = { + bank: FaUniversity, + fire: FaFire, + users: FaUsers, + 'trending-up': FaChartLine, + cpu: FaMicrochip, + 'shield-check': FaShieldAlt, +}; + +// ==================== 样式常量 ==================== + +// 卡片通用样式(含顶部金色边框) +export const CARD_STYLES = { + bg: THEME.dark.bg, + shadow: 'lg', + border: '1px solid', + borderColor: 'whiteAlpha.100', + overflow: 'hidden', + position: 'relative', + _before: { + content: '""', + position: 'absolute', + top: 0, + left: 0, + right: 0, + height: '3px', + background: THEME.dark.borderGradient, + }, +} as const; + +// HighlightCard hover 样式 +export const HIGHLIGHT_HOVER_STYLES = { + _hover: { borderColor: 'whiteAlpha.200' }, +} as const; + +// 响应式布局常量 +export const GRID_COLUMNS = { + twoColumn: { base: '1fr', lg: 'repeat(2, 1fr)' }, + twoColumnMd: { base: '1fr', md: 'repeat(2, 1fr)' }, +} as const; + +export const BORDER_RIGHT_RESPONSIVE = { lg: '1px solid' } as const;