fix: 修复分页、筛选和模式切换相关问题

主要修复:
1. 修复模式切换时 per_page 参数错误
   - 在 useEffect 内直接根据 mode 计算 per_page
   - 避免使用可能过时的 pageSize prop

2. 修复 DISPLAY_MODES 未定义错误
   - 在 DynamicNewsCard.js 中导入 DISPLAY_MODES 常量

3. 添加空状态显示
   - VerticalModeLayout 添加无数据时的友好提示
   - 显示图标和提示文字,引导用户调整筛选条件

4. 修复无限请求循环问题
   - 移除模式切换 useEffect 中的 filters 依赖
   - 避免筛选和模式切换 useEffect 互相触发

5. 修复筛选参数传递问题
   - usePagination 使用 useRef 存储最新 filters
   - 避免 useCallback 闭包捕获旧值
   - 修复时间筛选参数丢失问题

6. 修复分页竞态条件
   - 允许用户在加载时切换到不同页面
   - 只阻止相同页面的重复请求

涉及文件:
- src/views/Community/components/DynamicNewsCard.js
- src/views/Community/components/DynamicNewsCard/VerticalModeLayout.js
- src/views/Community/components/DynamicNewsCard/hooks/usePagination.js
- src/views/Community/hooks/useEventFilters.js
- src/store/slices/communityDataSlice.js
- src/views/Community/components/UnifiedSearchBox.js

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-11-06 17:39:03 +08:00
parent 8799964961
commit 319a78d34c
6 changed files with 429 additions and 172 deletions

View File

@@ -2,8 +2,8 @@
// 纵向分栏模式布局组件
import React, { useState, useEffect } from 'react';
import { Box, IconButton, Tooltip, VStack, Flex } from '@chakra-ui/react';
import { ViewIcon, ViewOffIcon } from '@chakra-ui/icons';
import { Box, IconButton, Tooltip, VStack, Flex, Center, Text } from '@chakra-ui/react';
import { ViewIcon, ViewOffIcon, InfoIcon } from '@chakra-ui/icons';
import HorizontalDynamicNewsEventCard from '../EventCard/HorizontalDynamicNewsEventCard';
import EventDetailScrollPanel from './EventDetailScrollPanel';
@@ -94,26 +94,41 @@ const VerticalModeLayout = ({
}}
>
{/* 事件列表 */}
<VStack
spacing={2}
align="stretch"
p={2}
>
{events.map((event) => (
<HorizontalDynamicNewsEventCard
key={event.id}
event={event}
isSelected={selectedEvent?.id === event.id}
onEventClick={() => onEventSelect(event)}
isFollowing={eventFollowStatus[event.id]?.isFollowing}
followerCount={eventFollowStatus[event.id]?.followerCount}
onToggleFollow={onToggleFollow}
timelineStyle={getTimelineBoxStyle()}
borderColor={borderColor}
indicatorSize={layoutMode === 'detail' ? 'default' : 'comfortable'}
/>
))}
</VStack>
{events && events.length > 0 ? (
<VStack
spacing={2}
align="stretch"
p={2}
>
{events.map((event) => (
<HorizontalDynamicNewsEventCard
key={event.id}
event={event}
isSelected={selectedEvent?.id === event.id}
onEventClick={() => onEventSelect(event)}
isFollowing={eventFollowStatus[event.id]?.isFollowing}
followerCount={eventFollowStatus[event.id]?.followerCount}
onToggleFollow={onToggleFollow}
timelineStyle={getTimelineBoxStyle()}
borderColor={borderColor}
indicatorSize={layoutMode === 'detail' ? 'default' : 'comfortable'}
/>
))}
</VStack>
) : (
/* 空状态 */
<Center h="100%" minH="400px">
<VStack spacing={4}>
<InfoIcon w={12} h={12} color="gray.400" />
<Text fontSize="lg" color="gray.500" textAlign="center">
当前筛选条件下暂无数据
</Text>
<Text fontSize="sm" color="gray.400" textAlign="center">
请尝试调整筛选条件
</Text>
</VStack>
</Center>
)}
</Box>
{/* 右侧:事件详情 - 独立滚动 */}