diff --git a/lib/controller/discover/room_controller.dart b/lib/controller/discover/room_controller.dart index ff3adcd..516d1a2 100644 --- a/lib/controller/discover/room_controller.dart +++ b/lib/controller/discover/room_controller.dart @@ -375,7 +375,6 @@ class RoomController extends GetxController with WidgetsBindingObserver { } Future leaveChannel() async { - // 如果是主播,先销毁 RTC 频道,然后发送结束直播消息 if (currentRole == CurrentRole.broadcaster) { try { // 先调用销毁 RTC 频道 API @@ -393,6 +392,22 @@ class RoomController extends GetxController with WidgetsBindingObserver { } catch (e) { print('❌ 销毁 RTC 频道异常: $e'); } + } else if (currentRole == CurrentRole.maleAudience || currentRole == CurrentRole.femaleAudience) { + try { + // 嘉宾离开时调用断开 RTC 频道连接接口 + final channelId = RTCManager.instance.currentChannelId; + if (channelId != null && channelId.isNotEmpty) { + final data = {'channelId': channelId}; + final response = await _networkService.rtcApi.disconnectRtcChannel(data); + if (response.data.isSuccess) { + print('✅ [RoomController] 嘉宾已断开 RTC 频道连接,channelId: $channelId'); + } else { + print('⚠️ [RoomController] 断开 RTC 频道连接失败: ${response.data.message}'); + } + } + } catch (e) { + print('❌ [RoomController] 断开 RTC 频道连接异常: $e'); + } } isLive.value = false; diff --git a/lib/model/rtc/consume_rtc_channel_response.dart b/lib/model/rtc/consume_rtc_channel_response.dart new file mode 100644 index 0000000..da631a4 --- /dev/null +++ b/lib/model/rtc/consume_rtc_channel_response.dart @@ -0,0 +1,42 @@ +/// 消费一对一RTC频道响应模型 +class ConsumeRtcChannelResponse { + final bool isFree; + final int status; + final int availableBalance; + final int unitSellingBalance; + final String? code; + + ConsumeRtcChannelResponse({ + required this.isFree, + required this.status, + required this.availableBalance, + required this.unitSellingBalance, + this.code, + }); + + factory ConsumeRtcChannelResponse.fromJson(Map json) { + return ConsumeRtcChannelResponse( + isFree: json['isFree'] as bool? ?? false, + status: json['status'] as int? ?? 0, + availableBalance: json['availableBalance'] as int? ?? 0, + unitSellingBalance: json['unitSellingBalance'] as int? ?? 0, + code: json['code'] as String?, + ); + } + + Map toJson() { + return { + 'isFree': isFree, + 'status': status, + 'availableBalance': availableBalance, + 'unitSellingBalance': unitSellingBalance, + 'code': code, + }; + } + + @override + String toString() { + return 'ConsumeRtcChannelResponse(isFree: $isFree, status: $status, availableBalance: $availableBalance, unitSellingBalance: $unitSellingBalance, code: $code)'; + } +} + diff --git a/lib/widget/message/call_item.dart b/lib/widget/message/call_item.dart index 7e9150e..4e513c7 100644 --- a/lib/widget/message/call_item.dart +++ b/lib/widget/message/call_item.dart @@ -136,7 +136,12 @@ class CallItem extends StatelessWidget { if (callStatus == CallStatus.rejected) { return Assets.imagesRejectCall; } else { - return Assets.imagesAcceptCall; + // 根据通话类型显示不同的图标:视频通话显示视频图标,语音通话显示语音图标 + if (callType == CallType.video) { + return Assets.imagesSendVideoCall; + } else { + return Assets.imagesSendCall; + } } } } @@ -225,6 +230,7 @@ class CallItem extends StatelessWidget { width: 24.w, height: 24.w, fit: BoxFit.contain, + color: isSentByMe ? Colors.white : Colors.orange, ), SizedBox(width: 8.w), // 状态文本 diff --git a/lib/widget/message/call_type_selection_dialog.dart b/lib/widget/message/call_type_selection_dialog.dart index 96072fe..afa5ae2 100644 --- a/lib/widget/message/call_type_selection_dialog.dart +++ b/lib/widget/message/call_type_selection_dialog.dart @@ -49,7 +49,8 @@ class CallTypeSelectionDialog extends StatelessWidget { @override Widget build(BuildContext context) { - String price = _formatPrice(voiceProduct); + String voicePrice = _formatPrice(voiceProduct); + String videoPrice = _formatPrice(videoProduct); return Container( decoration: BoxDecoration( color: Colors.white, @@ -72,7 +73,7 @@ class CallTypeSelectionDialog extends StatelessWidget { padding: EdgeInsets.symmetric(vertical: 16.w), child: Center( child: Text( - price.isNotEmpty ? '语音通话 ($price)' : '语音通话', + voicePrice.isNotEmpty ? '语音通话 ($voicePrice)' : '语音通话', style: TextStyle( fontSize: 16.sp, color: const Color.fromRGBO(51, 51, 51, 1), @@ -98,7 +99,7 @@ class CallTypeSelectionDialog extends StatelessWidget { padding: EdgeInsets.symmetric(vertical: 16.w), child: Center( child: Text( - price.isNotEmpty ? '视频通话 ($price)' : '视频通话', + videoPrice.isNotEmpty ? '视频通话 ($videoPrice)' : '视频通话', style: TextStyle( fontSize: 16.sp, color: const Color.fromRGBO(51, 51, 51, 1),