1.首页tab重构

2.账号密码登录、匿名登录、获取会议室列表接口调用
This commit is contained in:
fuenmao 2024-11-25 17:59:05 +08:00
parent ae520861ad
commit b34ede3ce7
28 changed files with 1104 additions and 859 deletions

View File

@ -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<BaseStructureResult<LoginRes>> toLogin(@Body() LoginParams loginParams);
///
@POST("/auth/login")
Future<BaseStructureResult<UserInfoEntity>> login(
@Field("account") String account,
@Field("pwd") String pwd
);
///
@POST("/auth/anon-login")
Future<BaseStructureResult<UserInfoEntity>> anonLogin(
@Field("deviceId") String deviceId,
@Field("nickName") String nickName,
@Field("roomNum") String roomNum
);
///
@GET("/home/room")
Future<BaseStructureResult<MeetingRoomItem>> getMeetingRoomList(
@Query("PageIndex") int PageIndex,
@Query("PageSize") int PageSize,
);
}

View File

@ -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/';

View File

@ -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> items;
MeetingRoomItem(this.totalPage, this.total,this.items,);
factory MeetingRoomItem.fromJson(Map<String, dynamic> 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<String, dynamic> srcJson) => _$ItemsFromJson(srcJson);
}

View File

@ -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>? gCSLists;
@JsonKey(name: 'LearnedCoursesNum')
int learnedCoursesNum;
@JsonKey(name: 'RoleAnys')
RoleAnys roleAnys;
@JsonKey(name: 'RoleIsShowMenus')
List<RoleIsShowMenus> roleIsShowMenus;
@JsonKey(name: 'OrgId')
int orgId;
@JsonKey(name: 'IsCanVerify')
bool isCanVerify;
@JsonKey(name: 'StageSubject')
StageSubject? stageSubject;
@JsonKey(name: 'UserOrgList')
List<UserOrgList> 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<String, dynamic> srcJson) => _$UserInfoDetailFromJson(srcJson);
Map<String, dynamic> toJson() => _$UserInfoDetailToJson(this);
}
@JsonSerializable()
class GCSLists extends Object {
@JsonKey(name: 'Value')
String value;
@JsonKey(name: 'Text')
String? text;
@JsonKey(name: 'GCSLists')
List<GCSLists>? gCSLists;
GCSLists(
this.value,
this.text,
this.gCSLists,
);
factory GCSLists.fromJson(Map<String, dynamic> srcJson) => _$GCSListsFromJson(srcJson);
Map<String, dynamic> 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<String, dynamic> srcJson) => _$RoleAnysFromJson(srcJson);
Map<String, dynamic> 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<dynamic>? children;
RoleIsShowMenus(
this.menuName,
this.menuUrl,
this.parameter,
this.children,
);
factory RoleIsShowMenus.fromJson(Map<String, dynamic> srcJson) => _$RoleIsShowMenusFromJson(srcJson);
Map<String, dynamic> 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<String, dynamic> srcJson) => _$StageSubjectFromJson(srcJson);
Map<String, dynamic> 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<String, dynamic> srcJson) => _$UserOrgListFromJson(srcJson);
Map<String, dynamic> toJson() => _$UserOrgListToJson(this);
}

View File

@ -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<String, dynamic> srcJson) => _$UserInfoEntityFromJson(srcJson);
}

View File

@ -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);
}
}

View File

@ -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: "密码");

View File

@ -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?> userInfo = Rx(null);
///
Rx<UserInfoDetail?> userDetailInfo = Rx(null);
///
Rx<UserInfoEntity?> 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<UserInfoDetail?> updateUserInfo() async {
Future<UserInfoEntity?> updateUserInfo() async {
// BaseStructureResult<UserInfoDetail> res = await getClient().getUser();
// var data = res.data;
// if (res.success && data != null) {

View File

@ -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<StadyTask> 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<MeetingRoomItem> 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 {}
}

View File

@ -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<Items> meetingRooms = RxList([]);
///
final RxInt total = 0.obs;
///
final RxInt totalPage = 0.obs;
}

View File

@ -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<HomePage> with AutomaticKeepAliveClientMixin {
final logic = Get.find<HomeLogic>();
final logic = Get.put(HomeLogic());
final state = Get.find<HomeLogic>().state;
Timer? _timer;
@override
@ -51,7 +50,7 @@ class HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin {
),
backgroundColor: Colors.white,
),
body: Column(
body: Obx(() => Column(
children: [
Container(
width: double.infinity,
@ -70,114 +69,122 @@ class HomePageState extends State<HomePage> 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,
),
),
),
)
],
)
))
);
}

View File

@ -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<UserInfoEntity> 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<UserInfoEntity> 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();
}
}

View File

@ -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();
/// 01
late RxInt pageState = 0.obs;

View File

@ -48,24 +48,24 @@ class _LoginPageState extends State<LoginPage> {
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<LoginPage> {
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: <TextInputFormatter>[
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: <TextInputFormatter>[
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: <TextInputFormatter>[
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: <TextInputFormatter>[
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);
},
)
],
),
)),
)),
),
)
],

View File

@ -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<StartPage> createState() => _StartPageState();
}
class _StartPageState extends State<StartPage> with RequestToolMixin {
DateTime? lastPopTime;
final _pageController = Get.find<StartPageController>();
late final List<Widget> _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<StartPageController>();
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>[
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());
}
}

View File

@ -0,0 +1,10 @@
import 'package:get/get.dart';
import 'start_page_logic.dart';
class StartPageBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => StartPageLogic());
}
}

View File

@ -0,0 +1,7 @@
import 'package:get/get.dart';
import 'start_page_state.dart';
class StartPageLogic extends GetxController {
final StartPageState state = StartPageState();
}

View File

@ -0,0 +1,9 @@
import 'package:get/get.dart';
class StartPageState {
StartPageState() {
///Initialize variables
}
final RxInt currentIndex = 0.obs;
}

View File

@ -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<StartPage> createState() => _StartPageState();
}
class _StartPageState extends State<StartPage> {
final StartPageLogic logic = Get.put(StartPageLogic());
final StartPageState state = Get.find<StartPageLogic>().state;
final List<BottomNavigationBarItem> 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<Widget> 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<StartPageLogic>();
super.dispose();
}
}

View File

@ -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);
}
}

View File

@ -1,6 +1,4 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class UserState {
UserState();
UserState() {}
}

View File

@ -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<UserPage> {
final logic = Get.find<UserLogic>();
final logic = Get.put(UserLogic());
final state = Get.find<UserLogic>().state;
@override
@ -66,20 +69,31 @@ class UserPageState extends State<UserPage> {
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<UserPage> {
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<UserPage> {
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<UserPage> {
),
),
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<UserPage> {
Get.delete<UserLogic>();
super.dispose();
}
}

View File

@ -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';

View File

@ -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<String> 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';
}
}
}

View File

@ -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<StatefulWidget> createState() {
return HintDialogState();
}
}
class HintDialogState extends State<HintDialog> {
@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: <Widget>[
_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: <Widget>[
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<HintIOSDialog> {
@override
Widget build(BuildContext context) {
return CupertinoAlertDialog(
title: Text(widget.title),
content: Text(widget.content!),
actions:!widget.hideCancelBtn ?
<Widget>[
_cancelIOSBtn(),
CupertinoDialogAction(
child: Text('确认'),
onPressed: () {
Navigator.of(context).pop();
widget.onConfirmTap();
},
)
] : <Widget>[
CupertinoDialogAction(
child: Text('确认'),
onPressed: () {
Navigator.of(context).pop();
widget.onConfirmTap();
},
)
],
);
}
///
_cancelIOSBtn() {
return CupertinoDialogAction(
child: Text('取消'),
onPressed: () {
Navigator.of(context).pop();
widget.onCancelTap!();
});
}
}

View File

@ -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"))

View File

@ -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:

View File

@ -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