diff --git a/lib/controller/message/call_controller.dart b/lib/controller/message/call_controller.dart index f5f826a..b1e1481 100644 --- a/lib/controller/message/call_controller.dart +++ b/lib/controller/message/call_controller.dart @@ -388,6 +388,15 @@ class CallController extends GetxController { // 保存 channelId 为全局变量 _callChannelId = channelId; + // 调用连接一对一RTC频道接口 + final connectResponse = await _networkService.rtcApi + .connectOneOnOneRtcChannel({'channelId': channelId}); + if (!connectResponse.data.isSuccess) { + SmartDialog.showToast(connectResponse.data.message); + return false; + } + print('✅ [CallController] 已调用连接一对一RTC频道接口,channelId: $channelId'); + // 根据通话类型设置摄像头状态 if (callType == CallType.voice) { // 语音通话:禁用视频(关闭摄像头) @@ -735,6 +744,19 @@ class CallController extends GetxController { return; } print('✅ [CallController] 已调用取消一对一RTC频道接口,channelId: $_callChannelId'); + } else if (callSession != null && + callDurationSeconds.value > 0 && + _callChannelId != null && + _callChannelId!.isNotEmpty) { + // 如果通话已接通(无论是发起方还是接收方),调用终止接口 + final response = await _networkService.rtcApi.terminateOneOnOneRtcChannel( + {'channelId': _callChannelId!}, + ); + if (!response.data.isSuccess) { + SmartDialog.showToast(response.data.message); + return; + } + print('✅ [CallController] 已调用终止一对一RTC频道接口,channelId: $_callChannelId'); } if (_callChannelId != null && diff --git a/lib/network/api_urls.dart b/lib/network/api_urls.dart index d8b24b4..53c84ab 100644 --- a/lib/network/api_urls.dart +++ b/lib/network/api_urls.dart @@ -137,6 +137,12 @@ class ApiUrls { static const String cancelOneOnOneRtcChannel = 'dating-agency-chat-audio/user/cancel/one-on-one/rtc-channel'; + static const String connectOneOnOneRtcChannel = + 'dating-agency-chat-audio/user/connect/one-on-one/rtc-channel'; + + static const String terminateOneOnOneRtcChannel = + 'dating-agency-chat-audio/user/terminate/one-on-one/rtc-channel'; + static const String getAppVersion = 'dating-agency-uec/user/get/app-version/update'; diff --git a/lib/network/rtc_api.dart b/lib/network/rtc_api.dart index d3573c7..622864f 100644 --- a/lib/network/rtc_api.dart +++ b/lib/network/rtc_api.dart @@ -111,4 +111,16 @@ abstract class RtcApi { Future>> cancelOneOnOneRtcChannel( @Body() Map data, ); + + /// 连接一对一RTC频道 + @POST(ApiUrls.connectOneOnOneRtcChannel) + Future>> connectOneOnOneRtcChannel( + @Body() Map data, + ); + + /// 终止一对一RTC频道 + @POST(ApiUrls.terminateOneOnOneRtcChannel) + Future>> terminateOneOnOneRtcChannel( + @Body() Map data, + ); } diff --git a/lib/network/rtc_api.g.dart b/lib/network/rtc_api.g.dart index 9951441..d141fc1 100644 --- a/lib/network/rtc_api.g.dart +++ b/lib/network/rtc_api.g.dart @@ -638,6 +638,74 @@ class _RtcApi implements RtcApi { return httpResponse; } + @override + Future>> connectOneOnOneRtcChannel( + 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/connect/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; + try { + _value = BaseResponse.fromJson( + _result.data!, + (json) => json as dynamic, + ); + } on Object catch (e, s) { + errorLogger?.logError(e, s, _options); + rethrow; + } + final httpResponse = HttpResponse(_value, _result); + return httpResponse; + } + + @override + Future>> terminateOneOnOneRtcChannel( + 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/terminate/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; + try { + _value = BaseResponse.fromJson( + _result.data!, + (json) => json as dynamic, + ); + } on Object catch (e, s) { + errorLogger?.logError(e, s, _options); + rethrow; + } + final httpResponse = HttpResponse(_value, _result); + return httpResponse; + } + RequestOptions _setStreamType(RequestOptions requestOptions) { if (T != dynamic && !(requestOptions.responseType == ResponseType.bytes || diff --git a/lib/widget/live/live_room_action_bar.dart b/lib/widget/live/live_room_action_bar.dart index 867d375..2f84737 100644 --- a/lib/widget/live/live_room_action_bar.dart +++ b/lib/widget/live/live_room_action_bar.dart @@ -88,30 +88,11 @@ class LiveRoomActionBar extends StatelessWidget { // ), // ), // SizedBox(width: 8.w), - InkWell( - onTap: onChargeTap, - child: Container( - width: 38.w, - height: 38.w, - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(38.w)), - gradient: const LinearGradient( - begin: Alignment.topLeft, - end: Alignment.bottomRight, - colors: [ - Color.fromRGBO(255, 43, 110, 1), - Color.fromRGBO(255, 52, 26, 1), - ], - ), - ), - child: Center( - child: Image.asset( - Assets.imagesRoseWhite, - width: 14.w, - height: 25.w, - ), - ), - ), + TextButton( + onPressed: onChargeTap, + child: Text('充值', style: TextStyle( + color: Colors.white + ),) ), SizedBox(width: 16.w), ], diff --git a/lib/widget/live/live_room_pay_item.dart b/lib/widget/live/live_room_pay_item.dart index b05146f..aa6b784 100644 --- a/lib/widget/live/live_room_pay_item.dart +++ b/lib/widget/live/live_room_pay_item.dart @@ -70,7 +70,7 @@ class _LiveRoomPayItemState extends State { ), ), Text( - "${(widget.item["price"] as num?)?.toStringAsFixed(1) ?? '0.0'}元", + "${(widget.item["price"] as num?)?.toStringAsFixed(0) ?? '0.0'}元", style: TextStyle( fontSize: 11.w, color: const Color.fromRGBO(144, 144, 144, 1),