/** * 消息发送服务 * 处理消息发送相关逻辑 */ import type { MessageResponse, MessageSegment, ConversationResponse } from '../../types/dto'; import { messageService } from '../../services/messageService'; import { saveMessage } from '../../services/database'; import type { IMessageSendService, IMessageStateManager } from './types'; export class MessageSendService implements IMessageSendService { private stateManager: IMessageStateManager; private getCurrentUserId: () => string | null; constructor(stateManager: IMessageStateManager, getCurrentUserId: () => string | null) { this.stateManager = stateManager; this.getCurrentUserId = getCurrentUserId; } /** * 发送消息 */ async sendMessage( conversationId: string, segments: MessageSegment[], options?: { replyToId?: string } ): Promise { try { // 调用API发送 const response = await messageService.sendMessage(conversationId, { segments, reply_to_id: options?.replyToId, }); if (response) { const currentUserId = this.getCurrentUserId(); // 添加到本地消息列表 const existingMessages = this.stateManager.getMessages(conversationId); const newMessage: MessageResponse = { id: response.id, conversation_id: conversationId, sender_id: currentUserId || '', seq: response.seq, segments, created_at: new Date().toISOString(), status: 'normal', }; const updatedMessages = this.mergeMessagesById(existingMessages, [newMessage]); this.stateManager.setMessages(conversationId, updatedMessages); // 关键:立即广播消息列表更新 this.stateManager.notifySubscribers({ type: 'messages_updated', payload: { conversationId, messages: updatedMessages, newMessage, source: 'send', }, timestamp: Date.now(), }); // 更新会话最后消息 this.updateConversationWithNewMessage(conversationId, newMessage); // 通知消息已发送 this.stateManager.notifySubscribers({ type: 'message_sent', payload: { conversationId, message: newMessage }, timestamp: Date.now(), }); // 保存到本地数据库 const textContent = segments ?.filter((s: any) => s.type === 'text') .map((s: any) => s.data?.text || '') .join('') || ''; saveMessage({ id: response.id, conversationId, senderId: currentUserId || '', content: textContent, type: segments?.find((s: any) => s.type === 'image') ? 'image' : 'text', isRead: true, createdAt: newMessage.created_at, seq: response.seq, status: 'normal', segments, }).catch(console.error); return newMessage; } return null; } catch (error) { console.error('[MessageSendService] 发送消息失败:', error); this.stateManager.notifySubscribers({ type: 'error', payload: { error, context: 'sendMessage' }, timestamp: Date.now(), }); return null; } } /** * 更新会话的最后消息信息 */ private updateConversationWithNewMessage( conversationId: string, message: MessageResponse ): void { const conversation = this.stateManager.getConversation(conversationId); const createdAt = message.created_at || new Date().toISOString(); if (conversation) { // 更新现有会话 const updatedConv: ConversationResponse = { ...conversation, last_seq: message.seq, last_message: message, last_message_at: createdAt, updated_at: createdAt, }; this.stateManager.updateConversation(updatedConv); } } /** * 按 message_id 合并消息并按 seq 排序 */ private mergeMessagesById(base: MessageResponse[], incoming: MessageResponse[]): MessageResponse[] { if (incoming.length === 0) return base; const merged = new Map(); [...base, ...incoming].forEach(msg => { merged.set(String(msg.id), msg); }); return Array.from(merged.values()).sort((a, b) => a.seq - b.seq); } }