事件中心UI优化
This commit is contained in:
@@ -24,6 +24,7 @@ export const IMPORTANCE_LEVELS = {
|
||||
icon: WarningIcon,
|
||||
label: '极高',
|
||||
stampText: '极', // 印章文字
|
||||
stampFont: "'STKaiti', 'KaiTi', 'SimKai', serif", // 楷体
|
||||
dotBg: 'red.800',
|
||||
description: '重大事件,市场影响深远',
|
||||
antdColor: '#cf1322',
|
||||
@@ -39,6 +40,7 @@ export const IMPORTANCE_LEVELS = {
|
||||
icon: WarningTwoIcon,
|
||||
label: '高',
|
||||
stampText: '高', // 印章文字
|
||||
stampFont: "'STXingkai', 'FangSong', 'STFangsong', cursive", // 行楷/草书
|
||||
dotBg: 'red.600',
|
||||
description: '重要事件,影响较大',
|
||||
antdColor: '#ff4d4f',
|
||||
@@ -54,6 +56,7 @@ export const IMPORTANCE_LEVELS = {
|
||||
icon: InfoIcon,
|
||||
label: '中',
|
||||
stampText: '中', // 印章文字
|
||||
stampFont: "'STKaiti', 'KaiTi', 'SimKai', serif", // 楷体
|
||||
dotBg: 'red.500',
|
||||
description: '普通事件,有一定影响',
|
||||
antdColor: '#ff7875',
|
||||
@@ -64,11 +67,12 @@ export const IMPORTANCE_LEVELS = {
|
||||
bgColor: 'red.50',
|
||||
borderColor: 'red.100',
|
||||
colorScheme: 'red',
|
||||
badgeBg: '#6b7280', // 圆形徽章背景色 - 灰色
|
||||
badgeBg: '#10b981', // 圆形徽章背景色 - 青绿色(替代灰色)
|
||||
badgeColor: 'white', // 圆形徽章文字颜色 - 白色
|
||||
icon: CheckCircleIcon,
|
||||
label: '低',
|
||||
stampText: '低', // 印章文字
|
||||
stampFont: "'STKaiti', 'KaiTi', 'SimKai', serif", // 楷体
|
||||
dotBg: 'red.400',
|
||||
description: '参考事件,影响有限',
|
||||
antdColor: '#ffa39e',
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
import { getImportanceConfig } from '../../../../constants/importanceLevels';
|
||||
|
||||
// 导入子组件
|
||||
import ImportanceBadge from './ImportanceBadge';
|
||||
import ImportanceStamp from './ImportanceStamp';
|
||||
import EventTimeline from './EventTimeline';
|
||||
import EventFollowButton from './EventFollowButton';
|
||||
import StockChangeIndicators from '../../../../components/StockChangeIndicators';
|
||||
@@ -57,6 +57,40 @@ const HorizontalDynamicNewsEventCard = ({
|
||||
const selectedBorderColor = useColorModeValue('blue.500', 'blue.400');
|
||||
const linkColor = useColorModeValue('blue.600', 'blue.400');
|
||||
|
||||
/**
|
||||
* 根据平均涨幅计算背景色(分级策略)- 使用毛玻璃效果
|
||||
* @param {number} avgChange - 平均涨跌幅
|
||||
* @returns {string} Chakra UI 颜色值
|
||||
*/
|
||||
const getChangeBasedBgColor = (avgChange) => {
|
||||
const numChange = Number(avgChange);
|
||||
|
||||
// 如果没有涨跌幅数据,使用半透明背景
|
||||
if (avgChange == null || isNaN(numChange)) {
|
||||
return useColorModeValue('rgba(255, 255, 255, 0.8)', 'rgba(26, 32, 44, 0.8)');
|
||||
}
|
||||
|
||||
// 根据涨跌幅分级返回半透明背景色(毛玻璃效果)
|
||||
const absChange = Math.abs(numChange);
|
||||
if (numChange > 0) {
|
||||
// 涨:红色系半透明
|
||||
if (absChange >= 9) return useColorModeValue('rgba(254, 202, 202, 0.9)', 'rgba(127, 29, 29, 0.9)');
|
||||
if (absChange >= 7) return useColorModeValue('rgba(254, 202, 202, 0.8)', 'rgba(153, 27, 27, 0.8)');
|
||||
if (absChange >= 5) return useColorModeValue('rgba(254, 226, 226, 0.8)', 'rgba(185, 28, 28, 0.8)');
|
||||
if (absChange >= 3) return useColorModeValue('rgba(254, 226, 226, 0.7)', 'rgba(220, 38, 38, 0.7)');
|
||||
return useColorModeValue('rgba(254, 242, 242, 0.7)', 'rgba(239, 68, 68, 0.7)');
|
||||
} else if (numChange < 0) {
|
||||
// 跌:绿色系半透明
|
||||
if (absChange >= 9) return useColorModeValue('rgba(187, 247, 208, 0.9)', 'rgba(20, 83, 45, 0.9)');
|
||||
if (absChange >= 7) return useColorModeValue('rgba(187, 247, 208, 0.8)', 'rgba(22, 101, 52, 0.8)');
|
||||
if (absChange >= 5) return useColorModeValue('rgba(209, 250, 229, 0.8)', 'rgba(21, 128, 61, 0.8)');
|
||||
if (absChange >= 3) return useColorModeValue('rgba(209, 250, 229, 0.7)', 'rgba(22, 163, 74, 0.7)');
|
||||
return useColorModeValue('rgba(240, 253, 244, 0.7)', 'rgba(34, 197, 94, 0.7)');
|
||||
}
|
||||
|
||||
return useColorModeValue('rgba(255, 255, 255, 0.8)', 'rgba(26, 32, 44, 0.8)');
|
||||
};
|
||||
|
||||
return (
|
||||
<HStack align="stretch" spacing={3} w="full">
|
||||
{/* 左侧时间轴 */}
|
||||
@@ -67,24 +101,31 @@ const HorizontalDynamicNewsEventCard = ({
|
||||
minHeight="60px"
|
||||
/>
|
||||
|
||||
{/* 右侧事件卡片 */}
|
||||
{/* 右侧事件卡片容器(带印章) */}
|
||||
<Box flex="1" position="relative" pt={6}>
|
||||
{/* 右上角:重要性印章(放在卡片外层) */}
|
||||
<Box position="absolute" top={-2} right={4} zIndex={10}>
|
||||
<ImportanceStamp importance={event.importance} size="sm" />
|
||||
</Box>
|
||||
|
||||
{/* 事件卡片 */}
|
||||
<Card
|
||||
flex="1"
|
||||
position="relative"
|
||||
bg={isSelected
|
||||
? selectedBg
|
||||
: (index % 2 === 0 ? cardBg : cardBgAlt)
|
||||
: getChangeBasedBgColor(event.related_avg_chg)
|
||||
}
|
||||
backdropFilter="blur(10px)" // 毛玻璃效果
|
||||
borderWidth={isSelected ? "2px" : "1px"}
|
||||
borderColor={isSelected
|
||||
? selectedBorderColor
|
||||
: borderColor
|
||||
}
|
||||
borderRadius="md"
|
||||
boxShadow={isSelected ? "lg" : "sm"}
|
||||
overflow="hidden"
|
||||
borderRadius="lg"
|
||||
boxShadow={isSelected ? "xl" : "md"}
|
||||
overflow="visible"
|
||||
_hover={{
|
||||
boxShadow: 'xl',
|
||||
boxShadow: '2xl',
|
||||
transform: 'translateY(-2px)',
|
||||
borderColor: isSelected ? 'blue.600' : importance.color,
|
||||
}}
|
||||
@@ -93,9 +134,6 @@ const HorizontalDynamicNewsEventCard = ({
|
||||
onClick={() => onEventClick?.(event)}
|
||||
>
|
||||
<CardBody p={3} pb={2}>
|
||||
{/* 左上角:重要性标签 */}
|
||||
<ImportanceBadge importance={event.importance} />
|
||||
|
||||
{/* 右上角:关注按钮 */}
|
||||
<Box position="absolute" top={2} right={2} zIndex={1}>
|
||||
<EventFollowButton
|
||||
@@ -149,6 +187,7 @@ const HorizontalDynamicNewsEventCard = ({
|
||||
</VStack>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Box>
|
||||
</HStack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,13 +13,23 @@ import { getImportanceConfig } from '../../../../constants/importanceLevels';
|
||||
* 重要性印章组件(模拟盖章效果)
|
||||
* @param {Object} props
|
||||
* @param {string} props.importance - 重要性等级 (S/A/B/C)
|
||||
* @param {string} props.size - 印章尺寸 ('sm' | 'md' | 'lg')
|
||||
*/
|
||||
const ImportanceStamp = ({ importance }) => {
|
||||
const ImportanceStamp = ({ importance, size = 'md' }) => {
|
||||
const config = getImportanceConfig(importance);
|
||||
|
||||
// 印章颜色
|
||||
const stampColor = useColorModeValue(config.badgeBg, config.badgeBg);
|
||||
|
||||
// 尺寸配置
|
||||
const sizeConfig = {
|
||||
sm: { outer: '40px', inner: '34px', fontSize: 'md', borderOuter: '2px', borderInner: '1.5px' },
|
||||
md: { outer: '50px', inner: '42px', fontSize: 'xl', borderOuter: '3px', borderInner: '2px' },
|
||||
lg: { outer: '60px', inner: '52px', fontSize: '2xl', borderOuter: '4px', borderInner: '2.5px' },
|
||||
};
|
||||
|
||||
const currentSize = sizeConfig[size];
|
||||
|
||||
return (
|
||||
<Box
|
||||
position="relative"
|
||||
@@ -28,41 +38,43 @@ const ImportanceStamp = ({ importance }) => {
|
||||
{/* 外层圆形边框(双圈) */}
|
||||
<Box
|
||||
position="relative"
|
||||
w="50px"
|
||||
h="50px"
|
||||
w={currentSize.outer}
|
||||
h={currentSize.outer}
|
||||
borderRadius="50%"
|
||||
borderWidth="3px"
|
||||
borderWidth={currentSize.borderOuter}
|
||||
borderColor={stampColor}
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
transform="rotate(-15deg)"
|
||||
opacity={0.85}
|
||||
boxShadow="0 2px 8px rgba(0,0,0,0.15)"
|
||||
opacity={0.9}
|
||||
boxShadow="0 3px 12px rgba(0,0,0,0.2)"
|
||||
bg={useColorModeValue('white', 'gray.800')}
|
||||
_hover={{
|
||||
opacity: 1,
|
||||
transform: "rotate(-15deg) scale(1.1)",
|
||||
transform: "rotate(-15deg) scale(1.15)",
|
||||
boxShadow: "0 4px 16px rgba(0,0,0,0.3)",
|
||||
}}
|
||||
transition="all 0.3s ease"
|
||||
>
|
||||
{/* 内层圆形边框 */}
|
||||
<Box
|
||||
position="absolute"
|
||||
w="42px"
|
||||
h="42px"
|
||||
w={currentSize.inner}
|
||||
h={currentSize.inner}
|
||||
borderRadius="50%"
|
||||
borderWidth="2px"
|
||||
borderWidth={currentSize.borderInner}
|
||||
borderColor={stampColor}
|
||||
/>
|
||||
|
||||
{/* 印章文字 */}
|
||||
<Text
|
||||
fontSize="xl"
|
||||
fontSize={currentSize.fontSize}
|
||||
fontWeight="black"
|
||||
color={stampColor}
|
||||
fontFamily="'STKaiti', 'KaiTi', 'SimKai', serif"
|
||||
fontFamily={config.stampFont}
|
||||
letterSpacing="2px"
|
||||
textShadow="0 0 1px currentColor"
|
||||
textShadow="0 0 2px currentColor"
|
||||
>
|
||||
{config.stampText}
|
||||
</Text>
|
||||
|
||||
Reference in New Issue
Block a user