From b6e2d5b8de42fbd574a465f2589025c3437247f8 Mon Sep 17 00:00:00 2001 From: Jolie <412895109@qq.com> Date: Tue, 30 Dec 2025 22:40:08 +0800 Subject: [PATCH] =?UTF-8?q?feat(call):=20=E5=AE=9E=E7=8E=B0=E9=80=9A?= =?UTF-8?q?=E8=AF=9D=E6=8B=92=E7=BB=9D=E5=8A=9F=E8=83=BD=E5=92=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=B6=88=E6=81=AF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 _handleRtmMessage 方法改为异步方法以支持异步操作 - 添加对 reject 消息的处理逻辑,包括取消频道订阅和关闭通话界面 - 实现拒绝通话时调用RTC接口并发送拒绝消息到RTM频道 - 优化 channelId 验证逻辑,避免空值导致的错误 - 添加通话拒绝时的音频停止和会话清理功能 --- lib/controller/message/call_controller.dart | 69 +++++++++++++++++++-- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/lib/controller/message/call_controller.dart b/lib/controller/message/call_controller.dart index bea6c70..fd5c727 100644 --- a/lib/controller/message/call_controller.dart +++ b/lib/controller/message/call_controller.dart @@ -128,7 +128,7 @@ class CallController extends GetxController { } /// 处理 RTM 消息 - void _handleRtmMessage(MessageEvent event) { + Future _handleRtmMessage(MessageEvent event) async { try { // 解析消息内容 String messageText; @@ -161,9 +161,33 @@ class CallController extends GetxController { } else if (event == 'hangup') { // 收到挂断消息,执行退出逻辑 print('📞 [CallController] 收到 hangup 消息,执行退出逻辑'); - RTMManager.instance.unsubscribe(messageData['channelId']); + final channelId = messageData['channelId'] as String?; + if (channelId != null && channelId.isNotEmpty) { + RTMManager.instance.unsubscribe(channelId); + } SmartDialog.dismiss(tag: 'video_call_invite_dialog'); _handleHangupMessage(); + } else if (event == 'reject') { + // 发起方收到 reject 消息,执行退出逻辑 + print('📞 [CallController] 收到 reject 消息,执行退出逻辑'); + final channelId = messageData['channelId'] as String?; + if (channelId != null && channelId.isNotEmpty) { + RTMManager.instance.unsubscribe(channelId); + print('✅ [CallController] 已取消订阅 RTM 频道: $channelId'); + } + // 关闭通话小窗口 + if (Get.isRegistered()) { + final overlayController = Get.find(); + overlayController.hideVideoCall(); + print('✅ [CallController] 已关闭通话小窗口'); + } + // 退出 VideoCallPage(如果当前在 VideoCallPage) + if (Get.currentRoute.contains('VideoCallPage')) { + Get.back(); + print('✅ [CallController] 已退出 VideoCallPage'); + } + // 结束通话 + await endCall(callDuration: callDurationSeconds.value); } } } catch (e) { @@ -391,12 +415,47 @@ class CallController extends GetxController { // 停止播放来电铃声(已拒绝) stopCallAudio(); + // 从消息中获取 channelId + String? channelId; + if (message.body is EMCustomMessageBody) { + final customBody = message.body as EMCustomMessageBody; + final params = customBody.params; + if (params != null && params.containsKey('channelId')) { + channelId = params['channelId']?.toString(); + } + } + + // 如果有 channelId,调用拒绝接口 + if (channelId != null && channelId.isNotEmpty) { + final response = await _networkService.rtcApi.refuseOneOnOneRtcChannel({ + 'channelId': channelId, + }); + if (!response.data.isSuccess) { + SmartDialog.showToast(response.data.message); + return false; + } + print('✅ [CallController] 已调用拒绝一对一RTC频道接口,channelId: $channelId'); + await RTMManager.instance.unsubscribe(channelId); + final callInfo = _parseCallInfo(message); + final callTypeStr = callInfo?['callType'] as String?; + final callType = callTypeStr == 'video' ? 'video' : 'voice'; + + // 发送拒绝 RTM 消息 + await RTMManager.instance.publishChannelMessage( + channelName: channelId, + message: json.encode({ + 'type': 'call_message', + 'uid': 0, + 'channelId': channelId, + 'callType': callType, + 'event': 'reject', + }), + ); + } + // 清理通话会话 currentCall.value = null; - // TODO: 这里可以集成实际的通话SDK,拒绝通话 - // 例如:await RTCManager.instance.rejectCall(message.from ?? ''); - return true; }