Browse Source

feat(rtc): 添加RTC频道创建功能

- 新增创建RTC频道的API接口
- 实现RoomController控制RTC频道创建逻辑
- 在discover页面集成RTC频道创建功能
- 添加RTC相关网络服务和数据模型
- 实现RTC频道创建后的加入逻辑- 添加错误处理和加载状态提示
ios
Jolie 4 months ago
parent
commit
f48f82502d
8 changed files with 205 additions and 5 deletions
  1. 56
      lib/controller/discover/room_controller.dart
  2. 28
      lib/model/rtc/rtc_channel_data.dart
  3. 1
      lib/network/api_urls.dart
  4. 3
      lib/network/index.dart
  5. 6
      lib/network/network_service.dart
  6. 18
      lib/network/rtc_api.dart
  7. 81
      lib/network/rtc_api.g.dart
  8. 17
      lib/pages/discover/discover_page.dart

56
lib/controller/discover/room_controller.dart

@ -0,0 +1,56 @@
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';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import '../../pages/discover/live_room_page.dart';
///
class RoomController extends GetxController {
RoomController({NetworkService? networkService})
: _networkService = networkService ?? Get.find<NetworkService>();
final NetworkService _networkService;
///
final Rxn<RtcChannelData> rtcChannel = Rxn<RtcChannelData>();
///
final RxBool isLoading = false.obs;
/// RTC
Future<void> createRtcChannel() async {
if (isLoading.value) return ;
try {
isLoading.value = true;
final response = await _networkService.rtcApi.createRtcChannel();
final base = response.data;
if (base.isSuccess && base.data != null) {
rtcChannel.value = base.data;
await _joinRtcChannel(base.data!);
} else {
final message = base.message.isNotEmpty ? base.message : '创建频道失败';
SmartDialog.showToast(message);
}
} catch (e) {
SmartDialog.showToast('创建频道异常:$e');
} finally {
isLoading.value = false;
}
}
Future<void> _joinRtcChannel(RtcChannelData data) async {
try {
await RTCManager.instance.joinChannel(
token: data.token,
channelId: data.channelId,
);
Get.to(() => const LiveRoomPage(id: 0));
} catch (e) {
SmartDialog.showToast('加入频道失败:$e');
}
}
}

28
lib/model/rtc/rtc_channel_data.dart

@ -0,0 +1,28 @@
/// RTC
class RtcChannelData {
final String channelId;
final String token;
RtcChannelData({
required this.channelId,
required this.token,
});
factory RtcChannelData.fromJson(Map<String, dynamic> json) {
return RtcChannelData(
channelId: json['channelId']?.toString() ?? '',
token: json['token']?.toString() ?? '',
);
}
Map<String, dynamic> toJson() {
return {
'channelId': channelId,
'token': token,
};
}
@override
String toString() => 'RtcChannelData(channelId: $channelId)';
}

1
lib/network/api_urls.dart

@ -23,6 +23,7 @@ class ApiUrls {
static const String getMaritalStatusList = 'dating-agency-service/user/get/marital/status/list';
static const String getPropertyList = 'dating-agency-service/user/get/property/permits';
static const String getOccupationList = 'dating-agency-service/user/get/occupation/list';
static const String createRtcChannel = 'dating-agency-chat-audio/user/create/rtc-channel';
//
static const String getMarriageList = 'dating-agency-service/user/page/dongwo/marriage-information';

3
lib/network/index.dart

@ -1,4 +1,5 @@
export 'api_service.dart';
export 'network_config.dart';
export 'network_service.dart';
export 'response_model.dart';
export 'response_model.dart';
export 'rtc_api.dart';

6
lib/network/network_service.dart

@ -5,6 +5,7 @@ import 'api_service.dart';
import 'home_api.dart';
import 'network_config.dart';
import 'user_api.dart';
import 'rtc_api.dart';
///
class NetworkService {
@ -14,6 +15,7 @@ class NetworkService {
late final ApiService _apiService; // API服务
late final UserApi _userApi;
late final HomeApi _homeApi;
late final RtcApi _rtcApi;
///
factory NetworkService() {
@ -26,6 +28,7 @@ class NetworkService {
_apiService = ApiService(dio);
_userApi = UserApi(dio);
_homeApi = HomeApi(dio);
_rtcApi = RtcApi(dio);
}
/// GET请求
@ -165,6 +168,9 @@ class NetworkService {
/// API
HomeApi get homeApi => _homeApi;
/// RTC相关API
RtcApi get rtcApi => _rtcApi;
void _showLoading() {
// 使FlutterSmartDialog显示加载指示器
SmartDialog.showLoading();

18
lib/network/rtc_api.dart

@ -0,0 +1,18 @@
import 'package:dating_touchme_app/model/rtc/rtc_channel_data.dart';
import 'package:dating_touchme_app/network/api_urls.dart';
import 'package:dating_touchme_app/network/response_model.dart';
import 'package:dio/dio.dart';
import 'package:retrofit/retrofit.dart';
part 'rtc_api.g.dart';
/// RTC
@RestApi(baseUrl: '')
abstract class RtcApi {
factory RtcApi(Dio dio) = _RtcApi;
///
@POST(ApiUrls.createRtcChannel)
Future<HttpResponse<BaseResponse<RtcChannelData>>> createRtcChannel();
}

81
lib/network/rtc_api.g.dart

@ -0,0 +1,81 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'rtc_api.dart';
// dart format off
// **************************************************************************
// RetrofitGenerator
// **************************************************************************
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations,unused_element_parameter,avoid_unused_constructor_parameters,unreachable_from_main
class _RtcApi implements RtcApi {
_RtcApi(this._dio, {this.baseUrl, this.errorLogger});
final Dio _dio;
String? baseUrl;
final ParseErrorLogger? errorLogger;
@override
Future<HttpResponse<BaseResponse<RtcChannelData>>> createRtcChannel() async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _options = _setStreamType<HttpResponse<BaseResponse<RtcChannelData>>>(
Options(method: 'POST', headers: _headers, extra: _extra)
.compose(
_dio.options,
'dating-agency-chat-audio/user/create/rtc-channel',
queryParameters: queryParameters,
data: _data,
)
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
);
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late BaseResponse<RtcChannelData> _value;
try {
_value = BaseResponse<RtcChannelData>.fromJson(
_result.data!,
(json) => RtcChannelData.fromJson(json as Map<String, dynamic>),
);
} on Object catch (e, s) {
errorLogger?.logError(e, s, _options);
rethrow;
}
final httpResponse = HttpResponse(_value, _result);
return httpResponse;
}
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
if (T != dynamic &&
!(requestOptions.responseType == ResponseType.bytes ||
requestOptions.responseType == ResponseType.stream)) {
if (T == String) {
requestOptions.responseType = ResponseType.plain;
} else {
requestOptions.responseType = ResponseType.json;
}
}
return requestOptions;
}
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
if (baseUrl == null || baseUrl.trim().isEmpty) {
return dioBaseUrl;
}
final url = Uri.parse(baseUrl);
if (url.isAbsolute) {
return url.toString();
}
return Uri.parse(dioBaseUrl).resolveUri(url).toString();
}
}
// dart format on

17
lib/pages/discover/discover_page.dart

@ -1,4 +1,5 @@
import 'package:dating_touchme_app/components/home_appbar.dart';
import 'package:dating_touchme_app/controller/discover/room_controller.dart';
import 'package:dating_touchme_app/generated/assets.dart';
import 'package:dating_touchme_app/pages/discover/live_room_page.dart';
import 'package:flutter/material.dart';
@ -13,8 +14,7 @@ class DiscoverPage extends StatefulWidget {
}
class _DiscoverPageState extends State<DiscoverPage> with AutomaticKeepAliveClientMixin{
late final RoomController roomController;
List<String> topNav = ["相亲", "聚会脱单"];
@ -42,6 +42,15 @@ class _DiscoverPageState extends State<DiscoverPage> with AutomaticKeepAliveClie
print("当前项: $active");
}
@override
void initState() {
super.initState();
if (Get.isRegistered<RoomController>()) {
roomController = Get.find<RoomController>();
} else {
roomController = Get.put(RoomController());
}
}
@override
Widget build(BuildContext context) {
@ -61,8 +70,8 @@ class _DiscoverPageState extends State<DiscoverPage> with AutomaticKeepAliveClie
child: Column(
children: [
HomeAppbar(topNav: topNav, changeNav: changeNav, right: InkWell(
onTap: (){
print("12121");
onTap: () async {
await roomController.createRtcChannel();
},
child: Container(
width: 52.w,

Loading…
Cancel
Save