From 1fd0db078a93249abb8c00461ab70ccb023b5132 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 7 Feb 2026 20:57:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=94=9F=E5=9B=BE=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=E6=B6=88=E6=81=AF=E8=A2=AB=E8=A6=86=E7=9B=96=E4=B8=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/messages/route.ts | 13 +++++++++++-- components/chat.tsx | 31 ++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/app/api/messages/route.ts b/app/api/messages/route.ts index 0073f2de8..fb8db4ad5 100644 --- a/app/api/messages/route.ts +++ b/app/api/messages/route.ts @@ -3,6 +3,9 @@ import { auth } from "@/app/(auth)/auth"; import { saveMessages, getMessagesByChatId } from "@/lib/db/queries"; import type { DBMessage } from "@/lib/db/schema"; +export const dynamic = "force-dynamic"; +export const revalidate = 0; + /** * 获取聊天消息 * 用于从数据库重新加载消息 @@ -41,7 +44,14 @@ export async function GET(request: NextRequest) { }; }); - return NextResponse.json({ messages: formattedMessages }); + return NextResponse.json( + { messages: formattedMessages }, + { + headers: { + "Cache-Control": "no-store, max-age=0", + }, + } + ); } catch (error) { console.error("[Messages API] GET Error:", error); return NextResponse.json( @@ -100,4 +110,3 @@ export async function POST(request: NextRequest) { ); } } - diff --git a/components/chat.tsx b/components/chat.tsx index da47c6c9d..17750dd6b 100644 --- a/components/chat.tsx +++ b/components/chat.tsx @@ -63,6 +63,14 @@ function normalizeImageParamsForProvider( return normalized; } +function sortMessagesByCreatedAt(messages: ChatMessage[]): ChatMessage[] { + return [...messages].sort((a, b) => { + const timeA = (a as any).createdAt ? new Date((a as any).createdAt).getTime() : 0; + const timeB = (b as any).createdAt ? new Date((b as any).createdAt).getTime() : 0; + return timeA - timeB; + }); +} + export function Chat({ id, initialMessages, @@ -465,15 +473,28 @@ export function Chat({ await new Promise(resolve => setTimeout(resolve, 500)); // 获取最新消息 - const response = await fetch(`/api/messages?chatId=${id}`); + const response = await fetch(`/api/messages?chatId=${id}&_t=${Date.now()}`, { + cache: "no-store", + }); if (response.ok) { const data = await response.json(); if (data.messages && Array.isArray(data.messages)) { console.log("[Chat] Reloading messages from database:", data.messages.length); - // 更新消息状态 - setMessages(data.messages); - // 清空 appendedMessages,因为已经从数据库加载了完整消息 - setAppendedMessages([]); + // 合并消息,避免数据库短暂延迟导致实时 append 的图片消息被覆盖丢失 + setMessages((prev) => { + const mergedMap = new Map(); + prev.forEach((message) => mergedMap.set(message.id, message)); + (data.messages as ChatMessage[]).forEach((message) => mergedMap.set(message.id, message)); + return sortMessagesByCreatedAt(Array.from(mergedMap.values())); + }); + + // 仅清理已经成功落库的 appended 消息,保留仍未在数据库中出现的实时消息 + const persistedIds = new Set( + (data.messages as ChatMessage[]).map((message) => message.id) + ); + setAppendedMessages((prev) => + prev.filter((message) => !persistedIds.has(message.id)) + ); } } } catch (error) {