From 4e2c3b15a8329a35a2418a76c09799180b975419 Mon Sep 17 00:00:00 2001 From: Jolie <412895109@qq.com> Date: Thu, 1 Jan 2026 00:59:38 +0800 Subject: [PATCH] =?UTF-8?q?feat(call):=20=E6=B7=BB=E5=8A=A0=E9=80=9A?= =?UTF-8?q?=E8=AF=9D=E7=8A=B6=E6=80=81=E7=BB=93=E6=9D=9F=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=E9=80=9A=E8=AF=9D=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 terminated 通话状态类型 - 在通话消息中添加日志记录功能 - 实现通话消息状态变更时的实时更新机制 - 支持通过 channelId 匹配通话消息进行更新 - 优化消息属性初始化逻辑 - 添加通话消息错误处理和日志记录 --- lib/im/im_manager.dart | 143 +++++++++++++++++++++++++++++- lib/widget/message/call_item.dart | 8 +- 2 files changed, 147 insertions(+), 4 deletions(-) diff --git a/lib/im/im_manager.dart b/lib/im/im_manager.dart index 197c4fe..4f895dd 100644 --- a/lib/im/im_manager.dart +++ b/lib/im/im_manager.dart @@ -249,6 +249,145 @@ class IMManager { Get.log('📨 [IMManager] 消息内容已修改: ${message.localTime}'); } + // 检查是否是通话消息 + bool isCallMessage = false; + try { + if (message.body.type == MessageType.CUSTOM) { + final customBody = message.body as EMCustomMessageBody; + isCallMessage = customBody.event == 'call'; + } + } catch (e) { + // 解析失败,不是通话消息 + } + + // 如果是通话消息,更新 CallItem 显示 + if (isCallMessage) { + try { + if (Get.isLogEnable) { + Get.log('📞 [IMManager] 检测到通话消息内容修改: msgId=${message.msgId}'); + } + + String? userId; + + // 根据消息方向确定对应的 userId + if (message.direction == MessageDirection.RECEIVE) { + // 接收到的消息,使用发送者ID + userId = message.from; + } else if (message.direction == MessageDirection.SEND) { + // 发送的消息,使用接收者ID + userId = message.to; + } + + if (Get.isLogEnable) { + Get.log('📞 [IMManager] 通话消息方向: ${message.direction}, userId: $userId'); + } + + // 找到对应的 ChatController 并更新消息 + if (userId != null && userId.isNotEmpty) { + final controller = _activeChatControllers[userId]; + if (controller != null) { + // 更新消息列表中的消息 + var index = controller.messages.indexWhere((msg) => msg.msgId == message.msgId); + if (index != -1) { + if (Get.isLogEnable) { + final oldMessage = controller.messages[index]; + final customBody = oldMessage.body as EMCustomMessageBody; + Get.log('📞 [IMManager] 找到通话消息,index=$index, 旧状态: ${customBody.params?['callStatus']}, 新状态: ${(message.body as EMCustomMessageBody).params?['callStatus']}'); + } + + // 更新消息对象 + controller.messages[index] = message; + // 强制刷新 RxList,确保 UI 更新 + controller.messages.refresh(); + // 调用 update() 触发 GetBuilder 重建 + controller.update(); + + if (Get.isLogEnable) { + Get.log('✅ [IMManager] 已更新通话消息: msgId=${message.msgId}, userId=$userId, index=$index'); + } else { + print('✅ [IMManager] 已更新通话消息: msgId=${message.msgId}, userId=$userId, index=$index'); + } + } else { + // 如果找不到消息,尝试通过通话消息的特征来匹配(通过channelId和时间戳) + if (Get.isLogEnable) { + Get.log('⚠️ [IMManager] 未找到通话消息(通过msgId),尝试其他匹配方式: msgId=${message.msgId}, userId=$userId'); + } + + // 尝试通过通话消息的特征来匹配(通过channelId) + final customBody = message.body as EMCustomMessageBody; + final channelId = customBody.params?['channelId']; + + if (channelId != null && channelId.isNotEmpty) { + // 尝试通过channelId和时间戳匹配 + final matchedIndex = controller.messages.indexWhere((msg) { + if (msg.body.type == MessageType.CUSTOM) { + final msgBody = msg.body as EMCustomMessageBody; + if (msgBody.event == 'call' && msgBody.params != null) { + final msgChannelId = msgBody.params?['channelId']; + // 匹配相同的channelId和相似的时间戳(允许一定误差) + if (msgChannelId == channelId) { + // 检查时间戳是否接近(允许5秒误差) + final timeDiff = (message.serverTime - msg.serverTime).abs(); + return timeDiff < 5000; + } + } + } + return false; + }); + + if (matchedIndex != -1) { + if (Get.isLogEnable) { + Get.log('📞 [IMManager] 通过channelId匹配到通话消息,index=$matchedIndex'); + } + + // 更新消息对象 + controller.messages[matchedIndex] = message; + controller.messages.refresh(); + controller.update(); + + if (Get.isLogEnable) { + Get.log('✅ [IMManager] 已通过channelId更新通话消息: msgId=${message.msgId}, userId=$userId, index=$matchedIndex'); + } else { + print('✅ [IMManager] 已通过channelId更新通话消息: msgId=${message.msgId}, userId=$userId, index=$matchedIndex'); + } + } else { + // 如果还是找不到,直接添加到列表(可能是新消息) + if (Get.isLogEnable) { + Get.log('⚠️ [IMManager] 无法匹配通话消息,添加到列表: msgId=${message.msgId}'); + } + controller.messages.add(message); + controller.messages.refresh(); + controller.update(); + } + } else { + if (Get.isLogEnable) { + Get.log('⚠️ [IMManager] 通话消息没有channelId,无法匹配: msgId=${message.msgId}'); + } + } + } + } else { + if (Get.isLogEnable) { + Get.log('⚠️ [IMManager] 未找到 ChatController: userId=$userId'); + } else { + print('⚠️ [IMManager] 未找到 ChatController: userId=$userId'); + } + } + } else { + if (Get.isLogEnable) { + Get.log('⚠️ [IMManager] userId 为空,无法更新通话消息'); + } + } + } catch (e, stackTrace) { + if (Get.isLogEnable) { + Get.log('⚠️ [IMManager] 处理通话消息更新失败: $e'); + Get.log('堆栈跟踪: $stackTrace'); + } else { + print('⚠️ [IMManager] 处理通话消息更新失败: $e'); + print('堆栈跟踪: $stackTrace'); + } + } + } + // 处理金币数值:只对接收到的消息处理金币标签 // 从消息 attributes 中的 revenueInfo 获取金币信息并直接显示 // 只处理接收到的消息(自己发送的消息不显示金币标签) @@ -1257,9 +1396,7 @@ class IMManager { // 同时存储发送者和接收者的信息 // 发送者信息:用于接收方在聊天列表显示发送者的头像和昵称 // 接收者信息:用于发送方在聊天列表显示接收者的头像和昵称 - if (message.attributes == null) { - message.attributes = {}; - } + message.attributes ??= {}; // 发送者信息(sender_ 前缀) message.attributes!['sender_userId'] = currentUserId; diff --git a/lib/widget/message/call_item.dart b/lib/widget/message/call_item.dart index 77f1c91..92fa6b9 100644 --- a/lib/widget/message/call_item.dart +++ b/lib/widget/message/call_item.dart @@ -20,6 +20,7 @@ enum CallStatus { missed, // 未接听 cancelled, // 已取消 rejected, // 已拒绝 + terminated } class CallItem extends StatelessWidget { @@ -46,6 +47,7 @@ class CallItem extends StatelessWidget { if (customBody.event == 'call' && customBody.params != null) { // 将 Map 转换为 Map final params = customBody.params!; + Get.log('通话信息: $params'); return { 'callType': params['callType'] ?? 'voice', 'callStatus': params['callStatus'] ?? 'missed', @@ -89,6 +91,8 @@ class CallItem extends StatelessWidget { return CallStatus.cancelled; } else if (statusStr == 'rejected') { return CallStatus.rejected; + } else if (statusStr == 'terminated') { + return CallStatus.terminated; } } return CallStatus.missed; // 默认未接听 @@ -151,7 +155,9 @@ class CallItem extends StatelessWidget { return '已取消'; } else if (callStatus == CallStatus.rejected) { return '已拒绝'; - } else { + } else if(callStatus == CallStatus.terminated){ + return '已结束'; + }else { return callType == CallType.video ? '视频通话' : '语音通话'; } }