From bd4c4878f1bcf7f704b16a893882ddcda72033a9 Mon Sep 17 00:00:00 2001 From: hicccc77 <98377878+hicccc77@users.noreply.github.com> Date: Sun, 15 Mar 2026 19:53:11 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E5=8F=96=E6=B6=88/=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=E6=8C=81=E7=BB=AD=E5=8D=A0=E7=94=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 全局搜索和会话内搜索均加 generation 计数,新搜索触发时丢弃旧结果 - 防抖从 400ms 统一改为 500ms - 关闭搜索时立即取消 pending 的 timer 和 generation --- src/pages/ChatPage.tsx | 56 +++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/src/pages/ChatPage.tsx b/src/pages/ChatPage.tsx index 0e32b64..4306e7c 100644 --- a/src/pages/ChatPage.tsx +++ b/src/pages/ChatPage.tsx @@ -2620,60 +2620,88 @@ function ChatPage(props: ChatPageProps) { } // 会话内搜索 + const inSessionSearchTimerRef = useRef | null>(null) + const inSessionSearchGenRef = useRef(0) const handleInSessionSearch = useCallback(async (keyword: string) => { setInSessionQuery(keyword) + if (inSessionSearchTimerRef.current) clearTimeout(inSessionSearchTimerRef.current) + inSessionSearchGenRef.current += 1 if (!keyword.trim() || !currentSessionId) { setInSessionResults([]) + setInSessionSearching(false) return } - setInSessionSearching(true) - try { - const res = await window.electronAPI.chat.searchMessages(keyword.trim(), currentSessionId, 50, 0) - setInSessionResults(res?.messages || []) - } catch { - setInSessionResults([]) - } finally { - setInSessionSearching(false) - } + const gen = inSessionSearchGenRef.current + const sid = currentSessionId + inSessionSearchTimerRef.current = setTimeout(async () => { + if (gen !== inSessionSearchGenRef.current) return + setInSessionSearching(true) + try { + const res = await window.electronAPI.chat.searchMessages(keyword.trim(), sid, 50, 0) + if (gen !== inSessionSearchGenRef.current) return + setInSessionResults(res?.messages || []) + } catch { + if (gen !== inSessionSearchGenRef.current) return + setInSessionResults([]) + } finally { + if (gen === inSessionSearchGenRef.current) setInSessionSearching(false) + } + }, 500) }, [currentSessionId]) const handleToggleInSessionSearch = useCallback(() => { setShowInSessionSearch(v => { - if (v) { setInSessionQuery(''); setInSessionResults([]) } - else setTimeout(() => inSessionSearchRef.current?.focus(), 50) + if (v) { + inSessionSearchGenRef.current += 1 + if (inSessionSearchTimerRef.current) clearTimeout(inSessionSearchTimerRef.current) + setInSessionQuery('') + setInSessionResults([]) + setInSessionSearching(false) + } else { + setTimeout(() => inSessionSearchRef.current?.focus(), 50) + } return !v }) }, []) // 全局消息搜索 const globalMsgSearchTimerRef = useRef | null>(null) + const globalMsgSearchGenRef = useRef(0) const handleGlobalMsgSearch = useCallback(async (keyword: string) => { setGlobalMsgQuery(keyword) if (globalMsgSearchTimerRef.current) clearTimeout(globalMsgSearchTimerRef.current) + globalMsgSearchGenRef.current += 1 if (!keyword.trim()) { setGlobalMsgResults([]) setShowGlobalMsgSearch(false) + setGlobalMsgSearching(false) return } setShowGlobalMsgSearch(true) + const gen = globalMsgSearchGenRef.current globalMsgSearchTimerRef.current = setTimeout(async () => { + if (gen !== globalMsgSearchGenRef.current) return setGlobalMsgSearching(true) try { const res = await window.electronAPI.chat.searchMessages(keyword.trim(), undefined, 50, 0) + if (gen !== globalMsgSearchGenRef.current) return setGlobalMsgResults(res?.messages || []) } catch { + if (gen !== globalMsgSearchGenRef.current) return setGlobalMsgResults([]) } finally { - setGlobalMsgSearching(false) + if (gen === globalMsgSearchGenRef.current) setGlobalMsgSearching(false) } - }, 400) + }, 500) }, []) const handleCloseGlobalMsgSearch = useCallback(() => { + globalMsgSearchGenRef.current += 1 + if (globalMsgSearchTimerRef.current) clearTimeout(globalMsgSearchTimerRef.current) setShowGlobalMsgSearch(false) setGlobalMsgQuery('') setGlobalMsgResults([]) - if (globalMsgSearchTimerRef.current) clearTimeout(globalMsgSearchTimerRef.current) + setGlobalMsgSearching(false) }, []) // 滚动加载更多 + 显示/隐藏回到底部按钮(优化:节流,避免频繁执行)