Files
tuiche/lib/pages/mh_page/user/page/mht_login_page.dart
2025-07-21 17:17:06 +08:00

1930 lines
122 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:io';
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:fluwx/fluwx.dart';
import 'package:get_storage/get_storage.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/appFontsize.dart';
import 'package:vbvs_app/common/util/CheckNetwork.dart';
import 'package:vbvs_app/common/util/CommonVariables.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/time/countdown_controller.dart';
import 'package:vbvs_app/pages/mh_page/user/controller/mht_login_controller.dart';
import 'package:vbvs_app/pages/mh_page/user/controller/mht_register_controller.dart';
class MHTLoginPage extends GetView<MHTLoginController> {
final scaffoldKey = GlobalKey<ScaffoldState>();
BoxConstraints? bodysize;
final ScrollController _scrollController = ScrollController();
final FocusNode _focusNode1 = FocusNode();
final FocusNode _focusNode2 = FocusNode();
final FocusNode _focusNode3 = FocusNode();
final FocusNode _focusNode4 = FocusNode();
MHTLoginPage({super.key}) {
controller.model.showPd = true;
_focusNode1.addListener(() {
if (_focusNode1.hasFocus) {
MyUtils.scrollToFocusedInput(_focusNode1, _scrollController);
}
});
_focusNode2.addListener(() {
if (_focusNode2.hasFocus) {
MyUtils.scrollToFocusedInput(_focusNode2, _scrollController);
}
});
_focusNode3.addListener(() {
if (_focusNode3.hasFocus) {
MyUtils.scrollToFocusedInput(_focusNode3, _scrollController);
}
});
_focusNode4.addListener(() {
if (_focusNode4.hasFocus) {
MyUtils.scrollToFocusedInput(_focusNode4, _scrollController);
}
});
// 微信登录监听
Fluwx fluwx = controller.fluwx;
/*
1、目前移动应用上微信登录只提供原生的登录方式需要用户安装微信客户端才能配合使用。
2、对于Android应用建议总是显示微信登录按钮当用户手机没有安装微信客户端时请引导用户下载安装微信客户端。
3、对于iOS应用考虑到iOS应用商店审核指南中的相关规定建议开发者接入微信登录时先检测用户手机是否已安装微信客户端
使用sdk中isWXAppInstalled函数 ),对未安装的用户隐藏微信登录按钮,只提供其他登录方式(比如手机号注册登录、游客登录等)
*/
if (isiOS) {
controller.model.isIos = true;
fluwx.isWeChatInstalled.then((isWeChatInstalled) {
debugPrint('is wechat installed: $isWeChatInstalled');
if (!isWeChatInstalled) {
// TODO ios未安装微信 隐藏微信一键登录按钮
controller.model.isWeChatNotInstalled = false;
} else {
controller.model.isWeChatNotInstalled = true;
}
controller.updateAll();
});
}
// 微信监听回调
controller.fluwxCancelable = fluwx.addSubscriber((response) async {
if (response is WeChatAuthResponse) {
debugPrint('state :${response.state} \n code:${response.code}');
int errCode = response.errCode ?? -9999;
if (errCode == 0) {
// TODO 微信登录成功 传递code给后台 再操作逻辑
String code = response.code ?? "";
//把微信登录返回的code传给后台剩下的事就交给后台处理
//首次未注册的用户引导去手机号填写页面
//已注册的用户直接跳转首页
if (CommonVariables.isNetWorkOn == false) {
TopSlideNotification.show(Get.context!,
text: "网络未连接,请开启设备网络后重试".tr,
textColor: themeController.currentColor.sc9);
return;
}
int rescode = await controller.loginByWechatCode(code);
if (rescode == 1) {
// TODO 操作全部跳转页面前成功以后移除监听,防止重复监听,其他方式登录成功也需要移出监听
controller.fluwxCancelable?.cancel();
// 登录成功移出网络检查监听
Checknetwork.subscription?.cancel();
Get.offAndToNamed("/mianPageBottomChange");
}
// TODO 操作全部跳转页面前成功以后移除监听,防止重复监听,其他方式登录成功也需要移出监听
// fluwxCancelable?.cancel();
} else if (errCode == -4) {
TopSlideNotification.show(Get.context!,
text: "用户拒绝授权".tr, textColor: themeController.currentColor.sc9);
} else if (errCode == -2) {
TopSlideNotification.show(Get.context!,
text: "用户取消授权".tr, textColor: themeController.currentColor.sc9);
}
}
});
}
DateTime? _lastBackPressedTime; // 记录上一次返回的时间
final getStorage = GetStorage();
@override
Widget build(BuildContext context) {
MHTRegisterController registerController = Get.find();
bool isProgrammaticPop = false; // 标记变量
Future.delayed(const Duration(milliseconds: 300), () {
String? isShowYingShiDialog = getStorage.read("isShowYingShiDialog");
if (isShowYingShiDialog == null || isShowYingShiDialog != "true") {
String btnName = "同意";
String cancelName = "取消";
if (Platform.isAndroid) {
cancelName = "退出";
}
}
});
return LayoutBuilder(builder: (context, cc) {
bodysize = cc;
return GestureDetector(
// onTap: () => FocusScope.of(context).unfocus(),,
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
resizeToAvoidBottomInset: false,
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
title: Container(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// Text(
// '用户注册',
// textAlign: TextAlign.center,
// style: TextStyle(
// color: Colors.white,
// fontSize: 30.rpx,
// ),
// ),
Positioned(
left: 0.rpx,
child: returnIconButtomNew,
),
],
),
),
actions: [],
centerTitle: false,
),
body: PopScope(
canPop: false,
onPopInvokedWithResult: (disposition, result) async {
if (isProgrammaticPop) {
// 如果是程序触发,重置标记并忽略
isProgrammaticPop = false;
return; // 阻止处理
}
if (Platform.isAndroid) {
var flag = await _handleBackPressed(context); // 自定义返回逻辑
if (flag) {
SystemNavigator.pop();
}
}
},
child: Align(
alignment: AlignmentDirectional(0, 0),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 1,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
SizedBox(
height: 50.rpx,
),
Expanded(
child: Container(
decoration: BoxDecoration(),
child: Container(
width: bodysize!.maxWidth,
decoration: BoxDecoration(),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Obx(() {
return Visibility(
visible: controller.model.loginStyle == 1
? true
: false,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
96.rpx, 0.rpx, 96.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.06,
decoration: BoxDecoration(),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.06,
decoration: BoxDecoration(),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: MediaQuery.sizeOf(
context)
.width *
0.165,
height: MediaQuery.sizeOf(
context)
.height *
1,
constraints: BoxConstraints(
minWidth: 100,
),
decoration: BoxDecoration(),
child: Container(
width: MediaQuery.sizeOf(
context)
.width *
0.165,
height: MediaQuery.sizeOf(
context)
.height *
1,
constraints:
BoxConstraints(
minWidth: 124,
),
decoration:
BoxDecoration(),
child: Column(
mainAxisSize:
MainAxisSize.max,
children: [
Padding(
padding:
EdgeInsetsDirectional
.fromSTEB(
0,
0,
0,
8),
child: Container(
width: MediaQuery
.sizeOf(
context)
.width *
0.165,
height: MediaQuery
.sizeOf(
context)
.height *
0.045,
constraints:
BoxConstraints(
minWidth: 124,
),
decoration:
BoxDecoration(),
child: Container(
width: MediaQuery.sizeOf(
context)
.width *
0.162,
height: MediaQuery.sizeOf(
context)
.height *
0.055,
decoration:
BoxDecoration(),
child: Align(
alignment:
AlignmentDirectional(
0, 1),
child: Text(
'密码登录'.tr,
style:
TextStyle(
fontFamily:
'Readex Pro',
color: stringToColor(
"#84F5FF"),
fontSize:
AppFontsize
.title_size,
letterSpacing:
0,
),
),
),
),
),
),
Align(
alignment:
AlignmentDirectional(
0, 0),
child: Container(
width: MediaQuery
.sizeOf(
context)
.width *
0.156,
height: MediaQuery
.sizeOf(
context)
.height *
0.003,
constraints:
BoxConstraints(
minWidth: 100,
maxWidth: 100,
maxHeight: 6,
),
decoration:
BoxDecoration(
color: stringToColor(
"#84F5FF"),
),
),
),
],
),
),
),
InkWell(
onTap: () {
controller
.model.loginStyle = 2;
controller.updateAll();
},
child: Container(
width: MediaQuery.sizeOf(
context)
.width *
0.165,
height: MediaQuery.sizeOf(
context)
.height *
1,
constraints:
BoxConstraints(
minWidth: 100,
),
decoration:
BoxDecoration(),
child: Column(
mainAxisSize:
MainAxisSize.max,
children: [
Container(
width: MediaQuery
.sizeOf(
context)
.width *
0.14,
height: MediaQuery
.sizeOf(
context)
.height *
0.045,
constraints:
BoxConstraints(
minWidth: 105,
),
decoration:
BoxDecoration(),
child: Align(
alignment:
AlignmentDirectional(
0, 1),
child: Text(
'短信登录'.tr,
style:
TextStyle(
fontFamily:
'Readex Pro',
color: Colors
.white,
fontSize:
AppFontsize
.normal_text_size,
letterSpacing:
0,
),
),
),
),
],
),
),
),
],
),
),
),
),
),
);
}),
Obx(() {
return Visibility(
visible: controller.model.loginStyle == 2
? true
: false,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
96.rpx, 0, 96.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.06,
decoration: BoxDecoration(),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.06,
decoration: BoxDecoration(),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
InkWell(
onTap: () {
controller
.model.loginStyle = 1;
controller.updateAll();
},
child: Container(
width: MediaQuery.sizeOf(
context)
.width *
0.165,
height: MediaQuery.sizeOf(
context)
.height *
1,
constraints:
BoxConstraints(
minWidth: 100,
),
decoration:
BoxDecoration(),
child: Column(
mainAxisSize:
MainAxisSize.max,
children: [
Align(
alignment:
AlignmentDirectional(
0, 1),
child: Container(
width: MediaQuery
.sizeOf(
context)
.width *
0.14,
height: MediaQuery
.sizeOf(
context)
.height *
0.045,
constraints:
BoxConstraints(
minWidth: 105,
),
decoration:
BoxDecoration(),
child: Align(
alignment:
AlignmentDirectional(
0, 1),
child: Text(
'密码登录'.tr,
style:
TextStyle(
fontFamily:
'Readex Pro',
color: Colors
.white,
fontSize:
AppFontsize
.normal_text_size,
letterSpacing:
0,
),
),
),
),
),
],
),
),
),
Container(
width: MediaQuery.sizeOf(
context)
.width *
0.165,
height: MediaQuery.sizeOf(
context)
.height *
1,
constraints: BoxConstraints(
minWidth: 100,
),
decoration: BoxDecoration(),
child: Container(
width: MediaQuery.sizeOf(
context)
.width *
0.165,
height: MediaQuery.sizeOf(
context)
.height *
1,
constraints:
BoxConstraints(
minWidth: 124,
),
decoration:
BoxDecoration(),
child: Column(
mainAxisSize:
MainAxisSize.max,
children: [
Padding(
padding:
EdgeInsetsDirectional
.fromSTEB(
0,
0,
0,
8),
child: Container(
width: MediaQuery
.sizeOf(
context)
.width *
0.165,
height: MediaQuery
.sizeOf(
context)
.height *
0.045,
constraints:
BoxConstraints(
minWidth: 124,
),
decoration:
BoxDecoration(),
child: Container(
width: MediaQuery.sizeOf(
context)
.width *
0.162,
height: MediaQuery.sizeOf(
context)
.height *
0.055,
decoration:
BoxDecoration(),
child: Align(
alignment:
AlignmentDirectional(
0, 1),
child: Text(
'短信登录'.tr,
style:
TextStyle(
fontFamily:
'Readex Pro',
color: stringToColor(
"#84F5FF"),
fontSize:
AppFontsize
.title_size,
letterSpacing:
0,
),
),
),
),
),
),
Align(
alignment:
AlignmentDirectional(
0, 0),
child: Container(
width: MediaQuery
.sizeOf(
context)
.width *
0.156,
height: MediaQuery
.sizeOf(
context)
.height *
0.003,
constraints:
BoxConstraints(
minWidth: 100,
maxWidth: 100,
maxHeight: 6,
),
decoration:
BoxDecoration(
color: stringToColor(
"#84F5FF"),
),
),
),
],
),
),
),
],
),
),
),
),
),
);
}),
Obx(() {
return Visibility(
visible: controller.model.loginStyle == 1
? true
: false,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
96.rpx, 17, 96.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: 46,
decoration: BoxDecoration(),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.06,
decoration: BoxDecoration(
color: Color(0xFFF3F5F6),
borderRadius:
BorderRadius.circular(12),
),
child: Align(
alignment:
AlignmentDirectional(0, 0),
child: TextFormField(
// focusNode: _focusNode1,
onChanged: (value) {
controller.model.account =
value;
},
initialValue:
controller.model.account,
obscureText: false,
decoration: InputDecoration(
labelStyle: TextStyle(
fontFamily: 'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
hintText: '请输入账号',
hintStyle: TextStyle(
fontFamily: 'Readex Pro',
color: Color(0xFFD2D2D2),
fontSize: 13.px,
letterSpacing: 0,
),
enabledBorder:
InputBorder.none,
focusedBorder:
InputBorder.none,
errorBorder: InputBorder.none,
focusedErrorBorder:
InputBorder.none,
contentPadding:
EdgeInsetsDirectional
.fromSTEB(
10, 0, 0, 5),
),
style: TextStyle(
fontFamily: 'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
),
),
),
),
),
);
}),
Obx(() {
return Visibility(
visible: controller.model.loginStyle == 1
? true
: false,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
96.rpx, 17, 96.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: 46,
decoration: BoxDecoration(),
child: Stack(
children: [
Align(
alignment:
AlignmentDirectional(0, 0),
child: Container(
width:
MediaQuery.sizeOf(context)
.width,
height: 46,
decoration: BoxDecoration(
color: Color(0xFFF3F5F6),
borderRadius:
BorderRadius.circular(
12),
),
child: Align(
alignment:
AlignmentDirectional(
0, 0),
child: TextFormField(
obscureText: controller
.model.showPd!,
onChanged: (value) {
controller.model
.password = value;
},
initialValue: controller
.model.password,
decoration:
InputDecoration(
labelStyle: TextStyle(
fontFamily:
'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
hintText: '请输入密码',
hintStyle: TextStyle(
fontFamily:
'Readex Pro',
color:
Color(0xFFD2D2D2),
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
enabledBorder:
InputBorder.none,
focusedBorder:
InputBorder.none,
errorBorder:
InputBorder.none,
focusedErrorBorder:
InputBorder.none,
contentPadding:
EdgeInsetsDirectional
.fromSTEB(10,
12, 0, 0),
suffixIcon: IconButton(
icon: Icon(
// 根据 pdshow 控制图标
controller.model
.showPd!
? Icons
.visibility_off
: Icons
.visibility,
color: Color(
0xFF333333),
size: 16,
),
onPressed: () {
// 切换 pdshow 状态
controller.model
.showPd =
!controller
.model
.showPd!;
controller
.updateAll();
},
),
),
style: TextStyle(
fontFamily:
'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
),
),
),
),
Obx(() {
return Visibility(
visible: controller
.model.loginStyle ==
2,
child: Align(
alignment:
AlignmentDirectional(
0.2, 0.3),
child: Container(
width: 3,
height: 30,
decoration: BoxDecoration(
color: stringToColor(
"#929699"),
),
),
),
);
}),
Obx(() {
return Visibility(
visible: controller
.model.loginStyle ==
2,
child: Align(
alignment:
AlignmentDirectional(
0.9, 0),
child: Container(
width: MediaQuery.sizeOf(
context)
.width *
0.157,
height: MediaQuery.sizeOf(
context)
.height *
0.014,
constraints:
BoxConstraints(
minWidth: 118,
minHeight: 30,
maxWidth: 118,
),
decoration:
BoxDecoration(),
child: Align(
alignment:
AlignmentDirectional(
0, 0),
child: Obx(() {
final CountdownController
countdownController =
Get.find<
CountdownController>();
return InkWell(
onTap: () async {
if (countdownController
.countdown
.value !=
0) {
return;
}
if (CommonVariables
.isNetWorkOn ==
false) {
TopSlideNotification.show(
context,
text:
"网络未连接,请开启设备网络后重试"
.tr,
textColor:
themeController
.currentColor
.sc9);
return;
}
String msg =
await controller
.getCode(
context);
if (msg
.isNotEmpty) {
return;
}
countdownController
.countdown
.value ==
0
? countdownController
.startCountdown(
AppConstants
.code_time)
: null;
},
child: Text(
countdownController
.countdown
.value ==
0
? '获取验证码'.tr
: '${countdownController.countdown.value}' +
''.tr,
style: TextStyle(
fontFamily:
'Readex Pro',
color: Color(
0xFF333333),
fontSize:
AppFontsize
.normal_text_size,
letterSpacing:
0,
),
),
);
}),
),
),
),
);
})
],
),
),
),
);
}),
Obx(() {
return Visibility(
visible: controller.model.loginStyle == 2
? true
: false,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
96.rpx, 17, 96.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: 46,
decoration: BoxDecoration(),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.06,
decoration: BoxDecoration(
color: Color(0xFFF3F5F6),
borderRadius:
BorderRadius.circular(12),
),
child: Align(
alignment:
AlignmentDirectional(0, 0),
child: TextFormField(
// focusNode: _focusNode3,
onChanged: (value) {
controller.model.phone =
value;
},
obscureText: false,
decoration: InputDecoration(
labelStyle: TextStyle(
fontFamily: 'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
hintText: '请输入手机号'.tr,
hintStyle: TextStyle(
fontFamily: 'Readex Pro',
color: Color(0xFFD2D2D2),
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
enabledBorder:
InputBorder.none,
focusedBorder:
InputBorder.none,
errorBorder: InputBorder.none,
focusedErrorBorder:
InputBorder.none,
contentPadding:
EdgeInsetsDirectional
.fromSTEB(
10, 0, 0, 5),
),
style: TextStyle(
fontFamily: 'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
),
),
),
),
),
);
}),
Obx(() {
return Visibility(
visible: controller.model.loginStyle == 2
? true
: false,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
96.rpx, 17, 96.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: 46,
decoration: BoxDecoration(),
child: Stack(
children: [
Align(
alignment:
AlignmentDirectional(0, 0),
child: Container(
width:
MediaQuery.sizeOf(context)
.width,
height: 46,
decoration: BoxDecoration(
color: Color(0xFFF3F5F6),
borderRadius:
BorderRadius.circular(
12),
),
child: Align(
alignment:
AlignmentDirectional(
0, 0),
child: TextFormField(
// focusNode: _focusNode4,
onChanged: (value) {
controller.model.code =
value;
},
obscureText: false,
decoration:
InputDecoration(
labelStyle: TextStyle(
fontFamily:
'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
hintText: '请输入验证码',
hintStyle: TextStyle(
fontFamily:
'Readex Pro',
color:
Color(0xFFD2D2D2),
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
enabledBorder:
InputBorder.none,
focusedBorder:
InputBorder.none,
errorBorder:
InputBorder.none,
focusedErrorBorder:
InputBorder.none,
contentPadding:
EdgeInsetsDirectional
.fromSTEB(10, 0,
0, 5),
),
style: TextStyle(
fontFamily:
'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
),
),
),
),
Align(
alignment: AlignmentDirectional(
0.2, 0.1),
child: Container(
width: 1.rpx,
height: 38.rpx,
decoration: BoxDecoration(
color: stringToColor(
"#929699"),
),
),
),
Align(
alignment: AlignmentDirectional(
0.9, 0),
child: Container(
width:
MediaQuery.sizeOf(context)
.width *
0.157,
height:
MediaQuery.sizeOf(context)
.height *
0.014,
constraints: BoxConstraints(
minWidth: 118,
minHeight: 30,
),
decoration: BoxDecoration(),
child: Align(
alignment:
AlignmentDirectional(
0, 0),
child: Obx(() {
final CountdownController
countdownController =
Get.find<
CountdownController>();
return InkWell(
onTap: () async {
if (countdownController
.countdown
.value !=
0) {
return;
}
if (CommonVariables
.isNetWorkOn ==
false) {
TopSlideNotification.show(
context,
text:
"网络未连接,请开启设备网络后重试"
.tr,
textColor:
themeController
.currentColor
.sc9);
return;
}
String msg =
await controller
.getCode(
context);
if (msg.isNotEmpty) {
return;
}
countdownController
.countdown
.value ==
0
? countdownController
.startCountdown(
AppConstants
.code_time)
: null;
},
child: Text(
countdownController
.countdown
.value ==
0
? '获取验证码'
: '${countdownController.countdown.value}' +
''.tr,
style: TextStyle(
fontFamily:
'Readex Pro',
color: Color(
0xFF333333),
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
),
);
}),
),
),
),
],
),
),
),
);
}),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
96.rpx, 34.rpx, 96.rpx, 0),
child: SizedBox(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.056,
child: CustomCard(
gradientDirection:
GradientDirection.vertical,
borderRadius: AppConstants()
.normal_container_radius,
onTap: () async {
if (CommonVariables.isNetWorkOn ==
false) {
TopSlideNotification.show(context,
text: "网络未连接,请开启设备网络后重试".tr,
textColor: themeController
.currentColor.sc9);
return;
}
String msg =
await controller.login(context);
if (msg == null || msg.isEmpty) {
final box = GetStorage();
box.remove('countdown');
CountdownController
countdownController =
Get.find();
countdownController.countdown =
0.obs;
countdownController
.startCountdown(0);
controller.fluwxCancelable
?.cancel();
Checknetwork.subscription?.cancel();
isProgrammaticPop = true;
MHTLoginController loginController =
Get.find();
loginController.model.account =
null;
loginController.model.password =
null;
loginController.model.phone = null;
loginController.model.code = null;
MHTRegisterController
registerController = Get.find();
registerController
.model.register_agree = false;
Get.offAndToNamed(
"/mianPageBottomChange");
//登陆成功
//
}
},
colors: [
stringToColor("FCFCFC"),
stringToColor("CEECE3")
], // 纯色背景
enableGradient: true, // 不启用渐变
child: Center(
child: Text(
'登录'.tr,
style: TextStyle(
color: stringToColor("#003058"),
fontSize: 26.rpx,
letterSpacing: 0,
),
),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
96.rpx, 38.rpx, 96.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.022,
constraints: BoxConstraints(
minWidth: 466,
minHeight: 30,
),
// decoration:
// BoxDecoration(color: Colors.green),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.022,
constraints: BoxConstraints(
minWidth: 466,
minHeight: 30,
),
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Align(
alignment:
AlignmentDirectional(0, 0),
child: Padding(
padding: EdgeInsetsDirectional
.fromSTEB(0, 3, 0, 0),
child: Container(
width: 36,
height: 36,
decoration: BoxDecoration(),
child: Align(
alignment:
AlignmentDirectional(
0, 0),
child: Theme(
data: ThemeData(
checkboxTheme:
CheckboxThemeData(
visualDensity:
VisualDensity
.compact,
materialTapTargetSize:
MaterialTapTargetSize
.shrinkWrap,
shape:
RoundedRectangleBorder(
borderRadius:
BorderRadius
.circular(
64),
),
),
unselectedWidgetColor:
Color(0xFFD3D3D3),
),
child: Obx(
() => Checkbox(
value: registerController
.model
.register_agree ??
false,
onChanged:
(newValue) async {
registerController
.model
.register_agree =
newValue;
controller
.updateAll();
registerController
.updateAll();
// 获取设备信息,需要用户点击确认隐私协议与用户协议选择框时才能获取
// if (newValue ==
// true) {
// Deviceconfig
// .initPlatformState();
// }
},
side: BorderSide(
width: 1.5,
color:
Colors.white,
),
activeColor:
stringToColor(
"#84F5FF"),
checkColor:
stringToColor(
"#011D33"),
),
)),
),
),
),
),
Flexible(
child: Padding(
padding: EdgeInsetsDirectional
.fromSTEB(0, 0, 0, 0),
child: Container(
width:
MediaQuery.sizeOf(context)
.width *
0.622,
height:
MediaQuery.sizeOf(context)
.height *
1,
constraints: BoxConstraints(
minWidth: 466,
minHeight: 30,
),
decoration: BoxDecoration(),
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(),
child: Row(
mainAxisSize:
MainAxisSize.max,
children: [
Align(
alignment:
AlignmentDirectional(
0, 0),
child: Text(
'我已阅读并同意'.tr,
style: TextStyle(
fontFamily:
'Readex Pro',
color:
Colors.white,
fontSize: 23.rpx,
letterSpacing: 0,
),
),
),
Align(
alignment:
AlignmentDirectional(
0, 0),
child: InkWell(
onTap: () {
// showCustomConfirmOfWebViewDialog(
// context,
// "用户协议",
// "/#/pages/agreement/agreement?type=2&hideHead=true",
// btnName:
// "同意并继续");
Get.toNamed(
"/userAgreementPage");
},
child: Text(
'《用户协议》'.tr,
style: TextStyle(
fontFamily:
'Readex Pro',
color:
stringToColor(
"FF9F66"),
fontSize:
23.rpx,
letterSpacing:
0,
),
),
),
),
Align(
alignment:
AlignmentDirectional(
0, 0),
child: Text(
''.tr,
style: TextStyle(
fontFamily:
'Readex Pro',
color:
Colors.white,
fontSize: 23.rpx,
letterSpacing: 0,
),
),
),
Align(
alignment:
AlignmentDirectional(
0, 0),
child: InkWell(
onTap: () {
// showCustomConfirmOfWebViewDialog(
// context,
// "隐私协议",
// "/#/pages/agreement/agreement?type=1&hideHead=true",
// btnName:
// "同意并继续");
Get.toNamed(
"/privacyPolicyPage");
},
child: Text(
'《隐私协议》'.tr,
style: TextStyle(
fontFamily:
'Readex Pro',
color:
stringToColor(
"FF9F66"),
fontSize:
23.rpx,
letterSpacing:
0,
),
),
),
),
],
),
),
),
),
),
],
),
),
),
),
Obx(() {
return Visibility(
visible: controller.model.loginStyle == 2,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
96.rpx, 0, 96.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.03,
decoration: BoxDecoration(),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.025,
constraints: BoxConstraints(
minWidth: 466,
minHeight: 30,
),
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Align(
alignment:
AlignmentDirectional(
0, 0),
child: Padding(
padding:
EdgeInsetsDirectional
.fromSTEB(
0, 0, 0, 0),
child: Container(
width: 36,
height: 36,
decoration:
BoxDecoration(),
),
),
),
Flexible(
child: Padding(
padding:
EdgeInsetsDirectional
.fromSTEB(
0, 0, 0, 0),
child: Container(
width: MediaQuery.sizeOf(
context)
.width *
0.622,
height: MediaQuery.sizeOf(
context)
.height *
1,
// constraints:
// BoxConstraints(
// minWidth: 466,
// minHeight: 30,
// ),
decoration:
BoxDecoration(),
child: Container(
// width: 100,
// height: 100,
decoration:
BoxDecoration(),
child: Row(
mainAxisSize:
MainAxisSize.max,
children: [
Align(
alignment:
AlignmentDirectional(
0, 0),
child: Text(
'注:首次登录会自动创建账号'
.tr,
style:
TextStyle(
fontFamily:
'Readex Pro',
color: stringToColor(
"#FFFFFF"),
fontSize:
23.rpx,
letterSpacing:
0,
),
),
),
],
),
),
),
),
),
],
),
),
),
),
);
}),
Obx(() {
return Visibility(
visible: controller.model.loginStyle == 2,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
96.rpx, 0, 96.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.03,
decoration: BoxDecoration(),
),
),
);
}),
Obx(() {
return Visibility(
visible: controller.model.loginStyle == 2,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
96.rpx, 0, 96.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.03,
decoration: BoxDecoration(),
),
),
);
}),
Obx(() {
return Visibility(
visible: controller.model.loginStyle == 1,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
96.rpx, 0, 96.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.03,
),
),
);
}),
Obx(() {
return Visibility(
visible: controller.model.loginStyle == 1,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
96.rpx, 0, 96.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.03,
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.06,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.end,
children: [
InkWell(
onTap: () {
Get.toNamed(
"/registerPage");
},
child: Text.rich(
TextSpan(
children: [
TextSpan(
text: "还没有账号? ".tr,
style: TextStyle(
color: Colors
.white, // 设置"还没有账号?"为白色
fontFamily:
'Readex Pro',
fontSize: AppFontsize
.small_text_size,
),
),
TextSpan(
text: '前往注册'.tr,
style: TextStyle(
color: stringToColor(
"#84F5FF"), // 保持"前往注册"为指定颜色
fontFamily:
'Readex Pro',
fontSize: AppFontsize
.small_text_size,
),
),
],
),
),
),
InkWell(
onTap: () {
Get.toNamed(
"/findPasswordPage");
},
child: Text(
'找回密码 '.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: stringToColor(
"#84F5FF"),
fontSize: AppFontsize
.small_text_size,
letterSpacing: 0,
),
),
),
].divide(SizedBox(
width: 57.rpx,
)),
),
),
),
),
);
}),
Obx(() {
return Visibility(
visible: controller.model.loginStyle == 1,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
96.rpx, 0, 96.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.03,
),
),
);
}),
Divider(
color: stringToColor("#495A67"), // 线的颜色
thickness: 1.rpx, // 线的粗细
height: 20, // 垂直方向的占位高度
indent: 16, // 左边缩进
endIndent: 16, // 右边缩进
),
Text(
"其他登录方式".tr,
style: TextStyle(
color: Colors.white,
fontSize: AppConstants()
.normal_text_fontSize),
),
SizedBox(
height: 30.rpx,
),
ClickableContainer(
backgroundColor: Colors.white, // 背景色
highlightColor: Colors.grey, // 点击水波纹颜色
borderRadius: 999.rpx,
padding: EdgeInsets.zero,
onTap: () async {
// loginController.model.isIos == true &&
MHTRegisterController
registerController = Get.find();
if (registerController
.model.register_agree ==
null ||
registerController
.model.register_agree !=
true) {
TopSlideNotification.show(
context,
text: "登录页.未同意协议".tr,
textColor:
themeController.currentColor.sc9,
);
return;
}
MHTLoginController loginController =
Get.find();
await loginController
.wxLoginSendAuth();
// TopSlideNotification.show(context,
// text: "测试阶段,暂不支持".tr);
},
child: Container(
width: 90.rpx,
height: 90.rpx,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/wechat.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
),
),
],
),
),
),
),
),
Container(
child: Column(
children: [
Container(
width: bodysize!.maxWidth * 0.365,
height: MediaQuery.sizeOf(context).height * 0.044,
decoration: BoxDecoration(),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.asset(
'assets/images/_18328.png',
width: 300,
height: 200,
fit: BoxFit.contain,
),
),
),
SizedBox(
height: 73.rpx,
),
Container(
width: bodysize!.maxWidth,
// height: bodysize!.maxHeight * 0.118,
height: bodysize!.maxHeight * 0.09,
constraints: BoxConstraints(
minWidth: 335,
minHeight: 61,
),
decoration: BoxDecoration(),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 1,
constraints: BoxConstraints(
minWidth: 335,
minHeight: 61,
),
decoration: BoxDecoration(),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Align(
alignment: AlignmentDirectional(0, 0),
child: Text(
'合肥眠花糖家具有限责任公司版权所有',
style: TextStyle(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: AppFontsize.explain_size,
letterSpacing: 0,
),
),
),
Align(
alignment: AlignmentDirectional(0, 0),
child: Text(
'Copyright© 2019-2029',
style: TextStyle(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: AppFontsize.explain_size,
letterSpacing: 0,
),
),
),
],
),
),
),
),
],
),
),
],
),
),
),
),
),
),
);
});
}
Future<bool> _handleBackPressed(BuildContext context) async {
final currentTime = DateTime.now();
// 如果上次点击返回键时间为空,或者间隔超过 1 秒
if (_lastBackPressedTime == null ||
currentTime.difference(_lastBackPressedTime!) > Duration(seconds: 2)) {
_lastBackPressedTime = currentTime;
TopSlideNotification.show(
context,
text: "再按一次退出程序".tr,
);
return false; // 阻止退出程序
} else {
return true; // 允许退出程序
}
}
}