王子贤 3 months ago
parent
commit
3e2b96605e
8 changed files with 285 additions and 5 deletions
  1. 34
      lib/controller/discover/room_controller.dart
  2. 4
      lib/controller/mine/auth_controller.dart
  3. 1
      lib/controller/mine/user_controller.dart
  4. 13
      lib/model/mine/user_data.dart
  5. 2
      lib/network/api_urls.dart
  6. 6
      lib/network/rtc_api.dart
  7. 34
      lib/network/rtc_api.g.dart
  8. 196
      lib/widget/live/disconnect_mic_dialog.dart

34
lib/controller/discover/room_controller.dart

@ -552,4 +552,38 @@ class RoomController extends GetxController with WidgetsBindingObserver {
print(455);
matchmakerFlag.value = GlobalData().userData!.matchmakerFlag!;
}
/// RTC
Future<void> kickingRtcChannelUser({
required int channelId,
required int kickingUId,
}) async {
try {
final requestData = {
'channelId': channelId,
'kickingUId': kickingUId,
};
final response = await _networkService.rtcApi.kickingRtcChannelUser(
requestData,
);
if (response.data.isSuccess) {
SmartDialog.showToast('已踢出用户');
//
final channelName = RTCManager.instance.currentChannelId;
if (channelName != null && channelName.isNotEmpty) {
await fetchRtcChannelDetail(channelName);
}
} else {
final message = response.data.message.isNotEmpty
? response.data.message
: '踢出用户失败';
SmartDialog.showToast(message);
}
} catch (e) {
print('❌ 踢出用户异常: $e');
SmartDialog.showToast('踢出用户失败');
}
}
}

4
lib/controller/mine/auth_controller.dart

@ -36,9 +36,7 @@ class AuthController extends GetxController {
if(information.identityCard != null){
realAuth = true;
}
if(information.profilePhoto != null){
checkPhoto = true;
}
checkPhoto = information.isPhotoAudited();
}
dataList.assignAll([
AuthCard( title: '手机绑定', desc: '防止账号丢失', index: 1, authed: true, defaultIcon: Assets.imagesPhoneChecked, activeIcon: Assets.imagesPhoneChecked, width: 28,height: 40),

1
lib/controller/mine/user_controller.dart

@ -116,7 +116,6 @@ class UserController extends GetxController {
information.realName = baseInfo.realName;
information.phone = baseInfo.phone;
GlobalData().userData = information;
// await storage.write('userId', GlobalData().userId);
if (_checkInformation(information)) {
//

13
lib/model/mine/user_data.dart

@ -9,6 +9,7 @@ class UserData {
String? identityCard;
int? genderCode;
Map? auditProfilePhoto;
bool? hasUploadProfilePhoto;
final String? genderValue;
final String? homeCountryCode;
final String? homeCountry;
@ -133,7 +134,8 @@ class UserData {
this.realName,
this.matchmakerFlag,
this.photoList,
this.matchmakerType
this.matchmakerType,
this.hasUploadProfilePhoto
});
// JSON映射创建实例
@ -145,6 +147,7 @@ class UserData {
profilePhoto: json['profilePhoto'],
identityCard: json['identityCard'],
genderCode: json['genderCode'] ?? 0,
hasUploadProfilePhoto: json['hasUploadProfilePhoto'] ?? false,
auditProfilePhoto: json['auditProfilePhoto'] ?? null,
genderValue: json['genderValue'] ?? '',
homeCountryCode: json['homeCountryCode'],
@ -212,6 +215,7 @@ class UserData {
'profilePhoto': profilePhoto,
'identityCard': identityCard,
'genderCode': genderCode,
'hasUploadProfilePhoto': hasUploadProfilePhoto,
'auditProfilePhoto': auditProfilePhoto,
'genderValue': genderValue,
'homeCountryCode': homeCountryCode,
@ -274,4 +278,11 @@ class UserData {
String toString() {
return 'UserData(id: $id, nickName: $nickName, genderCode: $genderCode, auditProfilePhoto: $auditProfilePhoto, genderValue: $genderValue, birthYear: $birthYear, photoList: $photoList)';
}
bool isPhotoAudited(){
if(hasUploadProfilePhoto! && profilePhoto != null){
return hasUploadProfilePhoto! && profilePhoto!.isNotEmpty;
}
return false;
}
}

2
lib/network/api_urls.dart

@ -106,4 +106,6 @@ class ApiUrls {
'dating-agency-chat-audio/user/get/own-user-management';
static const String submitMatchmakerOrder = 'dating-agency-mall/user/submit/matchmaker-order';
static const String kickingRtcChannelUser =
'dating-agency-chat-audio/user/user//kicking/rtc-channel-user';
}

6
lib/network/rtc_api.dart

@ -82,4 +82,10 @@ abstract class RtcApi {
Future<HttpResponse<BaseResponse<dynamic>>> costImGift(
@Body() Map<String, dynamic> data,
);
/// RTC
@POST(ApiUrls.kickingRtcChannelUser)
Future<HttpResponse<BaseResponse<dynamic>>> kickingRtcChannelUser(
@Body() Map<String, dynamic> data,
);
}

34
lib/network/rtc_api.g.dart

@ -467,6 +467,40 @@ class _RtcApi implements RtcApi {
return httpResponse;
}
@override
Future<HttpResponse<BaseResponse<dynamic>>> kickingRtcChannelUser(
Map<String, dynamic> data,
) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(data);
final _options = _setStreamType<HttpResponse<BaseResponse<dynamic>>>(
Options(method: 'POST', headers: _headers, extra: _extra)
.compose(
_dio.options,
'dating-agency-chat-audio/user/user//kicking/rtc-channel-user',
queryParameters: queryParameters,
data: _data,
)
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
);
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late BaseResponse<dynamic> _value;
try {
_value = BaseResponse<dynamic>.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<T>(RequestOptions requestOptions) {
if (T != dynamic &&
!(requestOptions.responseType == ResponseType.bytes ||

196
lib/widget/live/disconnect_mic_dialog.dart

@ -0,0 +1,196 @@
import 'package:dating_touchme_app/controller/discover/room_controller.dart';
import 'package:dating_touchme_app/generated/assets.dart';
import 'package:dating_touchme_app/model/rtc/rtc_channel_detail.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
///
class DisconnectMicDialog extends StatelessWidget {
const DisconnectMicDialog({super.key});
@override
Widget build(BuildContext context) {
final roomController = Get.find<RoomController>();
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.w),
),
child: Container(
padding: EdgeInsets.all(20.w),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
//
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'解除连麦',
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
),
GestureDetector(
onTap: () => SmartDialog.dismiss(),
child: Icon(
Icons.close,
size: 24.w,
color: Colors.grey,
),
),
],
),
SizedBox(height: 20.w),
//
Obx(() {
final maleInfo = roomController.rtcChannelDetail.value?.maleInfo;
final femaleInfo = roomController.rtcChannelDetail.value?.femaleInfo;
//
if (maleInfo == null && femaleInfo == null) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 20.w),
child: Text(
'暂无嘉宾连麦',
style: TextStyle(
fontSize: 14.sp,
color: Colors.grey,
),
),
);
}
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
//
if (maleInfo != null)
Expanded(
child: _buildGuestItem(
context: context,
userInfo: maleInfo,
roomController: roomController,
isMale: true,
),
),
if (maleInfo != null && femaleInfo != null)
SizedBox(width: 20.w),
//
if (femaleInfo != null)
Expanded(
child: _buildGuestItem(
context: context,
userInfo: femaleInfo,
roomController: roomController,
isMale: false,
),
),
],
);
}),
SizedBox(height: 10.w),
],
),
),
);
}
///
Widget _buildGuestItem({
required BuildContext context,
required RtcSeatUserInfo userInfo,
required RoomController roomController,
required bool isMale,
}) {
//
final isConnected = userInfo.isMicrophoneOn;
return Column(
children: [
//
ClipOval(
child: Image.network(
userInfo.profilePhoto,
width: 60.w,
height: 60.w,
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return Image.asset(
Assets.imagesUserAvatar,
width: 60.w,
height: 60.w,
);
},
),
),
SizedBox(height: 10.w),
//
Text(
userInfo.nickName,
style: TextStyle(
fontSize: 14.sp,
color: Colors.black87,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
SizedBox(height: 10.w),
//
GestureDetector(
onTap: isConnected
? () async {
//
await _disconnectMic(roomController, isMale);
}
: null,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.w),
decoration: BoxDecoration(
color: isConnected ? const Color(0xFF8B5CF6) : Colors.grey[300],
borderRadius: BorderRadius.circular(20.w),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Image.asset(
Assets.imagesMicOff,
width: 14.w,
color: isConnected ? Colors.white : Colors.grey[600],
),
SizedBox(width: 4.w),
Text(
isConnected ? '解除连麦' : '已解除连麦',
style: TextStyle(
fontSize: 12.sp,
color: isConnected ? Colors.white : Colors.grey[600],
),
),
],
),
),
),
],
);
}
///
Future<void> _disconnectMic(RoomController roomController, bool isMale) async {
// -
final currentDetail = roomController.rtcChannelDetail.value;
if (currentDetail != null) {
final newDetail = RtcChannelDetail(
channelId: currentDetail.channelId,
anchorInfo: currentDetail.anchorInfo,
maleInfo: isMale ? null : currentDetail.maleInfo,
femaleInfo: !isMale ? null : currentDetail.femaleInfo,
);
roomController.rtcChannelDetail.value = newDetail;
}
}
}
Loading…
Cancel
Save