AI对话bug修复
This commit is contained in:
+70
-19
@@ -59,6 +59,9 @@ export const useChatStore = defineStore('chat', () => {
|
||||
)
|
||||
})
|
||||
|
||||
// 已处理的消息ID集合 - 用于防止重复处理
|
||||
const processedMessageIds = ref<Set<string>>(new Set())
|
||||
|
||||
// 处理消息队列 - 批量处理消息以避免竞态条件
|
||||
const processMessageQueue = async () => {
|
||||
if (isProcessingQueue.value || messageQueue.value.length === 0) {
|
||||
@@ -70,11 +73,24 @@ export const useChatStore = defineStore('chat', () => {
|
||||
// 一次性取出所有待处理消息
|
||||
const batch = messageQueue.value.splice(0, messageQueue.value.length)
|
||||
|
||||
// 批量添加消息到数组
|
||||
const newMessages = batch.map(item => item.message)
|
||||
messages.value.push(...newMessages)
|
||||
// 过滤掉已存在的消息(基于ID去重)
|
||||
const newMessages = batch
|
||||
.map(item => item.message)
|
||||
.filter(msg => {
|
||||
// 检查是否已存在于当前消息列表中
|
||||
const exists = messages.value.some(m => m.id === msg.id)
|
||||
if (exists) {
|
||||
console.log(`⚠️ 消息已存在,跳过: ${msg.id}`)
|
||||
}
|
||||
return !exists
|
||||
})
|
||||
|
||||
console.log(`✅ 消息队列处理完成,添加了 ${newMessages.length} 条消息,当前总数: ${messages.value.length}`)
|
||||
if (newMessages.length > 0) {
|
||||
messages.value.push(...newMessages)
|
||||
console.log(`✅ 消息队列处理完成,添加了 ${newMessages.length} 条消息,当前总数: ${messages.value.length}`)
|
||||
} else {
|
||||
console.log(`⏭️ 队列中的消息都已存在,无需添加`)
|
||||
}
|
||||
} finally {
|
||||
isProcessingQueue.value = false
|
||||
}
|
||||
@@ -82,6 +98,15 @@ export const useChatStore = defineStore('chat', () => {
|
||||
|
||||
// 将消息加入队列而不是直接添加
|
||||
const queueMessage = (message: ChatMessage) => {
|
||||
// 先检查是否已处理过该消息ID
|
||||
if (processedMessageIds.value.has(message.id)) {
|
||||
console.log(`⚠️ 消息已处理过,跳过队列: ${message.id}`)
|
||||
return
|
||||
}
|
||||
|
||||
// 标记消息ID为已处理
|
||||
processedMessageIds.value.add(message.id)
|
||||
|
||||
messageQueue.value.push({
|
||||
message,
|
||||
timestamp: Date.now()
|
||||
@@ -90,11 +115,11 @@ export const useChatStore = defineStore('chat', () => {
|
||||
}
|
||||
|
||||
// 添加消息 - 现在返回消息但不直接添加到数组
|
||||
const addMessage = (message: Omit<ChatMessage, 'id' | 'timestamp'>) => {
|
||||
const addMessage = (message: Omit<ChatMessage, 'id' | 'timestamp'> & { id?: string, timestamp?: string }) => {
|
||||
const newMessage: ChatMessage = {
|
||||
...message,
|
||||
id: Date.now().toString(),
|
||||
timestamp: new Date().toISOString(),
|
||||
id: message.id || Date.now().toString(), // 优先使用传入的ID
|
||||
timestamp: message.timestamp || new Date().toISOString(), // 优先使用传入的时间戳
|
||||
status: message.type === 'user' ? 'sending' : 'sent'
|
||||
}
|
||||
// 将消息加入队列而不是直接添加
|
||||
@@ -228,12 +253,17 @@ export const useChatStore = defineStore('chat', () => {
|
||||
// 如果需要过滤特定会话的消息,可以在这里添加过滤逻辑
|
||||
// const sessionMessages = sortedMessages.filter(msg => msg.sessionId === sessionId)
|
||||
|
||||
// 清空并重新设置已处理消息ID集合
|
||||
processedMessageIds.value.clear()
|
||||
sortedMessages.forEach(msg => processedMessageIds.value.add(msg.id))
|
||||
|
||||
messages.value = sortedMessages
|
||||
console.log('📨 会话消息加载完成,消息数量:', messages.value.length)
|
||||
console.log('📨 会话消息加载完成,消息数量:', messages.value.length, '已处理ID数量:', processedMessageIds.value.size)
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 加载会话消息失败:', error)
|
||||
messages.value = []
|
||||
processedMessageIds.value.clear()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,6 +291,9 @@ export const useChatStore = defineStore('chat', () => {
|
||||
// 清空消息
|
||||
const clearMessages = () => {
|
||||
messages.value = []
|
||||
// 同时清空已处理消息ID集合,避免后续加载时被错误过滤
|
||||
processedMessageIds.value.clear()
|
||||
console.log('✅ 消息和已处理ID集合已清空')
|
||||
}
|
||||
|
||||
// 搜索消息:支持本地搜索和远程搜索
|
||||
@@ -390,31 +423,47 @@ export const useChatStore = defineStore('chat', () => {
|
||||
// 使用优化的排序和去重方法
|
||||
const sortedMessages = MessageService.sortAndDeduplicateMessages(chatMessages)
|
||||
|
||||
// 清空并重新设置已处理消息ID集合
|
||||
processedMessageIds.value.clear()
|
||||
sortedMessages.forEach(msg => processedMessageIds.value.add(msg.id))
|
||||
|
||||
// 直接设置消息数组(初始加载时不使用队列)
|
||||
messages.value = sortedMessages
|
||||
console.log('📝 最近消息已加载并排序,消息总数:', messages.value.length)
|
||||
console.log('📝 最近消息已加载并排序,消息总数:', messages.value.length, '已处理ID数量:', processedMessageIds.value.size)
|
||||
|
||||
return chatMessages
|
||||
} catch (error) {
|
||||
console.error('❌ 加载最近消息失败:', error)
|
||||
messages.value = []
|
||||
processedMessageIds.value.clear()
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// 添加AI回复消息(使用队列处理)
|
||||
const addAiReplyMessages = async (content: string) => {
|
||||
const addAiReplyMessages = async (wsMessage: WebSocketMessage) => {
|
||||
// 停止输入状态
|
||||
isTyping.value = false
|
||||
|
||||
// 添加AI消息到队列
|
||||
// 使用后端提供的messageId,确保去重能正常工作
|
||||
const messageId = wsMessage.messageId || Date.now().toString()
|
||||
|
||||
// 检查是否已处理过该消息(基于后端messageId去重)
|
||||
if (processedMessageIds.value.has(messageId)) {
|
||||
console.log(`⚠️ AI消息已处理过,跳过: ${messageId}`)
|
||||
return
|
||||
}
|
||||
|
||||
// 添加AI消息到队列,使用后端的messageId
|
||||
const aiMessage = addMessage({
|
||||
content: content.trim(),
|
||||
id: messageId,
|
||||
content: wsMessage.content.trim(),
|
||||
type: 'ai',
|
||||
conversationId: currentSession.value?.id
|
||||
conversationId: wsMessage.conversationId || currentSession.value?.id,
|
||||
timestamp: wsMessage.createTime || new Date().toISOString()
|
||||
})
|
||||
|
||||
console.log('✅ AI消息已加入队列,消息ID:', aiMessage.id)
|
||||
console.log('✅ AI消息已加入队列,消息ID:', aiMessage.id, '(后端ID:', wsMessage.messageId, ')')
|
||||
|
||||
// 立即处理队列
|
||||
await processMessageQueue()
|
||||
@@ -422,13 +471,13 @@ export const useChatStore = defineStore('chat', () => {
|
||||
|
||||
// WebSocket消息处理 - 使用队列处理所有消息
|
||||
let handleWebSocketMessage = async (wsMessage: WebSocketMessage) => {
|
||||
console.log('收到WebSocket消息:', wsMessage.type, wsMessage.senderType)
|
||||
console.log('收到WebSocket消息:', wsMessage.type, wsMessage.senderType, '消息ID:', wsMessage.messageId)
|
||||
|
||||
switch (wsMessage.type) {
|
||||
case 'TEXT':
|
||||
if (wsMessage.senderType === 'AI') {
|
||||
// AI回复消息 - 加入队列处理
|
||||
await addAiReplyMessages(wsMessage.content)
|
||||
// AI回复消息 - 传递完整的wsMessage以获取后端messageId
|
||||
await addAiReplyMessages(wsMessage)
|
||||
}
|
||||
break
|
||||
|
||||
@@ -443,8 +492,9 @@ export const useChatStore = defineStore('chat', () => {
|
||||
break
|
||||
|
||||
case 'ERROR':
|
||||
// 错误消息 - 加入队列处理
|
||||
// 错误消息 - 加入队列处理,使用后端messageId
|
||||
addMessage({
|
||||
id: wsMessage.messageId || Date.now().toString(),
|
||||
content: wsMessage.content,
|
||||
type: 'ai',
|
||||
sessionId: currentSession.value?.id
|
||||
@@ -453,8 +503,9 @@ export const useChatStore = defineStore('chat', () => {
|
||||
break
|
||||
|
||||
case 'SYSTEM':
|
||||
// 系统消息 - 加入队列处理
|
||||
// 系统消息 - 加入队列处理,使用后端messageId
|
||||
addMessage({
|
||||
id: wsMessage.messageId || Date.now().toString(),
|
||||
content: wsMessage.content,
|
||||
type: 'ai',
|
||||
sessionId: currentSession.value?.id
|
||||
|
||||
Reference in New Issue
Block a user