refactor(AI): 优化打字机效果和流式回答处理

- 调整打字速度为 30 毫秒/字
- 修复流式回答中思考状态的判断逻辑
- 优化打字机效果,支持整块文本的逐字输出
- 调整代码结构,提高可读性和可维护性
This commit is contained in:
陈昱达
2025-06-18 17:48:52 +08:00
parent f6e60df2d3
commit ac240892dd

View File

@@ -106,8 +106,9 @@ export default {
// 打字机相关 // 打字机相关
typingText: '', typingText: '',
typingQueue: [], typingQueue: [],
typingQueueText: [],
isTyping: false, isTyping: false,
typingSpeed: 50, typingSpeed: 30,
typingTimeout: null, typingTimeout: null,
} }
}, },
@@ -269,8 +270,8 @@ export default {
if (data.answer) { if (data.answer) {
this.answerMap += data.answer this.answerMap += data.answer
} }
this.updateConversationState(data)
return data return this.updateConversationState(data)
} catch (error) { } catch (error) {
console.error('流数据解析失败:', error) console.error('流数据解析失败:', error)
return null return null
@@ -279,27 +280,42 @@ export default {
updateConversationState(data) { updateConversationState(data) {
this.$emit('update:conversationId', data.conversation_id || '') this.$emit('update:conversationId', data.conversation_id || '')
if (data.answer && data.answer.indexOf('<think>') !== -1) { if (data.answer && data.answer.indexOf('<think>') !== -1) {
data.isThink = true
this.isThink = true this.isThink = true
this.$emit('getIsThink', true) this.$emit('getIsThink', true)
} }
if (data.answer && data.answer.indexOf('</think>') !== -1) { if (data.answer && data.answer.indexOf('</think>') !== -1) {
data.isThink = true
this.isThink = false this.isThink = false
this.$emit('getIsThink', 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') { if (event === 'message_end') {
this.$emit('update:messageStatus', 'stop') this.$emit('update:messageStatus', 'stop')
} }
if (!this.currentMessage || !answer) return if (!this.currentMessage || !answer) return
const mode = this.isThink ? 'think' : 'text' const mode = isThink ? 'think' : 'text'
const chars = answer.split('') const chars = {
this.typingQueue.push(...chars) answer: answer,
isThink: isThink,
}
this.typingQueue.push(chars)
if (!this.isTyping) { if (!this.isTyping) {
this.startTypingAnimation(mode) this.startTypingAnimation(mode)
} }
}, },
startTypingAnimation(mode) { startTypingAnimation() {
this.isTyping = true this.isTyping = true
const typeNextChar = () => { const typeNextChar = () => {
@@ -308,10 +324,24 @@ export default {
return 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() typeNextChar()