diff --git a/src/views/AI/components/chat.vue b/src/views/AI/components/chat.vue index fed0555..2eb54e6 100644 --- a/src/views/AI/components/chat.vue +++ b/src/views/AI/components/chat.vue @@ -106,8 +106,9 @@ export default { // 打字机相关 typingText: '', typingQueue: [], + typingQueueText: [], isTyping: false, - typingSpeed: 50, + typingSpeed: 30, typingTimeout: null, } }, @@ -269,8 +270,8 @@ export default { if (data.answer) { this.answerMap += data.answer } - this.updateConversationState(data) - return data + + return this.updateConversationState(data) } catch (error) { console.error('流数据解析失败:', error) return null @@ -279,27 +280,42 @@ export default { updateConversationState(data) { this.$emit('update:conversationId', data.conversation_id || '') if (data.answer && data.answer.indexOf('') !== -1) { + data.isThink = true this.isThink = true this.$emit('getIsThink', true) } if (data.answer && data.answer.indexOf('') !== -1) { + data.isThink = true this.isThink = false this.$emit('getIsThink', false) } + if (data.answer && this.isThink) { + data.isThink = true + } + if (data.answer && !this.isThink) { + data.isThink = false + } + + return data }, - updateMessageContent({ answer, event }) { + updateMessageContent(parse) { + let { event, answer, isThink } = parse if (event === 'message_end') { this.$emit('update:messageStatus', 'stop') } if (!this.currentMessage || !answer) return - const mode = this.isThink ? 'think' : 'text' - const chars = answer.split('') - this.typingQueue.push(...chars) + const mode = isThink ? 'think' : 'text' + const chars = { + answer: answer, + isThink: isThink, + } + + this.typingQueue.push(chars) if (!this.isTyping) { this.startTypingAnimation(mode) } }, - startTypingAnimation(mode) { + startTypingAnimation() { this.isTyping = true const typeNextChar = () => { @@ -308,10 +324,24 @@ export default { return } - const char = this.typingQueue.shift() - this.currentMessage[mode] += char + // 取出一个完整文本块 + const chunk = this.typingQueue.shift() + const chars = chunk.answer.split('') + const isThink = chunk.isThink + // 内部递归函数,用于逐字输出当前块 + const outputChar = () => { + if (chars.length === 0) { + // 当前块输出完毕,继续处理下一个 + setTimeout(typeNextChar, 10) + return + } + const char = chars.shift() + this.currentMessage[isThink ? 'think' : 'text'] += char + const delay = this.getTypingDelay(char) + setTimeout(outputChar, delay) + } - this.typingTimeout = setTimeout(typeNextChar, this.getTypingDelay(char)) + outputChar() } typeNextChar()