From eb453493fc211ef481c79f14f4d1eaa2dfe54eb8 Mon Sep 17 00:00:00 2001 From: wangyunfei <1224056307@qq,com> Date: Wed, 17 Sep 2025 09:29:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=AA=E6=B5=81=E5=BC=8F=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatConversation/ChatConversation.js | 60 +++++++++++++++++-- src/utils/pageConversationStore.js | 17 ++++++ 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/pages/chatConversation/ChatConversation.js b/src/pages/chatConversation/ChatConversation.js index 02e67ee..49bf2b8 100644 --- a/src/pages/chatConversation/ChatConversation.js +++ b/src/pages/chatConversation/ChatConversation.js @@ -47,6 +47,13 @@ function ChatConversation() { const [typingMessage, setTypingMessage] = useState('') const [isTyping, setIsTyping] = useState(false) + + const [streamingContent, setStreamingContent] = useState('') +const [isStreaming, setIsStreaming] = useState(false) +const [currentStreamingMessageId, setCurrentStreamingMessageId] = useState(null) + + + // 流式输出状态 - 已移除 const messagesEndRef = useRef(null) @@ -127,6 +134,36 @@ function ChatConversation() { typeNextWords() } + // 模拟流式效果 + const simulateStreamingEffect = (fullContent, messageId) => { + setIsStreaming(true) + setStreamingContent('') + + let currentIndex = 0 + const chunkSize = 3 // 每次显示3个字符 + const delay = 50 // 50ms间隔,可以调整速度 + + const streamNext = () => { + if (currentIndex < fullContent.length) { + const nextIndex = Math.min(currentIndex + chunkSize, fullContent.length) + const currentContent = fullContent.substring(0, nextIndex) + + setStreamingContent(currentContent) + conversationStore.updateMessage(messageId, currentContent) + + currentIndex = nextIndex + setTimeout(streamNext, delay) + } else { + // 流式效果完成 + setIsStreaming(false) + setStreamingContent('') + setCurrentStreamingMessageId(null) + } + } + + streamNext() + } + // 创建新对话 const createNewConversation = () => { @@ -183,7 +220,7 @@ function ChatConversation() { setLoading(true) try { - // 调用本地后端接口(非流式版本) + // 调用本地后端接口 const result = await callLocalChatAPI(messageText) console.log('API result:', result) @@ -200,9 +237,12 @@ function ChatConversation() { console.log('Final content:', finalContent) if (finalContent.trim()) { - // 暂时直接添加消息,不使用打字机效果 - console.log('Adding message directly:', finalContent) - conversationStore.addMessage('assistant', finalContent) + // 先添加一个空的助手消息 + const assistantMessageId = conversationStore.addMessage('assistant', '') + setCurrentStreamingMessageId(assistantMessageId) + + // 开始模拟流式效果 + simulateStreamingEffect(finalContent, assistantMessageId) } else { console.log('No content, adding fallback message') conversationStore.addMessage('assistant', '抱歉,我无法生成回复内容。') @@ -270,14 +310,22 @@ function ChatConversation() { // 渲染单条消息 ================================== const renderMessage = (msg, index) => { const isUser = msg.role === 'user' - const displayContent = msg.content || '' + + // 如果是当前正在流式输出的消息,显示流式内容 + const isCurrentStreaming = isStreaming && + currentStreamingMessageId === msg.id && + msg.role === 'assistant' + + const displayContent = isCurrentStreaming ? streamingContent : (msg.content || '') // 调试信息 if (msg.role === 'assistant') { console.log('Rendering assistant message:', { index, content: msg.content, - displayContent + displayContent, + isCurrentStreaming, + streamingContent }) } diff --git a/src/utils/pageConversationStore.js b/src/utils/pageConversationStore.js index f7a58f2..ff511df 100644 --- a/src/utils/pageConversationStore.js +++ b/src/utils/pageConversationStore.js @@ -102,6 +102,7 @@ class PageConversationStore { const currentConversation = this.getCurrentConversation() if (currentConversation) { const newMessage = { + id: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, role, content, timestamp: new Date() @@ -118,6 +119,22 @@ class PageConversationStore { this.saveToStorage() this.notifySubscribers() + return newMessage.id + } + return null + } + + // 更新指定消息的内容 + updateMessage(messageId, newContent) { + const currentConversation = this.getCurrentConversation() + if (currentConversation) { + const message = currentConversation.messages.find(msg => msg.id === messageId) + if (message) { + message.content = newContent + currentConversation.lastUpdate = new Date() + this.saveToStorage() + this.notifySubscribers() + } } }