diff --git a/lib/controller/message/call_controller.dart b/lib/controller/message/call_controller.dart index 291bbea..9b9f798 100644 --- a/lib/controller/message/call_controller.dart +++ b/lib/controller/message/call_controller.dart @@ -3,6 +3,7 @@ import 'package:agora_rtc_engine/agora_rtc_engine.dart'; import 'package:audioplayers/audioplayers.dart'; import 'package:dating_touchme_app/generated/assets.dart'; import 'package:dating_touchme_app/model/rtc/chat_audio_product_model.dart'; +import 'package:dating_touchme_app/model/rtc/consume_rtc_channel_response.dart'; import 'package:dating_touchme_app/model/rtc/rtc_channel_data.dart'; import 'package:dating_touchme_app/network/network_service.dart'; import 'package:dating_touchme_app/rtc/rtc_manager.dart'; @@ -117,6 +118,9 @@ class CallController extends GetxController { String? _callChannelId; int? _callUid; + // 消费响应数据(用于显示玫瑰剩余数量和每分钟价格) + final Rxn consumeResponse = Rxn(); + @override void onInit() { super.onInit(); @@ -450,9 +454,6 @@ class CallController extends GetxController { // 接收方接听后,立即调用一次消费接口并启动定时器 // 确保 _callChannelId 已设置 if (_callChannelId != null && _callChannelId!.isNotEmpty) { - Future .delayed(Duration(seconds: 1), () async { - await _consumeOneOnOneRtcChannel(); - }); _startConsumeTimer(); print('✅ [CallController] 接收方接听后已启动消费定时器'); } @@ -591,6 +592,8 @@ class CallController extends GetxController { void _stopConsumeTimer() { _consumeTimer?.cancel(); _consumeTimer = null; + // 清空消费响应数据 + consumeResponse.value = null; } /// 调用消费一对一RTC频道接口 @@ -606,7 +609,28 @@ class CallController extends GetxController { 'channelId': consumeChannelId, }); if (response.data.isSuccess) { - print('✅ [CallController] 已调用消费一对一RTC频道接口,channelId: $consumeChannelId'); + final consumeData = response.data.data; + if (consumeData != null) { + // 更新消费响应数据 + consumeResponse.value = consumeData; + + print('✅ [CallController] 已调用消费一对一RTC频道接口,channelId: $consumeChannelId, isFree: ${consumeData.isFree}, status: ${consumeData.status}, availableBalance: ${consumeData.availableBalance}, unitSellingBalance: ${consumeData.unitSellingBalance}'); + + // 如果 status == 3,挂断通话 + if (consumeData.status == 3) { + print('⚠️ [CallController] 检测到 status=3,自动挂断通话'); + await hangUpCall(); + return; + } + + // 如果是免费通话,停止定时器,不再调用消费接口 + if (consumeData.isFree) { + _stopConsumeTimer(); + print('✅ [CallController] 检测到免费通话,已停止消费定时器'); + } + } else { + print('✅ [CallController] 已调用消费一对一RTC频道接口,channelId: $consumeChannelId'); + } } else { print('⚠️ [CallController] 消费一对一RTC频道接口失败: ${response.data.message}'); } diff --git a/lib/network/rtc_api.dart b/lib/network/rtc_api.dart index 9346b0e..1a2db80 100644 --- a/lib/network/rtc_api.dart +++ b/lib/network/rtc_api.dart @@ -1,6 +1,7 @@ import 'package:dating_touchme_app/model/discover/rtc_channel_model.dart'; import 'package:dating_touchme_app/model/live/gift_product_model.dart'; import 'package:dating_touchme_app/model/rtc/chat_audio_product_model.dart'; +import 'package:dating_touchme_app/model/rtc/consume_rtc_channel_response.dart'; import 'package:dating_touchme_app/model/rtc/link_mic_card_model.dart'; import 'package:dating_touchme_app/model/rtc/rtc_channel_data.dart'; import 'package:dating_touchme_app/model/rtc/rtc_channel_detail.dart'; @@ -133,7 +134,7 @@ abstract class RtcApi { /// 消费一对一RTC频道 @POST(ApiUrls.consumeOneOnOneRtcChannel) - Future>> consumeOneOnOneRtcChannel( + Future>> consumeOneOnOneRtcChannel( @Body() Map data, ); } diff --git a/lib/network/rtc_api.g.dart b/lib/network/rtc_api.g.dart index 7dd2990..bb9cad9 100644 --- a/lib/network/rtc_api.g.dart +++ b/lib/network/rtc_api.g.dart @@ -750,30 +750,33 @@ class _RtcApi implements RtcApi { } @override - Future>> consumeOneOnOneRtcChannel( - Map data, - ) async { + Future>> + consumeOneOnOneRtcChannel(Map data) async { final _extra = {}; final queryParameters = {}; final _headers = {}; final _data = {}; _data.addAll(data); - final _options = _setStreamType>>( - Options(method: 'POST', headers: _headers, extra: _extra) - .compose( - _dio.options, - 'dating-agency-chat-audio/user/consume/one-on-one/rtc-channel', - queryParameters: queryParameters, - data: _data, - ) - .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), - ); + final _options = + _setStreamType>>( + Options(method: 'POST', headers: _headers, extra: _extra) + .compose( + _dio.options, + 'dating-agency-chat-audio/user/consume/one-on-one/rtc-channel', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl), + ), + ); final _result = await _dio.fetch>(_options); - late BaseResponse _value; + late BaseResponse _value; try { - _value = BaseResponse.fromJson( + _value = BaseResponse.fromJson( _result.data!, - (json) => json as dynamic, + (json) => + ConsumeRtcChannelResponse.fromJson(json as Map), ); } on Object catch (e, s) { errorLogger?.logError(e, s, _options); diff --git a/lib/pages/message/video_call_page.dart b/lib/pages/message/video_call_page.dart index dde7e37..89bbc69 100644 --- a/lib/pages/message/video_call_page.dart +++ b/lib/pages/message/video_call_page.dart @@ -561,15 +561,45 @@ class _VideoCallPageState extends State { bottom: MediaQuery.of(context).size.height * 0.25, left: 0, right: 0, - child: Center( - child: Text( - isCallConnected ? _formatDuration(duration) : '正在呼叫中', - style: TextStyle( - color: Colors.white, - fontSize: 16.sp, - fontWeight: FontWeight.w500, + child: Column( + children: [ + Center( + child: Text( + isCallConnected ? _formatDuration(duration) : '正在呼叫中', + style: TextStyle( + color: Colors.white, + fontSize: 16.sp, + fontWeight: FontWeight.w500, + ), + ), ), - ), + Obx(() { + final callSession = _callController.currentCall.value; + final consumeData = _callController.consumeResponse.value; + + // 呼叫中(waitCalling)或免费时不显示 + final isCalling = callSession?.status == CallStatus.waitCalling; + final isFree = consumeData?.isFree == true; + + if (isCalling || isFree) { + return const SizedBox.shrink(); + } + + final availableBalance = consumeData?.availableBalance ?? 44; + final unitSellingBalance = consumeData?.unitSellingBalance ?? 35; + + return Center( + child: Text( + '玫瑰剩余$availableBalance支($unitSellingBalance玫瑰/分钟)', + style: TextStyle( + color: Colors.white, + fontSize: 16.sp, + fontWeight: FontWeight.w500, + ), + ), + ); + }) + ], ), ); });