From 2e83cb8e72e9588680c55cd1ead4967b589d8ace Mon Sep 17 00:00:00 2001 From: chengkai3 Date: Sat, 27 Jun 2026 06:26:10 +0800 Subject: [PATCH] =?UTF-8?q?feat:[FL-189][AI=E9=97=AE=E7=AD=94=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=EF=BC=9A=E5=8F=96=E6=B6=88=E9=BB=98=E8=AE=A4=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=88=9B=E5=BB=BA=E4=BC=9A=E8=AF=9D=EF=BC=8C=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E9=A6=96=E6=AC=A1=E9=97=AE=E7=AD=94=E6=97=B6=E7=94=9F?= =?UTF-8?q?=E6=88=90]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主要改动: 1. 移除页面加载时自动创建空会话的逻辑 2. 修改发送消息函数,支持在无会话时自动创建会话 3. 根据用户首条问题内容智能生成会话标题(截取前20字或首行) 4. 优化欢迎界面,支持无会话状态下直接输入问题 5. 保持手动新建会话功能不变 Co-Authored-By: Claude Sonnet 4.6 Co-authored-by: multica-agent --- web/src/app/admin/ai-chat/page.tsx | 124 +++++++++++++++++++++++------ 1 file changed, 99 insertions(+), 25 deletions(-) diff --git a/web/src/app/admin/ai-chat/page.tsx b/web/src/app/admin/ai-chat/page.tsx index 3e640d6..a9ed66b 100644 --- a/web/src/app/admin/ai-chat/page.tsx +++ b/web/src/app/admin/ai-chat/page.tsx @@ -46,7 +46,6 @@ export default function AiChatPage() { const [streamingMessageId, setStreamingMessageId] = useState(null); const [optimisticMessages, setOptimisticMessages] = useState>({}); const messagesEndRef = useRef(null); - const hasAttemptedAutoCreate = useRef(false); useToastFeedback({ errorMessage: error, @@ -104,11 +103,9 @@ export default function AiChatPage() { queryClient.invalidateQueries({ queryKey: ["ai-chat-conversations"] }); setSelectedConvId(data.id); setSuccess("创建对话成功"); - hasAttemptedAutoCreate.current = false; }, onError: (err: Error) => { setError(`创建对话失败: ${err.message}`); - hasAttemptedAutoCreate.current = false; }, }); @@ -271,13 +268,36 @@ export default function AiChatPage() { }, }); - const handleSendMessage = useCallback(() => { - if (!selectedConvId || !messageInput.trim()) return; - sendMessageMutation.mutate({ - convId: selectedConvId, - content: messageInput.trim(), - }); - }, [selectedConvId, messageInput, sendMessageMutation]); + const handleSendMessage = useCallback(async () => { + const content = messageInput.trim(); + if (!content) return; + + // If no conversation is selected, create one with a title based on the message + if (!selectedConvId) { + try { + // Generate title from the first message (take first 20 chars or up to first newline) + const title = content.length > 20 + ? content.substring(0, 20) + "..." + : content.split('\n')[0] || "新对话"; + + const newConv = await createConvMutation.mutateAsync(title); + // Send the message to the newly created conversation + sendMessageMutation.mutate({ + convId: newConv.id, + content, + }); + } catch (err) { + // Error already handled by createConvMutation + return; + } + } else { + // Send to existing conversation + sendMessageMutation.mutate({ + convId: selectedConvId, + content, + }); + } + }, [selectedConvId, messageInput, sendMessageMutation, createConvMutation]); useEffect(() => { messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); @@ -290,14 +310,6 @@ export default function AiChatPage() { } }, [convLoading, conversations?.items, selectedConvId, createConvMutation.isPending]); - // Auto-create conversation if none exist (only on initial load, not after deletions) - useEffect(() => { - if (!convLoading && conversations?.items && conversations.items.length === 0 && !hasAttemptedAutoCreate.current && !createConvMutation.isPending) { - hasAttemptedAutoCreate.current = true; - createConvMutation.mutate("新对话"); - } - }, [convLoading, conversations?.items, createConvMutation]); - if (initializing) { return (
@@ -335,7 +347,7 @@ export default function AiChatPage() { ) : conversations?.items.length === 0 ? (
- {createConvMutation.isPending ? "正在创建对话..." : "暂无对话"} + 暂无对话
) : ( @@ -441,12 +453,74 @@ export default function AiChatPage() { }} > {!selectedConvId ? ( -
- -
+ <> + {/* Welcome Area */} +
+
+ + + 欢迎使用 AI 问答助手 + + + {conversations?.items && conversations.items.length > 0 + ? "选择左侧对话继续,或直接输入问题开始新对话" + : "输入您的问题,开始第一个对话"} + +
+ } + image={Empty.PRESENTED_IMAGE_SIMPLE} + /> +
+
+ + {/* Input Area for new conversation */} +
+
+