From 612b58c98327c926ee7bf47318a382df3b446958 Mon Sep 17 00:00:00 2001
From: zdl <3489966805@qq.com>
Date: Wed, 5 Nov 2025 19:15:36 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20feat:=20=E4=BC=98=E5=8C=96=E4=BA=8B?=
=?UTF-8?q?=E4=BB=B6=E5=8D=A1=E7=89=87=20UI=20=E5=92=8C=E4=BA=A4=E4=BA=92?=
=?UTF-8?q?=E4=BD=93=E9=AA=8C=20=E4=BF=AE=E5=A4=8D=20useColorModeValue=20?=
=?UTF-8?q?=E8=B0=83=E7=94=A8=E4=BD=8D=E7=BD=AE=EF=BC=88=E6=8F=90=E5=8D=87?=
=?UTF-8?q?=E5=88=B0=E9=A1=B6=E5=B1=82=EF=BC=89=20=E4=BC=98=E5=8C=96?=
=?UTF-8?q?=E5=88=86=E9=A1=B5=E5=92=8C=E6=BB=9A=E5=8A=A8=E9=80=BB=E8=BE=91?=
=?UTF-8?q?=20=E5=8A=A8=E6=80=81=20indicatorSize=20=E6=94=AF=E6=8C=81?=
=?UTF-8?q?=EF=BC=88detail/list=20=E6=A8=A1=E5=BC=8F=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../DynamicNewsCard/EventScrollList.js | 41 +++++++-----
.../DynamicNewsCard/hooks/usePagination.js | 64 +++++++++----------
.../HorizontalDynamicNewsEventCard.js | 15 +++--
src/views/Community/index.js | 14 +---
4 files changed, 66 insertions(+), 68 deletions(-)
diff --git a/src/views/Community/components/DynamicNewsCard/EventScrollList.js b/src/views/Community/components/DynamicNewsCard/EventScrollList.js
index a0113ecd..6d71957b 100644
--- a/src/views/Community/components/DynamicNewsCard/EventScrollList.js
+++ b/src/views/Community/components/DynamicNewsCard/EventScrollList.js
@@ -1,7 +1,7 @@
// src/views/Community/components/DynamicNewsCard/EventScrollList.js
// 横向滚动事件列表组件
-import React, { useRef } from 'react';
+import React, { useRef, useCallback } from 'react';
import {
Box,
Flex,
@@ -44,6 +44,7 @@ const EventScrollList = ({
totalPages,
onPageChange,
loading = false,
+ error, // 错误状态
mode = 'vertical',
onModeChange,
hasMore = true,
@@ -72,20 +73,27 @@ const EventScrollList = ({
};
};
+ // 重试函数
+ const handleRetry = useCallback(() => {
+ if (onPageChange) {
+ onPageChange(currentPage);
+ }
+ }, [onPageChange, currentPage]);
+
return (
- {/* 顶部控制栏:模式切换按钮(左)+ 分页控制器(右) */}
+ {/* 顶部控制栏:模式切换按钮 + 分页控制器 */}
- {/* 模式切换按钮 */}
+ {/* 左侧:模式切换按钮 */}
- {/* 分页控制器(平铺模式不显示,使用无限滚动) */}
- {totalPages > 1 && mode !== 'four-row' && (
-
+ {/* 右侧:分页控制器(纵向和平铺模式都显示) */}
+ {totalPages > 1 && (
+
)}
@@ -116,11 +124,9 @@ const EventScrollList = ({
)}
@@ -170,9 +179,9 @@ const EventScrollList = ({
onToggleFollow={onToggleFollow}
getTimelineBoxStyle={getTimelineBoxStyle}
borderColor={borderColor}
- scrollbarTrackBg={scrollbarTrackBg}
- scrollbarThumbBg={scrollbarThumbBg}
- scrollbarThumbHoverBg={scrollbarThumbHoverBg}
+ currentPage={currentPage}
+ totalPages={totalPages}
+ onPageChange={onPageChange}
/>
)}
diff --git a/src/views/Community/components/DynamicNewsCard/hooks/usePagination.js b/src/views/Community/components/DynamicNewsCard/hooks/usePagination.js
index 2ac070fb..8b916995 100644
--- a/src/views/Community/components/DynamicNewsCard/hooks/usePagination.js
+++ b/src/views/Community/components/DynamicNewsCard/hooks/usePagination.js
@@ -34,16 +34,12 @@ export const usePagination = ({ allCachedEvents, total, cachedCount, dispatch, t
// 根据模式决定每页显示数量
const pageSize = (() => {
switch (mode) {
- case DISPLAY_MODES.CAROUSEL:
- return PAGINATION_CONFIG.CAROUSEL_PAGE_SIZE;
- case DISPLAY_MODES.GRID:
- return PAGINATION_CONFIG.GRID_PAGE_SIZE;
case DISPLAY_MODES.FOUR_ROW:
return PAGINATION_CONFIG.FOUR_ROW_PAGE_SIZE;
case DISPLAY_MODES.VERTICAL:
return PAGINATION_CONFIG.VERTICAL_PAGE_SIZE;
default:
- return PAGINATION_CONFIG.CAROUSEL_PAGE_SIZE;
+ return PAGINATION_CONFIG.VERTICAL_PAGE_SIZE;
}
})();
@@ -126,20 +122,37 @@ export const usePagination = ({ allCachedEvents, total, cachedCount, dispatch, t
try {
console.log(`%c🟢 [API请求] 开始加载第${targetPage}页数据`, 'color: #16A34A; font-weight: bold;');
- console.log(`%c 请求参数: page=${targetPage}, per_page=${pageSize}`, 'color: #16A34A;');
+ console.log(`%c 请求参数: page=${targetPage}, per_page=${pageSize}, mode=${mode}`, 'color: #16A34A;');
+ console.log(`%c 筛选条件:`, 'color: #16A34A;', filters);
logger.debug('DynamicNewsCard', '开始加载页面数据', {
targetPage,
- pageSize
+ pageSize,
+ mode,
+ filters
});
- await dispatch(fetchDynamicNews({
+ // 🔍 调试:dispatch 前
+ console.log(`%c🔵 [dispatch] 准备调用 fetchDynamicNews`, 'color: #3B82F6; font-weight: bold;', {
+ mode,
page: targetPage,
per_page: pageSize,
+ pageSize,
+ clearCache: false,
+ filters
+ });
+
+ const result = await dispatch(fetchDynamicNews({
+ mode: mode, // 传递 mode 参数
+ per_page: pageSize,
pageSize: pageSize,
- clearCache: false
+ clearCache: false,
+ ...filters, // 先展开筛选条件
+ page: targetPage, // 然后覆盖 page 参数(避免被 filters.page 覆盖)
})).unwrap();
+ // 🔍 调试:dispatch 后
+ console.log(`%c🔵 [dispatch] fetchDynamicNews 返回结果`, 'color: #3B82F6; font-weight: bold;', result);
console.log(`%c🟢 [API请求] 第${targetPage}页加载完成`, 'color: #16A34A; font-weight: bold;');
logger.debug('DynamicNewsCard', `第 ${targetPage} 页加载完成`);
@@ -185,10 +198,12 @@ export const usePagination = ({ allCachedEvents, total, cachedCount, dispatch, t
logger.debug('DynamicNewsCard', '返回第一页,清空缓存重新加载');
setCurrentPage(1);
dispatch(fetchDynamicNews({
- page: 1,
+ mode: mode, // 传递 mode 参数
per_page: pageSize,
pageSize: pageSize,
- clearCache: true // 清空缓存
+ clearCache: true, // 清空缓存
+ ...filters, // 先展开筛选条件
+ page: 1, // 然后覆盖 page 参数
}));
return;
}
@@ -305,7 +320,7 @@ export const usePagination = ({ allCachedEvents, total, cachedCount, dispatch, t
}
}, [currentPage, loadingPage, handlePageChange]);
- // 模式切换处理
+ // 模式切换处理(简化版 - 模式切换时始终请求数据,因为两种模式使用独立存储)
const handleModeToggle = useCallback((newMode) => {
if (newMode === mode) return;
@@ -314,36 +329,15 @@ export const usePagination = ({ allCachedEvents, total, cachedCount, dispatch, t
const newPageSize = (() => {
switch (newMode) {
- case DISPLAY_MODES.CAROUSEL:
- return PAGINATION_CONFIG.CAROUSEL_PAGE_SIZE;
- case DISPLAY_MODES.GRID:
- return PAGINATION_CONFIG.GRID_PAGE_SIZE;
case DISPLAY_MODES.FOUR_ROW:
return PAGINATION_CONFIG.FOUR_ROW_PAGE_SIZE;
case DISPLAY_MODES.VERTICAL:
return PAGINATION_CONFIG.VERTICAL_PAGE_SIZE;
default:
- return PAGINATION_CONFIG.CAROUSEL_PAGE_SIZE;
+ return PAGINATION_CONFIG.VERTICAL_PAGE_SIZE;
}
})();
-
- // 检查第1页的数据是否完整(排除 null)
- const firstPageData = allCachedEvents.slice(0, newPageSize);
- const validFirstPageCount = firstPageData.filter(e => e !== null).length;
- const needsRefetch = validFirstPageCount < Math.min(newPageSize, total);
-
- if (needsRefetch) {
- // 第1页数据不完整,清空缓存重新请求
- dispatch(fetchDynamicNews({
- page: 1,
- per_page: newPageSize,
- pageSize: newPageSize, // 传递 pageSize 确保索引计算一致
- clearCache: true,
- ...filters // 应用筛选条件
- }));
- }
- // 如果第1页数据完整,不发起请求,直接切换
- }, [mode, allCachedEvents, total, dispatch, filters]);
+ }, [mode]);
return {
// 状态
diff --git a/src/views/Community/components/EventCard/HorizontalDynamicNewsEventCard.js b/src/views/Community/components/EventCard/HorizontalDynamicNewsEventCard.js
index bffa9a62..6ef496f9 100644
--- a/src/views/Community/components/EventCard/HorizontalDynamicNewsEventCard.js
+++ b/src/views/Community/components/EventCard/HorizontalDynamicNewsEventCard.js
@@ -33,6 +33,7 @@ import StockChangeIndicators from '../../../../components/StockChangeIndicators'
* @param {Function} props.onToggleFollow - 切换关注事件
* @param {Object} props.timelineStyle - 时间轴样式配置
* @param {string} props.borderColor - 边框颜色
+ * @param {string} props.indicatorSize - 涨幅指标尺寸 ('default' | 'comfortable' | 'large')
*/
const HorizontalDynamicNewsEventCard = ({
event,
@@ -45,9 +46,15 @@ const HorizontalDynamicNewsEventCard = ({
onToggleFollow,
timelineStyle,
borderColor,
+ indicatorSize = 'comfortable',
}) => {
const importance = getImportanceConfig(event.importance);
+
+ // 所有 useColorModeValue 必须在顶层调用
const cardBg = useColorModeValue('white', 'gray.800');
+ const cardBgAlt = useColorModeValue('gray.50', 'gray.750');
+ const selectedBg = useColorModeValue('blue.50', 'blue.900');
+ const selectedBorderColor = useColorModeValue('blue.500', 'blue.400');
const linkColor = useColorModeValue('blue.600', 'blue.400');
return (
@@ -65,12 +72,12 @@ const HorizontalDynamicNewsEventCard = ({
flex="1"
position="relative"
bg={isSelected
- ? useColorModeValue('blue.50', 'blue.900')
- : (index % 2 === 0 ? cardBg : useColorModeValue('gray.50', 'gray.750'))
+ ? selectedBg
+ : (index % 2 === 0 ? cardBg : cardBgAlt)
}
borderWidth={isSelected ? "2px" : "1px"}
borderColor={isSelected
- ? useColorModeValue('blue.500', 'blue.400')
+ ? selectedBorderColor
: borderColor
}
borderRadius="md"
@@ -137,7 +144,7 @@ const HorizontalDynamicNewsEventCard = ({
avgChange={event.related_avg_chg}
maxChange={event.related_max_chg}
weekChange={event.related_week_chg}
- size="comfortable"
+ size={indicatorSize}
/>
diff --git a/src/views/Community/index.js b/src/views/Community/index.js
index d7c01dde..7859634e 100644
--- a/src/views/Community/index.js
+++ b/src/views/Community/index.js
@@ -5,8 +5,7 @@ import { useSelector, useDispatch } from 'react-redux';
import {
fetchPopularKeywords,
fetchHotEvents,
- fetchDynamicNews,
- selectDynamicNewsWithLoading
+ fetchDynamicNews
} from '../../store/slices/communityDataSlice';
import {
Box,
@@ -39,13 +38,6 @@ const Community = () => {
// Redux状态
const { popularKeywords, hotEvents } = useSelector(state => state.communityData);
- const {
- data: allCachedEvents,
- loading: dynamicNewsLoading,
- error: dynamicNewsError,
- total: dynamicNewsTotal,
- cachedCount: dynamicNewsCachedCount
- } = useSelector(selectDynamicNewsWithLoading);
// Chakra UI hooks
const bgColor = useColorModeValue('gray.50', 'gray.900');
@@ -167,10 +159,6 @@ const Community = () => {
{/* 实时要闻·动态追踪 - 横向滚动 */}