From 06a9eb44d02bc7541efde6589db36254a06ac4ff Mon Sep 17 00:00:00 2001 From: fuenmao <980740792@qq.com> Date: Thu, 28 Nov 2024 11:22:50 +0800 Subject: [PATCH] =?UTF-8?q?1.=E8=81=8A=E5=A4=A9=E6=8E=A5=E5=8F=A3=E6=8E=A5?= =?UTF-8?q?=E5=85=A5=202.=E8=81=8A=E5=A4=A9=E5=92=8C=E6=88=90=E5=91=98?= =?UTF-8?q?=E5=BA=95=E9=83=A8=E5=BC=B9=E7=AA=97=E5=88=B7=E6=96=B0=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/common/models/meeting_room_msg.dart | 23 ++ wgshare/lib/pages/homePage/home_view.dart | 12 +- .../lib/pages/metting/meeting_main_logic.dart | 36 ++- .../lib/pages/metting/meeting_main_state.dart | 5 + .../lib/pages/metting/meeting_main_view.dart | 277 ++++++++++-------- 5 files changed, 217 insertions(+), 136 deletions(-) create mode 100644 wgshare/lib/common/models/meeting_room_msg.dart diff --git a/wgshare/lib/common/models/meeting_room_msg.dart b/wgshare/lib/common/models/meeting_room_msg.dart new file mode 100644 index 0000000..9043751 --- /dev/null +++ b/wgshare/lib/common/models/meeting_room_msg.dart @@ -0,0 +1,23 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'meeting_room_msg.g.dart'; + +@JsonSerializable() +class MeetingRoomMsg extends Object{ + + String uid; + + String userName; + + String message; + + // 0:别人,1:自己 + int source; + + MeetingRoomMsg(this.uid,this.userName,this.message,this.source); + + factory MeetingRoomMsg.fromJson(Map srcJson) => _$MeetingRoomMsgFromJson(srcJson); + +} + + diff --git a/wgshare/lib/pages/homePage/home_view.dart b/wgshare/lib/pages/homePage/home_view.dart index 2f9284e..38d47da 100644 --- a/wgshare/lib/pages/homePage/home_view.dart +++ b/wgshare/lib/pages/homePage/home_view.dart @@ -90,7 +90,7 @@ class HomePageState extends State with AutomaticKeepAliveClientMixin { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - state.meetingRooms[index].roomName, + state.meetingRooms.value[index].roomName, style: TextStyle( fontSize: 14.sp, color: ColorUtil.Color_89_88_88, @@ -105,7 +105,7 @@ class HomePageState extends State with AutomaticKeepAliveClientMixin { height: 16.h, ), Text( - '${state.meetingRooms[index].onlineUserCount}人', + '${state.meetingRooms.value[index].onlineUserCount}人', style: TextStyle( fontSize: 12.sp, color: ColorUtil.Color_177_177_177, @@ -122,7 +122,7 @@ class HomePageState extends State with AutomaticKeepAliveClientMixin { Row( children: [ Text( - state.meetingRooms[index].roomNum, + state.meetingRooms.value[index].roomNum, style: TextStyle( fontSize: 12.sp, color: ColorUtil.Color_177_177_177, @@ -136,7 +136,7 @@ class HomePageState extends State with AutomaticKeepAliveClientMixin { height: 16.h, ), onTap: (){ - Clipboard.setData(ClipboardData(text: state.meetingRooms[index].roomNum)); + Clipboard.setData(ClipboardData(text: state.meetingRooms.value[index].roomNum)); ToastUtils.showSuccess("复制成功"); }, ) @@ -169,7 +169,7 @@ class HomePageState extends State with AutomaticKeepAliveClientMixin { ), ), onTap: (){ - Get.toNamed(Routes.meetingMainPage, arguments: {"roomNumber": state.meetingRooms[index].roomNum}); + Get.toNamed(Routes.meetingMainPage, arguments: {"roomNumber": state.meetingRooms.value[index].roomNum}); }, ) ], @@ -178,7 +178,7 @@ class HomePageState extends State with AutomaticKeepAliveClientMixin { ), ); }, - itemCount: state.meetingRooms.length, + itemCount: state.meetingRooms.value.length, ), ), ), diff --git a/wgshare/lib/pages/metting/meeting_main_logic.dart b/wgshare/lib/pages/metting/meeting_main_logic.dart index 873058c..64ca905 100644 --- a/wgshare/lib/pages/metting/meeting_main_logic.dart +++ b/wgshare/lib/pages/metting/meeting_main_logic.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:convert'; - import 'package:agora_rtc_engine/agora_rtc_engine.dart'; import 'package:flutter/foundation.dart'; import 'package:get/get.dart'; @@ -10,6 +9,7 @@ import '../../common/config/request_config.dart'; import '../../common/mixins/request_tool_mixin.dart'; import '../../common/models/common/base_structure_result.dart'; import '../../common/models/meeting_room_info.dart'; +import '../../common/models/meeting_room_msg.dart'; import '../../common/models/meeting_room_user.dart'; import '../../utils/permission_handler.dart'; import '../../utils/toast_utils.dart'; @@ -33,6 +33,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{ void onClose() { super.onClose(); state.memberNameSearchController.dispose(); + state.sendMsgController.dispose(); stopTime(); leaveMeetingToRtc(); leaveMeetingToSocket(); @@ -154,7 +155,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{ /// 远端用户或主播加入会议室回调 state.hubConnection.value?.on("UserJoined", (user){ - var jsonStr = json.encode(user); + var jsonStr = const Utf8Decoder().convert(json.encode(user).runes.toList()); var listDynamic = jsonDecode(jsonStr); List meetingRoomUsers = (listDynamic as List).map((e) => MeetingRoomUser.fromJson((e as Map))).toList(); state.cacheUsers.value.addAll(meetingRoomUsers); @@ -164,7 +165,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{ /// 远端用户或主播离开会议室回调 state.hubConnection.value?.on("UserLeave", (uid){ - var jsonStr = json.encode(uid); + var jsonStr = const Utf8Decoder().convert(json.encode(uid).runes.toList()); List listDynamic = jsonDecode(jsonStr); for(String uidStr in listDynamic){ for(var j = 0; j < state.cacheUsers.value.length; j++){ @@ -179,7 +180,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{ /// 申请/结束发言-管理员同意或拒绝回调 state.hubConnection.value?.on("ManagerRefresh", (e){ - var jsonStr = json.encode(e?[0]); + var jsonStr = const Utf8Decoder().convert(json.encode(e?[0]).runes.toList()); var listDynamic = jsonDecode(jsonStr); MeetingRoomUser meetingRoomUser = MeetingRoomUser.fromJson(listDynamic); if(meetingRoomUser.isRoomManager == true){ @@ -205,7 +206,20 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{ state.isSpeak.value = false; setEnableLocalAudio(false); } + update(); + }); + /// 会议室接收消息 + state.hubConnection.value?.on("ReceiveMessage", (e){ + var jsonStr = const Utf8Decoder().convert(json.encode(e).runes.toList()); + List list = json.decode(jsonStr); + MeetingRoomMsg meetingRoomMsg = MeetingRoomMsg(list[0],list[1],list[2],0); + state.meetingRoomMsgs.value.add(meetingRoomMsg); + update(); + Future.delayed(const Duration(milliseconds: 100), () { + state.chatController.jumpTo(state.chatController.position.maxScrollExtent); + }); + debugPrint("wgs输出===:Socket-会议室接收消息:$jsonStr"); }); } @@ -220,6 +234,20 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{ await state.hubConnection.value?.invoke("levelChannel", args: [state.roomNumber.value]); } + /// 会议室发送消息 + Future sendMsg(String msg) async { + MeetingRoomMsg meetingRoomMsg = MeetingRoomMsg( + UserStore.to.userInfoEntity.value!.uid, + UserStore.to.userInfoEntity.value!.userName, + msg,1); + state.meetingRoomMsgs.value.add(meetingRoomMsg); + update(); + Future.delayed(const Duration(milliseconds: 100), () { + state.chatController.jumpTo(state.chatController.position.maxScrollExtent); + }); + await state.hubConnection.value?.invoke("sendChannelMsg", args: [state.roomNumber.value, msg]); + } + /// --------------------------声网SDK相关 /// 初始化声网SDK Future initRtc() async { diff --git a/wgshare/lib/pages/metting/meeting_main_state.dart b/wgshare/lib/pages/metting/meeting_main_state.dart index dac8512..fe2db6a 100644 --- a/wgshare/lib/pages/metting/meeting_main_state.dart +++ b/wgshare/lib/pages/metting/meeting_main_state.dart @@ -7,6 +7,7 @@ import 'package:get/get_rx/src/rx_types/rx_types.dart'; import 'package:signalr_core/signalr_core.dart'; import '../../common/models/meeting_room_info.dart'; +import '../../common/models/meeting_room_msg.dart'; import '../../common/models/meeting_room_user.dart'; class MeetingMainState { @@ -16,6 +17,7 @@ class MeetingMainState { } late TextEditingController memberNameSearchController = TextEditingController(); + late TextEditingController sendMsgController = TextEditingController(); /// 是否显示会议信息浮层 late RxBool isShowMeetingInfoFloatingLayer = false.obs; @@ -52,6 +54,9 @@ class MeetingMainState { /// 是否被允许发言 late RxBool isSpeak = false.obs; + /// 聊天数据 + late RxList meetingRoomMsgs = RxList([]); + /// signalR 长连接相关 late RxString serviceUrl = "http://192.168.2.9:5192/session-manage".obs; late Rx hubConnection = Rx(null); diff --git a/wgshare/lib/pages/metting/meeting_main_view.dart b/wgshare/lib/pages/metting/meeting_main_view.dart index 84e454e..442129a 100644 --- a/wgshare/lib/pages/metting/meeting_main_view.dart +++ b/wgshare/lib/pages/metting/meeting_main_view.dart @@ -148,7 +148,7 @@ class MeetingMainPage extends StatelessWidget { // 语音 Visibility( visible: true, - child: MeetingMainVoiceComponent(users: state.cacheUsers) + child: MeetingMainVoiceComponent(users: state.cacheUsers.value) ), // 视频 @@ -324,7 +324,7 @@ class MeetingMainPage extends StatelessWidget { onTap: () { Get.bottomSheet( isScrollControlled: true, - Obx(() => queryMemberFloatingLayer(context)), + queryMemberFloatingLayer(context), ); }, ), @@ -880,121 +880,124 @@ class MeetingMainPage extends StatelessWidget { margin: const EdgeInsets.only(top: 18, left: 16, right: 16, bottom: 16), child: Text( - '会议中(${state.users.length})', + '会议中(${state.users.value.length})', style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w500, color: ColorUtil.Color_85_117_242), ), ), + Expanded( child: ScrollConfiguration( behavior: CusBehavior(), - child: ListView.builder( - itemBuilder: (context, index) { - return Container( - width: double.infinity, - margin: EdgeInsets.only(bottom: index == 9 ? 18 : 0), - child: Column( - children: [ - Container( - padding: const EdgeInsets.only(left: 16, right: 16), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(100), - color: ColorUtil.Color_85_117_242 - ), - margin: const EdgeInsets.only(right: 8), - width: 36.w, - height: 36.h, - alignment: Alignment.center, - child: Text( - state.users[index].userName.length > 3 - ? state.users[index].userName.substring(state.users[index].userName.length - 2,state.users[index].userName.length) - : state.users[index].userName, - style: TextStyle( - fontSize: 12.sp, - color: ColorUtil.Color_244_244_244 + child: GetBuilder(builder: (controll){ + return ListView.builder( + itemBuilder: (context, index) { + return Container( + width: double.infinity, + margin: EdgeInsets.only(bottom: index == 9 ? 18 : 0), + child: Column( + children: [ + Container( + padding: const EdgeInsets.only(left: 16, right: 16), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(100), + color: ColorUtil.Color_85_117_242 + ), + margin: const EdgeInsets.only(right: 8), + width: 36.w, + height: 36.h, + alignment: Alignment.center, + child: Text( + state.users.value[index].userName.length > 3 + ? state.users.value[index].userName.substring(state.users.value[index].userName.length - 2,state.users.value[index].userName.length) + : state.users.value[index].userName, + style: TextStyle( + fontSize: 12.sp, + color: ColorUtil.Color_244_244_244 + ), ), ), - ), - Text( - state.users[index].userName, - style: TextStyle( - fontSize: 14.sp, - fontWeight: FontWeight.w600, - color: ColorUtil.Color_243_243_243), - ), - SizedBox(width: 8.w), - Visibility( - visible: state.users[index].roleId == "1" || state.users[index].roleId == "3" ? true : false, - child: Text( - '主持人', + Text( + state.users.value[index].userName, style: TextStyle( - fontSize: 12.sp, - fontWeight: FontWeight.w500, - color: ColorUtil.Color_2_177_136), + fontSize: 14.sp, + fontWeight: FontWeight.w600, + color: ColorUtil.Color_243_243_243), ), - ), - Visibility( - visible: state.users[index].roleId == "2" && state.users[index].isRoomManager == true ? true : false, - child: Text( - '发言人', - style: TextStyle( - fontSize: 12.sp, - fontWeight: FontWeight.w500, - color: ColorUtil.Color_2_177_136), + SizedBox(width: 8.w), + Visibility( + visible: state.users.value[index].roleId == "1" || state.users.value[index].roleId == "3" ? true : false, + child: Text( + '主持人', + style: TextStyle( + fontSize: 12.sp, + fontWeight: FontWeight.w500, + color: ColorUtil.Color_2_177_136), + ), ), - ) - ], - ), - Row( - children: [ - Container( - child: Image.asset( - 'assets/images/meeting_main_share_currently.png', - width: 17.w, - height: 17.h, + Visibility( + visible: state.users.value[index].roleId == "2" && state.users.value[index].isRoomManager == true ? true : false, + child: Text( + '发言人', + style: TextStyle( + fontSize: 12.sp, + fontWeight: FontWeight.w500, + color: ColorUtil.Color_2_177_136), + ), + ) + ], + ), + Row( + children: [ + Container( + child: Image.asset( + 'assets/images/meeting_main_share_currently.png', + width: 17.w, + height: 17.h, + ), ), - ), - Container( - margin: const EdgeInsets.only(left: 12), - child: Image.asset( - state.users[index].enableMicr == true ? 'assets/images/meeting_main_microphone_default.png' : 'assets/images/meeting_main_microphone_close.png', - width: 17.w, - height: 17.h, + Container( + margin: const EdgeInsets.only(left: 12), + child: Image.asset( + state.users.value[index].enableMicr == true ? 'assets/images/meeting_main_microphone_default.png' : 'assets/images/meeting_main_microphone_close.png', + width: 17.w, + height: 17.h, + ), ), - ), - Container( - margin: const EdgeInsets.only(left: 12), - child: Image.asset( - state.users[index].enableCamera == true ? 'assets/images/meeting_main_camera_default.png' : 'assets/images/meeting_main_camera_close.png', - width: 17.w, - height: 17.h, - ), - ) - ], - ) - ], + Container( + margin: const EdgeInsets.only(left: 12), + child: Image.asset( + state.users.value[index].enableCamera == true ? 'assets/images/meeting_main_camera_default.png' : 'assets/images/meeting_main_camera_close.png', + width: 17.w, + height: 17.h, + ), + ) + ], + ) + ], + ), ), - ), - Container( - width: double.infinity, - height: 0.5.h, - margin: const EdgeInsets.only(top: 12, bottom: 12), - color: ColorUtil.Color_49_47_47, - ) - ], - ), - ); - }, - itemCount: state.users.length, - ) + Container( + width: double.infinity, + height: 0.5.h, + margin: const EdgeInsets.only(top: 12, bottom: 12), + color: ColorUtil.Color_49_47_47, + ) + ], + ), + ); + }, + itemCount: state.users.value.length, + ); + }) ), ) ], @@ -1049,13 +1052,15 @@ class MeetingMainPage extends StatelessWidget { Expanded( child: ScrollConfiguration( behavior: CusBehavior(), - child: ListView.builder( - controller: state.chatController, - itemBuilder: (context, index) { - return index == 0 || index == 2 ? chartItemToOthers(index) : chartItemToOwn(index); - }, - itemCount: 6, - ) + child: GetBuilder(builder: (controll){ + return ListView.builder( + controller: state.chatController, + itemBuilder: (context, index) { + return state.meetingRoomMsgs.value[index].source == 0 ? chartItemToOthers(index) : chartItemToOwn(index); + }, + itemCount: state.meetingRoomMsgs.value.length, + ); + }) ), ), Container( @@ -1070,17 +1075,27 @@ class MeetingMainPage extends StatelessWidget { color: ColorUtil.Color_53_53_53, ), child: TextField( + controller: state.sendMsgController, style: TextStyle( fontSize: 14.sp, color: ColorUtil.Color_235_235_235 ), decoration: InputDecoration( - contentPadding: EdgeInsets.all(0), - border: OutlineInputBorder(borderSide: BorderSide.none), + contentPadding: const EdgeInsets.all(0), + border: const OutlineInputBorder(borderSide: BorderSide.none), hintText: '请输入内容...', hintStyle: TextStyle( color: ColorUtil.Color_235_235_235, - fontSize: 14.sp)), + fontSize: 14.sp) + ), + onSubmitted: (value){ + if(value.isNotEmpty){ + logic.sendMsg(value); + state.sendMsgController.text = ""; + }else{ + ToastUtils.showError("请输入内容"); + } + }, ), ), ) @@ -1102,15 +1117,20 @@ class MeetingMainPage extends StatelessWidget { Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(99), - image: DecorationImage( - fit: BoxFit.cover, - image: NetworkImage( - "https://ts4.cn.mm.bing.net/th?id=OIP-C.QDl_Z7HdQWX_XbVYgBLJLQAAAA&w=250&h=250&c=8&rs=1&qlt=90&o=6&pid=3.1&rm=2", - ), - ), + color: ColorUtil.Color_85_117_242 ), width: 50.w, height: 50.h, + alignment: Alignment.center, + child: Text( + state.meetingRoomMsgs.value[index].userName.length > 3 + ? state.meetingRoomMsgs.value[index].userName.substring(state.meetingRoomMsgs.value[index].userName.length - 2,state.meetingRoomMsgs.value[index].userName.length) + : state.meetingRoomMsgs.value[index].userName, + style: TextStyle( + fontSize: 14.sp, + color: ColorUtil.Color_244_244_244 + ), + ), ), Expanded( child: Column( @@ -1119,7 +1139,7 @@ class MeetingMainPage extends StatelessWidget { Container( margin: const EdgeInsets.only(left: 6), child: Text( - '晓晓', + state.meetingRoomMsgs.value[index].userName, style: TextStyle( fontSize: 10.sp, color: ColorUtil.Color_202_202_202), @@ -1138,7 +1158,7 @@ class MeetingMainPage extends StatelessWidget { color: ColorUtil.Color_53_53_53, ), child: Text( - '你好啊...............你好啊...............', + state.meetingRoomMsgs.value[index].message, style: TextStyle( fontSize: 12.sp, color: ColorUtil.Color_235_235_235), @@ -1169,7 +1189,7 @@ class MeetingMainPage extends StatelessWidget { Container( margin: const EdgeInsets.only(right: 6), child: Text( - '晓晓', + state.meetingRoomMsgs.value[index].userName, style: TextStyle( fontSize: 10.sp, color: ColorUtil.Color_202_202_202), @@ -1189,7 +1209,7 @@ class MeetingMainPage extends StatelessWidget { color: ColorUtil.Color_85_117_242, ), child: Text( - '你好啊...............你好啊...............', + state.meetingRoomMsgs.value[index].message, style: TextStyle( fontSize: 12.sp, color: ColorUtil.Color_235_235_235), @@ -1201,15 +1221,20 @@ class MeetingMainPage extends StatelessWidget { Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(99), - image: DecorationImage( - fit: BoxFit.cover, - image: NetworkImage( - "https://ts4.cn.mm.bing.net/th?id=OIP-C.QDl_Z7HdQWX_XbVYgBLJLQAAAA&w=250&h=250&c=8&rs=1&qlt=90&o=6&pid=3.1&rm=2", - ), - ), + color: ColorUtil.Color_85_117_242 ), width: 50.w, height: 50.h, + alignment: Alignment.center, + child: Text( + state.meetingRoomMsgs.value[index].userName.length > 3 + ? state.meetingRoomMsgs.value[index].userName.substring(state.meetingRoomMsgs.value[index].userName.length - 2,state.meetingRoomMsgs.value[index].userName.length) + : state.meetingRoomMsgs.value[index].userName, + style: TextStyle( + fontSize: 14.sp, + color: ColorUtil.Color_244_244_244 + ), + ), ) ], ),