feat: 战略分析Ui调整
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
* 显示公司战略方向和战略举措
|
* 显示公司战略方向和战略举措
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React, { memo, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardBody,
|
CardBody,
|
||||||
@@ -17,63 +17,118 @@ import {
|
|||||||
Icon,
|
Icon,
|
||||||
Grid,
|
Grid,
|
||||||
GridItem,
|
GridItem,
|
||||||
|
Center,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { FaRocket } from 'react-icons/fa';
|
import { FaRocket, FaChartBar } from 'react-icons/fa';
|
||||||
import { DisclaimerBox } from '../atoms';
|
|
||||||
import type { Strategy } from '../types';
|
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 {
|
interface StrategyAnalysisCardProps {
|
||||||
strategy: Strategy;
|
strategy: Strategy;
|
||||||
cardBg?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const StrategyAnalysisCard: React.FC<StrategyAnalysisCardProps> = ({
|
// 空状态组件 - 独立 memo 避免重复渲染
|
||||||
strategy,
|
const EmptyState = memo(() => (
|
||||||
cardBg,
|
<Box {...EMPTY_BOX_STYLES}>
|
||||||
}) => {
|
<Center>
|
||||||
const purpleBg = 'purple.50';
|
<VStack spacing={3}>
|
||||||
const orangeBg = 'orange.50';
|
<Icon as={FaChartBar} boxSize={10} color="yellow.600" />
|
||||||
|
<Text fontWeight="medium">战略数据更新中</Text>
|
||||||
|
<Text fontSize="sm" color="gray.500">
|
||||||
|
战略方向和具体举措数据将在近期更新
|
||||||
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
</Center>
|
||||||
|
</Box>
|
||||||
|
));
|
||||||
|
|
||||||
return (
|
EmptyState.displayName = 'StrategyEmptyState';
|
||||||
<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>
|
|
||||||
|
|
||||||
<GridItem colSpan={{ base: 2, md: 1 }}>
|
// 内容项组件 - 复用结构
|
||||||
<VStack align="stretch" spacing={3}>
|
interface ContentItemProps {
|
||||||
<Text fontWeight="bold" fontSize="sm" color="gray.600">
|
title: string;
|
||||||
战略举措
|
content: string;
|
||||||
</Text>
|
}
|
||||||
<Box p={4} bg={orangeBg} borderRadius="md">
|
|
||||||
<Text fontSize="sm">
|
const ContentItem = memo<ContentItemProps>(({ title, content }) => (
|
||||||
{strategy.strategic_initiatives || '暂无数据'}
|
<VStack align="stretch" spacing={3}>
|
||||||
</Text>
|
<Text fontWeight="bold" fontSize="sm" color="yellow.500">
|
||||||
</Box>
|
{title}
|
||||||
</VStack>
|
</Text>
|
||||||
</GridItem>
|
<Box {...CONTENT_BOX_STYLES}>
|
||||||
</Grid>
|
<Text fontSize="sm" color="white">
|
||||||
</CardBody>
|
{content}
|
||||||
</Card>
|
</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;
|
export default StrategyAnalysisCard;
|
||||||
|
|||||||
Reference in New Issue
Block a user