const Conversation = require('../models/Conversation'); const Message = require('../models/Message'); const cacheManager = require('../utils/cache'); class ConversationService { constructor() { this.cachePrefix = 'conv_service'; } /** * 创建新对话 */ async createConversation(title = '新对话') { try { const conversation = await Conversation.create(title); // 清除对话列表缓存 this.clearConversationListCache(); console.log('创建新对话:', conversation.id); return conversation; } catch (error) { console.error('ConversationService.createConversation错误:', error); throw new Error('创建对话失败'); } } /** * 获取对话列表 */ async getConversations(limit = 50) { try { const cacheKey = `${this.cachePrefix}:list:${limit}`; // 尝试从缓存获取 let conversations = cacheManager.get(cacheKey); if (conversations) { console.log('从缓存获取对话列表'); return conversations; } // 从数据库获取 conversations = await Conversation.findAll(limit); // 缓存结果(5分钟) cacheManager.set(cacheKey, conversations, { ttl: 300000 }); console.log(`获取对话列表: ${conversations.length}条`); return conversations; } catch (error) { console.error('ConversationService.getConversations错误:', error); throw new Error('获取对话列表失败'); } } /** * 根据ID获取对话详情 */ async getConversationById(id) { try { if (!id || isNaN(id)) { throw new Error('无效的对话ID'); } const cacheKey = `${this.cachePrefix}:detail:${id}`; // 尝试从缓存获取 let conversation = cacheManager.get(cacheKey); if (conversation) { console.log(`从缓存获取对话详情: ${id}`); return conversation; } // 从数据库获取 conversation = await Conversation.findById(id); if (!conversation) { throw new Error('对话不存在'); } // 缓存结果(10分钟) cacheManager.set(cacheKey, conversation, { ttl: 600000 }); console.log(`获取对话详情: ${id}`); return conversation; } catch (error) { console.error('ConversationService.getConversationById错误:', error); throw error; } } /** * 获取对话的消息列表 */ async getConversationMessages(conversationId, limit = 100, offset = 0) { try { if (!conversationId || isNaN(conversationId)) { throw new Error('无效的对话ID'); } // 确保对话存在 const conversation = await this.getConversationById(conversationId); if (!conversation) { throw new Error('对话不存在'); } const cacheKey = `${this.cachePrefix}:messages:${conversationId}:${limit}:${offset}`; // 尝试从缓存获取 let messages = cacheManager.get(cacheKey); if (messages) { console.log(`从缓存获取对话消息: ${conversationId}`); return messages; } // 从数据库获取 messages = await Message.findByConversationId(conversationId, limit, offset); // 缓存结果(5分钟) cacheManager.set(cacheKey, messages, { ttl: 300000 }); console.log(`获取对话消息: ${conversationId}, ${messages.length}条`); return messages; } catch (error) { console.error('ConversationService.getConversationMessages错误:', error); throw error; } } /** * 更新对话标题 */ async updateConversationTitle(id, title) { try { if (!id || isNaN(id)) { throw new Error('无效的对话ID'); } if (!title || title.trim().length === 0) { throw new Error('标题不能为空'); } const conversation = await Conversation.updateTitle(id, title.trim()); // 清除相关缓存 this.clearConversationCache(id); this.clearConversationListCache(); console.log(`更新对话标题: ${id} -> ${title}`); return conversation; } catch (error) { console.error('ConversationService.updateConversationTitle错误:', error); throw error; } } /** * 删除对话 */ async deleteConversation(id) { try { if (!id || isNaN(id)) { throw new Error('无效的对话ID'); } // 确保对话存在 const conversation = await this.getConversationById(id); if (!conversation) { throw new Error('对话不存在'); } await Conversation.delete(id); // 清除相关缓存 this.clearConversationCache(id); this.clearConversationListCache(); cacheManager.deleteConversationContext(id); console.log(`删除对话: ${id}`); return true; } catch (error) { console.error('ConversationService.deleteConversation错误:', error); throw error; } } /** * 批量删除对话 */ async deleteMultipleConversations(ids) { try { if (!Array.isArray(ids) || ids.length === 0) { throw new Error('无效的对话ID列表'); } // 验证所有ID const validIds = ids.filter(id => id && !isNaN(id)); if (validIds.length === 0) { throw new Error('没有有效的对话ID'); } const deletedCount = await Conversation.deleteMultiple(validIds); // 清除相关缓存 validIds.forEach(id => { this.clearConversationCache(id); cacheManager.deleteConversationContext(id); }); this.clearConversationListCache(); console.log(`批量删除对话: ${deletedCount}条`); return deletedCount; } catch (error) { console.error('ConversationService.deleteMultipleConversations错误:', error); throw error; } } /** * 获取对话统计信息 */ async getConversationStats(conversationId) { try { if (!conversationId || isNaN(conversationId)) { throw new Error('无效的对话ID'); } const conversation = await this.getConversationById(conversationId); if (!conversation) { throw new Error('对话不存在'); } const messageCount = await Message.getMessageCount(conversationId); return { id: conversation.id, title: conversation.title, created_at: conversation.created_at, updated_at: conversation.updated_at, message_count: messageCount }; } catch (error) { console.error('ConversationService.getConversationStats错误:', error); throw error; } } /** * 搜索对话 */ async searchConversations(query, limit = 20) { try { if (!query || query.trim().length === 0) { throw new Error('搜索关键词不能为空'); } // 搜索消息内容 const messages = await Message.search(query.trim(), null, limit); // 提取关联的对话ID const conversationIds = [...new Set(messages.map(msg => msg.conversation_id))]; // 获取对话详情 const conversations = await Promise.all( conversationIds.map(id => this.getConversationById(id)) ); // 过滤掉不存在的对话 const validConversations = conversations.filter(conv => conv !== null); console.log(`搜索对话: "${query}" -> ${validConversations.length}条结果`); return validConversations; } catch (error) { console.error('ConversationService.searchConversations错误:', error); throw error; } } /** * 自动生成对话标题(基于第一条用户消息) */ async generateConversationTitle(conversationId) { try { const messages = await Message.findByConversationId(conversationId, 5); // 找到第一条用户消息 const firstUserMessage = messages.find(msg => msg.role === 'user'); if (!firstUserMessage) { return '新对话'; } // 从第一条用户消息生成标题(取前20个字符) let title = firstUserMessage.content.trim(); if (title.length > 20) { title = title.substring(0, 20) + '...'; } // 更新对话标题 await this.updateConversationTitle(conversationId, title); console.log(`自动生成对话标题: ${conversationId} -> ${title}`); return title; } catch (error) { console.error('ConversationService.generateConversationTitle错误:', error); return '新对话'; } } /** * 清除对话详情缓存 */ clearConversationCache(conversationId) { const detailKey = `${this.cachePrefix}:detail:${conversationId}`; cacheManager.delete(detailKey); // 清除消息缓存(可能有多个分页) for (let i = 0; i < 10; i++) { const messageKey = `${this.cachePrefix}:messages:${conversationId}:100:${i * 100}`; cacheManager.delete(messageKey); } } /** * 清除对话列表缓存 */ clearConversationListCache() { // 清除不同分页的列表缓存 for (let limit = 10; limit <= 100; limit += 10) { const listKey = `${this.cachePrefix}:list:${limit}`; cacheManager.delete(listKey); } } /** * 更新对话活动时间 */ async updateLastActivity(conversationId) { try { await Conversation.updateLastActivity(conversationId); // 清除相关缓存 this.clearConversationCache(conversationId); this.clearConversationListCache(); } catch (error) { console.error('ConversationService.updateLastActivity错误:', error); // 这是一个辅助操作,失败不应该影响主流程 } } } module.exports = ConversationService;