## 改动内容
- 替换所有 Moment.js 引用为 Day.js (29 个文件)
- 更新 Webpack 配置,调整 calendar-lib chunk
- 添加 Day.js 插件支持 (isSameOrBefore, isSameOrAfter)
- 移除 Moment.js 依赖
## 性能提升
- JavaScript 打包体积减少: ~50 KB (未压缩)
- gzip 后减少: ~15-18 KB
- 预计首屏加载时间提升: 15-20%
## 影响范围
- Dashboard 组件: 5 个文件
- Community 组件: 19 个文件
- 工具函数: tradingTimeUtils.js (添加插件)
- 其他组件: 5 个文件
## 测试状态
- ✅ 构建成功 (npm run build)
143 lines
4.2 KiB
JavaScript
143 lines
4.2 KiB
JavaScript
// src/views/Community/components/DynamicNewsDetail/EventHeaderInfo.js
|
||
// 事件头部信息区组件
|
||
|
||
import React from 'react';
|
||
import {
|
||
Box,
|
||
Flex,
|
||
HStack,
|
||
Heading,
|
||
Text,
|
||
Badge,
|
||
Icon,
|
||
useColorModeValue,
|
||
} from '@chakra-ui/react';
|
||
import { ViewIcon } from '@chakra-ui/icons';
|
||
import dayjs from 'dayjs';
|
||
import StockChangeIndicators from '../../../../components/StockChangeIndicators';
|
||
import EventFollowButton from '../EventCard/EventFollowButton';
|
||
|
||
/**
|
||
* 事件头部信息区组件
|
||
* @param {Object} props
|
||
* @param {Object} props.event - 事件对象
|
||
* @param {Object} props.importance - 重要性配置对象(包含 level, color 等)
|
||
* @param {boolean} props.isFollowing - 是否已关注
|
||
* @param {number} props.followerCount - 关注数
|
||
* @param {Function} props.onToggleFollow - 切换关注回调
|
||
*/
|
||
const EventHeaderInfo = ({ event, importance, isFollowing, followerCount, onToggleFollow }) => {
|
||
const sectionBg = useColorModeValue('gray.50', 'gray.750');
|
||
const headingColor = useColorModeValue('gray.700', 'gray.200');
|
||
|
||
// 获取重要性文本
|
||
const getImportanceText = () => {
|
||
const levelMap = {
|
||
'S': '极高',
|
||
'A': '高',
|
||
'B': '中',
|
||
'C': '低'
|
||
};
|
||
return levelMap[importance.level] || '中';
|
||
};
|
||
|
||
// 格式化涨跌幅数字
|
||
const formatChange = (value) => {
|
||
if (value === null || value === undefined) return '--';
|
||
const prefix = value > 0 ? '+' : '';
|
||
return `${prefix}${value.toFixed(2)}%`;
|
||
};
|
||
|
||
return (
|
||
<Box bg={sectionBg} p={3} borderRadius="md" position="relative">
|
||
{/* 粉色圆角标签(左上角绝对定位) */}
|
||
{event.related_avg_chg !== null && event.related_avg_chg !== undefined && (
|
||
<Box
|
||
position="absolute"
|
||
top="-8px"
|
||
left="-8px"
|
||
bg="pink.500"
|
||
color="white"
|
||
px={3}
|
||
py={1}
|
||
borderRadius="full"
|
||
fontSize="sm"
|
||
fontWeight="bold"
|
||
boxShadow="md"
|
||
zIndex={1}
|
||
>
|
||
{formatChange(event.related_avg_chg)}
|
||
</Box>
|
||
)}
|
||
|
||
{/* 第一行:标题 + 关注按钮 */}
|
||
<Flex align="center" justify="space-between" mb={3} gap={4}>
|
||
{/* 标题 */}
|
||
<Heading size="md" color={headingColor} flex={1}>
|
||
{event.title}
|
||
</Heading>
|
||
|
||
{/* 关注按钮 */}
|
||
<EventFollowButton
|
||
isFollowing={isFollowing}
|
||
followerCount={followerCount}
|
||
onToggle={onToggleFollow}
|
||
size="sm"
|
||
showCount={true}
|
||
/>
|
||
</Flex>
|
||
{/* 第二行:浏览数 + 日期 */}
|
||
<Flex align="left" mb={3} gap={4}>
|
||
{/* 浏览数 */}
|
||
<HStack spacing={1}>
|
||
<ViewIcon color="gray.400" boxSize={4} />
|
||
<Text fontSize="sm" color="gray.400" whiteSpace="nowrap">
|
||
{(event.view_count || 0).toLocaleString()}次浏览
|
||
</Text>
|
||
</HStack>
|
||
|
||
{/* 日期 */}
|
||
<Text fontSize="sm" color="red.500" fontWeight="medium" whiteSpace="nowrap">
|
||
{dayjs(event.created_at).format('YYYY年MM月DD日')}
|
||
</Text>
|
||
</Flex>
|
||
|
||
{/* 第三行:涨跌幅指标 + 重要性徽章 */}
|
||
<HStack spacing={3} align="center">
|
||
<Box maxW="500px">
|
||
<StockChangeIndicators
|
||
avgChange={event.related_avg_chg}
|
||
maxChange={event.related_max_chg}
|
||
weekChange={event.related_week_chg}
|
||
/>
|
||
</Box>
|
||
|
||
{/* 重要性徽章 - 使用渐变色和图标 */}
|
||
<Badge
|
||
px={4}
|
||
py={2}
|
||
borderRadius="full"
|
||
fontSize="md"
|
||
fontWeight="bold"
|
||
bgGradient={
|
||
importance.level === 'S' ? 'linear(to-r, red.500, red.700)' :
|
||
importance.level === 'A' ? 'linear(to-r, orange.500, orange.700)' :
|
||
importance.level === 'B' ? 'linear(to-r, blue.500, blue.700)' :
|
||
'linear(to-r, gray.500, gray.700)'
|
||
}
|
||
color="white"
|
||
boxShadow="lg"
|
||
display="flex"
|
||
alignItems="center"
|
||
gap={2}
|
||
>
|
||
<Icon as={importance.icon} boxSize={5} />
|
||
<Text>重要性:{getImportanceText()}</Text>
|
||
</Badge>
|
||
</HStack>
|
||
</Box>
|
||
);
|
||
};
|
||
|
||
export default EventHeaderInfo;
|