diff --git a/lib/controller/message/call_controller.dart b/lib/controller/message/call_controller.dart index 6c2c717..bea6c70 100644 --- a/lib/controller/message/call_controller.dart +++ b/lib/controller/message/call_controller.dart @@ -161,6 +161,8 @@ class CallController extends GetxController { } else if (event == 'hangup') { // 收到挂断消息,执行退出逻辑 print('📞 [CallController] 收到 hangup 消息,执行退出逻辑'); + RTMManager.instance.unsubscribe(messageData['channelId']); + SmartDialog.dismiss(tag: 'video_call_invite_dialog'); _handleHangupMessage(); } } @@ -231,8 +233,6 @@ class CallController extends GetxController { // 清空之前的远端用户UID和通话信息 remoteUid.value = null; - _callChannelId = null; - _callUid = null; print( '📞 [CallController] 发起${callType == CallType.video ? "视频" : "语音"}通话,目标用户: $targetUserId', @@ -241,7 +241,8 @@ class CallController extends GetxController { // 发起通话前,先创建一对一 RTC 频道 final type = callType == CallType.video ? 2 : 1; // 1为音频,2为视频 final channelData = await createOneOnOneRtcChannel(type: type); - + _callUid = channelData?.uid; + _callChannelId = channelData?.channelId; if (channelData == null) { print('❌ [CallController] 创建RTC频道失败,无法发起通话'); SmartDialog.showToast('创建通话频道失败'); @@ -399,30 +400,6 @@ class CallController extends GetxController { return true; } - /// 取消通话 - /// [message] 通话消息(可选,如果是发起方取消) - /// [chatController] 聊天控制器,用于更新通话消息 - Future cancelCall({ - EMMessage? message, - ChatController? chatController, - }) async { - print('📞 [CallController] 取消通话'); - - // 停止播放来电铃声(已取消) - stopCallAudio(); - - // 停止计时 - _stopCallTimer(); - - // 清理通话会话 - currentCall.value = null; - - // TODO: 这里可以集成实际的通话SDK,取消通话 - // 例如:await RTCManager.instance.cancelCall(); - - return true; - } - /// 结束通话(通话完成) /// [callDuration] 通话时长(秒) /// [chatController] 聊天控制器,用于更新通话消息 @@ -647,11 +624,27 @@ class CallController extends GetxController { /// 挂断通话 Future hangUpCall() async { - // 发送 RTM 挂断消息 + final callSession = currentCall.value; + + // 如果是发起方且处于呼叫中状态(对方还没接听),先调用取消接口 + if (callSession != null && + callSession.isInitiator && + callDurationSeconds.value == 0 && + _callChannelId != null && + _callChannelId!.isNotEmpty) { + final response = await _networkService.rtcApi.cancelOneOnOneRtcChannel({ + 'channelId': _callChannelId!, + }); + if (!response.data.isSuccess) { + SmartDialog.showToast(response.data.message); + return; + } + print('✅ [CallController] 已调用取消一对一RTC频道接口,channelId: $_callChannelId'); + } + if (_callChannelId != null && _callChannelId!.isNotEmpty && _callUid != null) { - final callSession = currentCall.value; final callType = callSession?.callType == CallType.video ? 'video' : 'voice'; @@ -661,6 +654,7 @@ class CallController extends GetxController { message: json.encode({ 'type': 'call_message', 'uid': _callUid!, + 'channelId': _callChannelId, 'callType': callType, 'event': 'hangup', }), @@ -687,6 +681,13 @@ class CallController extends GetxController { /// 处理挂断消息(对方挂断时调用) Future _handleHangupMessage() async { + // 关闭视频通话邀请弹框(如果正在显示) + SmartDialog.dismiss(); + print('✅ [CallController] 已关闭视频通话邀请弹框'); + + // 停止播放来电铃声 + stopCallAudio(); + // 离开RTC频道 await RTCManager.instance.leaveChannel(); diff --git a/lib/im/im_manager.dart b/lib/im/im_manager.dart index 9ede731..197c4fe 100644 --- a/lib/im/im_manager.dart +++ b/lib/im/im_manager.dart @@ -1,5 +1,6 @@ import 'dart:io'; import 'dart:async'; +import 'package:dating_touchme_app/rtc/rtm_manager.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -1457,6 +1458,7 @@ class IMManager { if (callInfo != null && callType != null && callStatus != null) { // 只处理视频通话且状态为 missed 或 calling 的消息(新邀请) if ((callType == 'video' || callType == 'voice') && (callStatus == 'waitCalling' || callStatus == 'calling')) { + RTMManager.instance.subscribe(channelId ?? ''); // 获取用户信息 Map? attributes; try { @@ -1502,6 +1504,7 @@ class IMManager { // 显示视频通话邀请弹框 SmartDialog.show( + tag: 'video_call_invite_dialog', builder: (context) { return VideoCallInviteDialog( avatarUrl: finalAvatarUrl, diff --git a/lib/pages/message/video_call_page.dart b/lib/pages/message/video_call_page.dart index b9efd49..eca74ce 100644 --- a/lib/pages/message/video_call_page.dart +++ b/lib/pages/message/video_call_page.dart @@ -668,13 +668,6 @@ class _VideoCallPageState extends State { chatController = Get.find(tag: tag); } - if (widget.callMessage == null) { - // 即使没有消息,也执行拒绝操作(关闭页面) - await _callController.endCall(callDuration: 0); - Get.back(); - return; - } - final rejected = await _callController.rejectCall( message: widget.callMessage!, chatController: chatController, diff --git a/lib/service/live_chat_message_service.dart b/lib/service/live_chat_message_service.dart index d26db52..4267e71 100644 --- a/lib/service/live_chat_message_service.dart +++ b/lib/service/live_chat_message_service.dart @@ -87,6 +87,17 @@ class LiveChatMessageService { callController.remoteUid.value = uid is int ? uid : int.tryParse(uid.toString()); print('📞 [LiveChatMessageService] 收到 accept 消息,设置 remoteUid: ${callController.remoteUid.value}'); } + } else if (event == 'hangup') { + // 接收方收到 hangup 消息,关闭视频通话邀请弹框 + SmartDialog.dismiss(); + print('📞 [LiveChatMessageService] 收到 hangup 消息,已关闭视频通话邀请弹框'); + + // 停止播放来电铃声 + if (Get.isRegistered()) { + final callController = Get.find(); + callController.stopCallAudio(); + print('📞 [LiveChatMessageService] 已停止播放来电铃声'); + } } return; }