From 3d60016d87add503277f05f4d7a8575e7b392df8 Mon Sep 17 00:00:00 2001 From: sp mac bookpro 2605 Date: Sat, 6 Jun 2026 14:19:44 +0800 Subject: [PATCH] chat: persist last session and require sessionId --- src/pages/chat/ChatPage.tsx | 66 ++++++++++++++++++++++++--- src/pages/chat/hooks/useChatData.ts | 5 +- src/pages/chat/hooks/useChatSender.ts | 18 ++++++-- 3 files changed, 77 insertions(+), 12 deletions(-) diff --git a/src/pages/chat/ChatPage.tsx b/src/pages/chat/ChatPage.tsx index 5f639b6..3062c61 100644 --- a/src/pages/chat/ChatPage.tsx +++ b/src/pages/chat/ChatPage.tsx @@ -14,6 +14,8 @@ import { useChatData } from './hooks/useChatData'; import { useChatSender } from './hooks/useChatSender'; import { markdownToPlainText } from './utils/copy'; +const lastSessionKey = (agentId: string) => `chat:lastSession:${agentId}`; + export default function ChatPage() { const { id } = useParams(); const navigate = useNavigate(); @@ -33,18 +35,70 @@ export default function ChatPage() { const { bodyRef, scrollBottom, initialScrollDoneRef } = useChatScroll(); useEffect(() => { + if (!id) return; + const s = searchParams.get('session'); const m = searchParams.get('msg'); + if (s) { setSessionId(s); - if (m) setHighlightId(m); - const next = new URLSearchParams(searchParams); - next.delete('session'); - next.delete('msg'); - setSearchParams(next, { replace: true }); + try { + localStorage.setItem(lastSessionKey(id), s); + } catch { + // ignore + } + if (m) { + setHighlightId(m); + const next = new URLSearchParams(searchParams); + next.delete('msg'); + setSearchParams(next, { replace: true }); + } + return; } + + const saved = (() => { + try { + return localStorage.getItem(lastSessionKey(id)); + } catch { + return null; + } + })(); + if (saved) { + setSessionId(saved); + return; + } + + (async () => { + try { + const list = await SessionAPI.list(id, '0'); + if (list.length > 0) { + setSessionId(list[0].id); + return; + } + const created = await SessionAPI.create(id); + setSessionId(created.id); + } catch (e: any) { + message.error('加载会话失败:' + (e?.message ?? e)); + } + })(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [searchParams]); + }, [id]); + + useEffect(() => { + if (!id || !sessionId) return; + try { + localStorage.setItem(lastSessionKey(id), sessionId); + } catch { + // ignore + } + const cur = searchParams.get('session'); + if (cur === sessionId) return; + const next = new URLSearchParams(searchParams); + next.set('session', sessionId); + next.delete('msg'); + setSearchParams(next, { replace: true }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [id, sessionId]); const { agent, agentList, messages, setMessages, branches, setBranches, loadMessages } = useChatData({ agentId: id, diff --git a/src/pages/chat/hooks/useChatData.ts b/src/pages/chat/hooks/useChatData.ts index dc0f782..02dcb99 100644 --- a/src/pages/chat/hooks/useChatData.ts +++ b/src/pages/chat/hooks/useChatData.ts @@ -48,7 +48,7 @@ export function useChatData(args: { }; const loadMessages = async () => { - if (!agentId) return; + if (!agentId || !sessionId) return; const his = await ChatAPI.history(agentId, sessionId || undefined); setMessages(Array.isArray(his.messages) ? his.messages : []); setBranches(his.branches || {}); @@ -92,7 +92,7 @@ export function useChatData(args: { }, [agentId]); useEffect(() => { - if (!agentId) return; + if (!agentId || !sessionId) return; loadMessages(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [sessionId, highlightId, agentId]); @@ -107,4 +107,3 @@ export function useChatData(args: { loadMessages }; } - diff --git a/src/pages/chat/hooks/useChatSender.ts b/src/pages/chat/hooks/useChatSender.ts index ac8ae90..cd449b2 100644 --- a/src/pages/chat/hooks/useChatSender.ts +++ b/src/pages/chat/hooks/useChatSender.ts @@ -52,6 +52,10 @@ export function useChatSender(args: { const handleSendStream = async (text: string) => { if (!agentId) return; + if (!sessionId) { + notify.error('会话未初始化,请稍后重试'); + return; + } const tempUser: ChatMessage = { id: 'tmp-' + Date.now(), role: 'user', content: text, createdAt: Date.now() }; args.setMessages((m) => [...(m || []), tempUser]); setStreaming({ active: true, reasoningText: '', answerText: '', errorMessage: null, retryInfo: null, retrieved: [], toolCalls: [] }); @@ -144,7 +148,7 @@ export function useChatSender(args: { } }, ctrl.signal, - sessionId || undefined, + sessionId, model, modelId, imageUrls @@ -167,6 +171,10 @@ export function useChatSender(args: { const handleSendNonStream = async (text: string) => { if (!agentId) return; + if (!sessionId) { + notify.error('会话未初始化,请稍后重试'); + return; + } const tempUser: ChatMessage = { id: 'tmp-' + Date.now(), role: 'user', content: text, createdAt: Date.now() }; args.setMessages((m) => [...(m || []), tempUser]); scrollBottom(true); @@ -174,7 +182,7 @@ export function useChatSender(args: { const content = attText ? `${text}\n\n${attText}` : text; const model = overrides.model || agentModels[0]?.name || ''; try { - const res = await ChatAPI.send(agentId, content, sessionId || undefined, model, imageUrls); + const res = await ChatAPI.send(agentId, content, sessionId, model, imageUrls); args.setMessages((m) => [...(m || []).filter((x) => x.id !== tempUser.id), res.user, res.assistant]); setSessionRefresh((t) => t + 1); setAttachments([]); @@ -206,7 +214,11 @@ export function useChatSender(args: { const handleClear = async () => { if (!agentId) return; - await ChatAPI.clear(agentId, sessionId || undefined); + if (!sessionId) { + notify.error('会话未初始化,请稍后重试'); + return; + } + await ChatAPI.clear(agentId, sessionId); args.setMessages(() => []); setBranches({}); notify.success('对话已清空');