Merge branch 'feature_bugfix/251201_vf_h5_ui' into feature_2025/251209_stock_pref

* feature_bugfix/251201_vf_h5_ui:
  feat: 事件关注功能优化 - Redux 乐观更新 + Mock 数据状态同步
  feat: 投资日历自选股功能优化 - Redux 集成 + 乐观更新
  fix: 修复投资日历切换月份时自动打开事件弹窗的问题
  fix: 修复 CompanyOverview 中 Hooks 顺序错误
This commit is contained in:
zdl
2025-12-09 16:36:46 +08:00
7 changed files with 220 additions and 55 deletions

View File

@@ -608,14 +608,40 @@ const communityDataSlice = createSlice({
state.error[stateKey] = action.payload;
logger.error('CommunityData', `${stateKey} 加载失败`, new Error(action.payload));
})
// toggleEventFollow
// ===== toggleEventFollow(乐观更新)=====
// pending: 立即切换状态
.addCase(toggleEventFollow.pending, (state, action) => {
const eventId = action.meta.arg;
const current = state.eventFollowStatus[eventId];
// 乐观切换:如果当前已关注则变为未关注,反之亦然
state.eventFollowStatus[eventId] = {
isFollowing: !(current?.isFollowing),
followerCount: current?.followerCount ?? 0
};
logger.debug('CommunityData', 'toggleEventFollow pending (乐观更新)', {
eventId,
newIsFollowing: !(current?.isFollowing)
});
})
// rejected: 回滚状态
.addCase(toggleEventFollow.rejected, (state, action) => {
const eventId = action.meta.arg;
const current = state.eventFollowStatus[eventId];
// 回滚:恢复到之前的状态(再次切换回去)
state.eventFollowStatus[eventId] = {
isFollowing: !(current?.isFollowing),
followerCount: current?.followerCount ?? 0
};
logger.error('CommunityData', 'toggleEventFollow rejected (已回滚)', {
eventId,
error: action.payload
});
})
// fulfilled: 使用 API 返回的准确数据覆盖
.addCase(toggleEventFollow.fulfilled, (state, action) => {
const { eventId, isFollowing, followerCount } = action.payload;
state.eventFollowStatus[eventId] = { isFollowing, followerCount };
logger.debug('CommunityData', 'toggleEventFollow fulfilled', { eventId, isFollowing, followerCount });
})
.addCase(toggleEventFollow.rejected, (_state, action) => {
logger.error('CommunityData', 'toggleEventFollow rejected', action.payload);
});
}
});

View File

@@ -460,9 +460,10 @@ const stockSlice = createSlice({
state.loading.allStocks = false;
})
// ===== toggleWatchlist =====
.addCase(toggleWatchlist.fulfilled, (state, action) => {
const { stockCode, stockName, isInWatchlist } = action.payload;
// ===== toggleWatchlist(乐观更新)=====
// pending: 立即更新状态
.addCase(toggleWatchlist.pending, (state, action) => {
const { stockCode, stockName, isInWatchlist } = action.meta.arg;
if (isInWatchlist) {
// 移除
state.watchlist = state.watchlist.filter(item => item.stock_code !== stockCode);
@@ -473,6 +474,25 @@ const stockSlice = createSlice({
state.watchlist.push({ stock_code: stockCode, stock_name: stockName });
}
}
})
// rejected: 回滚状态
.addCase(toggleWatchlist.rejected, (state, action) => {
const { stockCode, stockName, isInWatchlist } = action.meta.arg;
// 回滚:与 pending 操作相反
if (isInWatchlist) {
// 之前移除了,现在加回来
const exists = state.watchlist.some(item => item.stock_code === stockCode);
if (!exists) {
state.watchlist.push({ stock_code: stockCode, stock_name: stockName });
}
} else {
// 之前添加了,现在移除
state.watchlist = state.watchlist.filter(item => item.stock_code !== stockCode);
}
})
// fulfilled: 乐观更新模式下状态已在 pending 更新,这里无需操作
.addCase(toggleWatchlist.fulfilled, () => {
// 状态已在 pending 时更新
});
}
});