From 8ebfad999280d150acc3c04bb0640bf91a720d20 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Mon, 3 Nov 2025 17:21:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8D=95=E6=8E=92/=E5=8F=8C=E6=8E=92?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=A8=A1=E5=BC=8F=E5=88=87=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Community/components/DynamicNewsCard.js | 21 ++- .../DynamicNewsCard/EventScrollList.js | 146 ++++++++++++------ src/views/Community/index.js | 1 + 3 files changed, 123 insertions(+), 45 deletions(-) diff --git a/src/views/Community/components/DynamicNewsCard.js b/src/views/Community/components/DynamicNewsCard.js index 7d5f1b4f..923a7849 100644 --- a/src/views/Community/components/DynamicNewsCard.js +++ b/src/views/Community/components/DynamicNewsCard.js @@ -25,7 +25,7 @@ import UnifiedSearchBox from './UnifiedSearchBox'; import { fetchDynamicNews } from '../../../store/slices/communityDataSlice'; /** - * 实时要闻·动态追踪 - 横向滚动卡片组件 + * 实时要闻·动态追踪 - 事件展示卡片组件 * @param {Array} events - 事件列表 * @param {boolean} loading - 加载状态 * @param {Object} pagination - 分页信息 { page, per_page, total, total_pages } @@ -36,6 +36,7 @@ import { fetchDynamicNews } from '../../../store/slices/communityDataSlice'; * @param {Function} onSearchFocus - 搜索框获得焦点回调 * @param {Function} onEventClick - 事件点击回调 * @param {Function} onViewDetail - 查看详情回调 + * @param {string} mode - 展示模式:'carousel'(单排轮播5个)| 'grid'(双排网格10个) * @param {Object} ref - 用于滚动的ref */ const DynamicNewsCard = forwardRef(({ @@ -55,11 +56,25 @@ const DynamicNewsCard = forwardRef(({ const cardBg = useColorModeValue('white', 'gray.800'); const borderColor = useColorModeValue('gray.200', 'gray.700'); const [selectedEvent, setSelectedEvent] = useState(null); + const [mode, setMode] = useState('carousel'); // 'carousel' 或 'grid',默认单排 - const pageSize = 5; // 每页显示5个事件 + // 根据模式决定每页显示数量 + const pageSize = mode === 'carousel' ? 5 : 10; // carousel: 5个, grid: 10个 const currentPage = pagination.page || 1; const totalPages = pagination.total_pages || 1; + // 模式切换处理 + const handleModeToggle = (newMode) => { + if (newMode !== mode) { + setMode(newMode); + // 切换模式时重置到第1页并重新请求数据 + const newPageSize = newMode === 'carousel' ? 5 : 10; + dispatch(fetchDynamicNews({ page: 1, per_page: newPageSize })); + // 清除当前选中的事件 + setSelectedEvent(null); + } + }; + // 默认选中第一个事件 useEffect(() => { if (events && events.length > 0 && !selectedEvent) { @@ -123,6 +138,8 @@ const DynamicNewsCard = forwardRef(({ totalPages={totalPages} onPageChange={handlePageChange} loading={loading} + mode={mode} + onModeChange={handleModeToggle} /> ) : !loading ? ( /* Empty 状态 - 只在非加载且无数据时显示 */ diff --git a/src/views/Community/components/DynamicNewsCard/EventScrollList.js b/src/views/Community/components/DynamicNewsCard/EventScrollList.js index 6a200a4a..81a9a9ff 100644 --- a/src/views/Community/components/DynamicNewsCard/EventScrollList.js +++ b/src/views/Community/components/DynamicNewsCard/EventScrollList.js @@ -5,7 +5,10 @@ import React, { useRef } from 'react'; import { Box, Flex, + Grid, IconButton, + Button, + ButtonGroup, Center, VStack, Spinner, @@ -17,7 +20,7 @@ import DynamicNewsEventCard from '../EventCard/DynamicNewsEventCard'; import PaginationControl from './PaginationControl'; /** - * 横向滚动事件列表组件 + * 事件列表组件 - 支持两种展示模式 * @param {Array} events - 当前页的事件列表(服务端已分页) * @param {Object} selectedEvent - 当前选中的事件 * @param {Function} onEventSelect - 事件选择回调 @@ -26,6 +29,8 @@ import PaginationControl from './PaginationControl'; * @param {number} totalPages - 总页数(由服务端返回) * @param {Function} onPageChange - 页码改变回调 * @param {boolean} loading - 加载状态 + * @param {string} mode - 展示模式:'carousel'(单排轮播)| 'grid'(双排网格) + * @param {Function} onModeChange - 模式切换回调 */ const EventScrollList = ({ events, @@ -35,7 +40,9 @@ const EventScrollList = ({ currentPage, totalPages, onPageChange, - loading = false + loading = false, + mode = 'carousel', + onModeChange }) => { const scrollContainerRef = useRef(null); @@ -52,16 +59,35 @@ const EventScrollList = ({ return ( - {/* 分页控制器 - 右上角相对定位 */} - {totalPages > 1 && ( - + {/* 顶部控制栏:模式切换按钮(左)+ 分页控制器(右) */} + + {/* 模式切换按钮 */} + + + + + + {/* 分页控制器 */} + {totalPages > 1 && ( - - )} + )} + {/* 横向滚动区域 */} @@ -122,17 +148,16 @@ const EventScrollList = ({ /> )} - {/* 横向滚动容器 */} - {/* 加载遮罩 */} {loading && ( @@ -175,35 +198,72 @@ const EventScrollList = ({ )} - {/* 事件卡片列表 */} - {events.map((event, index) => ( - + {events.map((event, index) => ( + + { + onEventSelect(clickedEvent); + }} + onTitleClick={(e) => { + e.preventDefault(); + e.stopPropagation(); + onEventSelect(event); + }} + onToggleFollow={() => {}} + timelineStyle={getTimelineBoxStyle()} + borderColor={borderColor} + /> + + ))} + + )} + + {/* 模式2: 双排网格模式 */} + {mode === 'grid' && ( + - { - onEventSelect(clickedEvent); - }} - onTitleClick={(e) => { - e.preventDefault(); - e.stopPropagation(); - onEventSelect(event); - }} - onToggleFollow={() => {}} - timelineStyle={getTimelineBoxStyle()} - borderColor={borderColor} - /> - - ))} - + {events.map((event, index) => ( + + { + onEventSelect(clickedEvent); + }} + onTitleClick={(e) => { + e.preventDefault(); + e.stopPropagation(); + onEventSelect(event); + }} + onToggleFollow={() => {}} + timelineStyle={getTimelineBoxStyle()} + borderColor={borderColor} + /> + + ))} + + )} + ); diff --git a/src/views/Community/index.js b/src/views/Community/index.js index 3ab1b193..6d4de096 100644 --- a/src/views/Community/index.js +++ b/src/views/Community/index.js @@ -196,6 +196,7 @@ const Community = () => { onSearchFocus={scrollToTimeline} onEventClick={handleEventClick} onViewDetail={handleViewDetail} + mode="grid" /> {/* 市场复盘 - 左右布局 */}