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

@@ -182,8 +182,12 @@ export const fetchDynamicNews = createAsyncThunk(
sort = 'new',
importance,
q,
date_range,
industry_code
date_range, // 兼容旧格式(已废弃)
industry_code,
// 时间筛选参数(从 TradingTimeFilter 传递)
start_date,
end_date,
recent_days
} = {}, { rejectWithValue }) => {
try {
// 【动态计算 per_page】根据 mode 自动选择合适的每页大小
@@ -197,8 +201,12 @@ export const fetchDynamicNews = createAsyncThunk(
if (sort) filters.sort = sort;
if (importance && importance !== 'all') filters.importance = importance;
if (q) filters.q = q;
if (date_range) filters.date_range = date_range;
if (date_range) filters.date_range = date_range; // 兼容旧格式
if (industry_code) filters.industry_code = industry_code;
// 时间筛选参数
if (start_date) filters.start_date = start_date;
if (end_date) filters.end_date = end_date;
if (recent_days) filters.recent_days = recent_days;
logger.debug('CommunityData', '开始获取动态新闻', {
mode,
@@ -443,6 +451,17 @@ const communityDataSlice = createSlice({
const { eventId, isFollowing, followerCount } = action.payload;
state.eventFollowStatus[eventId] = { isFollowing, followerCount };
logger.debug('CommunityData', '设置事件关注状态', { eventId, isFollowing, followerCount });
},
/**
* 更新分页页码(用于缓存场景,无需 API 请求)
* @param {Object} action.payload - { mode, page }
*/
updatePaginationPage: (state, action) => {
const { mode, page } = action.payload;
const paginationKey = mode === 'four-row' ? 'fourRowPagination' : 'verticalPagination';
state[paginationKey].current_page = page;
logger.debug('CommunityData', '同步更新分页页码(缓存场景)', { mode, page });
}
},
@@ -603,7 +622,7 @@ const communityDataSlice = createSlice({
// ==================== 导出 ====================
export const { clearCache, clearSpecificCache, preloadData, setEventFollowStatus } = communityDataSlice.actions;
export const { clearCache, clearSpecificCache, preloadData, setEventFollowStatus, updatePaginationPage } = communityDataSlice.actions;
// 基础选择器Selectors
export const selectPopularKeywords = (state) => state.communityData.popularKeywords;