feat: 战略分析Ui调整

This commit is contained in:
zdl
2025-12-11 17:37:24 +08:00
parent a47e0feed8
commit 6797f54b6c

View File

@@ -4,7 +4,7 @@
* 显示公司战略方向和战略举措
*/
import React from 'react';
import React, { memo, useMemo } from 'react';
import {
Card,
CardBody,
@@ -17,63 +17,118 @@ import {
Icon,
Grid,
GridItem,
Center,
} from '@chakra-ui/react';
import { FaRocket } from 'react-icons/fa';
import { DisclaimerBox } from '../atoms';
import { FaRocket, FaChartBar } from 'react-icons/fa';
import type { Strategy } from '../types';
// 样式常量 - 避免每次渲染创建新对象
const CARD_STYLES = {
bg: 'transparent',
border: '1px solid',
borderColor: 'yellow.600',
shadow: 'md',
} as const;
const CONTENT_BOX_STYLES = {
p: 4,
border: '1px solid',
borderColor: 'yellow.600',
borderRadius: 'md',
} as const;
const EMPTY_BOX_STYLES = {
border: '1px dashed',
borderColor: 'yellow.600',
borderRadius: 'md',
py: 12,
} as const;
const GRID_RESPONSIVE_COLSPAN = { base: 2, md: 1 } as const;
interface StrategyAnalysisCardProps {
strategy: Strategy;
cardBg?: string;
}
const StrategyAnalysisCard: React.FC<StrategyAnalysisCardProps> = ({
strategy,
cardBg,
}) => {
const purpleBg = 'purple.50';
const orangeBg = 'orange.50';
// 空状态组件 - 独立 memo 避免重复渲染
const EmptyState = memo(() => (
<Box {...EMPTY_BOX_STYLES}>
<Center>
<VStack spacing={3}>
<Icon as={FaChartBar} boxSize={10} color="yellow.600" />
<Text fontWeight="medium"></Text>
<Text fontSize="sm" color="gray.500">
</Text>
</VStack>
</Center>
</Box>
));
EmptyState.displayName = 'StrategyEmptyState';
// 内容项组件 - 复用结构
interface ContentItemProps {
title: string;
content: string;
}
const ContentItem = memo<ContentItemProps>(({ title, content }) => (
<VStack align="stretch" spacing={3}>
<Text fontWeight="bold" fontSize="sm" color="yellow.500">
{title}
</Text>
<Box {...CONTENT_BOX_STYLES}>
<Text fontSize="sm" color="white">
{content}
</Text>
</Box>
</VStack>
));
ContentItem.displayName = 'StrategyContentItem';
const StrategyAnalysisCard: React.FC<StrategyAnalysisCardProps> = memo(
({ strategy }) => {
// 缓存数据检测结果
const hasData = useMemo(
() => !!(strategy?.strategy_description || strategy?.strategic_initiatives),
[strategy?.strategy_description, strategy?.strategic_initiatives]
);
return (
<Card bg={cardBg} shadow="md">
<Card {...CARD_STYLES}>
<CardHeader>
<HStack>
<Icon as={FaRocket} color="red.500" />
<Icon as={FaRocket} color="yellow.500" />
<Heading size="sm"></Heading>
</HStack>
</CardHeader>
<CardBody>
<DisclaimerBox />
{!hasData ? (
<EmptyState />
) : (
<Grid templateColumns="repeat(2, 1fr)" gap={6}>
<GridItem colSpan={{ base: 2, md: 1 }}>
<VStack align="stretch" spacing={3}>
<Text fontWeight="bold" fontSize="sm" color="gray.600">
</Text>
<Box p={4} bg={purpleBg} borderRadius="md">
<Text fontSize="sm">
{strategy.strategy_description || '暂无数据'}
</Text>
</Box>
</VStack>
<GridItem colSpan={GRID_RESPONSIVE_COLSPAN}>
<ContentItem
title="战略方向"
content={strategy.strategy_description || '暂无数据'}
/>
</GridItem>
<GridItem colSpan={{ base: 2, md: 1 }}>
<VStack align="stretch" spacing={3}>
<Text fontWeight="bold" fontSize="sm" color="gray.600">
</Text>
<Box p={4} bg={orangeBg} borderRadius="md">
<Text fontSize="sm">
{strategy.strategic_initiatives || '暂无数据'}
</Text>
</Box>
</VStack>
<GridItem colSpan={GRID_RESPONSIVE_COLSPAN}>
<ContentItem
title="战略举措"
content={strategy.strategic_initiatives || '暂无数据'}
/>
</GridItem>
</Grid>
)}
</CardBody>
</Card>
);
};
}
);
StrategyAnalysisCard.displayName = 'StrategyAnalysisCard';
export default StrategyAnalysisCard;