/** * 聊天消息处理器 * 专门处理WebSocket接收到的聊天相关消息 */ class ChatMessageHandler { constructor() { this.messageListeners = new Map(); this.statusListeners = new Map(); this.conversationListeners = new Map(); } // 处理WebSocket消息 handleMessage(message) { console.log('🔄 聊天消息处理器收到消息:', message.type); switch (message.type) { case 'new_message': this.handleNewMessage(message.data); break; case 'message_status_update': this.handleMessageStatusUpdate(message.data); break; case 'message_recalled': this.handleMessageRecalled(message.data); break; case 'conversation_update': this.handleConversationUpdate(message.data); break; case 'typing_status': this.handleTypingStatus(message.data); break; case 'read_receipt': this.handleReadReceipt(message.data); break; default: console.log('未处理的聊天消息类型:', message.type); } } // 处理新消息 handleNewMessage(messageData) { console.log('📨 收到新消息:', messageData); // 格式化消息数据 const formattedMessage = this.formatMessage(messageData); // 通知所有监听器 this.notifyMessageListeners('new_message', formattedMessage); // 更新会话信息 this.updateConversationLastMessage(formattedMessage); } // 处理消息状态更新 handleMessageStatusUpdate(statusData) { console.log('📊 消息状态更新:', statusData); this.notifyStatusListeners('status_update', statusData); } // 处理消息撤回 handleMessageRecalled(recallData) { console.log('↩️ 消息被撤回:', recallData); this.notifyMessageListeners('message_recalled', recallData); } // 处理会话更新 handleConversationUpdate(conversationData) { console.log('💬 会话更新:', conversationData); this.notifyConversationListeners('conversation_update', conversationData); } // 处理输入状态 handleTypingStatus(typingData) { console.log('⌨️ 输入状态:', typingData); this.notifyMessageListeners('typing_status', typingData); } // 处理已读回执 handleReadReceipt(readData) { console.log('✅ 已读回执:', readData); this.notifyStatusListeners('read_receipt', readData); } // 格式化消息数据 formatMessage(messageData) { return { messageId: messageData.messageId, senderId: messageData.senderId, receiverId: messageData.receiverId, conversationId: messageData.conversationId || this.generateConversationId(messageData.senderId, messageData.receiverId), chatType: messageData.chatType || 0, msgType: messageData.msgType || 1, content: messageData.content || '', status: messageData.status || 1, sendTime: messageData.sendTime || new Date().toISOString(), senderName: messageData.senderName || '', senderAvatar: messageData.senderAvatar || '', replyTo: messageData.replyTo || '', atUsers: messageData.atUsers || [], extra: messageData.extra || '', // 客户端扩展字段 isOwn: false, // 需要在使用时设置 displayTime: this.formatDisplayTime(messageData.sendTime), contentType: this.getContentType(messageData.msgType), parsedContent: this.parseContent(messageData.content, messageData.msgType) }; } // 生成会话ID generateConversationId(senderId, receiverId) { // 单聊会话ID生成规则:较小的ID在前 const ids = [senderId, receiverId].sort(); return `conv_${ids[0]}_${ids[1]}`; } // 格式化显示时间 formatDisplayTime(timeString) { if (!timeString) return ''; const messageTime = new Date(timeString); const now = new Date(); const diffMs = now - messageTime; const diffMinutes = Math.floor(diffMs / (1000 * 60)); const diffHours = Math.floor(diffMs / (1000 * 60 * 60)); const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); if (diffMinutes < 1) { return '刚刚'; } else if (diffMinutes < 60) { return `${diffMinutes}分钟前`; } else if (diffHours < 24) { return messageTime.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }); } else if (diffDays < 7) { const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; return weekdays[messageTime.getDay()]; } else { return messageTime.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' }); } } // 获取内容类型 getContentType(msgType) { const typeMap = { 1: 'text', 2: 'image', 3: 'voice', 4: 'video', 5: 'file', 6: 'emoji', 7: 'location', 8: 'system', 9: 'recall', 10: 'redpacket' }; return typeMap[msgType] || 'text'; } // 解析消息内容 parseContent(content, msgType) { try { switch (msgType) { case 2: // 图片 return { url: content, type: 'image' }; case 3: // 语音 const voiceData = JSON.parse(content); return { url: voiceData.url, duration: voiceData.duration, type: 'voice' }; case 4: // 视频 const videoData = JSON.parse(content); return { url: videoData.url, duration: videoData.duration, thumbnail: videoData.thumbnail, type: 'video' }; case 5: // 文件 const fileData = JSON.parse(content); return { url: fileData.url, name: fileData.name, size: fileData.size, type: 'file' }; case 7: // 位置 const locationData = JSON.parse(content); return { latitude: locationData.latitude, longitude: locationData.longitude, address: locationData.address, type: 'location' }; default: return { text: content, type: 'text' }; } } catch (error) { console.warn('解析消息内容失败:', error); return { text: content, type: 'text' }; } } // 更新会话最后消息 updateConversationLastMessage(message) { const conversationUpdate = { conversationId: message.conversationId, lastMessage: { content: this.getDisplayContent(message), sendTime: message.sendTime, senderId: message.senderId, senderName: message.senderName }, unreadCount: message.isOwn ? 0 : 1 // 如果是自己发的消息,未读数为0 }; this.notifyConversationListeners('last_message_update', conversationUpdate); } // 获取显示内容 getDisplayContent(message) { switch (message.msgType) { case 1: return message.content; case 2: return '[图片]'; case 3: return '[语音]'; case 4: return '[视频]'; case 5: return '[文件]'; case 6: return '[表情]'; case 7: return '[位置]'; case 8: return message.content; case 9: return '撤回了一条消息'; case 10: return '[红包]'; default: return message.content; } } // 注册消息监听器 onMessage(event, listener) { if (!this.messageListeners.has(event)) { this.messageListeners.set(event, []); } this.messageListeners.get(event).push(listener); } // 注册状态监听器 onStatus(event, listener) { if (!this.statusListeners.has(event)) { this.statusListeners.set(event, []); } this.statusListeners.get(event).push(listener); } // 注册会话监听器 onConversation(event, listener) { if (!this.conversationListeners.has(event)) { this.conversationListeners.set(event, []); } this.conversationListeners.get(event).push(listener); } // 通知消息监听器 notifyMessageListeners(event, data) { const listeners = this.messageListeners.get(event); if (listeners) { listeners.forEach(listener => { try { listener(data); } catch (error) { console.error(`消息监听器错误 [${event}]:`, error); } }); } } // 通知状态监听器 notifyStatusListeners(event, data) { const listeners = this.statusListeners.get(event); if (listeners) { listeners.forEach(listener => { try { listener(data); } catch (error) { console.error(`状态监听器错误 [${event}]:`, error); } }); } } // 通知会话监听器 notifyConversationListeners(event, data) { const listeners = this.conversationListeners.get(event); if (listeners) { listeners.forEach(listener => { try { listener(data); } catch (error) { console.error(`会话监听器错误 [${event}]:`, error); } }); } } // 清理监听器 removeAllListeners() { this.messageListeners.clear(); this.statusListeners.clear(); this.conversationListeners.clear(); } } // 创建全局实例 const chatMessageHandler = new ChatMessageHandler(); module.exports = chatMessageHandler;