From cad53942e8033486b1bc5f2b9e86244219aac21e Mon Sep 17 00:00:00 2001 From: freefire Date: Wed, 2 Sep 2026 19:29:01 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=9C=AA=E8=AF=BB=E6=95=B0=E5=90=8C=E6=AD=A5=E5=92=8C=E5=B8=96?= =?UTF-8?q?=E5=AD=90=E8=AF=A6=E6=83=85=E5=BF=AB=E7=85=A7=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - MessagesPage: 新增 updateConvUnread 统一更新会话未读数及 session 缓存, 缓存命中时仍调用 markConversationRead 并触发未读刷新, 全部标为已读时同步更新 session 缓存避免 stale 数据 - PostDetailPage: 仅 POP 导航类型使用 session 快照恢复, 非 POP 导航和下拉刷新始终强制重拉确保拿到最新数据 --- frontend/src/pages/MessagesPage.tsx | 35 ++++++++++++++++++++++++--- frontend/src/pages/PostDetailPage.tsx | 16 +++--------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/frontend/src/pages/MessagesPage.tsx b/frontend/src/pages/MessagesPage.tsx index dcac5a3..0c9f73e 100644 --- a/frontend/src/pages/MessagesPage.tsx +++ b/frontend/src/pages/MessagesPage.tsx @@ -346,6 +346,23 @@ export default function MessagesPage() { }); }, []); + /** 更新会话未读数,同时同步 session 缓存防止后续恢复 stale 数据 */ + const updateConvUnread = useCallback((peerId: number, unread: number) => { + setConversations((prev) => { + const next = prev.map((c) => + c.peer_user_id === peerId ? { ...c, unread_count: unread } : c + ); + const cached = getSessionSnapshot('messages:conv:1'); + if (cached) { + setSessionSnapshot('messages:conv:1', { + ...cached, + conversations: next, + }); + } + return next; + }); + }, []); + const clearConvSearch = useCallback(() => { setConvSearchQuery(''); setConvSearchResults([]); @@ -584,6 +601,11 @@ export default function MessagesPage() { setPeerUser(cached.peerUser); if (cached.peerUser) ensurePeerConversation(cached.peerUser); setThreadLoading(false); + // 缓存命中时仍需标记后端已读,并更新前端会话列表未读数 + void api.markConversationRead(selectedPeer).catch(() => undefined); + updateConvUnread(selectedPeer, 0); + window.dispatchEvent(new Event('messages-unread-refresh')); + void refreshUnreadSplit(); return; } let cancelled = false; @@ -603,9 +625,7 @@ export default function MessagesPage() { total: r.total || 0, peerUser: peer, }); - setConversations((prev) => prev.map((c) => ( - c.peer_user_id === selectedPeer ? { ...c, unread_count: 0 } : c - ))); + updateConvUnread(selectedPeer, 0); window.dispatchEvent(new Event('messages-unread-refresh')); void refreshUnreadSplit(); }) @@ -662,7 +682,14 @@ export default function MessagesPage() { notify.success('通知已全部标为已读'); } else { await api.markAllMessagesRead(); - setConversations((prev) => prev.map((c) => ({ ...c, unread_count: 0 }))); + setConversations((prev) => { + const next = prev.map((c) => ({ ...c, unread_count: 0 })); + const cached = getSessionSnapshot('messages:conv:1'); + if (cached) { + setSessionSnapshot('messages:conv:1', { ...cached, conversations: next }); + } + return next; + }); setDmUnread(0); setNotifyUnread(0); notify.success('已全部标为已读'); diff --git a/frontend/src/pages/PostDetailPage.tsx b/frontend/src/pages/PostDetailPage.tsx index da8f5e8..4fbb015 100644 --- a/frontend/src/pages/PostDetailPage.tsx +++ b/frontend/src/pages/PostDetailPage.tsx @@ -109,7 +109,7 @@ export default function PostDetailPage() { const { limits } = useForumLimits(); const { setPostOutline, isMobile } = useOutletContext(); - const initialSnap = (postId && !Number.isNaN(postId)) + const initialSnap = (postId && !Number.isNaN(postId) && navType === 'POP') ? getSessionSnapshot(postDetailCacheKey(postId)) : undefined; @@ -259,7 +259,7 @@ export default function PostDetailPage() { if (mode === 'force') { deleteSessionSnapshot(postDetailCacheKey(postId)); } - const cached = mode === 'force' + const cached = mode === 'force' || navType !== 'POP' ? undefined : getSessionSnapshot(postDetailCacheKey(postId)); if (cached) { @@ -329,19 +329,9 @@ export default function PostDetailPage() { }, [postId]); useEffect(() => { - // 下拉已预热则应用快照;否则强制重拉 + // 下拉/软刷新:始终强制重拉,确保拿到最新数据 const onForce = () => { if (!postId || Number.isNaN(postId)) return; - const warm = getSessionSnapshot(postDetailCacheKey(postId)); - if (warm) { - loadSeq.current += 1; - applySnapshot(warm, { restoreScroll: false }); - setLoading(false); - const el = pageRef.current; - if (el) el.scrollTop = 0; - scrollTopRef.current = 0; - return; - } loadPostRef.current('force'); }; window.addEventListener(PAGE_FORCE_REFRESH_EVENT, onForce);