feat: 战略分析Ui调整
This commit is contained in:
@@ -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>
|
||||
));
|
||||
|
||||
return (
|
||||
<Card bg={cardBg} shadow="md">
|
||||
<CardHeader>
|
||||
<HStack>
|
||||
<Icon as={FaRocket} color="red.500" />
|
||||
<Heading size="sm">战略分析</Heading>
|
||||
</HStack>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<DisclaimerBox />
|
||||
<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>
|
||||
EmptyState.displayName = 'StrategyEmptyState';
|
||||
|
||||
<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>
|
||||
</Grid>
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
// 内容项组件 - 复用结构
|
||||
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 {...CARD_STYLES}>
|
||||
<CardHeader>
|
||||
<HStack>
|
||||
<Icon as={FaRocket} color="yellow.500" />
|
||||
<Heading size="sm">战略分析</Heading>
|
||||
</HStack>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
{!hasData ? (
|
||||
<EmptyState />
|
||||
) : (
|
||||
<Grid templateColumns="repeat(2, 1fr)" gap={6}>
|
||||
<GridItem colSpan={GRID_RESPONSIVE_COLSPAN}>
|
||||
<ContentItem
|
||||
title="战略方向"
|
||||
content={strategy.strategy_description || '暂无数据'}
|
||||
/>
|
||||
</GridItem>
|
||||
<GridItem colSpan={GRID_RESPONSIVE_COLSPAN}>
|
||||
<ContentItem
|
||||
title="战略举措"
|
||||
content={strategy.strategic_initiatives || '暂无数据'}
|
||||
/>
|
||||
</GridItem>
|
||||
</Grid>
|
||||
)}
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
StrategyAnalysisCard.displayName = 'StrategyAnalysisCard';
|
||||
|
||||
export default StrategyAnalysisCard;
|
||||
|
||||
Reference in New Issue
Block a user