From 71a4504f78038516ba9500cb329bf6b5dafa4897 Mon Sep 17 00:00:00 2001 From: wyf <494641114@qq.com> Date: Sat, 7 Jun 2025 18:00:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=99=BB=E5=BD=95=E5=B8=83?= =?UTF-8?q?=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/images/wechat.png | Bin 1547 -> 2222 bytes assets/img/background.png | Bin 0 -> 33293 bytes assets/mhlangs/zh_CN.json | 33 +- lib/common/color/appConstants.dart | 1 + .../mh_controller/mh_language_controller.dart | 4 +- .../mh_language_controller.g.dart | 4 +- lib/main.dart | 10 +- .../SingleBlueteethDeviceCompoentWidget.dart | 1 + .../component/main_page_b_bottom_change.dart | 4 +- .../user/controller/mht_login_controller.dart | 189 ++ .../controller/mht_login_controller.g.dart | 33 + .../controller/mht_register_controller.dart | 131 + .../controller/mht_register_controller.g.dart | 28 + .../{ => user/page}/find_password_page.dart | 59 +- .../mh_page/user/page/mht_login_page.dart | 2151 +++++++++++++++++ .../{ => user/page}/register_page.dart | 98 +- lib/routers/mh_routers.dart | 13 +- 17 files changed, 2651 insertions(+), 108 deletions(-) create mode 100644 assets/img/background.png create mode 100644 lib/pages/mh_page/user/controller/mht_login_controller.dart create mode 100644 lib/pages/mh_page/user/controller/mht_login_controller.g.dart create mode 100644 lib/pages/mh_page/user/controller/mht_register_controller.dart create mode 100644 lib/pages/mh_page/user/controller/mht_register_controller.g.dart rename lib/pages/mh_page/{ => user/page}/find_password_page.dart (97%) create mode 100644 lib/pages/mh_page/user/page/mht_login_page.dart rename lib/pages/mh_page/{ => user/page}/register_page.dart (96%) diff --git a/assets/images/wechat.png b/assets/images/wechat.png index a12ce174e7030a174f1b30dc66054d8f763d7c06..e04e541b3bdf51f9790e54e040114aa335570dad 100644 GIT binary patch literal 2222 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 literal 1547 zcmV+m2K4!fP)Nd@OWZ0Z)+Mwb0>?X-{Rn(G`>V;NsVIYBhx@<0vyuP?Y5==dzlG=h(INqS68A)siA~e(Y&jCmw$E0~TbeGO z)-Wn<=8K_SSggi{Ug_y&0Q_t-4%l1TEPCKyMhq{t*>=D`kJM~TJz0HVJ2HR0t<9^& z>cr`O&)~aX68n3<-{-O$ zNB0-s;r$){Qqn(Lo81%odHpHB;N=%4#HjIM7u1K27I^ZMQ?$>Qt({tTW-RxF2XnmL zBl`FAQ+7Re2(6f$(k5ww1R$vUNYGRdzsy}vw#EY=dQkrcC-hwa7yUc&gS52aNa7I+6}|`n3TZfy2rmDWZsFZA`tWMc zxFu<>?d5!tqwmJ}eII_t_5TDtPAL_XBHgJIS+Enjkt5$#^uX@0eVAEI|BQ#$na_jH z0jKZb4nRan5JhraIVA*1>AV>VrbQ8XeakiO^coMmO>A%H`<9uXW5ml>7=|&T|2Y&t z$`l_Ym_WmLzzLA^5}y|$xL1|4E-|cp8bPrjGI?GH>9&rL<#Xc>BQP~iB}WWx~AqdF!4F|@Z0gttgCat z;Uq)L!|imboFcTaVV8KXK;8xKI(vL2fp zhf&8#1h5ng1vM&E!cfD=3`7iZ*?;SN8K#>3xI+!!f$pLtyxY1H!7L-v@SwU!ZMW6Zb*;zH~ z5QpL6f=53daKrEA)xot#FP$?DEq#2eICO~-ho#)V*7|n~6Z?2@(En5EMT*z^zhWFy zhUFajFy|ee=Kqfw<_DkOpFEFzE5I$in`>L+!|PFFZR^2T79VU?`o_BYL-Ehs^bf^< zgZ_cSr)5vo%R{WKudN%ZrVqWFN(Ru8{{Wkw-GtA}5qF?>C!y@XVx${1Rs-O*56s54 xi+24qYg7rndfhIUZ>te#xm<2fKEkXbQ002ovPDHLkV1iyP{xSdn diff --git a/assets/img/background.png b/assets/img/background.png new file mode 100644 index 0000000000000000000000000000000000000000..f34dd5cc7f3f40560f74e702d3944be978984b50 GIT binary patch literal 33293 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 Mvd~YieH?Y json) { try { - return _$LanguageModelFromJson(json); + return _$MHLanguageModelFromJson(json); } catch (e) { return MHLanguageModel(); // 或者返回一个带有错误信息的特定实例 } } - Map toJson() => _$LanguageModelToJson(this); + Map toJson() => _$MHLanguageModelToJson(this); } class MHLanguageController extends GetControllerEx { diff --git a/lib/controller/mh_controller/mh_language_controller.g.dart b/lib/controller/mh_controller/mh_language_controller.g.dart index 5386c92..14c310d 100644 --- a/lib/controller/mh_controller/mh_language_controller.g.dart +++ b/lib/controller/mh_controller/mh_language_controller.g.dart @@ -6,14 +6,14 @@ part of 'mh_language_controller.dart'; // JsonSerializableGenerator // ************************************************************************** -MHLanguageModel _$LanguageModelFromJson(Map json) => +MHLanguageModel _$MHLanguageModelFromJson(Map json) => MHLanguageModel() ..filename = json['filename'] as String? ..language_name = json['language_name'] as String? ..selected = json['selected'] as bool? ..language_code = json['language_code'] as String?; -Map _$LanguageModelToJson(MHLanguageModel instance) => +Map _$MHLanguageModelToJson(MHLanguageModel instance) => { 'filename': instance.filename, 'language_name': instance.language_name, diff --git a/lib/main.dart b/lib/main.dart index 57f4e67..1dae682 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -63,6 +63,8 @@ import 'package:vbvs_app/model/CustomThemeColor.dart'; import 'package:vbvs_app/model/user_data.dart'; import 'package:vbvs_app/pages/main_bottom/component/main_page_b_bottom_change.dart'; import 'package:vbvs_app/pages/mh_page/MattressControl.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'; import 'package:vbvs_app/routers/mh_routers.dart'; import 'controller/mh_controller/apply_repair_controller.dart'; @@ -279,7 +281,8 @@ class MyApp extends StatelessWidget { debugShowCheckedModeBanner: false, title: '', theme: themeController.currentTheme, - home: MainPageBBottomChange(), + // home: MainPageBBottomChange(), + initialRoute: "/loginPage", onGenerateRoute: mhonGenerateRoute, initialBinding: BindingsBuilder(() => [ // Get.lazyPut(() => UserInfoController()), @@ -316,6 +319,8 @@ class MyApp extends StatelessWidget { Get.lazyPut(() => DeviceShareListController()), Get.lazyPut(() => DeviceCalibrationController()), Get.lazyPut(() => RepairController()), + Get.lazyPut(() => MHTLoginController()), + Get.lazyPut(() => MHTRegisterController()), ])); } @@ -367,7 +372,8 @@ class MyApp extends StatelessWidget { ])); } - final selectapp = "th"; + // final selectapp = "th"; + final selectapp = "mht"; // This widget is the root of your application. @override Widget build(BuildContext context) { diff --git a/lib/pages/device_bind/componnet/SingleBlueteethDeviceCompoentWidget.dart b/lib/pages/device_bind/componnet/SingleBlueteethDeviceCompoentWidget.dart index 08b5de5..52592fb 100644 --- a/lib/pages/device_bind/componnet/SingleBlueteethDeviceCompoentWidget.dart +++ b/lib/pages/device_bind/componnet/SingleBlueteethDeviceCompoentWidget.dart @@ -110,6 +110,7 @@ class _SingleBlueteethDeviceCompoentWidgetState } }, onCancel: () { + print('用户点击了取消'); blueteethBindController.currentDeviceMac.value = ""; blueteethBindController.updateAll(); diff --git a/lib/pages/main_bottom/component/main_page_b_bottom_change.dart b/lib/pages/main_bottom/component/main_page_b_bottom_change.dart index 603cce4..bec2ebd 100644 --- a/lib/pages/main_bottom/component/main_page_b_bottom_change.dart +++ b/lib/pages/main_bottom/component/main_page_b_bottom_change.dart @@ -154,11 +154,9 @@ import 'package:flutter/material.dart'; import 'package:vbvs_app/pages/common/bezier_bottom_navigation_bar.dart'; import 'package:vbvs_app/pages/mh_page/MattressControl.dart'; -import 'package:vbvs_app/pages/mh_page/find_password_page.dart'; import 'package:vbvs_app/pages/mh_page/new_Home_page.dart'; import 'package:vbvs_app/pages/mh_page/new_mine_page.dart'; -import 'package:vbvs_app/pages/mh_page/register_page.dart'; -import 'package:vbvs_app/pages/mh_page/score_page.dart'; +import 'package:vbvs_app/pages/mh_page/user/page/register_page.dart'; class MainPageBBottomChange extends StatefulWidget { @override diff --git a/lib/pages/mh_page/user/controller/mht_login_controller.dart b/lib/pages/mh_page/user/controller/mht_login_controller.dart new file mode 100644 index 0000000..5d06e25 --- /dev/null +++ b/lib/pages/mh_page/user/controller/mht_login_controller.dart @@ -0,0 +1,189 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:fluwx/fluwx.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; +import 'package:vbvs_app/pages/mh_page/user/controller/mht_register_controller.dart'; + +part 'mht_login_controller.g.dart'; + +@JsonSerializable() +class LoginModel { + //版本id + int? loginStyle = 1; //1.密码登录 2.短信登录 + + String? account = '17649984946'; //账户 + // String? account = '13953240733'; //账户 + String? password = 'wyf123,.'; //密码 + // String? account = '15255134931'; //账户 + // String? password = 'mht123,.'; //密码 + + // String? account = '18607922869'; //账户 + // String? password = '373068'; //密码 + // String? account = ''; //账户 + // String? password = ''; //密码 + + String? phone; //手机号 + String? code; //验证码 + + String? register_code; + + bool? showPd = true; + + int? forceLogin = 0; + + bool? isIos; //是否为ios设备 + + bool? isWeChatNotInstalled; //是否安装微信 + + LoginModel(); + + static LoginModel fromJson(Map json) => + _$LoginModelFromJson(json); + Map toJson() => _$LoginModelToJson(this); +} + +class MHTLoginController extends GetControllerEx { + // 初始化实例 + final Fluwx fluwx = Fluwx(); + // 微信监听返回值 + FluwxCancelable? fluwxCancelable; + + MHTLoginController() { + attr = GetModel(LoginModel()).obs; + } + + MHTRegisterController registerController = Get.find(); + + //登录 + Future login(BuildContext context) async { + String message = ''; + String account = ''; + String password = ''; + if (model.loginStyle == null) { + message = '请选择登录方式'.tr; + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + if (model.loginStyle == 1) { + //账号登录 + if (model.account == null || model.account!.isEmpty) { + message = '账户不能为空'.tr; + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + if (model.password == null || model.password!.isEmpty) { + message = '密码不能为空'.tr; + + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + + return message; + } + account = model.account!; + password = model.password!; + } + if (model.loginStyle == 2) { + //账号登录 + if (model.phone == null || model.phone!.isEmpty) { + message = '请输入手机号'.tr; + + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + if (!MyUtils.isValidPhoneNumber(model.phone!)) { + message = '请输入正确的手机号'.tr; + + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + if (model.code == null || model.code!.isEmpty) { + message = '验证码不能为空'.tr; + + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + account = model.phone!; + password = model.code!; + } + + if (registerController.model.register_agree == null || + registerController.model.register_agree != true) { + message = "需要同意协议".tr; + showToast(message); + return message; + } + model.forceLogin = 0; + return message; + } + + Future getCode(BuildContext context) async { + String message = ""; + if (registerController.model.register_agree == null || + registerController.model.register_agree != true) { + message = "需要同意协议".tr; + showToast(message); + return message; + } + if (model.phone == null || model.phone!.isEmpty) { + message = "请输入手机号".tr; + showToast(message); + return message; + } + if (!MyUtils.isValidPhoneNumber(model.phone!)) { + message = '请输入正确的手机号'.tr; + showToast(message); + return message; + } + return ''; + } + + //微信登录 + Future wxLoginSendAuth() async { + /* + 1、目前移动应用上微信登录只提供原生的登录方式,需要用户安装微信客户端才能配合使用。 + 2、对于Android应用,建议总是显示微信登录按钮,当用户手机没有安装微信客户端时,请引导用户下载安装微信客户端。 + 3、对于iOS应用,考虑到iOS应用商店审核指南中的相关规定,建议开发者接入微信登录时,先检测用户手机是否已安装微信客户端 + (使用sdk中isWXAppInstalled函数 ),对未安装的用户隐藏微信登录按钮,只提供其他登录方式(比如手机号注册登录、游客登录等) + */ + if (isAndroid) { + bool isWeChatInstalled = await fluwx.isWeChatInstalled; + debugPrint('is wechat installed: $isWeChatInstalled'); + if (!isWeChatInstalled) { + showToast("请先安装微信APP,再使用微信登录"); + return; + } + } + fluwx + .authBy( + which: NormalAuth( + scope: 'snsapi_userinfo', + state: 'wechat_sdk_zhmht_wxlogin', + )) + .then((data) { + //返回true表示成功或者false表示失败,这边没有意义从login_controller页面构造函数监听中去处理 + debugPrint('msg:$data'); + }); + } + + //退出登录 + Future logout() async { + // await repository.logout(); + } + + loginByWechatCode(String code) async { + // return await repository.loginByWechatCode(code); + } + + //注销账号 + deletedAccount() async { + // return await repository.deletedAccount(); + } +} diff --git a/lib/pages/mh_page/user/controller/mht_login_controller.g.dart b/lib/pages/mh_page/user/controller/mht_login_controller.g.dart new file mode 100644 index 0000000..49c28e8 --- /dev/null +++ b/lib/pages/mh_page/user/controller/mht_login_controller.g.dart @@ -0,0 +1,33 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'mht_login_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +LoginModel _$LoginModelFromJson(Map json) => LoginModel() + ..loginStyle = (json['loginStyle'] as num?)?.toInt() + ..account = json['account'] as String? + ..password = json['password'] as String? + ..phone = json['phone'] as String? + ..code = json['code'] as String? + ..register_code = json['register_code'] as String? + ..showPd = json['showPd'] as bool? + ..forceLogin = (json['forceLogin'] as num?)?.toInt() + ..isIos = json['isIos'] as bool? + ..isWeChatNotInstalled = json['isWeChatNotInstalled'] as bool?; + +Map _$LoginModelToJson(LoginModel instance) => + { + 'loginStyle': instance.loginStyle, + 'account': instance.account, + 'password': instance.password, + 'phone': instance.phone, + 'code': instance.code, + 'register_code': instance.register_code, + 'showPd': instance.showPd, + 'forceLogin': instance.forceLogin, + 'isIos': instance.isIos, + 'isWeChatNotInstalled': instance.isWeChatNotInstalled, + }; diff --git a/lib/pages/mh_page/user/controller/mht_register_controller.dart b/lib/pages/mh_page/user/controller/mht_register_controller.dart new file mode 100644 index 0000000..80afc23 --- /dev/null +++ b/lib/pages/mh_page/user/controller/mht_register_controller.dart @@ -0,0 +1,131 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; + +part 'mht_register_controller.g.dart'; + +@JsonSerializable() +class RegisterModel { + String? register_phone; //注册手机号 + String? register_pd; //注册密码 + String? register_confirm_pd; //注册确认密码 + String? register_code; //注册验证码 + + bool? register_agree = false; //注册协议 + bool? save_password = false; //记住密码 + + bool? pdshow = true; //是否显示密码 + bool? cpdshow = true; //是否显示密码 + + RegisterModel(); + static RegisterModel fromJson(Map json) => + _$RegisterModelFromJson(json); + Map toJson() => _$RegisterModelToJson(this); +} + +class MHTRegisterController extends GetControllerEx { + MHTRegisterController() { + attr = GetModel(RegisterModel()).obs; + } + + Future registerUser(BuildContext context) async { + String message = ""; + if (model.register_phone == null || model.register_phone!.isEmpty) { + message = "请输入手机号".tr; + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + if (!MyUtils.isValidPhoneNumber(model.register_phone!)) { + message = '请输入正确的手机号'.tr; + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + if (model.register_pd == null || model.register_pd!.isEmpty) { + message = "请输入密码".tr; + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + String passwordMsg = "密码格式提示".tr; + bool hasUppercase = model.register_pd!.contains(RegExp(r'[A-Z]')); + bool hasDigit = model.register_pd!.contains(RegExp(r'[0-9]')); + bool hasSpecialCharacters = + model.register_pd!.contains(RegExp(r'[!@#$%^&*(),.?":{}|<>]')); + bool hasLetter = model.register_pd!.contains(RegExp(r'[a-zA-Z]')); + + if (model.register_pd!.length < 8) { + message = passwordMsg; + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + + if (!hasLetter || !hasDigit) { + message = passwordMsg; + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + + if (!(hasSpecialCharacters || hasUppercase)) { + message = passwordMsg; + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + if (model.register_confirm_pd == null || + model.register_confirm_pd!.isEmpty) { + message = "请输入确认密码".tr; + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + if (model.register_pd != model.register_confirm_pd) { + message = "两次密码不一致".tr; + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + if (model.register_code == null || model.register_code!.isEmpty) { + message = "请输入验证码".tr; + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + if (model.register_agree == null || model.register_agree != true) { + message = "需要同意协议".tr; + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + // message = await repository.createUser( + // model.register_pd!, model.register_phone!, model.register_code!); + // if (message.isNotEmpty) { + // showToast(message); + // return message; + // } + + return ""; + } + + Future getCode(BuildContext context) async { + String message = ""; + if (model.register_phone == null || model.register_phone!.isEmpty) { + message = "请输入手机号".tr; + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + if (!MyUtils.isValidPhoneNumber(model.register_phone!)) { + message = '请输入正确的手机号'.tr; + TopSlideNotification.show(context, + text: message, textColor: stringToColor("#FF7159")); + return message; + } + return ''; + } +} diff --git a/lib/pages/mh_page/user/controller/mht_register_controller.g.dart b/lib/pages/mh_page/user/controller/mht_register_controller.g.dart new file mode 100644 index 0000000..dca2e2b --- /dev/null +++ b/lib/pages/mh_page/user/controller/mht_register_controller.g.dart @@ -0,0 +1,28 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'mht_register_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +RegisterModel _$RegisterModelFromJson(Map json) => + RegisterModel() + ..register_phone = json['register_phone'] as String? + ..register_pd = json['register_pd'] as String? + ..register_confirm_pd = json['register_confirm_pd'] as String? + ..register_code = json['register_code'] as String? + ..register_agree = json['register_agree'] as bool? + ..pdshow = json['pdshow'] as bool? + ..cpdshow = json['cpdshow'] as bool?; + +Map _$RegisterModelToJson(RegisterModel instance) => + { + 'register_phone': instance.register_phone, + 'register_pd': instance.register_pd, + 'register_confirm_pd': instance.register_confirm_pd, + 'register_code': instance.register_code, + 'register_agree': instance.register_agree, + 'pdshow': instance.pdshow, + 'cpdshow': instance.cpdshow, + }; diff --git a/lib/pages/mh_page/find_password_page.dart b/lib/pages/mh_page/user/page/find_password_page.dart similarity index 97% rename from lib/pages/mh_page/find_password_page.dart rename to lib/pages/mh_page/user/page/find_password_page.dart index a882395..bcfd35b 100644 --- a/lib/pages/mh_page/find_password_page.dart +++ b/lib/pages/mh_page/user/page/find_password_page.dart @@ -58,7 +58,7 @@ class FindPasswordPage extends GetView { children: [ // 中间居中的标题 Text( - '找回密码', + '找回密码'.tr, textAlign: TextAlign.center, style: TextStyle( color: Colors.white, @@ -84,9 +84,6 @@ class FindPasswordPage extends GetView { child: Column( mainAxisSize: MainAxisSize.max, children: [ - // TitleComponentWidget( - // titleName: '找回密码', - // ), Expanded( child: Padding( padding: EdgeInsetsDirectional.fromSTEB( @@ -134,17 +131,17 @@ class FindPasswordPage extends GetView { .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), - hintText: '请输入手机号', + hintText: '请输入手机号'.tr, hintStyle: FlutterFlowTheme.of( context) .labelMedium .override( fontFamily: 'Readex Pro', color: Color(0xFF929699), - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), enabledBorder: InputBorder.none, @@ -155,7 +152,7 @@ class FindPasswordPage extends GetView { contentPadding: EdgeInsetsDirectional .fromSTEB(20.rpx, 0, 0, - 10.rpx), + 0.rpx), ), style: FlutterFlowTheme.of(context) @@ -163,7 +160,7 @@ class FindPasswordPage extends GetView { .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), ), @@ -216,7 +213,7 @@ class FindPasswordPage extends GetView { letterSpacing: 0, ), - hintText: '请输验证码', + hintText: '请输验证码'.tr, hintStyle: FlutterFlowTheme.of( context) @@ -227,7 +224,7 @@ class FindPasswordPage extends GetView { color: Color( 0xFF929699), fontSize: - 20.rpx, + 26.rpx, letterSpacing: 0, ), @@ -242,7 +239,7 @@ class FindPasswordPage extends GetView { contentPadding: EdgeInsetsDirectional .fromSTEB(20.rpx, - 0, 0, 10.rpx), + 0, 0, 0.rpx), ), style: FlutterFlowTheme.of( context) @@ -250,7 +247,7 @@ class FindPasswordPage extends GetView { .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), ), @@ -259,18 +256,19 @@ class FindPasswordPage extends GetView { ), Align( alignment: AlignmentDirectional( - 0.2, 0.3), + 0.4, 0.1), child: Container( - width: 3, - height: 30, + width: 1.rpx, + height: 38.rpx, decoration: BoxDecoration( - color: Color(0xFFCCCCCC), + color: + stringToColor("#929699"), ), ), ), Align( alignment: - AlignmentDirectional(0.9, 0), + AlignmentDirectional(1.2, 0), child: Container( width: bodysize!.maxWidth * 0.157, @@ -326,10 +324,9 @@ class FindPasswordPage extends GetView { .value == 0 ? '获取验证码' - : '${countdownController.countdown.value}秒', + : '${countdownController.countdown.value}' + + '秒'.tr, style: TextStyle( - fontFamily: - 'Readex Pro', color: Color(0xFF333333), fontSize: 20.rpx, @@ -381,10 +378,10 @@ class FindPasswordPage extends GetView { .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), - hintText: '请输入新密码', + hintText: '请输入新密码'.tr, hintStyle: FlutterFlowTheme .of(context) .labelMedium @@ -393,7 +390,7 @@ class FindPasswordPage extends GetView { 'Readex Pro', color: Color(0xFF929699), - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), enabledBorder: @@ -406,7 +403,7 @@ class FindPasswordPage extends GetView { contentPadding: EdgeInsetsDirectional .fromSTEB( - 10, 10, 0, 0), + 10, 26.rpx, 0, 0), suffixIcon: IconButton( icon: Icon( // 根据 pdshow 控制图标 @@ -431,7 +428,7 @@ class FindPasswordPage extends GetView { .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), ); @@ -477,7 +474,7 @@ class FindPasswordPage extends GetView { .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), hintText: '确认新密码', @@ -489,7 +486,7 @@ class FindPasswordPage extends GetView { 'Readex Pro', color: Color(0xFF929699), - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), enabledBorder: @@ -502,7 +499,7 @@ class FindPasswordPage extends GetView { contentPadding: EdgeInsetsDirectional .fromSTEB( - 10, 10, 0, 0), + 10, 26.rpx, 0, 0), suffixIcon: IconButton( icon: Icon( // 根据 pdshow 控制图标 @@ -527,7 +524,7 @@ class FindPasswordPage extends GetView { .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), ); @@ -608,7 +605,7 @@ class FindPasswordPage extends GetView { fontFamily: 'Readex Pro', color: Color(0XFF003058), letterSpacing: 0, - fontSize: 30.rpx, + fontSize: 26.rpx, ), ), ), diff --git a/lib/pages/mh_page/user/page/mht_login_page.dart b/lib/pages/mh_page/user/page/mht_login_page.dart new file mode 100644 index 0000000..75dbcec --- /dev/null +++ b/lib/pages/mh_page/user/page/mht_login_page.dart @@ -0,0 +1,2151 @@ +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/CustomCard.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 { + final scaffoldKey = GlobalKey(); + 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) { + showToast("网络未连接,请开启设备网络后重试"); + return; + } + String msg = await controller.loginByWechatCode(code); + if (msg.isEmpty) { + // TODO 操作全部跳转页面前成功以后移除监听,防止重复监听,其他方式登录成功也需要移出监听 + controller.fluwxCancelable?.cancel(); + // 登录成功移出网络检查监听 + Checknetwork.subscription?.cancel(); + Get.offAndToNamed("/mianPageBottomChange"); + } + // TODO 操作全部跳转页面前成功以后移除监听,防止重复监听,其他方式登录成功也需要移出监听 + // fluwxCancelable?.cancel(); + } else if (errCode == -4) { + showToast("用户拒绝授权"); + } else if (errCode == -2) { + showToast("用户取消授权"); + } + } + }); + } + + 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: Scaffold( + resizeToAvoidBottomInset: true, + // key: scaffoldKey, + 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: SingleChildScrollView( + controller: _scrollController, + child: Align( + alignment: AlignmentDirectional(0, 0), + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 1, + decoration: BoxDecoration( + color: Color(0xFF000750), + image: DecorationImage( + fit: BoxFit.contain, + image: Image.asset( + 'assets/img/background.png', + ).image, + ), + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 0.07, + decoration: BoxDecoration(), + ), + Expanded( + child: Align( + alignment: AlignmentDirectional(0, 0), + child: Container( + // width: bodysize!.maxWidth * 0.74, + height: bodysize!.maxHeight * 0.79, + decoration: BoxDecoration(), + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 1, + decoration: BoxDecoration(), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Obx(() { + return Visibility( + visible: controller.model.loginStyle == 1 + ? true + : false, + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 96.rpx, 54, 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: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + 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: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + 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, 54, 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: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + 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: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + 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: + FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + ), + hintText: '请输入账号', + hintStyle: FlutterFlowTheme + .of(context) + .labelMedium + .override( + 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: + FlutterFlowTheme.of(context) + .bodyMedium + .override( + 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: + FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize + .normal_text_size, + letterSpacing: + 0, + ), + hintText: '请输入密码', + hintStyle: + FlutterFlowTheme.of( + context) + .labelMedium + .override( + 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: FlutterFlowTheme + .of(context) + .bodyMedium + .override( + 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) { + showToast( + "网络未连接,请开启设备网络后重试"); + 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, + ), + ), + ); + }), + ), + ), + ), + ); + }) + ], + ), + ), + ), + ); + }), + 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: + FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + ), + hintText: '请输入手机号'.tr, + hintStyle: FlutterFlowTheme + .of(context) + .labelMedium + .override( + 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: + FlutterFlowTheme.of(context) + .bodyMedium + .override( + 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: + FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize + .normal_text_size, + letterSpacing: + 0, + ), + hintText: '请输入验证码', + hintStyle: + FlutterFlowTheme.of( + context) + .labelMedium + .override( + 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: FlutterFlowTheme + .of(context) + .bodyMedium + .override( + 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) { + showToast( + "网络未连接,请开启设备网络后重试"); + 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, 17, 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) { + showToast("网络未连接,请开启设备网络后重试"); + 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; + + Get.offAndToNamed( + "/mianPageBottomChange"); + } else { + showToast(msg); + } + }, + 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, 19, 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: FlutterFlowTheme + .of(context) + .secondaryText, + ), + 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: FlutterFlowTheme + .of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: Colors + .white, + fontSize: 12, + letterSpacing: + 0, + ), + ), + ), + Align( + alignment: + AlignmentDirectional( + 0, 0), + child: InkWell( + onTap: () { + // showCustomConfirmOfWebViewDialog( + // context, + // "用户协议", + // "/#/pages/agreement/agreement?type=2&hideHead=true", + // btnName: + // "同意并继续"); + }, + child: Text( + '《用户协议》'.tr, + style: FlutterFlowTheme + .of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: stringToColor( + "FF9F66"), + fontSize: + 12, + letterSpacing: + 0, + ), + ), + ), + ), + Align( + alignment: + AlignmentDirectional( + 0, 0), + child: Text( + '与'.tr, + style: FlutterFlowTheme + .of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: Colors + .white, + fontSize: 12, + letterSpacing: + 0, + ), + ), + ), + Align( + alignment: + AlignmentDirectional( + 0, 0), + child: InkWell( + onTap: () { + // showCustomConfirmOfWebViewDialog( + // context, + // "隐私协议", + // "/#/pages/agreement/agreement?type=1&hideHead=true", + // btnName: + // "同意并继续"); + }, + child: Text( + '《隐私协议》'.tr, + style: FlutterFlowTheme + .of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: stringToColor( + "FF9F66"), + fontSize: + 12, + letterSpacing: + 0, + ), + ), + ), + ), + ], + ), + ), + ), + ), + ), + ], + ), + ), + ), + ), + Obx(() { + return Visibility( + // maintainState: true, + // maintainAnimation: true, + // maintainSize: true, + 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: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: stringToColor( + "#FFFFFF"), + fontSize: + 23.rpx, + letterSpacing: + 0, + ), + ), + ), + ], + ), + ), + ), + ), + ), + ], + ), + ), + ), + ), + ); + }), + Obx(() { + return Visibility( + // maintainState: true, + // maintainAnimation: true, + // maintainSize: true, + 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( + // maintainState: true, + // maintainAnimation: true, + // maintainSize: true, + 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( + // maintainState: true, + // maintainAnimation: true, + // maintainSize: true, + 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.06, + height: bodysize!.maxHeight * 0.03, + // decoration: + // BoxDecoration(color: Colors.pink), + ), + ), + ); + }), + Obx(() { + return Visibility( + // maintainState: true, + // maintainAnimation: true, + // maintainSize: true, + visible: controller.model.loginStyle == 1, + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 96.rpx, 0, 131.rpx, 0), + child: Container( + width: bodysize!.maxWidth, + // height: bodysize!.maxHeight * 0.06, + height: bodysize!.maxHeight * 0.03, + // decoration: + // BoxDecoration(color: Colors.pink), + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 0.06, + decoration: BoxDecoration(), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Flexible( + child: InkWell( + onTap: () async {}, + child: Container( + width: MediaQuery.sizeOf( + context) + .width * + 0.253, + height: MediaQuery.sizeOf( + context) + .height * + 0.06, + constraints: + BoxConstraints( + minWidth: 190, + ), + decoration: + BoxDecoration(), + child: Row( + mainAxisSize: + MainAxisSize.max, + children: [ + 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 + .save_password ?? + false, + onChanged: + (newValue) async { + registerController + .model + .save_password = newValue; + + controller + .updateAll(); + registerController + .updateAll(); + // 获取设备信息,需要用户点击确认隐私协议与用户协议选择框时才能获取 + // if (newValue == + // true) { + // Deviceconfig + // .initPlatformState(); + // } + }, + side: + BorderSide( + width: + 1.5, + color: FlutterFlowTheme.of(context) + .secondaryText, + ), + activeColor: + stringToColor( + "#84F5FF"), + checkColor: + stringToColor( + "#011D33"), + ), + )), + ), + ), + Text( + "记住密码".tr, + style: TextStyle( + fontSize: + AppConstants() + .middler_text_fontSize, + color: stringToColor( + "#FFFFFF")), + ), + ], + ), + ), + ), + ), + Flexible( + child: Container( + width: MediaQuery.sizeOf( + context) + .width * + 0.201, + height: MediaQuery.sizeOf( + context) + .height * + 0.06, + constraints: BoxConstraints( + minWidth: 230, + ), + decoration: BoxDecoration(), + child: Row( + mainAxisSize: + MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.end, + children: [ + Flexible( + child: Container( + width: MediaQuery + .sizeOf( + context) + .width * + 0.124, + height: MediaQuery + .sizeOf( + context) + .height * + 1, + constraints: + BoxConstraints( + minHeight: 23, + ), + decoration: + BoxDecoration(), + child: Align( + alignment: + AlignmentDirectional( + 0, 0), + child: InkWell( + onTap: () { + Get.toNamed( + "/findPasswordPage"); + }, + child: Text( + '找回密码'.tr, + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: stringToColor( + "#84F5FF"), + fontSize: + AppFontsize.small_text_size, + letterSpacing: + 0, + ), + ), + ), + ), + ), + ), + SizedBox( + width: 29, + ), + Flexible( + child: Container( + width: MediaQuery + .sizeOf( + context) + .width * + 0.061, + height: MediaQuery + .sizeOf( + context) + .height * + 1, + constraints: + BoxConstraints( + minWidth: 30, + minHeight: 23, + ), + decoration: + BoxDecoration(), + child: Container( + width: MediaQuery + .sizeOf( + context) + .width * + 0.061, + height: 100, + constraints: + BoxConstraints( + minWidth: 46, + minHeight: 23, + ), + decoration: + BoxDecoration(), + child: Align( + alignment: + AlignmentDirectional( + 0, 0), + child: + InkWell( + onTap: () { + Get.toNamed( + "/registerPage"); + }, + child: Text( + '注册'.tr, + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: + stringToColor("#84F5FF"), + fontSize: + AppFontsize.small_text_size, + letterSpacing: + 0, + ), + ), + )), + ), + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ), + ); + }), + Obx(() { + return Visibility( + // maintainState: true, + // maintainAnimation: true, + // maintainSize: true, + 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.06, + height: bodysize!.maxHeight * 0.03, + // decoration: + // BoxDecoration(color: Colors.pink), + ), + ), + ); + }), + 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, + ), + Container( + width: 90.rpx, + height: 90.rpx, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + 'assets/images/wechat.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + ), + ], + ), + ), + ), + ), + ), + 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: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: AppFontsize.explain_size, + letterSpacing: 0, + ), + ), + ), + Align( + alignment: AlignmentDirectional(0, 0), + child: Text( + 'Copyright© 2019-2029', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: AppFontsize.explain_size, + letterSpacing: 0, + ), + ), + ), + // Align( + // alignment: AlignmentDirectional(0, 0), + // child: Text( + // ' 网上国网 版权所有', + // style: FlutterFlowTheme.of(context) + // .bodyMedium + // .override( + // fontFamily: 'Readex Pro', + // color: Color(0xFF9EA4B7), + // fontSize: AppFontsize.explain_size, + // letterSpacing: 0, + // ), + // ), + // ), + ], + ), + ), + ), + ), + ], + ), + ), + ), + ), + ), + ), + ); + }); + } + + Future _handleBackPressed(BuildContext context) async { + final currentTime = DateTime.now(); + // 如果上次点击返回键时间为空,或者间隔超过 1 秒 + if (_lastBackPressedTime == null || + currentTime.difference(_lastBackPressedTime!) > Duration(seconds: 2)) { + _lastBackPressedTime = currentTime; + showToast("再按一次退出程序", color: color_warning, closeTime: 2); + return false; // 阻止退出程序 + } else { + return true; // 允许退出程序 + } + } +} diff --git a/lib/pages/mh_page/register_page.dart b/lib/pages/mh_page/user/page/register_page.dart similarity index 96% rename from lib/pages/mh_page/register_page.dart rename to lib/pages/mh_page/user/page/register_page.dart index fd537a9..5e753d0 100644 --- a/lib/pages/mh_page/register_page.dart +++ b/lib/pages/mh_page/user/page/register_page.dart @@ -12,36 +12,11 @@ class RegisterPage extends GetView { BoxConstraints? bodysize; final ScrollController _scrollController = ScrollController(); - // final FocusNode _focusNode1 = FocusNode(); - // final FocusNode _focusNode2 = FocusNode(); - // final FocusNode _focusNode3 = FocusNode(); - // final FocusNode _focusNode4 = FocusNode(); RegisterPage() { controller.model.pdshow = true; controller.model.cpdshow = true; Get.put(RegisterController()); - - // _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); - // } - // }); } @override @@ -146,17 +121,17 @@ class RegisterPage extends GetView { .labelMedium .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), - hintText: '请输入手机号', + hintText: '请输入手机号'.tr, hintStyle: FlutterFlowTheme.of(context) .labelMedium .override( fontFamily: 'Readex Pro', color: Color(0xFF929699), - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), enabledBorder: InputBorder.none, @@ -172,7 +147,7 @@ class RegisterPage extends GetView { .bodyMedium .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), ), @@ -214,17 +189,17 @@ class RegisterPage extends GetView { .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), - hintText: '请输入密码', + hintText: '请输入密码'.tr, hintStyle: FlutterFlowTheme.of( context) .labelMedium .override( fontFamily: 'Readex Pro', color: Color(0xFF929699), - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), enabledBorder: InputBorder.none, @@ -234,8 +209,8 @@ class RegisterPage extends GetView { InputBorder.none, contentPadding: EdgeInsetsDirectional - .fromSTEB(20.rpx, - 20.rpx, 0, 0), + .fromSTEB( + 10, 26.rpx, 0, 0), suffixIcon: IconButton( icon: Icon( // 根据 pdshow 控制图标 @@ -260,7 +235,7 @@ class RegisterPage extends GetView { .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), ); @@ -303,17 +278,17 @@ class RegisterPage extends GetView { .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), - hintText: '确认密码', + hintText: '请输入确认密码'.tr, hintStyle: FlutterFlowTheme.of( context) .labelMedium .override( fontFamily: 'Readex Pro', color: Color(0xFF929699), - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), enabledBorder: InputBorder.none, @@ -323,8 +298,8 @@ class RegisterPage extends GetView { InputBorder.none, contentPadding: EdgeInsetsDirectional - .fromSTEB(20.rpx, - 20.rpx, 0, 0), + .fromSTEB( + 10, 26.rpx, 0, 0), suffixIcon: IconButton( icon: Icon( // 根据 pdshow 控制图标 @@ -349,7 +324,7 @@ class RegisterPage extends GetView { .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), ); @@ -395,10 +370,10 @@ class RegisterPage extends GetView { .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), - hintText: '请输验证码', + hintText: '请输入验证码', hintStyle: FlutterFlowTheme .of(context) .labelMedium @@ -407,7 +382,7 @@ class RegisterPage extends GetView { 'Readex Pro', color: Color(0xFF929699), - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), enabledBorder: @@ -420,7 +395,7 @@ class RegisterPage extends GetView { contentPadding: EdgeInsetsDirectional .fromSTEB(20.rpx, 0, - 0, 10.rpx), + 0, 0.rpx), ), style: FlutterFlowTheme.of(context) @@ -428,7 +403,7 @@ class RegisterPage extends GetView { .override( fontFamily: 'Readex Pro', - fontSize: 20.rpx, + fontSize: 26.rpx, letterSpacing: 0, ), ), @@ -437,18 +412,18 @@ class RegisterPage extends GetView { ), Align( alignment: - AlignmentDirectional(0.2, 0.1), + AlignmentDirectional(0.4, 0.1), child: Container( - width: 3, - height: 30, + width: 1.rpx, + height: 38.rpx, decoration: BoxDecoration( - color: Color(0xFFCCCCCC), + color: stringToColor("#929699"), ), ), ), Align( alignment: - AlignmentDirectional(0.9, 0), + AlignmentDirectional(1.2, 0), child: Container( width: bodysize!.maxWidth * 0.157, height: bodysize!.maxHeight * 0.014, @@ -500,8 +475,9 @@ class RegisterPage extends GetView { .countdown .value == 0 - ? '获取验证码' - : '${countdownController.countdown.value}秒', + ? '获取验证码'.tr + : '${countdownController.countdown.value}' + + '秒'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: Color(0xFF333333), @@ -652,7 +628,7 @@ class RegisterPage extends GetView { AlignmentDirectional( 0, 0), child: Text( - '我已阅读并同意', + '我已阅读并同意'.tr, style: FlutterFlowTheme .of(context) .bodyMedium @@ -679,15 +655,15 @@ class RegisterPage extends GetView { "/#/pages/agreement/agreement?type=2&hideHead=true"); }, child: Text( - '《用户协议》', + '《用户协议》'.tr, style: FlutterFlowTheme .of(context) .bodyMedium .override( fontFamily: 'Readex Pro', - color: Color( - 0xFF1890FF), + color: stringToColor( + "FF9F66"), fontSize: 12, letterSpacing: 0, @@ -700,7 +676,7 @@ class RegisterPage extends GetView { AlignmentDirectional( 0, 0), child: Text( - '与', + '与'.tr, style: FlutterFlowTheme .of(context) .bodyMedium @@ -727,15 +703,15 @@ class RegisterPage extends GetView { "/#/pages/agreement/agreement?type=1&hideHead=true"); }, child: Text( - '《隐私协议》', + '《隐私协议》'.tr, style: FlutterFlowTheme .of(context) .bodyMedium .override( fontFamily: 'Readex Pro', - color: Color( - 0xFF1890FF), + color: stringToColor( + "FF9F66"), fontSize: 12, letterSpacing: 0, diff --git a/lib/routers/mh_routers.dart b/lib/routers/mh_routers.dart index f192fc2..70f7f3d 100644 --- a/lib/routers/mh_routers.dart +++ b/lib/routers/mh_routers.dart @@ -1,10 +1,8 @@ import 'package:ef/ef.dart'; import 'package:flutter/cupertino.dart'; -import 'package:path/path.dart'; import 'package:vbvs_app/controller/mh_controller/muser_info_controller.dart'; - import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; - +import 'package:vbvs_app/pages/main_bottom/component/main_page_b_bottom_change.dart'; import 'package:vbvs_app/pages/mh_page/HomeDeviceType.dart'; import 'package:vbvs_app/pages/mh_page/LanguagePage.dart'; import 'package:vbvs_app/pages/mh_page/address_list_page.dart'; @@ -15,16 +13,17 @@ import 'package:vbvs_app/pages/mh_page/device_people_info.dart'; import 'package:vbvs_app/pages/mh_page/edit_bed.dart'; import 'package:vbvs_app/pages/mh_page/edit_userinfo_page.dart'; import 'package:vbvs_app/pages/mh_page/experience_store_page.dart'; -import 'package:vbvs_app/pages/mh_page/find_password_page.dart'; import 'package:vbvs_app/pages/mh_page/issue_list_page.dart'; import 'package:vbvs_app/pages/mh_page/my_experience_page.dart'; import 'package:vbvs_app/pages/mh_page/people_info.dart'; -import 'package:vbvs_app/pages/mh_page/register_page.dart'; +import 'package:vbvs_app/pages/mh_page/user/page/register_page.dart'; import 'package:vbvs_app/pages/mh_page/repair_history_page.dart'; import 'package:vbvs_app/pages/mh_page/repair_list.dart'; import 'package:vbvs_app/pages/mh_page/room_picker.dart'; import 'package:vbvs_app/pages/mh_page/sleep_habit.dart'; import 'package:vbvs_app/pages/mh_page/smys.dart'; +import 'package:vbvs_app/pages/mh_page/user/page/find_password_page.dart'; +import 'package:vbvs_app/pages/mh_page/user/page/mht_login_page.dart'; import '../pages/mh_page/bluetooth.dart'; import '../pages/mh_page/edit_address_page.dart'; @@ -34,6 +33,7 @@ import '../pages/mh_page/new_settingPage.dart'; ThemeController themeController = Get.find(); var mhroutes = { + "/mianPageBottomChange": (contxt) => MainPageBBottomChange(), "/homeDeviceType": (contxt) => HomeDeviceType(), "/editUserInfoPage": (contxt) => EditUserInfoPage(), "/peopleInfoPage": (contxt) => PeopleInfoPage(), @@ -58,7 +58,8 @@ var mhroutes = { BookSuccessPage(data: arguments["data"]), "/myExperiencePage": (context) => MyExperiencePage(), "/registerPage": (context) => RegisterPage(), - "/findPasswordPage": (context) => FindPasswordPage(), + "/findPasswordPage": (context) => FindPasswordPage(), + "/loginPage": (context) => MHTLoginPage(), }; var mhonGenerateRoute = (RouteSettings settings) { final String? name = settings.name; // 获取路由名称,如 /news 或 /search