From ad933e9fb25a1be411b868561493a5cdc1fc6464 Mon Sep 17 00:00:00 2001
From: zdl <3489966805@qq.com>
Date: Wed, 5 Nov 2025 23:54:43 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20UI=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/StockChangeIndicators.js | 21 +-
.../EventCard/DynamicNewsEventCard.js | 206 ++++++++++++------
2 files changed, 152 insertions(+), 75 deletions(-)
diff --git a/src/components/StockChangeIndicators.js b/src/components/StockChangeIndicators.js
index 0d0ecbc4..b9cc3039 100644
--- a/src/components/StockChangeIndicators.js
+++ b/src/components/StockChangeIndicators.js
@@ -90,13 +90,15 @@ const StockChangeIndicators = ({
borderWidth={isLarge ? "2px" : "1px"}
borderColor={borderColor}
borderRadius="md"
- px={isLarge ? 4 : (isDefault ? 2 : (isComfortable ? 3 : 2))}
+ px={isLarge ? 4 : (isDefault ? 1.5 : (isComfortable ? 3 : 2))}
py={isLarge ? 3 : (isDefault ? 1.5 : (isComfortable ? 2 : 1))}
display="flex"
flexDirection={(isLarge || isDefault) ? "column" : "row"}
alignItems={(isLarge || isDefault) ? "flex-start" : "center"}
gap={(isLarge || isDefault) ? (isLarge ? 2 : 1) : 1}
- maxW={isLarge ? "200px" : (isDefault ? "120px" : "none")}
+ maxW={isLarge ? "200px" : "none"}
+ flex="0 1 auto"
+ minW="0"
>
{/* Large 和 Default 模式:标签单独一行 */}
{(isLarge || isDefault) && (
@@ -111,14 +113,14 @@ const StockChangeIndicators = ({
{value !== 0 && (
value > 0 ? (
) : (
)
@@ -131,6 +133,8 @@ const StockChangeIndicators = ({
color={numberColor}
lineHeight="1.2"
whiteSpace="nowrap"
+ overflow="hidden"
+ textOverflow="ellipsis"
>
{/* Comfortable 模式:标签和数字在同一行 */}
{!isLarge && !isDefault && (
@@ -138,7 +142,8 @@ const StockChangeIndicators = ({
{label}
)}
- {sign}{numStr}%
+ {sign}{numStr}
+ %
@@ -151,7 +156,7 @@ const StockChangeIndicators = ({
}
return (
-
+
{renderIndicator('平均涨幅', avgChange)}
{renderIndicator('最大涨幅', maxChange)}
{renderIndicator('周涨幅', weekChange)}
diff --git a/src/views/Community/components/EventCard/DynamicNewsEventCard.js b/src/views/Community/components/EventCard/DynamicNewsEventCard.js
index 32e360c5..3153bdcc 100644
--- a/src/views/Community/components/EventCard/DynamicNewsEventCard.js
+++ b/src/views/Community/components/EventCard/DynamicNewsEventCard.js
@@ -48,9 +48,9 @@ const DynamicNewsEventCard = ({
const importance = getImportanceConfig(event.importance);
/**
- * 判断交易时段(盘前、盘中、盘后)
+ * 判断交易时段(盘前、盘中上午、午休、盘中下午、盘后)
* @param {string} timestamp - 事件时间戳
- * @returns {'pre-market' | 'trading' | 'after-market'}
+ * @returns {'pre-market' | 'morning-trading' | 'lunch-break' | 'afternoon-trading' | 'after-market'}
*/
const getTradingPeriod = (timestamp) => {
const eventTime = moment(timestamp);
@@ -58,18 +58,30 @@ const DynamicNewsEventCard = ({
const minute = eventTime.minute();
const timeInMinutes = hour * 60 + minute;
- // 盘中时间:09:30-11:30, 13:00-15:00
- const morningStart = 9 * 60 + 30; // 09:30 = 570分钟
- const morningEnd = 11 * 60 + 30; // 11:30 = 690分钟
- const afternoonStart = 13 * 60; // 13:00 = 780分钟
- const afternoonEnd = 15 * 60; // 15:00 = 900分钟
+ // 时间常量
+ const morningStart = 9 * 60 + 30; // 09:30 = 570分钟
+ const morningEnd = 11 * 60 + 30; // 11:30 = 690分钟
+ const lunchEnd = 13 * 60; // 13:00 = 780分钟
+ const afternoonEnd = 15 * 60; // 15:00 = 900分钟
- if ((timeInMinutes >= morningStart && timeInMinutes < morningEnd) ||
- (timeInMinutes >= afternoonStart && timeInMinutes < afternoonEnd)) {
- return 'trading';
- } else if (timeInMinutes < morningStart) {
+ // 盘中上午:09:30-11:30
+ if (timeInMinutes >= morningStart && timeInMinutes < morningEnd) {
+ return 'morning-trading';
+ }
+ // 午休:11:30-13:00
+ else if (timeInMinutes >= morningEnd && timeInMinutes < lunchEnd) {
+ return 'lunch-break';
+ }
+ // 盘中下午:13:00-15:00
+ else if (timeInMinutes >= lunchEnd && timeInMinutes < afternoonEnd) {
+ return 'afternoon-trading';
+ }
+ // 盘前:00:00-09:30
+ else if (timeInMinutes < morningStart) {
return 'pre-market';
- } else {
+ }
+ // 盘后:15:00-23:59
+ else {
return 'after-market';
}
};
@@ -82,26 +94,34 @@ const DynamicNewsEventCard = ({
const getTimeLabelStyle = (period) => {
switch (period) {
case 'pre-market':
- // 盘前:蓝色系
+ // 盘前:粉红色系(浅红)
return {
- bg: useColorModeValue('blue.50', 'blue.900'),
- borderColor: useColorModeValue('blue.400', 'blue.500'),
- textColor: useColorModeValue('blue.600', 'blue.300'),
+ bg: useColorModeValue('pink.50', 'pink.900'),
+ borderColor: useColorModeValue('pink.300', 'pink.500'),
+ textColor: useColorModeValue('pink.600', 'pink.300'),
};
- case 'trading':
- // 盘中:绿色系(表示交易中)
+ case 'morning-trading':
+ case 'afternoon-trading':
+ // 盘中:红色系(强烈,表示交易活跃)
return {
- bg: useColorModeValue('green.50', 'green.900'),
- borderColor: useColorModeValue('green.400', 'green.500'),
- textColor: useColorModeValue('green.600', 'green.300'),
+ bg: useColorModeValue('red.50', 'red.900'),
+ borderColor: useColorModeValue('red.400', 'red.500'),
+ textColor: useColorModeValue('red.700', 'red.300'),
};
- case 'after-market':
- // 盘后:灰色系(市场关闭)
+ case 'lunch-break':
+ // 午休:灰色系(中性)
return {
bg: useColorModeValue('gray.100', 'gray.800'),
borderColor: useColorModeValue('gray.400', 'gray.500'),
textColor: useColorModeValue('gray.600', 'gray.400'),
};
+ case 'after-market':
+ // 盘后:橙色系(暖色但区别于盘中红色)
+ return {
+ bg: useColorModeValue('orange.50', 'orange.900'),
+ borderColor: useColorModeValue('orange.400', 'orange.500'),
+ textColor: useColorModeValue('orange.600', 'orange.300'),
+ };
default:
return {
bg: useColorModeValue('gray.100', 'gray.800'),
@@ -111,61 +131,75 @@ const DynamicNewsEventCard = ({
}
};
+ /**
+ * 获取交易时段文字标签
+ * @param {string} period - 交易时段
+ * @returns {string} 时段文字标签
+ */
+ const getPeriodLabel = (period) => {
+ switch (period) {
+ case 'pre-market':
+ return '盘前';
+ case 'morning-trading':
+ case 'afternoon-trading':
+ return '盘中';
+ case 'lunch-break':
+ return '午休';
+ case 'after-market':
+ return '盘后';
+ default:
+ return '';
+ }
+ };
+
/**
* 根据平均涨幅计算背景色(分级策略)
* @param {number} avgChange - 平均涨跌幅
* @returns {string} Chakra UI 颜色值
*/
const getChangeBasedBgColor = (avgChange) => {
- // 如果没有涨跌幅数据,使用默认的奇偶行背景
- if (avgChange == null) {
+ // 转换为数字类型(处理可能的字符串类型数据)
+ const numChange = Number(avgChange);
+
+ // 🔍 调试日志:排查背景色计算问题
+ console.log('📊 [背景色计算]', {
+ rawValue: avgChange,
+ numValue: numChange,
+ type: typeof avgChange,
+ isNull: avgChange == null,
+ isNaN: isNaN(numChange),
+ title: event.title.substring(0, 30) + '...'
+ });
+
+ // 如果没有涨跌幅数据或转换失败,使用默认的奇偶行背景
+ if (avgChange == null || isNaN(numChange)) {
return index % 2 === 0 ? cardBg : useColorModeValue('gray.50', 'gray.750');
}
// 根据涨跌幅分级返回背景色
- if (avgChange >= 5) {
+ if (numChange >= 5) {
return useColorModeValue('red.100', 'red.900');
- } else if (avgChange >= 3) {
- return useColorModeValue('red.75', 'red.800');
- } else if (avgChange > 0) {
+ } else if (numChange >= 3) {
+ return useColorModeValue('red.100', 'red.800');
+ } else if (numChange > 0) {
return useColorModeValue('red.50', 'red.700');
- } else if (avgChange > -3) {
+ } else if (numChange > -3) {
return useColorModeValue('green.50', 'green.700');
- } else if (avgChange > -5) {
- return useColorModeValue('green.75', 'green.800');
+ } else if (numChange > -5) {
+ return useColorModeValue('green.100', 'green.800');
} else {
return useColorModeValue('green.100', 'green.900');
}
};
- // 获取当前事件的交易时段和样式
+ // 获取当前事件的交易时段、样式和文字标签
const tradingPeriod = getTradingPeriod(event.created_at);
const timeLabelStyle = getTimeLabelStyle(tradingPeriod);
+ const periodLabel = getPeriodLabel(tradingPeriod);
return (
-
- {/* 时间标签 - 在卡片上方,宽度自适应,左对齐 */}
-
-
- {moment(event.created_at).format('YYYY-MM-DD HH:mm')}
-
-
+
+
{/* 事件卡片 */}
{/* 左上角:重要性标签 */}
-
+
+
+ {/* 时间标签 - 在卡片上方,宽度自适应,左对齐 */}
+
+
+ {moment(event.created_at).format('YYYY-MM-DD HH:mm')}
+ {periodLabel && (
+ <>
+ {' • '}
+
+ {periodLabel}
+
+ >
+ )}
+
+
{/* 右上角:关注按钮 */}
@@ -207,7 +275,7 @@ const DynamicNewsEventCard = ({
- {/* 标题 - 最多两行,hover 显示完整内容 */}
+ {/* 标题 - 固定两行高度,保持卡片高度一致 */}
onTitleClick?.(e, event)}
mt={1}
paddingRight="10px"
+ minHeight="2.8em"
+ display="flex"
+ alignItems="center"
>
{event.title}
-
- {/* 第二行:涨跌幅数据 */}
-
+
+ {/* 第二行:涨跌幅数据 */}
+
+