/** * MessageService * 负责消息的 CRUD 操作 * * 职责: * - 消息的创建、读取、更新、删除 * - 消息状态管理 * - 消息查询和过滤 */ import type { Message, Conversation } from '../../types/chat' import type { CreateMessageOptions, UpdateMessageOptions, MessageQueryResult } from './types' export class MessageService { private conversations: Map constructor(conversations: Map) { this.conversations = conversations } /** * 在指定对话中创建新消息 */ createMessage(conversationId: string, options: CreateMessageOptions): Message { const conversation = this.conversations.get(conversationId) if (!conversation) { throw new Error(`Conversation not found: ${conversationId}`) } const message: Message = { id: this.generateId(), role: options.role, content: options.content, status: options.status || 'success', timestamp: new Date(), model: options.model, tokens: options.tokens } conversation.messages.push(message) conversation.updatedAt = new Date() return message } /** * 获取指定对话的所有消息 */ getMessages(conversationId: string): Message[] { const conversation = this.conversations.get(conversationId) return conversation?.messages || [] } /** * 根据 topicId 获取消息 */ getMessagesByTopicId(topicId: string): Message[] { for (const conv of this.conversations.values()) { if (conv.topicId === topicId) { return conv.messages } } return [] } /** * 获取指定消息 */ getMessage(conversationId: string, messageId: string): Message | undefined { const conversation = this.conversations.get(conversationId) if (!conversation) return undefined return conversation.messages.find(m => m.id === messageId) } /** * 查找消息及其位置信息 */ findMessage(messageId: string, topicId?: string): MessageQueryResult { for (const conv of this.conversations.values()) { if (topicId && conv.topicId !== topicId) continue const index = conv.messages.findIndex(m => m.id === messageId) if (index !== -1) { return { message: conv.messages[index], conversation: conv, index } } } return { message: undefined, conversation: undefined, index: -1 } } /** * 更新消息 */ updateMessage( conversationId: string, messageId: string, options: UpdateMessageOptions ): boolean { const conversation = this.conversations.get(conversationId) if (!conversation) return false const message = conversation.messages.find(m => m.id === messageId) if (!message) return false // 更新消息字段 if (options.content !== undefined) { message.content = options.content } if (options.status !== undefined) { message.status = options.status } if (options.tokens !== undefined) { message.tokens = options.tokens } conversation.updatedAt = new Date() return true } /** * 更新消息状态 */ updateMessageStatus( conversationId: string, messageId: string, status: 'sending' | 'success' | 'error' | 'paused' ): boolean { return this.updateMessage(conversationId, messageId, { status }) } /** * 追加消息内容(用于流式响应) */ appendMessageContent( conversationId: string, messageId: string, content: string ): boolean { const conversation = this.conversations.get(conversationId) if (!conversation) return false const message = conversation.messages.find(m => m.id === messageId) if (!message) return false message.content += content conversation.updatedAt = new Date() return true } /** * 删除消息 */ deleteMessage(conversationId: string, messageId: string): boolean { const conversation = this.conversations.get(conversationId) if (!conversation) return false const index = conversation.messages.findIndex(m => m.id === messageId) if (index === -1) return false conversation.messages.splice(index, 1) conversation.updatedAt = new Date() return true } /** * 删除指定消息之后的所有消息(包括该消息) */ deleteMessagesAfter(conversationId: string, messageId: string): boolean { const conversation = this.conversations.get(conversationId) if (!conversation) return false const index = conversation.messages.findIndex(m => m.id === messageId) if (index === -1) return false conversation.messages.splice(index) conversation.updatedAt = new Date() return true } /** * 获取对话中最后一条用户消息 */ getLastUserMessage(conversationId: string): Message | undefined { const conversation = this.conversations.get(conversationId) if (!conversation) return undefined for (let i = conversation.messages.length - 1; i >= 0; i--) { if (conversation.messages[i].role === 'user') { return conversation.messages[i] } } return undefined } /** * 获取对话中最后一条消息 */ getLastMessage(conversationId: string): Message | undefined { const conversation = this.conversations.get(conversationId) if (!conversation) return undefined const messages = conversation.messages return messages.length > 0 ? messages[messages.length - 1] : undefined } /** * 获取消息预览文本 */ getMessagePreview(content: string, maxLength = 50): string { if (!content) return '' const text = content.replace(/\n/g, ' ').trim() return text.length > maxLength ? text.slice(0, maxLength) + '...' : text } /** * 获取对话中成功的消息(用于发送给 LLM) */ getSuccessMessages(conversationId: string): Message[] { const conversation = this.conversations.get(conversationId) if (!conversation) return [] return conversation.messages.filter(m => m.status === 'success' || m.status === 'paused' ) } /** * 获取最近的 N 条成功消息 */ getRecentSuccessMessages(conversationId: string, limit: number): Message[] { const successMessages = this.getSuccessMessages(conversationId) return successMessages.slice(-limit) } /** * 生成唯一 ID */ private generateId(): string { return `${Date.now()}_${Math.random().toString(36).substr(2, 9)}` } }