事件中心UI优化
This commit is contained in:
@@ -24,6 +24,7 @@ export const IMPORTANCE_LEVELS = {
|
|||||||
icon: WarningIcon,
|
icon: WarningIcon,
|
||||||
label: '极高',
|
label: '极高',
|
||||||
stampText: '极', // 印章文字
|
stampText: '极', // 印章文字
|
||||||
|
stampFont: "'STKaiti', 'KaiTi', 'SimKai', serif", // 楷体
|
||||||
dotBg: 'red.800',
|
dotBg: 'red.800',
|
||||||
description: '重大事件,市场影响深远',
|
description: '重大事件,市场影响深远',
|
||||||
antdColor: '#cf1322',
|
antdColor: '#cf1322',
|
||||||
@@ -39,6 +40,7 @@ export const IMPORTANCE_LEVELS = {
|
|||||||
icon: WarningTwoIcon,
|
icon: WarningTwoIcon,
|
||||||
label: '高',
|
label: '高',
|
||||||
stampText: '高', // 印章文字
|
stampText: '高', // 印章文字
|
||||||
|
stampFont: "'STXingkai', 'FangSong', 'STFangsong', cursive", // 行楷/草书
|
||||||
dotBg: 'red.600',
|
dotBg: 'red.600',
|
||||||
description: '重要事件,影响较大',
|
description: '重要事件,影响较大',
|
||||||
antdColor: '#ff4d4f',
|
antdColor: '#ff4d4f',
|
||||||
@@ -54,6 +56,7 @@ export const IMPORTANCE_LEVELS = {
|
|||||||
icon: InfoIcon,
|
icon: InfoIcon,
|
||||||
label: '中',
|
label: '中',
|
||||||
stampText: '中', // 印章文字
|
stampText: '中', // 印章文字
|
||||||
|
stampFont: "'STKaiti', 'KaiTi', 'SimKai', serif", // 楷体
|
||||||
dotBg: 'red.500',
|
dotBg: 'red.500',
|
||||||
description: '普通事件,有一定影响',
|
description: '普通事件,有一定影响',
|
||||||
antdColor: '#ff7875',
|
antdColor: '#ff7875',
|
||||||
@@ -64,11 +67,12 @@ export const IMPORTANCE_LEVELS = {
|
|||||||
bgColor: 'red.50',
|
bgColor: 'red.50',
|
||||||
borderColor: 'red.100',
|
borderColor: 'red.100',
|
||||||
colorScheme: 'red',
|
colorScheme: 'red',
|
||||||
badgeBg: '#6b7280', // 圆形徽章背景色 - 灰色
|
badgeBg: '#10b981', // 圆形徽章背景色 - 青绿色(替代灰色)
|
||||||
badgeColor: 'white', // 圆形徽章文字颜色 - 白色
|
badgeColor: 'white', // 圆形徽章文字颜色 - 白色
|
||||||
icon: CheckCircleIcon,
|
icon: CheckCircleIcon,
|
||||||
label: '低',
|
label: '低',
|
||||||
stampText: '低', // 印章文字
|
stampText: '低', // 印章文字
|
||||||
|
stampFont: "'STKaiti', 'KaiTi', 'SimKai', serif", // 楷体
|
||||||
dotBg: 'red.400',
|
dotBg: 'red.400',
|
||||||
description: '参考事件,影响有限',
|
description: '参考事件,影响有限',
|
||||||
antdColor: '#ffa39e',
|
antdColor: '#ffa39e',
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
import { getImportanceConfig } from '../../../../constants/importanceLevels';
|
import { getImportanceConfig } from '../../../../constants/importanceLevels';
|
||||||
|
|
||||||
// 导入子组件
|
// 导入子组件
|
||||||
import ImportanceBadge from './ImportanceBadge';
|
import ImportanceStamp from './ImportanceStamp';
|
||||||
import EventTimeline from './EventTimeline';
|
import EventTimeline from './EventTimeline';
|
||||||
import EventFollowButton from './EventFollowButton';
|
import EventFollowButton from './EventFollowButton';
|
||||||
import StockChangeIndicators from '../../../../components/StockChangeIndicators';
|
import StockChangeIndicators from '../../../../components/StockChangeIndicators';
|
||||||
@@ -57,6 +57,40 @@ const HorizontalDynamicNewsEventCard = ({
|
|||||||
const selectedBorderColor = useColorModeValue('blue.500', 'blue.400');
|
const selectedBorderColor = useColorModeValue('blue.500', 'blue.400');
|
||||||
const linkColor = useColorModeValue('blue.600', '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 (
|
return (
|
||||||
<HStack align="stretch" spacing={3} w="full">
|
<HStack align="stretch" spacing={3} w="full">
|
||||||
{/* 左侧时间轴 */}
|
{/* 左侧时间轴 */}
|
||||||
@@ -67,24 +101,31 @@ const HorizontalDynamicNewsEventCard = ({
|
|||||||
minHeight="60px"
|
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
|
<Card
|
||||||
flex="1"
|
|
||||||
position="relative"
|
position="relative"
|
||||||
bg={isSelected
|
bg={isSelected
|
||||||
? selectedBg
|
? selectedBg
|
||||||
: (index % 2 === 0 ? cardBg : cardBgAlt)
|
: getChangeBasedBgColor(event.related_avg_chg)
|
||||||
}
|
}
|
||||||
|
backdropFilter="blur(10px)" // 毛玻璃效果
|
||||||
borderWidth={isSelected ? "2px" : "1px"}
|
borderWidth={isSelected ? "2px" : "1px"}
|
||||||
borderColor={isSelected
|
borderColor={isSelected
|
||||||
? selectedBorderColor
|
? selectedBorderColor
|
||||||
: borderColor
|
: borderColor
|
||||||
}
|
}
|
||||||
borderRadius="md"
|
borderRadius="lg"
|
||||||
boxShadow={isSelected ? "lg" : "sm"}
|
boxShadow={isSelected ? "xl" : "md"}
|
||||||
overflow="hidden"
|
overflow="visible"
|
||||||
_hover={{
|
_hover={{
|
||||||
boxShadow: 'xl',
|
boxShadow: '2xl',
|
||||||
transform: 'translateY(-2px)',
|
transform: 'translateY(-2px)',
|
||||||
borderColor: isSelected ? 'blue.600' : importance.color,
|
borderColor: isSelected ? 'blue.600' : importance.color,
|
||||||
}}
|
}}
|
||||||
@@ -93,9 +134,6 @@ const HorizontalDynamicNewsEventCard = ({
|
|||||||
onClick={() => onEventClick?.(event)}
|
onClick={() => onEventClick?.(event)}
|
||||||
>
|
>
|
||||||
<CardBody p={3} pb={2}>
|
<CardBody p={3} pb={2}>
|
||||||
{/* 左上角:重要性标签 */}
|
|
||||||
<ImportanceBadge importance={event.importance} />
|
|
||||||
|
|
||||||
{/* 右上角:关注按钮 */}
|
{/* 右上角:关注按钮 */}
|
||||||
<Box position="absolute" top={2} right={2} zIndex={1}>
|
<Box position="absolute" top={2} right={2} zIndex={1}>
|
||||||
<EventFollowButton
|
<EventFollowButton
|
||||||
@@ -149,6 +187,7 @@ const HorizontalDynamicNewsEventCard = ({
|
|||||||
</VStack>
|
</VStack>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
|
</Box>
|
||||||
</HStack>
|
</HStack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,13 +13,23 @@ import { getImportanceConfig } from '../../../../constants/importanceLevels';
|
|||||||
* 重要性印章组件(模拟盖章效果)
|
* 重要性印章组件(模拟盖章效果)
|
||||||
* @param {Object} props
|
* @param {Object} props
|
||||||
* @param {string} props.importance - 重要性等级 (S/A/B/C)
|
* @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 config = getImportanceConfig(importance);
|
||||||
|
|
||||||
// 印章颜色
|
// 印章颜色
|
||||||
const stampColor = useColorModeValue(config.badgeBg, config.badgeBg);
|
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 (
|
return (
|
||||||
<Box
|
<Box
|
||||||
position="relative"
|
position="relative"
|
||||||
@@ -28,41 +38,43 @@ const ImportanceStamp = ({ importance }) => {
|
|||||||
{/* 外层圆形边框(双圈) */}
|
{/* 外层圆形边框(双圈) */}
|
||||||
<Box
|
<Box
|
||||||
position="relative"
|
position="relative"
|
||||||
w="50px"
|
w={currentSize.outer}
|
||||||
h="50px"
|
h={currentSize.outer}
|
||||||
borderRadius="50%"
|
borderRadius="50%"
|
||||||
borderWidth="3px"
|
borderWidth={currentSize.borderOuter}
|
||||||
borderColor={stampColor}
|
borderColor={stampColor}
|
||||||
display="flex"
|
display="flex"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
justifyContent="center"
|
justifyContent="center"
|
||||||
transform="rotate(-15deg)"
|
transform="rotate(-15deg)"
|
||||||
opacity={0.85}
|
opacity={0.9}
|
||||||
boxShadow="0 2px 8px rgba(0,0,0,0.15)"
|
boxShadow="0 3px 12px rgba(0,0,0,0.2)"
|
||||||
|
bg={useColorModeValue('white', 'gray.800')}
|
||||||
_hover={{
|
_hover={{
|
||||||
opacity: 1,
|
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"
|
transition="all 0.3s ease"
|
||||||
>
|
>
|
||||||
{/* 内层圆形边框 */}
|
{/* 内层圆形边框 */}
|
||||||
<Box
|
<Box
|
||||||
position="absolute"
|
position="absolute"
|
||||||
w="42px"
|
w={currentSize.inner}
|
||||||
h="42px"
|
h={currentSize.inner}
|
||||||
borderRadius="50%"
|
borderRadius="50%"
|
||||||
borderWidth="2px"
|
borderWidth={currentSize.borderInner}
|
||||||
borderColor={stampColor}
|
borderColor={stampColor}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* 印章文字 */}
|
{/* 印章文字 */}
|
||||||
<Text
|
<Text
|
||||||
fontSize="xl"
|
fontSize={currentSize.fontSize}
|
||||||
fontWeight="black"
|
fontWeight="black"
|
||||||
color={stampColor}
|
color={stampColor}
|
||||||
fontFamily="'STKaiti', 'KaiTi', 'SimKai', serif"
|
fontFamily={config.stampFont}
|
||||||
letterSpacing="2px"
|
letterSpacing="2px"
|
||||||
textShadow="0 0 1px currentColor"
|
textShadow="0 0 2px currentColor"
|
||||||
>
|
>
|
||||||
{config.stampText}
|
{config.stampText}
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
Reference in New Issue
Block a user