diff --git a/wgshare/lib/common/api/retrofit_client.dart b/wgshare/lib/common/api/retrofit_client.dart index b3f6d92..2e42689 100644 --- a/wgshare/lib/common/api/retrofit_client.dart +++ b/wgshare/lib/common/api/retrofit_client.dart @@ -2,6 +2,8 @@ import 'package:dio/dio.dart' hide Headers; import 'package:retrofit/retrofit.dart'; import '../models/common/base_structure_result.dart'; +import '../models/meeting_room_item.dart'; +import '../models/user_info_entity.dart'; part 'retrofit_client.g.dart'; @@ -10,6 +12,25 @@ part 'retrofit_client.g.dart'; abstract class RetrofitClient { factory RetrofitClient(Dio dio, {String? baseUrl}) = _RetrofitClient; - // @POST("/api/user/users/login") - // Future> toLogin(@Body() LoginParams loginParams); + /// 账号密码登录 + @POST("/auth/login") + Future> login( + @Field("account") String account, + @Field("pwd") String pwd + ); + + /// 会议号昵称登录 + @POST("/auth/anon-login") + Future> anonLogin( + @Field("deviceId") String deviceId, + @Field("nickName") String nickName, + @Field("roomNum") String roomNum + ); + + /// 获取会议列表 + @GET("/home/room") + Future> getMeetingRoomList( + @Query("PageIndex") int PageIndex, + @Query("PageSize") int PageSize, + ); } diff --git a/wgshare/lib/common/config/request_config.dart b/wgshare/lib/common/config/request_config.dart index dff8037..687f419 100644 --- a/wgshare/lib/common/config/request_config.dart +++ b/wgshare/lib/common/config/request_config.dart @@ -2,7 +2,8 @@ import 'package:wgshare/common/models/common/base_page.dart'; class RequestConfig { // static const _devBaseUrl = "https://zyapitest.23544.com:16440"; // 开发 - static const _devBaseUrl = "https://zyapitest.23544.com:16440"; // 开发 + // static const _devBaseUrl = "https://zyapitest.23544.com:16440"; // 开发 + static const _devBaseUrl = "http://192.168.2.9:5192"; // 开发 // static const _proBaseUrl = "http://192.168.2.119:1091"; // 生产 static const _proBaseUrl = "https://zyapi.23544.com/ipadapi"; // 生产 static const imgUrl = 'https://dpc-job-oss.23544.com/'; diff --git a/wgshare/lib/common/models/meeting_room_item.dart b/wgshare/lib/common/models/meeting_room_item.dart new file mode 100644 index 0000000..39248ce --- /dev/null +++ b/wgshare/lib/common/models/meeting_room_item.dart @@ -0,0 +1,50 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'meeting_room_item.g.dart'; + +@JsonSerializable() +class MeetingRoomItem extends Object{ + + @JsonKey(name: 'totalPage') + int totalPage; + + @JsonKey(name: 'total') + int total; + + @JsonKey(name: 'items') + List items; + + MeetingRoomItem(this.totalPage, this.total,this.items,); + + factory MeetingRoomItem.fromJson(Map srcJson) => _$MeetingRoomItemFromJson(srcJson); + +} + +@JsonSerializable() +class Items extends Object{ + + @JsonKey(name: 'id') + String id; + + @JsonKey(name: 'roomName') + String roomName; + + @JsonKey(name: 'roomNum') + String roomNum; + + @JsonKey(name: 'onlineUserCount') + int onlineUserCount; + + @JsonKey(name: 'year') + int year; + + @JsonKey(name: 'subject') + int subject; + + Items(this.id,this.roomName,this.roomNum,this.onlineUserCount,this.year,this.subject,); + + factory Items.fromJson(Map srcJson) => _$ItemsFromJson(srcJson); + +} + + diff --git a/wgshare/lib/common/models/user_info_detail.dart b/wgshare/lib/common/models/user_info_detail.dart deleted file mode 100644 index 12dc650..0000000 --- a/wgshare/lib/common/models/user_info_detail.dart +++ /dev/null @@ -1,278 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'user_info_detail.g.dart'; - -@JsonSerializable(checked: true) -class UserInfoDetail extends Object { - @JsonKey(name: 'Name') - String name; - - @JsonKey(name: 'Status') - int status; - - @JsonKey(name: 'Mobile') - String? mobile; - - @JsonKey(name: 'Account') - String account; - - @JsonKey(name: 'UserType') - int userType; - - @JsonKey(name: 'SchoolId') - int schoolId; - - @JsonKey(name: 'SchoolName') - String? schoolName; - - @JsonKey(name: 'Email') - String? email; - - @JsonKey(name: 'Id') - int id; - - @JsonKey(name: 'RecordIsShow') - bool recordIsShow; - - @JsonKey(name: 'LiveIsShow') - bool liveIsShow; - - @JsonKey(name: 'FileIsShow') - bool fileIsShow; - - @JsonKey(name: 'EquipmentIsShow') - bool equipmentIsShow; - - @JsonKey(name: 'DataIsShow') - bool dataIsShow; - - @JsonKey(name: 'DataUrl') - String? dataUrl; - - @JsonKey(name: 'TaskIsShow') - bool taskIsShow; - - @JsonKey(name: 'DataMonitorIsShow') - bool dataMonitorIsShow; - - @JsonKey(name: 'GCSLists') - List? gCSLists; - - @JsonKey(name: 'LearnedCoursesNum') - int learnedCoursesNum; - - @JsonKey(name: 'RoleAnys') - RoleAnys roleAnys; - - @JsonKey(name: 'RoleIsShowMenus') - List roleIsShowMenus; - - @JsonKey(name: 'OrgId') - int orgId; - - @JsonKey(name: 'IsCanVerify') - bool isCanVerify; - - @JsonKey(name: 'StageSubject') - StageSubject? stageSubject; - - @JsonKey(name: 'UserOrgList') - List userOrgList; - - // 蓝牙笔 SN - @JsonKey(name: 'PointPenSn') - String? pointPenSn; - - // 蓝牙笔 Mac - @JsonKey(name: 'PointPenMAC') - String? pointPenMac; - - UserInfoDetail( - this.name, - this.status, - this.mobile, - this.account, - this.userType, - this.schoolId, - this.schoolName, - this.email, - this.id, - this.recordIsShow, - this.liveIsShow, - this.fileIsShow, - this.equipmentIsShow, - this.dataIsShow, - this.dataUrl, - this.taskIsShow, - this.dataMonitorIsShow, - this.gCSLists, - this.learnedCoursesNum, - this.roleAnys, - this.roleIsShowMenus, - this.orgId, - this.isCanVerify, - this.stageSubject, - this.userOrgList, - this.pointPenSn, - this.pointPenMac, - ) { - // 系統如果被非法操作,否则不会出现此情况,Mac 不会单独存在 - if (pointPenSn == null && pointPenMac != null) { - pointPenMac = null; - } - } - - factory UserInfoDetail.fromJson(Map srcJson) => _$UserInfoDetailFromJson(srcJson); - - Map toJson() => _$UserInfoDetailToJson(this); -} - -@JsonSerializable() -class GCSLists extends Object { - @JsonKey(name: 'Value') - String value; - - @JsonKey(name: 'Text') - String? text; - - @JsonKey(name: 'GCSLists') - List? gCSLists; - - GCSLists( - this.value, - this.text, - this.gCSLists, - ); - - factory GCSLists.fromJson(Map srcJson) => _$GCSListsFromJson(srcJson); - - Map toJson() => _$GCSListsToJson(this); -} - -@JsonSerializable() -class RoleAnys extends Object { - @JsonKey(name: 'YxIsShow') - bool yxIsShow; - - @JsonKey(name: 'HtzxIsShow') - bool htzxIsShow; - - @JsonKey(name: 'ZjIsShow') - bool zjIsShow; - - @JsonKey(name: 'LjzkIsShow') - bool ljzkIsShow; - - @JsonKey(name: 'IsResoure') - bool isResoure; - - @JsonKey(name: 'YxNeiBuIsShow') - bool yxNeiBuIsShow; - - @JsonKey(name: 'HtNeiBuIsShow') - bool htNeiBuIsShow; - - @JsonKey(name: 'ZhongZhiIsShow') - bool zhongZhiIsShow; - - @JsonKey(name: 'JSCZIsShow') - bool jSCZIsShow; - - @JsonKey(name: 'YLRHYXIsShow') - bool yLRHYXIsShow; - - @JsonKey(name: 'CSFZIsShow') - bool cSFZIsShow; - - @JsonKey(name: 'YBYXIsShow') - bool yBYXIsShow; - - RoleAnys( - this.yxIsShow, - this.htzxIsShow, - this.zjIsShow, - this.ljzkIsShow, - this.isResoure, - this.yxNeiBuIsShow, - this.htNeiBuIsShow, - this.zhongZhiIsShow, - this.jSCZIsShow, - this.yLRHYXIsShow, - this.cSFZIsShow, - this.yBYXIsShow, - ); - - factory RoleAnys.fromJson(Map srcJson) => _$RoleAnysFromJson(srcJson); - - Map toJson() => _$RoleAnysToJson(this); -} - -@JsonSerializable() -class RoleIsShowMenus extends Object { - @JsonKey(name: 'MenuName') - String menuName; - - @JsonKey(name: 'MenuUrl') - String menuUrl; - - @JsonKey(name: 'Parameter') - String? parameter; - - @JsonKey(name: 'Children') - List? children; - - RoleIsShowMenus( - this.menuName, - this.menuUrl, - this.parameter, - this.children, - ); - - factory RoleIsShowMenus.fromJson(Map srcJson) => _$RoleIsShowMenusFromJson(srcJson); - - Map toJson() => _$RoleIsShowMenusToJson(this); -} - -@JsonSerializable() -class StageSubject extends Object { - @JsonKey(name: 'StageId') - int stageId; - - @JsonKey(name: 'StageName') - String stageName; - - @JsonKey(name: 'SubjectId') - int subjectId; - - @JsonKey(name: 'SubjectName') - String subjectName; - - StageSubject( - this.stageId, - this.stageName, - this.subjectId, - this.subjectName, - ); - - factory StageSubject.fromJson(Map srcJson) => _$StageSubjectFromJson(srcJson); - - Map toJson() => _$StageSubjectToJson(this); -} - -@JsonSerializable() -class UserOrgList extends Object { - @JsonKey(name: 'Id') - int id; - - @JsonKey(name: 'Name') - String name; - - UserOrgList( - this.id, - this.name, - ); - - factory UserOrgList.fromJson(Map srcJson) => _$UserOrgListFromJson(srcJson); - - Map toJson() => _$UserOrgListToJson(this); -} diff --git a/wgshare/lib/common/models/user_info_entity.dart b/wgshare/lib/common/models/user_info_entity.dart new file mode 100644 index 0000000..3047fce --- /dev/null +++ b/wgshare/lib/common/models/user_info_entity.dart @@ -0,0 +1,45 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'user_info_entity.g.dart'; + +@JsonSerializable() +class UserInfoEntity extends Object{ + + @JsonKey(name: 'perms') + int perms; + + @JsonKey(name: 'token') + String token; + + @JsonKey(name: 'refresh_token') + String refreshToken; + + @JsonKey(name: 'roleId') + String roleId; + + @JsonKey(name: 'userName') + String userName; + + @JsonKey(name: 'tenantName') + String tenantName; + + @JsonKey(name: 'expire') + int expire; + + @JsonKey(name: 'account') + String account; + + @JsonKey(name: 'uid') + String uid; + + @JsonKey(name: 'screenShareId') + String screenShareId; + + @JsonKey(name: 'isAnonymous') + bool isAnonymous; + + UserInfoEntity(this.perms,this.token,this.refreshToken,this.roleId,this.userName,this.tenantName,this.expire,this.account,this.uid,this.screenShareId,this.isAnonymous,); + + factory UserInfoEntity.fromJson(Map srcJson) => _$UserInfoEntityFromJson(srcJson); + +} diff --git a/wgshare/lib/common/request/rest_dio.dart b/wgshare/lib/common/request/rest_dio.dart index fdcb517..a8af8fd 100644 --- a/wgshare/lib/common/request/rest_dio.dart +++ b/wgshare/lib/common/request/rest_dio.dart @@ -104,12 +104,12 @@ class ResponseHandle extends Interceptor { @override void onResponse(Response response, ResponseInterceptorHandler handler) { int? statusCode = response.statusCode; - var data = response.data; var flag = data != null && ((data['code'] != null && (data['code'] == 401 || data['code'] == '401')) || (data['Code'] != null && (data['Code'] == 401 || data['Code'] == '401'))); + if (statusCode == 401 || flag) { Future.delayed(const Duration(seconds: 2), () { StorageService.to.erase(); @@ -117,6 +117,10 @@ class ResponseHandle extends Interceptor { }); } + if(data['code'] != 200){ + ToastUtils.showError(data['message']); + } + super.onResponse(response, handler); } } diff --git a/wgshare/lib/common/store/app_storage_key.dart b/wgshare/lib/common/store/app_storage_key.dart index 5498953..2fc6818 100644 --- a/wgshare/lib/common/store/app_storage_key.dart +++ b/wgshare/lib/common/store/app_storage_key.dart @@ -2,7 +2,7 @@ enum AppStorageKey { token(value: 'TOKEN', label: "登录用户的token"), - userInfo(value: 'USERINFO', label: "登录用户的基本信息 及 token过期时间"), + userInfo(value: 'USERINFO', label: "登录用户的基本信息"), account(value: 'ACCOUNT', label: "用户名"), pwd(value: 'PWD', label: "密码"); diff --git a/wgshare/lib/common/store/user_store.dart b/wgshare/lib/common/store/user_store.dart index 0246b75..7d6df82 100644 --- a/wgshare/lib/common/store/user_store.dart +++ b/wgshare/lib/common/store/user_store.dart @@ -1,34 +1,33 @@ import 'package:get/get.dart'; import 'package:wgshare/common/mixins/request_tool_mixin.dart'; -import 'package:wgshare/common/models/common/base_structure_result.dart'; -import 'package:wgshare/common/models/user_info_detail.dart'; import 'package:wgshare/common/store/app_storage_key.dart'; -import 'package:wgshare/routes/app_routes.dart'; import 'package:wgshare/utils/storage.dart'; +import '../models/user_info_entity.dart'; + + class UserStore extends GetxController with RequestToolMixin { static UserStore get to => Get.find(); /// 是否登录 String? token; - /// 用户Token及过期时间信息 - // Rx userInfo = Rx(null); - /// 用户详细信息 - Rx userDetailInfo = Rx(null); + /// 用户信息 + Rx userInfoEntity = Rx(null); UserStore init() { token = StorageService.to.read(AppStorageKey.token.value); try { var userDetail = StorageService.to.read(AppStorageKey.userInfo.value); if (userDetail != null) { - userDetailInfo.value = UserInfoDetail.fromJson(userDetail); + userInfoEntity.value = UserInfoEntity.fromJson(userDetail); } } catch (err) { print('$err'); StorageService.to.remove(AppStorageKey.userInfo.value); } - if ((token?.isNotEmpty ?? false) && userDetailInfo.value != null) { + if ((token?.isNotEmpty ?? false) && userInfoEntity.value != null) { + } else { /// TODO 返回登录页面 // Get.offAllNamed(Routes.login); @@ -36,28 +35,28 @@ class UserStore extends GetxController with RequestToolMixin { return this; } - /// 保存 token + /// 保存token void setToken(String token) { this.token = token; StorageService.to.write(AppStorageKey.token.value, token); } - /// 保存 用户信息 - void setUserDetailInfo(UserInfoDetail info) { - userDetailInfo.value = info; + /// 保存用户信息 + void setUserDetailInfo(UserInfoEntity info) { + userInfoEntity.value = info; StorageService.to.write(AppStorageKey.userInfo.value, info); } + /// 清除数据 void erase() { - // userInfo.value = null; - userDetailInfo.value = null; + userInfoEntity.value = null; token = null; StorageService.to.erase(); } // 用户信息更新 - Future updateUserInfo() async { + Future updateUserInfo() async { // BaseStructureResult res = await getClient().getUser(); // var data = res.data; // if (res.success && data != null) { diff --git a/wgshare/lib/pages/homePage/home_logic.dart b/wgshare/lib/pages/homePage/home_logic.dart index 3bfe513..5418dd7 100644 --- a/wgshare/lib/pages/homePage/home_logic.dart +++ b/wgshare/lib/pages/homePage/home_logic.dart @@ -2,23 +2,55 @@ import 'package:get/get.dart'; import 'package:wgshare/common/models/common/base_structure_result.dart'; import 'package:wgshare/common/mixins/request_tool_mixin.dart'; +import '../../common/models/meeting_room_item.dart'; import 'home_state.dart'; class HomeLogic extends GetxController with RequestToolMixin { + final HomeState state = HomeState(); @override void onInit() { super.onInit(); + doHttpGetMeetingRoomList(state.pageIndex.value,state.pageSize.value); } - void getTask() async { - // BaseStructureResult res = await getClient().getStadyTask(state.currentSubject.value.subjectId); - // if (res.data != null) { - // state.morningTask.value = res.data!.morningTask ?? MorningTask(00, '', '', ''); - // state.nightTask.value = res.data!.nightTask ?? MorningTask(00, '', '', ''); - // } + /// 直接进入会议(匿名登录) + void doHttpGetMeetingRoomList(int pageIndex, int pageSize) async { + BaseStructureResult res = await getClient().getMeetingRoomList(pageIndex,pageSize); + if(null != res.data){ + if(state.pageIndex == 1){ + state.meetingRooms.value = res.data!.items; + state.totalPage.value = res.data!.totalPage; + state.total.value = res.data!.total; + state.refreshController.refreshCompleted(resetFooterState: true); + }else{ + if(state.pageIndex.value < state.totalPage.value){ + state.meetingRooms.value.addAll(res.data!.items); + state.refreshController.loadComplete(); + }else{ + state.refreshController.loadNoData(); + } + } + } + } + + /// 下拉刷新 + void onRefresh(){ + state.pageIndex.value = 1; + doHttpGetMeetingRoomList(state.pageIndex.value,state.pageSize.value); + } + + /// 上滑加载更多 + void onLoading(){ + state.pageIndex.value += 1; + doHttpGetMeetingRoomList(state.pageIndex.value,state.pageSize.value); + } + + @override + void dispose() { + super.dispose(); + state.refreshController.dispose(); } - void out() async {} } diff --git a/wgshare/lib/pages/homePage/home_state.dart b/wgshare/lib/pages/homePage/home_state.dart index a30b543..00b7222 100644 --- a/wgshare/lib/pages/homePage/home_state.dart +++ b/wgshare/lib/pages/homePage/home_state.dart @@ -1,9 +1,28 @@ import 'package:get/get.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; + +import '../../common/models/meeting_room_item.dart'; class HomeState { HomeState() { ///Initialize variables } - final RxString userName = ''.obs; + final RefreshController refreshController = RefreshController(initialRefresh: false); + + /// 当前页码 + final RxInt pageIndex = 1.obs; + + /// 每页条数 + final RxInt pageSize = 10.obs; + + /// 会议列表 + final RxList meetingRooms = RxList([]); + + /// 会议列表总条数 + final RxInt total = 0.obs; + + /// 总页数 + final RxInt totalPage = 0.obs; + } diff --git a/wgshare/lib/pages/homePage/home_view.dart b/wgshare/lib/pages/homePage/home_view.dart index fe0592e..8688390 100644 --- a/wgshare/lib/pages/homePage/home_view.dart +++ b/wgshare/lib/pages/homePage/home_view.dart @@ -4,13 +4,10 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:wgshare/common/models/user_info_detail.dart'; -import 'package:wgshare/common/store/user_store.dart'; -import 'package:wgshare/main.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:wgshare/routes/app_routes.dart'; import 'package:wgshare/utils/cus_behavior.dart'; -import 'package:wgshare/utils/my_text.dart'; -import 'package:wgshare/utils/storage.dart'; +import 'package:wgshare/utils/toast_utils.dart'; import '../../utils/color_util.dart'; import 'home_logic.dart'; @@ -22,8 +19,10 @@ class HomePage extends StatefulWidget { } class HomePageState extends State with AutomaticKeepAliveClientMixin { - final logic = Get.find(); + + final logic = Get.put(HomeLogic()); final state = Get.find().state; + Timer? _timer; @override @@ -51,7 +50,7 @@ class HomePageState extends State with AutomaticKeepAliveClientMixin { ), backgroundColor: Colors.white, ), - body: Column( + body: Obx(() => Column( children: [ Container( width: double.infinity, @@ -70,114 +69,122 @@ class HomePageState extends State with AutomaticKeepAliveClientMixin { Expanded( child: Container( color: ColorUtil.Color_244_244_244, - child: ScrollConfiguration( - behavior: CusBehavior(), - child: ListView.builder( - itemBuilder: (context, index) { - return Container( - width: double.infinity, - decoration: const BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(6)), - color: Colors.white, - ), - margin: EdgeInsets.only(top: index == 0 ? 20 : 12, bottom: index == 19 ? 20 : 0, left: 16, right: 16), - padding: const EdgeInsets.all(12), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - '奉节中学期末考试分析总结会议', - style: TextStyle( - fontSize: 14.sp, - color: ColorUtil.Color_89_88_88, - fontWeight: FontWeight.w500 - ), + child: SmartRefresher( + enablePullUp: true, + controller: state.refreshController, + onRefresh: logic.onRefresh, + onLoading: logic.onLoading, + child: ListView.builder( + itemBuilder: (context, index) { + return Container( + width: double.infinity, + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(6)), + color: Colors.white, + ), + margin: EdgeInsets.only(top: index == 0 ? 20 : 12, bottom: index == 19 ? 20 : 0, left: 16, right: 16), + padding: const EdgeInsets.all(12), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + state.meetingRooms[index].roomName, + style: TextStyle( + fontSize: 14.sp, + color: ColorUtil.Color_89_88_88, + fontWeight: FontWeight.w500 ), - Row( - children: [ - Image.asset( - 'assets/images/index_persons.png', - width: 16.w, - height: 16.h, + ), + Row( + children: [ + Image.asset( + 'assets/images/index_persons.png', + width: 16.w, + height: 16.h, + ), + Text( + '${state.meetingRooms[index].onlineUserCount}人', + style: TextStyle( + fontSize: 12.sp, + color: ColorUtil.Color_177_177_177, ), - Text( - '2人', - style: TextStyle( - fontSize: 12.sp, - color: ColorUtil.Color_177_177_177, - ), + ), + ], + ) + ], + ), + SizedBox(height: 20.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Text( + state.meetingRooms[index].roomNum, + style: TextStyle( + fontSize: 12.sp, + color: ColorUtil.Color_177_177_177, ), - ], - ) - ], - ), - SizedBox(height: 20.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Text( - '2525353', - style: TextStyle( - fontSize: 12.sp, - color: ColorUtil.Color_177_177_177, - ), - ), - SizedBox(width: 6.w), - Image.asset( + ), + SizedBox(width: 6.w), + GestureDetector( + child: Image.asset( 'assets/images/index_copy.png', width: 16.w, height: 16.h, - ) - ], - ), - GestureDetector( - child: Container( - width: 78.w, - height: 30.h, - decoration: BoxDecoration( - borderRadius: const BorderRadius.all(Radius.circular(6)), - color: ColorUtil.Color_85_117_242, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - '进入', - style: TextStyle( - fontSize: 12.sp, - color: Colors.white, - ), - ), - Image.asset( - 'assets/images/index_right.png', - width: 16.w, - height: 16.h, - ) - ], ), + onTap: (){ + Clipboard.setData(ClipboardData(text: state.meetingRooms[index].roomNum)); + ToastUtils.showSuccess("复制成功"); + }, + ) + ], + ), + GestureDetector( + child: Container( + width: 78.w, + height: 30.h, + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(6)), + color: ColorUtil.Color_85_117_242, ), - onTap: (){ - Get.toNamed(Routes.meetingMainPage); - // Navigator.of(context).push(MaterialPageRoute(builder: (context) => MeetingMainPage())); - }, - ) - ], - ) - ], - ), - ); - }, - itemCount: 20, - ) + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '进入', + style: TextStyle( + fontSize: 12.sp, + color: Colors.white, + ), + ), + Image.asset( + 'assets/images/index_right.png', + width: 16.w, + height: 16.h, + ) + ], + ), + ), + onTap: (){ + Get.toNamed(Routes.meetingMainPage); + }, + ) + ], + ) + ], + ), + ); + }, + itemCount: state.meetingRooms.length, + ), ), ), ) ], - ) + )) ); } diff --git a/wgshare/lib/pages/loginPage/login_logic.dart b/wgshare/lib/pages/loginPage/login_logic.dart index e081931..24b2b8a 100644 --- a/wgshare/lib/pages/loginPage/login_logic.dart +++ b/wgshare/lib/pages/loginPage/login_logic.dart @@ -1,6 +1,15 @@ +import 'dart:convert'; + +import 'package:crypto/crypto.dart'; import 'package:get/get.dart'; import 'package:wgshare/common/mixins/request_tool_mixin.dart'; +import 'package:wgshare/utils/device_info.dart'; +import 'package:wgshare/utils/toast_utils.dart'; +import '../../common/models/common/base_structure_result.dart'; +import '../../common/models/user_info_entity.dart'; +import '../../common/store/user_store.dart'; +import '../../routes/app_routes.dart'; import 'login_state.dart'; class LoginLogic extends GetxController with RequestToolMixin { @@ -12,15 +21,58 @@ class LoginLogic extends GetxController with RequestToolMixin { } /// 改变勾选协议状态 - void changeAgreementState(bool checkAgreementBool){ + void changeAgreementState(bool checkAgreementBool) { state.checkAgreementBool.value = checkAgreementBool; } + /// 登录 + void doHttpLogin() async { + if(state.userNameController.text.isEmpty){ + ToastUtils.showError("请输入账号"); + }else if(state.passwordController.text.isEmpty){ + ToastUtils.showError("请输入密码"); + }else if(state.checkAgreementBool != true){ + ToastUtils.showError("请阅读并勾选相关协议"); + }else{ + ToastUtils.showLoading(); + BaseStructureResult res = await getClient().login(state.userNameController.text, md5.convert(utf8.encode(state.passwordController.text)).toString()); + ToastUtils.dismiss(); + if (null != res.data) { + UserStore.to.setToken(res.data!.token); + UserStore.to.setUserDetailInfo(res.data!); + Get.toNamed(Routes.startPage); + } + } + } + + /// 直接进入会议(匿名登录) + void doHttpAnonymousLogin() async { + if(state.meetingCodeController.text.isEmpty){ + ToastUtils.showError("请输入会议号"); + }else if(state.meetingCodeController.text.length != 8){ + ToastUtils.showError("请输入正确的会议号"); + }else if(state.nickNameCodeController.text.isEmpty){ + ToastUtils.showError("请输入昵称"); + }else if(state.checkAgreementBool != true){ + ToastUtils.showError("请阅读并勾选相关协议"); + }else{ + ToastUtils.showLoading(); + BaseStructureResult res = await getClient().anonLogin(await DeviceInfo.getDeviceId(),state.nickNameCodeController.text, state.meetingCodeController.text); + ToastUtils.dismiss(); + if (null != res.data) { + UserStore.to.setToken(res.data!.token); + UserStore.to.setUserDetailInfo(res.data!); + Get.toNamed(Routes.meetingMainPage); + } + } + } + @override void dispose() { super.dispose(); - state.passwordFocus.dispose(); state.passwordController.dispose(); state.userNameController.dispose(); + state.meetingCodeController.dispose(); + state.nickNameCodeController.dispose(); } } diff --git a/wgshare/lib/pages/loginPage/login_state.dart b/wgshare/lib/pages/loginPage/login_state.dart index 2369923..0c0b47b 100644 --- a/wgshare/lib/pages/loginPage/login_state.dart +++ b/wgshare/lib/pages/loginPage/login_state.dart @@ -7,9 +7,8 @@ class LoginState { late TextEditingController userNameController = TextEditingController(); late TextEditingController passwordController = TextEditingController(); - late FocusNode passwordFocus = FocusNode(); - - late RxBool canLogin = true.obs; + late TextEditingController meetingCodeController = TextEditingController(); + late TextEditingController nickNameCodeController = TextEditingController(); /// 页面状态,0:账号,1:会议号 late RxInt pageState = 0.obs; diff --git a/wgshare/lib/pages/loginPage/login_view.dart b/wgshare/lib/pages/loginPage/login_view.dart index 2040581..b0c37b3 100644 --- a/wgshare/lib/pages/loginPage/login_view.dart +++ b/wgshare/lib/pages/loginPage/login_view.dart @@ -48,24 +48,24 @@ class _LoginPageState extends State { children: [ Expanded( child: Container( - margin: const EdgeInsets.only(top: 20), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset( - 'assets/images/logo.png', - width: 80.w, - height: 80.h, - ), - SizedBox(height: 20.h), - Image.asset( - 'assets/images/logo_title.png', - width: 70.w, - height: 24.h, - ) - ], + margin: const EdgeInsets.only(top: 20), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/images/logo.png', + width: 80.w, + height: 80.h, ), - )), + SizedBox(height: 20.h), + Image.asset( + 'assets/images/logo_title.png', + width: 70.w, + height: 24.h, + ) + ], + ), + )), Container( height: 40, decoration: const BoxDecoration( @@ -81,235 +81,302 @@ class _LoginPageState extends State { Expanded( child: SingleChildScrollView( child: Obx(() => Container( - child: Column( - children: [ - Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - GestureDetector( - child: Container( - width: 140.w, - height: 40.h, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage(state.pageState.value == 0 ? 'assets/images/login_tab_left_select_y.png' : 'assets/images/login_tab_left_select_n.png'), - fit: BoxFit.fill, + child: Column( + children: [ + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + GestureDetector( + child: Container( + width: 140.w, + height: 40.h, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage(state.pageState.value == + 0 + ? 'assets/images/login_tab_left_select_y.png' + : 'assets/images/login_tab_left_select_n.png'), + fit: BoxFit.fill, + ), + ), + alignment: Alignment.center, + child: Text( + '账号', + style: TextStyle( + fontSize: 14.sp, + color: state.pageState.value == 0 + ? Colors.white + : ColorUtil.Color_120_137_203), + ), ), + onTap: () { + logic.changePageState(0); + }, ), - alignment: Alignment.center, - child: Text( - '账号', + GestureDetector( + child: Container( + width: 140.w, + height: 40.h, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage(state.pageState.value == + 0 + ? 'assets/images/login_tab_right_select_n.png' + : 'assets/images/login_tab_right_select_y.png'), + fit: BoxFit.fill, + ), + ), + alignment: Alignment.center, + child: Text( + '会议号', + style: TextStyle( + fontSize: 14.sp, + color: state.pageState.value == 0 + ? ColorUtil.Color_120_137_203 + : Colors.white), + ), + ), + onTap: () { + logic.changePageState(1); + }, + ) + ], + ), + ), + + /** + * 账号密码输入框 + */ + Visibility( + visible: state.pageState.value == 0 ? true : false, + child: Container( + width: 280.w, + height: 40.h, + margin: const EdgeInsets.only(top: 30), + padding: const EdgeInsets.only(left: 12, right: 12), + decoration: BoxDecoration( + borderRadius: + const BorderRadius.all(Radius.circular(99)), + border: Border.all( + width: 1.w, + color: ColorUtil.Color_153_153_153), + ), + child: TextField( + controller: state.userNameController, + style: TextStyle( + fontSize: 14.sp, + ), + inputFormatters: [ + LengthLimitingTextInputFormatter(18) + ], + decoration: InputDecoration( + contentPadding: const EdgeInsets.all(0), + border: const OutlineInputBorder( + borderSide: BorderSide.none), + hintText: '请输入账号', + hintStyle: TextStyle( + color: ColorUtil.Color_153_153_153, + fontSize: 14.sp)), + ), + ), + ), + + Visibility( + visible: state.pageState.value == 0 ? true : false, + child: Container( + width: 280.w, + height: 40.h, + margin: const EdgeInsets.only(top: 12), + padding: const EdgeInsets.only(left: 12, right: 12), + decoration: BoxDecoration( + borderRadius: + const BorderRadius.all(Radius.circular(99)), + border: Border.all( + width: 1.w, + color: ColorUtil.Color_153_153_153), + ), + child: TextField( + controller: state.passwordController, + style: TextStyle( + fontSize: 14.sp, + ), + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + LengthLimitingTextInputFormatter(20) + //限制长度 + ], + decoration: InputDecoration( + contentPadding: const EdgeInsets.all(0), + border: const OutlineInputBorder( + borderSide: BorderSide.none), + hintText: '请输入密码', + hintStyle: TextStyle( + color: ColorUtil.Color_153_153_153, + fontSize: 14.sp)), + ), + ), + ), + + /// 会议号输入框 + Visibility( + visible: state.pageState.value == 0 ? false : true, + child: Container( + width: 280.w, + height: 40.h, + margin: const EdgeInsets.only(top: 30), + padding: const EdgeInsets.only(left: 12, right: 12), + decoration: BoxDecoration( + borderRadius: + const BorderRadius.all(Radius.circular(99)), + border: Border.all( + width: 1.w, + color: ColorUtil.Color_153_153_153), + ), + child: TextField( + controller: state.meetingCodeController, + style: TextStyle( + fontSize: 14.sp, + ), + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + LengthLimitingTextInputFormatter(8) + //限制长度 + ], + decoration: InputDecoration( + contentPadding: const EdgeInsets.all(0), + border: const OutlineInputBorder( + borderSide: BorderSide.none), + hintText: '请输入会议号', + hintStyle: TextStyle( + color: ColorUtil.Color_153_153_153, + fontSize: 14.sp)), + ), + ), + ), + + /// 昵称输入框 + Visibility( + visible: state.pageState.value == 0 ? false : true, + child: Container( + width: 280.w, + height: 40.h, + margin: const EdgeInsets.only(top: 12), + padding: const EdgeInsets.only(left: 12, right: 12), + decoration: BoxDecoration( + borderRadius: + const BorderRadius.all(Radius.circular(99)), + border: Border.all( + width: 1.w, + color: ColorUtil.Color_153_153_153), + ), + child: TextField( + controller: state.nickNameCodeController, + style: TextStyle( + fontSize: 14.sp, + ), + inputFormatters: [ + LengthLimitingTextInputFormatter(10) + //限制长度 + ], + decoration: InputDecoration( + contentPadding: const EdgeInsets.all(0), + border: const OutlineInputBorder( + borderSide: BorderSide.none), + hintText: '请输入昵称', + hintStyle: TextStyle( + color: ColorUtil.Color_153_153_153, + fontSize: 14.sp)), + ), + ), + ), + + /// 相关协议 + Container( + width: 280.w, + margin: const EdgeInsets.only(top: 16), + child: Row( + children: [ + GestureDetector( + child: Image.asset( + state.checkAgreementBool.value == false + ? 'assets/images/login_agreement_select_n.png' + : 'assets/images/login_agreement_select_y.png', + width: 16.w, + height: 16.h, + ), + onTap: () { + if (state.checkAgreementBool.value == false) { + logic.changeAgreementState(true); + } else { + logic.changeAgreementState(false); + } + }, + ), + SizedBox(width: 6.w), + Text( + '我阅读并同意', style: TextStyle( - fontSize: 14.sp, - color: state.pageState.value == 0 ? Colors.white : ColorUtil.Color_120_137_203 + fontSize: 12.sp, + color: ColorUtil.Color_153_153_153, ), ), - ), - onTap: (){ - logic.changePageState(0); - }, - ), - GestureDetector( - child: Container( - width: 140.w, - height: 40.h, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage(state.pageState.value == 0 ? 'assets/images/login_tab_right_select_n.png' : 'assets/images/login_tab_right_select_y.png'), - fit: BoxFit.fill, - ), - ), - alignment: Alignment.center, - child: Text( - '会议号', + Text( + '《服务协议》', style: TextStyle( - fontSize: 14.sp, - color: state.pageState.value == 0 ? ColorUtil.Color_120_137_203 : Colors.white + fontSize: 12.sp, + color: ColorUtil.Color_153_153_153, ), ), - ), - onTap: (){ - logic.changePageState(1); - }, - ) - ], - ), - ), - - /** - * 账号密码输入框 - */ - Visibility( - visible: state.pageState.value == 0 ? true : false, - child: Container( - width: 280.w, - height: 40.h, - margin: const EdgeInsets.only(top: 30), - padding: const EdgeInsets.only(left: 12, right: 12), - decoration: BoxDecoration( - borderRadius: const BorderRadius.all(Radius.circular(99)), - border: Border.all( - width: 1.w, - color: ColorUtil.Color_153_153_153 - ), - ), - child: TextField( - style: TextStyle( - fontSize: 14.sp, - ), - decoration: InputDecoration( - contentPadding: EdgeInsets.all(0), - border: OutlineInputBorder(borderSide: BorderSide.none), - hintText: '请输入账号', - hintStyle: TextStyle( + Text( + '和', + style: TextStyle( + fontSize: 12.sp, color: ColorUtil.Color_153_153_153, - fontSize: 14.sp) - ), - ), - ), - ), - - Visibility( - visible: state.pageState.value == 0 ? true : false, - child: Container( - width: 280.w, - height: 40.h, - margin: const EdgeInsets.only(top: 12), - padding: const EdgeInsets.only(left: 12, right: 12), - decoration: BoxDecoration( - borderRadius: const BorderRadius.all(Radius.circular(99)), - border: Border.all( - width: 1.w, - color: ColorUtil.Color_153_153_153 - ), - ), - child: TextField( - style: TextStyle( - fontSize: 14.sp, - ), - decoration: InputDecoration( - contentPadding: EdgeInsets.all(0), - border: OutlineInputBorder(borderSide: BorderSide.none), - hintText: '请输入密码', - hintStyle: TextStyle( + ), + ), + Text( + '《隐私政策》', + style: TextStyle( + fontSize: 12.sp, color: ColorUtil.Color_153_153_153, - fontSize: 14.sp) + ), + ) + ], ), ), - ), - ), - /// 会议号输入框 - Visibility( - visible: state.pageState.value == 0 ? false : true, - child: Container( - width: 280.w, - height: 40.h, - margin: const EdgeInsets.only(top: 30), - padding: const EdgeInsets.only(left: 12, right: 12), - decoration: BoxDecoration( - borderRadius: const BorderRadius.all(Radius.circular(99)), - border: Border.all( - width: 1.w, - color: ColorUtil.Color_153_153_153 + /// 按钮 + GestureDetector( + child: Container( + width: 280.w, + height: 44.h, + margin: const EdgeInsets.only(top: 50), + decoration: const BoxDecoration( + borderRadius: + BorderRadius.all(Radius.circular(99)), + color: ColorUtil.Color_85_117_242, + ), + alignment: Alignment.center, + child: Text( + state.pageState.value == 0 ? '登录' : '加入会议', + style: TextStyle( + fontSize: 16.sp, + color: Colors.white, + ), + ), ), - ), - child: TextField( - style: TextStyle( - fontSize: 14.sp, - ), - decoration: InputDecoration( - contentPadding: EdgeInsets.all(0), - border: OutlineInputBorder(borderSide: BorderSide.none), - hintText: '请输入会议号', - hintStyle: TextStyle( - color: ColorUtil.Color_153_153_153, - fontSize: 14.sp) - ), - ), - ), + onTap: () { + if (state.pageState.value == 0) { + logic.doHttpLogin(); + } else { + logic.doHttpAnonymousLogin(); + } + }, + ) + ], ), - - /// 相关协议 - Container( - width: 280.w, - margin: const EdgeInsets.only(top: 16), - child: Row( - children: [ - GestureDetector( - child: Image.asset( - state.checkAgreementBool.value == false ? 'assets/images/login_agreement_select_n.png' : 'assets/images/login_agreement_select_y.png', - width: 16.w, - height: 16.h, - ), - onTap: (){ - if(state.checkAgreementBool.value == false){ - logic.changeAgreementState(true); - }else{ - logic.changeAgreementState(false); - } - }, - ), - SizedBox(width: 6.w), - Text( - '我阅读并同意', - style: TextStyle( - fontSize: 12.sp, - color: ColorUtil.Color_153_153_153, - ), - ), - Text( - '《服务协议》', - style: TextStyle( - fontSize: 12.sp, - color: ColorUtil.Color_153_153_153, - ), - ), - Text( - '和', - style: TextStyle( - fontSize: 12.sp, - color: ColorUtil.Color_153_153_153, - ), - ), - Text( - '《隐私政策》', - style: TextStyle( - fontSize: 12.sp, - color: ColorUtil.Color_153_153_153, - ), - ) - ], - ), - ), - - /// 按钮 - GestureDetector( - child: Container( - width: 280.w, - height: 44.h, - margin: const EdgeInsets.only(top: 50), - decoration: const BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(99)), - color: ColorUtil.Color_85_117_242, - ), - alignment: Alignment.center, - child: Text( - state.pageState.value == 0 ? '登录' : '加入会议', - style: TextStyle( - fontSize: 16.sp, - color: Colors.white, - ), - ), - ), - onTap: (){ - Get.toNamed(Routes.startPage); - }, - ) - ], - ), - )), + )), ), ) ], diff --git a/wgshare/lib/pages/start_page.dart b/wgshare/lib/pages/start_page.dart deleted file mode 100644 index f37dc6a..0000000 --- a/wgshare/lib/pages/start_page.dart +++ /dev/null @@ -1,177 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:get/get.dart'; -import 'package:wgshare/common/mixins/request_tool_mixin.dart'; -import 'package:wgshare/common/models/user_info_detail.dart'; -import 'package:wgshare/common/store/user_store.dart'; -import 'package:wgshare/pages/homePage/home_logic.dart'; -import 'package:wgshare/pages/userPage/user_logic.dart'; -import 'package:wgshare/pages/userPage/user_view.dart'; -import 'package:wgshare/utils/toast_utils.dart'; - -import '../utils/color_util.dart'; -import 'homePage/home_view.dart'; - -class StartPage extends StatefulWidget { - const StartPage({super.key}); - - @override - State createState() => _StartPageState(); -} - -class _StartPageState extends State with RequestToolMixin { - DateTime? lastPopTime; - final _pageController = Get.find(); - - late final List _bodyList; - - @override - void initState() { - super.initState(); - Get.put(HomeLogic()); - Get.put(UserLogic()); - - _bodyList = [ - const HomePage(), - const UserPage(), - ]; - - String? token = UserStore.to.token; - UserInfoDetail? userInfoDetail = UserStore.to.userDetailInfo.value; - - if ((token?.isNotEmpty ?? false) && userInfoDetail != null) { - UserStore.to.updateUserInfo(); // 更新用户信息 - } else { - /// 没有登录返回登录页 - Future.delayed(const Duration(milliseconds: 100)).then((e) { - // UserStore.to.erase(); - // StorageService.to.erase(); - // Get.offAllNamed(Routes.login); - }); - } - } - - @override - void dispose() { - Get.delete(); - super.dispose(); - } - - /// 获取项目 icon - Widget getItemIcon(String icon) { - return Image.asset( - icon, - fit: BoxFit.contain, - width: 24.w, - height: 24.h, - ); - } - - @override - Widget build(BuildContext context) { - return WillPopScope( - child: Scaffold( - body: PageView( - controller: _pageController._pageIndexState.pageController, - physics: const BouncingScrollPhysics(), - onPageChanged: (index) { - _pageController._pageIndexState.pageIndex.value = index; - }, - children: _bodyList, - ), - bottomNavigationBar: Theme( - data: ThemeData( - splashColor: Colors.transparent, - highlightColor: Colors.transparent, - ), - child: Obx(() { - return BottomNavigationBar ( - iconSize: 24.sp, - items: [ - BottomNavigationBarItem( - label: '首页', - icon: Image.asset( - 'assets/images/home_index_select_n.png', - width: 22.w, - height: 22.h, - ), - activeIcon: Image.asset( - 'assets/images/home_index_select_y.png', - width: 22.w, - height: 22.h, - ), - ), - BottomNavigationBarItem( - label: '我的', - icon: Image.asset( - 'assets/images/home_user_select_n.png', - width: 22.w, - height: 22.h, - ), - activeIcon: Image.asset( - 'assets/images/home_user_select_y.png', - width: 22.w, - height: 22.h, - ), - ), - ], - //设置显示的模式 - type: BottomNavigationBarType.fixed, - backgroundColor: Colors.white, - selectedFontSize: 14.sp, - selectedItemColor: ColorUtil.Color_85_117_242, - unselectedFontSize: 14.sp, - unselectedItemColor: ColorUtil.Color_80_87_103, - //设置当前的索引 - currentIndex: _pageController._pageIndexState.pageIndex.value, - //tabBottom的点击监听 - onTap: (index) { - print('appbar下标:${index}'); - _pageController._pageIndexState.pageController.jumpToPage(index); - }, - ); - })), - ), - onWillPop: () async { - if (lastPopTime == null || DateTime.now().difference(lastPopTime!) > const Duration(seconds: 1)) { - lastPopTime = DateTime.now(); - ToastUtils.getFluttertoast(context: context, msg: '连续两次返回就退出'); - return Future.value(false); - } else { - lastPopTime = DateTime.now(); - // 退出app - return Future.value(true); - } - }, - ); - } -} - -class StartPageState { - StartPageState({required this.pageController, this.showUpgrade = false}); - - RxInt pageIndex = 0.obs; - bool showUpgrade; - - //文本输入框控制器 - final PageController pageController; -} - -class StartPageController extends GetxController with RequestToolMixin { - late StartPageState _pageIndexState; - - @override - void onInit() { - _pageIndexState = StartPageState(pageController: PageController()); - super.onInit(); - } -} - -class StartPageBinding extends Bindings { - @override - void dependencies() { - Get.lazyPut(() => StartPageController()); - } -} diff --git a/wgshare/lib/pages/start_page_binding.dart b/wgshare/lib/pages/start_page_binding.dart new file mode 100644 index 0000000..0caa049 --- /dev/null +++ b/wgshare/lib/pages/start_page_binding.dart @@ -0,0 +1,10 @@ +import 'package:get/get.dart'; + +import 'start_page_logic.dart'; + +class StartPageBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut(() => StartPageLogic()); + } +} diff --git a/wgshare/lib/pages/start_page_logic.dart b/wgshare/lib/pages/start_page_logic.dart new file mode 100644 index 0000000..c7b3bae --- /dev/null +++ b/wgshare/lib/pages/start_page_logic.dart @@ -0,0 +1,7 @@ +import 'package:get/get.dart'; + +import 'start_page_state.dart'; + +class StartPageLogic extends GetxController { + final StartPageState state = StartPageState(); +} diff --git a/wgshare/lib/pages/start_page_state.dart b/wgshare/lib/pages/start_page_state.dart new file mode 100644 index 0000000..a6346a8 --- /dev/null +++ b/wgshare/lib/pages/start_page_state.dart @@ -0,0 +1,9 @@ +import 'package:get/get.dart'; + +class StartPageState { + StartPageState() { + ///Initialize variables + } + + final RxInt currentIndex = 0.obs; +} diff --git a/wgshare/lib/pages/start_page_view.dart b/wgshare/lib/pages/start_page_view.dart new file mode 100644 index 0000000..046b875 --- /dev/null +++ b/wgshare/lib/pages/start_page_view.dart @@ -0,0 +1,104 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:wgshare/pages/userPage/user_logic.dart'; +import 'package:wgshare/pages/userPage/user_view.dart'; + +import '../utils/color_util.dart'; +import 'homePage/home_logic.dart'; +import 'homePage/home_view.dart'; +import 'start_page_logic.dart'; +import 'start_page_state.dart'; + +class StartPage extends StatefulWidget { + const StartPage({super.key}); + + @override + State createState() => _StartPageState(); +} + +class _StartPageState extends State { + + final StartPageLogic logic = Get.put(StartPageLogic()); + final StartPageState state = Get.find().state; + + final List bottomNavItems = [ + BottomNavigationBarItem( + icon: Image.asset( + 'assets/images/home_index_select_n.png', + width: 22, + height: 22, + ), + activeIcon: Image.asset( + 'assets/images/home_index_select_y.png', + width: 22, + height: 22, + ), + label: "首页", + ), + BottomNavigationBarItem( + icon: Image.asset( + 'assets/images/home_user_select_n.png', + width: 22, + height: 22, + ), + activeIcon: Image.asset( + 'assets/images/home_user_select_y.png', + width: 22, + height: 22, + ), + label: "我的", + ), + ]; + + + late final List pages; + + @override + void initState() { + + Get.put(HomeLogic()); + Get.lazyPut(() => HomeLogic()); + + Get.put(UserLogic()); + Get.lazyPut(() => UserLogic()); + + pages = [ + HomePage(), + UserPage(), + ]; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + bottomNavigationBar: Theme( + data: ThemeData( + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + ), + child: Obx(() => BottomNavigationBar( + items: bottomNavItems, + currentIndex: state.currentIndex.value, + type: BottomNavigationBarType.fixed, + backgroundColor: Colors.white, + selectedFontSize: 14, + selectedItemColor: ColorUtil.Color_85_117_242, + unselectedFontSize: 14, + unselectedItemColor: ColorUtil.Color_80_87_103, + onTap: (index) { + if(index != state.currentIndex.value){ + state.currentIndex.value = index; + } + }, + )), + ), + body: Obx(() => pages[state.currentIndex.value]) + ); + } + + @override + void dispose() { + Get.delete(); + super.dispose(); + } +} diff --git a/wgshare/lib/pages/userPage/user_logic.dart b/wgshare/lib/pages/userPage/user_logic.dart index fd3971e..a83a0f2 100644 --- a/wgshare/lib/pages/userPage/user_logic.dart +++ b/wgshare/lib/pages/userPage/user_logic.dart @@ -1,13 +1,16 @@ import 'package:get/get.dart'; import 'package:wgshare/common/mixins/request_tool_mixin.dart'; +import 'package:wgshare/common/store/user_store.dart'; +import '../../routes/app_routes.dart'; import 'user_state.dart'; class UserLogic extends GetxController with RequestToolMixin { final UserState state = UserState(); - @override - void onClose() { - super.dispose(); + /// 退出登录 + void logout(){ + UserStore.to.erase(); + Get.offAllNamed(Routes.loginPage); } } diff --git a/wgshare/lib/pages/userPage/user_state.dart b/wgshare/lib/pages/userPage/user_state.dart index e07a357..5ef1b35 100644 --- a/wgshare/lib/pages/userPage/user_state.dart +++ b/wgshare/lib/pages/userPage/user_state.dart @@ -1,6 +1,4 @@ -import 'package:flutter/material.dart'; -import 'package:get/get.dart'; class UserState { - UserState(); + UserState() {} } diff --git a/wgshare/lib/pages/userPage/user_view.dart b/wgshare/lib/pages/userPage/user_view.dart index 6968c15..15e9aa8 100644 --- a/wgshare/lib/pages/userPage/user_view.dart +++ b/wgshare/lib/pages/userPage/user_view.dart @@ -4,7 +4,10 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:wgshare/main.dart'; import 'package:wgshare/pages/userPage/user_logic.dart'; +import '../../common/store/user_store.dart'; import '../../utils/color_util.dart'; +import '../../utils/hint_dialog.dart'; +import '../../utils/storage.dart'; class UserPage extends StatefulWidget { const UserPage({super.key}); @@ -15,7 +18,7 @@ class UserPage extends StatefulWidget { class UserPageState extends State { - final logic = Get.find(); + final logic = Get.put(UserLogic()); final state = Get.find().state; @override @@ -66,20 +69,31 @@ class UserPageState extends State { child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(100), - image: DecorationImage( + color: ColorUtil.Color_85_117_242 + /*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", ), - ), + ),*/ ), width: 132.w, height: 132.h, + alignment: Alignment.center, + child: Text( + UserStore.to.userInfoEntity.value!.userName.length >= 3 + ? UserStore.to.userInfoEntity.value!.userName.substring(1,UserStore.to.userInfoEntity.value!.userName.length) + : UserStore.to.userInfoEntity.value!.userName, + style: TextStyle( + fontSize: 30.sp, + color: ColorUtil.Color_244_244_244 + ), + ), ), ), Container( child: Text( - '晓晓', + UserStore.to.userInfoEntity.value!.userName, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w500, @@ -104,7 +118,7 @@ class UserPageState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - '晓晓', + UserStore.to.userInfoEntity.value!.userName, style: TextStyle( fontSize: 12.sp, color: ColorUtil.Color_51_51_51 @@ -127,7 +141,6 @@ class UserPageState extends State { color: ColorUtil.Color_230_230_230, margin: const EdgeInsets.only(top: 12, left: 16, right: 16), ), - Container( padding: const EdgeInsets.only(left: 16, right: 16), margin: const EdgeInsets.only(top: 20), @@ -173,20 +186,25 @@ class UserPageState extends State { ), ), - Container( - width: 280.w, - height: 44.h, - margin: const EdgeInsets.only(top: 40), - decoration: const BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(99)), - color: ColorUtil.Color_85_117_242, - ), - alignment: Alignment.center, - child: Text( - '退出登录', - style: TextStyle( - fontSize: 16.sp, - color: Colors.white, + GestureDetector( + onTap: (){ + + }, + child: Container( + width: 280.w, + height: 44.h, + margin: const EdgeInsets.only(top: 40), + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(99)), + color: ColorUtil.Color_85_117_242, + ), + alignment: Alignment.center, + child: Text( + '退出登录', + style: TextStyle( + fontSize: 16.sp, + color: Colors.white, + ), ), ), ) @@ -201,4 +219,5 @@ class UserPageState extends State { Get.delete(); super.dispose(); } + } diff --git a/wgshare/lib/routes/app_pages.dart b/wgshare/lib/routes/app_pages.dart index 3fbf11c..d66467e 100644 --- a/wgshare/lib/routes/app_pages.dart +++ b/wgshare/lib/routes/app_pages.dart @@ -5,7 +5,8 @@ import 'package:wgshare/pages/loginPage/login_binding.dart'; import 'package:wgshare/pages/loginPage/login_view.dart'; import 'package:wgshare/pages/metting/meeting_main_binding.dart'; import 'package:wgshare/pages/metting/meeting_main_view.dart'; -import 'package:wgshare/pages/start_page.dart'; +import '../pages/start_page_binding.dart'; +import '../pages/start_page_view.dart'; import '../pages/userPage/user_binding.dart'; import '../pages/userPage/user_view.dart'; diff --git a/wgshare/lib/utils/device_info.dart b/wgshare/lib/utils/device_info.dart new file mode 100644 index 0000000..289943e --- /dev/null +++ b/wgshare/lib/utils/device_info.dart @@ -0,0 +1,20 @@ +import 'dart:io'; + +import 'package:device_info_plus/device_info_plus.dart'; +import 'package:flutter/services.dart'; + +class DeviceInfo { + + static Future getDeviceId() async { + DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin(); + if (Platform.isAndroid) { + AndroidDeviceInfo deviceInfo = await deviceInfoPlugin.androidInfo; + return deviceInfo.fingerprint ?? 'android error'; + } else if (Platform.isIOS) { + IosDeviceInfo? deviceInfo = await deviceInfoPlugin.iosInfo; + return deviceInfo.identifierForVendor ?? 'ios error'; + } else { + return 'error'; + } + } +} \ No newline at end of file diff --git a/wgshare/lib/utils/hint_dialog.dart b/wgshare/lib/utils/hint_dialog.dart new file mode 100644 index 0000000..fb857aa --- /dev/null +++ b/wgshare/lib/utils/hint_dialog.dart @@ -0,0 +1,202 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'dart:io'; + +import 'color_util.dart'; + +showHintDialog( + BuildContext context, + String? content, + Function onConfirmTap, { + String title = "提示", + btnWidth = 70.0, + btnHeight = 32.0, + bool hideCancelBtn = false, + Function? onCancelTap, +}) { + if (Platform.isIOS) { + showCupertinoDialog( + context: context, + builder: (_) => HintIOSDialog( + title, content, hideCancelBtn, onCancelTap, onConfirmTap) + ); + } else { + showDialog( + context: context, + barrierDismissible: true, + builder: (_) => HintDialog( + title, + content, + btnWidth, + btnHeight, + hideCancelBtn, + onCancelTap, + onConfirmTap, + )); + } +} + +/// 提示dialog new CircularProgressIndicator(), +class HintDialog extends StatefulWidget { + final String title; //标题 + final String? content; //提示内容 + final double btnWidth; //按钮宽度 + final double btnHeight; //按钮高度 + final bool hideCancelBtn; //是否隐藏取消btn + final Function? onCancelTap; //取消事件 + final Function onConfirmTap; //确认时件 + + HintDialog( + this.title, + this.content, + this.btnWidth, + this.btnHeight, + this.hideCancelBtn, + this.onCancelTap, + this.onConfirmTap, + ); + + @override + State createState() { + return HintDialogState(); + } +} + +class HintDialogState extends State { + @override + Widget build(BuildContext context) { + return Center( + child: Container( + height: 168.0, + margin: EdgeInsets.only(left: 20.0, right: 20.0), + padding: EdgeInsets.only(left: 15.0, top: 15.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(4.0), + ), + child: _contentStyle(), + ), + ); + } + + ///内容区域样式 + _contentStyle() { + return Column( + children: [ + _title(), + Expanded( + child: _hintMsg(), + ), + Container( + margin: EdgeInsets.only(bottom: 15.0, right: 15.0), + child: _bottomBtn(), + ), + ], + ); + } + + ///提示标题布局 + _title() { + return Container( + alignment: Alignment.centerLeft, + child: Text(widget.title, + style: TextStyle( + fontSize: 16, + color: ColorUtil.Color_85_117_242, + decoration: TextDecoration.none)), + ); + } + + ///提示信息布局 + _hintMsg() { + return Container( + alignment: Alignment.topLeft, + margin: EdgeInsets.all(10.0), + child: Text(widget.content!, + style: TextStyle( + fontSize: 14.0, + color: ColorUtil.Color_85_117_242, + decoration: TextDecoration.none)), + ); + } + + ///取消 确认按钮布局 + _bottomBtn() { + return Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + child: Text('取消'), + ), + Container( + child: Text('确认'), + ), + ], + ); + } + + ///取消事件 + _onCancelTap() { + Navigator.of(context).pop(); + widget.onCancelTap!(); + } + + ///确认事件 + _onConfirmTap() { + Navigator.of(context).pop(); + widget.onConfirmTap(); + } +} + +class HintIOSDialog extends StatefulWidget { + final String title; //标题 + final String? content; //提示内容 + final bool hideCancelBtn; //是否隐藏取消btn + final Function? onCancelTap; //取消事件 + final Function onConfirmTap; //确认时件 + HintIOSDialog(this.title, this.content, this.hideCancelBtn, this.onCancelTap, + this.onConfirmTap); + + @override + _HintIOSDialogState createState() => _HintIOSDialogState(); +} + +class _HintIOSDialogState extends State { + @override + Widget build(BuildContext context) { + return CupertinoAlertDialog( + title: Text(widget.title), + content: Text(widget.content!), + actions:!widget.hideCancelBtn ? + [ + _cancelIOSBtn(), + CupertinoDialogAction( + child: Text('确认'), + onPressed: () { + Navigator.of(context).pop(); + widget.onConfirmTap(); + }, + ) + ] : [ + CupertinoDialogAction( + child: Text('确认'), + onPressed: () { + Navigator.of(context).pop(); + widget.onConfirmTap(); + }, + ) + ], + ); + } + + ///取消 + _cancelIOSBtn() { + return CupertinoDialogAction( + child: Text('取消'), + onPressed: () { + Navigator.of(context).pop(); + widget.onCancelTap!(); + }); + } +} diff --git a/wgshare/macos/Flutter/GeneratedPluginRegistrant.swift b/wgshare/macos/Flutter/GeneratedPluginRegistrant.swift index b796cca..731e795 100644 --- a/wgshare/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/wgshare/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,12 +5,14 @@ import FlutterMacOS import Foundation +import device_info_plus import geolocator_apple import package_info_plus import path_provider_foundation import sqflite_darwin func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) diff --git a/wgshare/pubspec.lock b/wgshare/pubspec.lock index 57970ee..362582a 100644 --- a/wgshare/pubspec.lock +++ b/wgshare/pubspec.lock @@ -183,7 +183,7 @@ packages: source: hosted version: "3.1.2" crypto: - dependency: transitive + dependency: "direct main" description: name: crypto sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" @@ -206,6 +206,22 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.3.7" + device_info_plus: + dependency: "direct main" + description: + name: device_info_plus + sha256: f545ffbadee826f26f2e1a0f0cbd667ae9a6011cc0f77c0f8f00a969655e6e95 + url: "https://pub.flutter-io.cn" + source: hosted + version: "11.1.1" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba" + url: "https://pub.flutter-io.cn" + source: hosted + version: "7.0.1" dio: dependency: "direct main" description: @@ -518,10 +534,10 @@ packages: dependency: "direct dev" description: name: json_serializable - sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b + sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c url: "https://pub.flutter-io.cn" source: hosted - version: "6.8.0" + version: "6.9.0" leak_tracker: dependency: transitive description: @@ -726,10 +742,10 @@ packages: dependency: transitive description: name: permission_handler_html - sha256: "6b9cb54b7135073841a35513fba39e598b421702d5f4d92319992fd6eb5532a9" + sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" url: "https://pub.flutter-io.cn" source: hosted - version: "0.1.3+4" + version: "0.1.3+5" permission_handler_platform_interface: dependency: transitive description: @@ -854,10 +870,10 @@ packages: dependency: transitive description: name: shelf_web_socket - sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" + sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67 url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.0" + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -915,10 +931,10 @@ packages: dependency: transitive description: name: sqflite_common - sha256: "4468b24876d673418a7b7147e5a08a715b4998a7ae69227acafaab762e0e5490" + sha256: "761b9740ecbd4d3e66b8916d784e581861fd3c3553eda85e167bc49fdb68f709" url: "https://pub.flutter-io.cn" source: hosted - version: "2.5.4+5" + version: "2.5.4+6" sqflite_darwin: dependency: transitive description: @@ -1079,6 +1095,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "5.8.0" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.5" xdg_directories: dependency: transitive description: diff --git a/wgshare/pubspec.yaml b/wgshare/pubspec.yaml index a66afc2..992b9c4 100644 --- a/wgshare/pubspec.yaml +++ b/wgshare/pubspec.yaml @@ -64,6 +64,11 @@ dependencies: photo_view: ^0.15.0 flutter_spinkit: ^5.2.1 + # MD5加密 + crypto: ^3.0.2 + + device_info_plus: ^11.1.1 + dev_dependencies: flutter_test: sdk: flutter