Browse Source

优化

dev-2.0
王子贤 1 month ago
parent
commit
3b4618daed
12 changed files with 345 additions and 52 deletions
  1. 46
      lib/controller/discover/room_controller.dart
  2. 22
      lib/controller/mine/login_controller.dart
  3. 4
      lib/model/discover/task_data.dart
  4. 18
      lib/model/mine/sys_data.dart
  5. 3
      lib/network/api_urls.dart
  6. 4
      lib/network/user_api.dart
  7. 31
      lib/network/user_api.g.dart
  8. 60
      lib/pages/mine/contact_page.dart
  9. 32
      lib/pages/mine/login_page.dart
  10. 76
      lib/widget/live/audience_item.dart
  11. 90
      lib/widget/live/live_room_anchor_showcase.dart
  12. 11
      lib/widget/live/live_room_invitation_list.dart

46
lib/controller/discover/room_controller.dart

@ -344,7 +344,7 @@ class RoomController extends GetxController with WidgetsBindingObserver {
getTaskTemplateData() async { getTaskTemplateData() async {
try{ try{
final response = await _networkService.rtcApi.userGetTaskTemplateDetail( final response = await _networkService.rtcApi.userGetTaskTemplateDetail(
id: "1",
id: taskData.value.taskTemplateId ?? "",
); );
if (response.data.isSuccess) { if (response.data.isSuccess) {
final data = response.data.data ?? TaskTemplateData(); final data = response.data.data ?? TaskTemplateData();
@ -1272,6 +1272,17 @@ class RoomController extends GetxController with WidgetsBindingObserver {
} catch (e) { } catch (e) {
print('❌ 处理下麦消息失败: $e'); print('❌ 处理下麦消息失败: $e');
} }
} else if (message['type'] == 'close_mic') {
//
try {
final channelName = RTCManager.instance.currentChannelId;
if (channelName != null && channelName.isNotEmpty) {
await fetchRtcChannelDetail(channelName);
}
print('✅ 其他用户收到下麦消息,已刷新房间详情');
} catch (e) {
print('❌ 处理下麦消息失败: $e');
}
} }
} }
@ -1322,6 +1333,39 @@ class RoomController extends GetxController with WidgetsBindingObserver {
return age; return age;
} }
changeMic(bool mic) async {
try {
final channelId = RTCManager.instance.currentChannelId;
var res = await _networkService.rtcApi.enableRtcChannelUserAudio(
{
"channelId": channelId,
"isMicrophoneOn": mic,
"isVideoOn": true
}
);
if(res.data.isSuccess){
final messageData = {
'type': 'close_mic',
'operatorId': GlobalData().userData?.id ?? '',
'operatorName': GlobalData().userData?.nickName ?? '',
};
final channelName = RTCManager.instance.currentChannelId;
if (channelName != null && channelName.isNotEmpty) {
await RTMManager.instance.publishChannelMessage(
channelName: channelName,
message: json.encode(messageData),
);
print("关闭麦克风成功");
}
}
} catch(e){
print("关闭麦克风失败");
}
}
inviteMic(List<Map<String, dynamic>> selectUserId) async { inviteMic(List<Map<String, dynamic>> selectUserId) async {
try { try {
final channelName = RTCManager.instance.currentChannelId; final channelName = RTCManager.instance.currentChannelId;

22
lib/controller/mine/login_controller.dart

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:dating_touchme_app/controller/global.dart'; import 'package:dating_touchme_app/controller/global.dart';
import 'package:dating_touchme_app/model/mine/sys_data.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart'; import 'package:get_storage/get_storage.dart';
@ -35,6 +36,27 @@ class LoginController extends GetxController with WidgetsBindingObserver {
_userApi = Get.find<UserApi>(); _userApi = Get.find<UserApi>();
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
getSysData();
}
final sysData = SysData().obs;
getSysData() async {
try {
final response = await _userApi.userGetSysInfo();
if (response.data.isSuccess && response.data.data != null) {
sysData.value = response.data.data ?? sysData();
} else {
//
throw Exception(response.data.message ?? '获取数据失败');
}
} catch(e){
print('钱包数据获取失败: $e');
SmartDialog.showToast('钱包数据获取失败');
rethrow;
}
} }
@override @override

4
lib/model/discover/task_data.dart

@ -1,5 +1,6 @@
class TaskData { class TaskData {
String? userTaskCompleteId; String? userTaskCompleteId;
String? taskTemplateId;
int? taskGroup; int? taskGroup;
int? taskType; int? taskType;
int? stageCode; int? stageCode;
@ -16,6 +17,7 @@ class TaskData {
TaskData( TaskData(
{this.userTaskCompleteId, {this.userTaskCompleteId,
this.taskGroup, this.taskGroup,
this.taskTemplateId,
this.taskType, this.taskType,
this.stageCode, this.stageCode,
this.taskName, this.taskName,
@ -30,6 +32,7 @@ class TaskData {
TaskData.fromJson(Map<String, dynamic> json) { TaskData.fromJson(Map<String, dynamic> json) {
userTaskCompleteId = json['userTaskCompleteId']; userTaskCompleteId = json['userTaskCompleteId'];
taskTemplateId = json['taskTemplateId'];
taskGroup = json['taskGroup']; taskGroup = json['taskGroup'];
taskType = json['taskType']; taskType = json['taskType'];
stageCode = json['stageCode']; stageCode = json['stageCode'];
@ -52,6 +55,7 @@ class TaskData {
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>(); final Map<String, dynamic> data = new Map<String, dynamic>();
data['userTaskCompleteId'] = this.userTaskCompleteId; data['userTaskCompleteId'] = this.userTaskCompleteId;
data['taskTemplateId'] = this.taskTemplateId;
data['taskGroup'] = this.taskGroup; data['taskGroup'] = this.taskGroup;
data['taskType'] = this.taskType; data['taskType'] = this.taskType;
data['stageCode'] = this.stageCode; data['stageCode'] = this.stageCode;

18
lib/model/mine/sys_data.dart

@ -0,0 +1,18 @@
class SysData {
String? customerServiceWeChat;
String? customerServicePhone;
SysData({this.customerServiceWeChat, this.customerServicePhone});
SysData.fromJson(Map<String, dynamic> json) {
customerServiceWeChat = json['customerServiceWeChat'];
customerServicePhone = json['customerServicePhone'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['customerServiceWeChat'] = this.customerServiceWeChat;
data['customerServicePhone'] = this.customerServicePhone;
return data;
}
}

3
lib/network/api_urls.dart

@ -178,4 +178,7 @@ class ApiUrls {
static const String userGetTaskTemplateDetail = static const String userGetTaskTemplateDetail =
'dating-agency-mall/user/get/task-template/detail'; 'dating-agency-mall/user/get/task-template/detail';
static const String userGetSysInfo =
'dating-agency-uec/user/get/sys-info';
} }

4
lib/network/user_api.dart

@ -12,6 +12,7 @@ import 'package:dating_touchme_app/model/mine/occupation_data.dart';
import 'package:dating_touchme_app/model/mine/payment_detail_data.dart'; import 'package:dating_touchme_app/model/mine/payment_detail_data.dart';
import 'package:dating_touchme_app/model/mine/rose_data.dart'; import 'package:dating_touchme_app/model/mine/rose_data.dart';
import 'package:dating_touchme_app/model/mine/rose_history_data.dart'; import 'package:dating_touchme_app/model/mine/rose_history_data.dart';
import 'package:dating_touchme_app/model/mine/sys_data.dart';
import 'package:dating_touchme_app/model/mine/user_base_data.dart'; import 'package:dating_touchme_app/model/mine/user_base_data.dart';
import 'package:dating_touchme_app/model/mine/user_count_data.dart'; import 'package:dating_touchme_app/model/mine/user_count_data.dart';
import 'package:dating_touchme_app/model/mine/user_data.dart'; import 'package:dating_touchme_app/model/mine/user_data.dart';
@ -291,4 +292,7 @@ abstract class UserApi {
@Body() Map<String, dynamic> data, @Body() Map<String, dynamic> data,
); );
@GET(ApiUrls.userGetSysInfo)
Future<HttpResponse<BaseResponse<SysData>>> userGetSysInfo();
} }

31
lib/network/user_api.g.dart

@ -1782,6 +1782,37 @@ class _UserApi implements UserApi {
return httpResponse; return httpResponse;
} }
@override
Future<HttpResponse<BaseResponse<SysData>>> userGetSysInfo() async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _options = _setStreamType<HttpResponse<BaseResponse<SysData>>>(
Options(method: 'GET', headers: _headers, extra: _extra)
.compose(
_dio.options,
'dating-agency-uec/user/get/sys-info',
queryParameters: queryParameters,
data: _data,
)
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
);
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late BaseResponse<SysData> _value;
try {
_value = BaseResponse<SysData>.fromJson(
_result.data!,
(json) => SysData.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) { RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
if (T != dynamic && if (T != dynamic &&
!(requestOptions.responseType == ResponseType.bytes || !(requestOptions.responseType == ResponseType.bytes ||

60
lib/pages/mine/contact_page.dart

@ -0,0 +1,60 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:dating_touchme_app/components/page_appbar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class ContactPage extends StatelessWidget {
String phone;
String weChat;
ContactPage({
super.key,
this.phone = "",
this.weChat = "",
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PageAppbar(title: "联系方式"),
body: Container(
width: 375.w,
padding: EdgeInsets.symmetric(
vertical: 20.w,
horizontal: 15.w
),
child: phone != "" ? Text(
"您好,人工客服热线为$phone\n工作时间9:00~21:00,请您在服务时间内拨打",
style: TextStyle(
fontSize: 14.w,
),
) : Column(
children: [
Text(
"您好,请扫一扫上面的二维码,添加客服微信,工作时间9:00~21:00,请您在服务时间内联系客服",
style: TextStyle(
fontSize: 14.w
),
),
Expanded(
child: CachedNetworkImage(
imageUrl: weChat,
width: 345.w,
fit: BoxFit.cover,
alignment: Alignment.topCenter,
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
image: DecorationImage(
image: imageProvider,
fit: BoxFit.fitWidth,
),
),
),
),
)
],
),
),
);
}
}

32
lib/pages/mine/login_page.dart

@ -1,4 +1,6 @@
import 'package:dating_touchme_app/extension/ex_widget.dart';
import 'package:dating_touchme_app/generated/assets.dart'; import 'package:dating_touchme_app/generated/assets.dart';
import 'package:dating_touchme_app/pages/mine/contact_page.dart';
import 'package:dating_touchme_app/pages/mine/open_webview.dart'; import 'package:dating_touchme_app/pages/mine/open_webview.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -270,6 +272,36 @@ class LoginPage extends StatelessWidget {
], ],
), ),
), ),
Positioned(
top: MediaQuery.of(context).padding.top + 17.w,
right: 15.w,
child: PopupMenuButton<String>(
tooltip: "",
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)),
color: Colors.white,
elevation: 8,
offset: Offset(0, 32.w), //
itemBuilder: (context) => [
if((controller.sysData.value.customerServiceWeChat != null && controller.sysData.value.customerServiceWeChat != "")) const PopupMenuItem(value: 'report', child: Text('微信联系')),
if((controller.sysData.value.customerServicePhone != null && controller.sysData.value.customerServicePhone != "")) const PopupMenuItem(value: 'block', child: Text('电话联系')),
],
onSelected: (v) {
if (v == 'report') {
Get.to(() => ContactPage(weChat: controller.sysData.value.customerServiceWeChat ?? "",));
} else if (v == 'block') {
Get.to(() => ContactPage(phone: controller.sysData.value.customerServicePhone ?? "",));
}
},
child: Text(
"联系客服",
style: TextStyle(
fontSize: 13.w,
color: const Color.fromRGBO(144, 144, 144, 1)
),
), //
),
)
], ],
), ),
), ),

76
lib/widget/live/audience_item.dart

@ -1,6 +1,7 @@
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:dating_touchme_app/generated/assets.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
@ -10,7 +11,16 @@ class AudienceItem extends StatefulWidget {
final Records item; final Records item;
final List<Map<String, dynamic>> selectUserId; final List<Map<String, dynamic>> selectUserId;
final Function(String, int) selectChange; final Function(String, int) selectChange;
const AudienceItem({super.key, required this.item, required this.selectUserId, required this.selectChange});
bool enableIf;
int nowSex;
AudienceItem({
super.key,
required this.item,
required this.selectUserId,
required this.selectChange,
this.enableIf = false,
this.nowSex = 0,
});
@override @override
State<AudienceItem> createState() => _AudienceItemState(); State<AudienceItem> createState() => _AudienceItemState();
@ -45,6 +55,7 @@ class _AudienceItemState extends State<AudienceItem> {
), ),
SizedBox(width: 5.w,), SizedBox(width: 5.w,),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
widget.item.nickName ?? "", widget.item.nickName ?? "",
@ -52,12 +63,53 @@ class _AudienceItemState extends State<AudienceItem> {
fontSize: 12.w fontSize: 12.w
), ),
), ),
Text(
"${widget.item.age ?? ""}",
style: TextStyle(
fontSize: 12.w,
color: const Color.fromRGBO(121, 121, 121, 1)
),
Row(
children: [
Text(
"${widget.item.age ?? ""}",
style: TextStyle(
fontSize: 12.w,
color: const Color.fromRGBO(121, 121, 121, 1)
),
),
SizedBox(width: 10.w,),
if(widget.item?.genderCode == 1) Container(
width: 13.w,
height: 13.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(13.w)),
color: const Color.fromRGBO(255, 237, 255, 1)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
Assets.imagesFemale,
width: 8.w,
height: 8.w,
),
],
),
),
if(widget.item?.genderCode == 0) Container(
width: 13.w,
height: 13.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(13.w)),
color: const Color.fromRGBO(237, 245, 255, 1)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
Assets.imagesMale,
width: 8.w,
height: 8.w,
),
],
),
),
],
), ),
], ],
) )
@ -66,13 +118,21 @@ class _AudienceItemState extends State<AudienceItem> {
Checkbox( Checkbox(
value: widget.selectUserId.indexWhere((e) => e["userId"] == widget.item.userId) != -1, value: widget.selectUserId.indexWhere((e) => e["userId"] == widget.item.userId) != -1,
onChanged: (value) {
onChanged: widget.enableIf && (widget.nowSex == widget.item.genderCode) ? null : (value) {
widget.selectChange(widget.item.userId ?? "", widget.item.userManagementId ?? 0); widget.selectChange(widget.item.userId ?? "", widget.item.userManagementId ?? 0);
}, },
activeColor: const Color.fromRGBO(117, 98, 249, 1), activeColor: const Color.fromRGBO(117, 98, 249, 1),
side: const BorderSide(color: Colors.grey), side: const BorderSide(color: Colors.grey),
shape: const CircleBorder(), shape: const CircleBorder(),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
fillColor: MaterialStateProperty.resolveWith((states) {
if (states.contains(MaterialState.disabled)) {
return const Color.fromRGBO(0, 0, 0, .1); //
} else if(states.contains(MaterialState.selected)){
return const Color.fromRGBO(117, 98, 249, 1);
}
return Colors.white;
}),
), ),
], ],
), ),

90
lib/widget/live/live_room_anchor_showcase.dart

@ -130,49 +130,55 @@ class _LiveRoomAnchorShowcaseState extends State<LiveRoomAnchorShowcase> {
), ),
); );
}), }),
Positioned(
left: 5.w,
bottom: 5.w,
child: Row(
children: [
Container(
width: 20.w,
height: 20.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(4.w),
Obx(() {
return Positioned(
left: 5.w,
bottom: 5.w,
child: Row(
children: [
Container(
width: 20.w,
height: 20.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(4.w),
),
color: const Color.fromRGBO(0, 0, 0, .65),
), ),
color: const Color.fromRGBO(0, 0, 0, .65),
),
child: Center(
child: Image.asset(
(_roomController
.rtcChannelDetail
.value?.anchorInfo?.isMicrophoneOn ?? false)
? Assets.imagesMicOpen
: Assets.imagesMicClose,
width: 10.w,
height: 11.w,
child: Center(
child: Image.asset(
(_roomController
.rtcChannelDetail
.value?.anchorInfo?.isMicrophoneOn ?? false)
? Assets.imagesMicOpen
: Assets.imagesMicClose,
width: 10.w,
height: 11.w,
),
), ),
),
).onTap(() {
if(_roomController.currentRole == CurrentRole.broadcaster){
_roomController
.rtcChannelDetail
.value?.anchorInfo?.isMicrophoneOn = !(_roomController
.rtcChannelDetail
.value?.anchorInfo?.isMicrophoneOn ?? false);
RTCManager.instance.muteLocalAudio(!(_roomController
.rtcChannelDetail
.value?.anchorInfo?.isMicrophoneOn ?? false));
setState(() {
).onTap(() {
if(_roomController.currentRole == CurrentRole.broadcaster){
_roomController
.rtcChannelDetail
.value?.anchorInfo?.isMicrophoneOn = !(_roomController
.rtcChannelDetail
.value?.anchorInfo?.isMicrophoneOn ?? false);
RTCManager.instance.muteLocalAudio(!(_roomController
.rtcChannelDetail
.value?.anchorInfo?.isMicrophoneOn ?? false));
});
}
}),
],
),
),
_roomController.changeMic(_roomController
.rtcChannelDetail
.value?.anchorInfo!.isMicrophoneOn ?? false);
setState(() {
});
}
}),
],
),
);
}),
], ],
), ),
SizedBox(height: 5.w), SizedBox(height: 5.w),
@ -386,6 +392,8 @@ class _LiveRoomAnchorShowcaseState extends State<LiveRoomAnchorShowcase> {
userInfo.isMicrophoneOn = !(userInfo.isMicrophoneOn ?? false); userInfo.isMicrophoneOn = !(userInfo.isMicrophoneOn ?? false);
RTCManager.instance.muteLocalAudio(!(userInfo.isMicrophoneOn ?? false)); RTCManager.instance.muteLocalAudio(!(userInfo.isMicrophoneOn ?? false));
_roomController.changeMic(userInfo.isMicrophoneOn ?? false);
setState(() { setState(() {
}); });
@ -445,7 +453,7 @@ class _LiveRoomAnchorShowcaseState extends State<LiveRoomAnchorShowcase> {
// return LiveRoomGuestListDialog( // return LiveRoomGuestListDialog(
// initialTab: isMaleSeat ? 1 : 0, // 0: , 1: // initialTab: isMaleSeat ? 1 : 0, // 0: , 1:
// ); // );
return LiveRoomInvitationList();
return LiveRoomInvitationList(nowSex: isMaleSeat ? 1 : 0,);
}, },
); );
} }

11
lib/widget/live/live_room_invitation_list.dart

@ -13,7 +13,8 @@ import 'package:tdesign_flutter/tdesign_flutter.dart';
import 'audience_item.dart'; import 'audience_item.dart';
class LiveRoomInvitationList extends StatefulWidget { class LiveRoomInvitationList extends StatefulWidget {
const LiveRoomInvitationList({super.key});
final int nowSex;
const LiveRoomInvitationList({super.key, required this.nowSex});
@override @override
State<LiveRoomInvitationList> createState() => _LiveRoomInvitationListState(); State<LiveRoomInvitationList> createState() => _LiveRoomInvitationListState();
@ -147,7 +148,13 @@ class _LiveRoomInvitationListState extends State<LiveRoomInvitationList> with Ti
} }
// //
final item = _roomController.audienceList[index]; final item = _roomController.audienceList[index];
return AudienceItem(item: item, selectUserId: selectUserId, selectChange: selectChange,);
return AudienceItem(
item: item,
selectUserId: selectUserId,
selectChange: selectChange,
enableIf: true,
nowSex: widget.nowSex,
);
}, },
separatorBuilder: (context, index) { separatorBuilder: (context, index) {
// //

Loading…
Cancel
Save