import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import 'package:gap/gap.dart'; import 'package:get/get.dart'; import 'package:demo001/tools/color_utils.dart'; import 'package:demo001/tools/textStyle.dart'; import 'package:demo001/tools/widgets.dart'; import 'login_logic.dart'; import 'login_state.dart'; /// @description: /// @author /// @date: 2025-01-11 17:25:10 class LoginScene extends StatelessWidget { final LoginLogic logic = Get.put(LoginLogic()); final LoginState state = Get.find().state; LoginScene({Key? key}) : super(key: key); double width = 0; double height = 0; @override Widget build(BuildContext context) { width = MediaQuery.of(context).size.width; height = MediaQuery.of(context).size.height; return Scaffold( backgroundColor: Color.fromARGB(255, 18, 19, 24), body: KeyboardDismissOnTap( child: Container( height: height, padding: EdgeInsets.all(8), child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.max, children: [ Gap(45), topWidget, Gap(50), logo, Gap(15), emailInput, Gap(15), pinInput, Gap(30), loginBtn, Gap(80), otherLogin, Gap(180), protocolWidget, Gap(15), ], ), ), ), ), ); } Widget get topWidget => Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '联系客服', style: Style.clean, ), Text( '登录/注册账号', style: Style.navTitle, ), Text( '联系客服', style: Style.normalWhiteGrey, ) ], ); Widget get logo => Container( child: Icon( Icons.logo_dev, size: 100, color: white, ), ); Widget get phoneInput => SizedBox( width: width * 0.9, child: Container( height: 45, decoration: BoxDecoration( color: inputBgColor, borderRadius: BorderRadius.circular(8)), child: Obx(() => TextField( controller: state.phoneContr, focusNode: state.phoneNode, textInputAction: TextInputAction.next, style: Style.normalBold, keyboardType: TextInputType.phone, inputFormatters: state.countryCode.value == '86' ? [ FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), LengthLimitingTextInputFormatter(11), ] : [ FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), ], decoration: InputDecoration( border: InputBorder.none, hintText: '请输入手机号', contentPadding: EdgeInsets.symmetric(horizontal: 8), ), onSubmitted: (value) { if (value.length != 11) { EasyLoading.showError('手机号码错误!'); } else { state.emailNode.nextFocus(); } }, )), ), ); Widget get emailInput => SizedBox( width: width * 0.9, child: Container( height: 45, decoration: BoxDecoration( color: inputBgColor, borderRadius: BorderRadius.circular(8)), child: TextField( controller: state.emailContr, focusNode: state.emailNode, style: Style.normalBold, textInputAction: TextInputAction.next, keyboardType: TextInputType.emailAddress, decoration: InputDecoration( border: InputBorder.none, hintText: '请输入邮箱', contentPadding: EdgeInsets.symmetric(horizontal: 8), ), onSubmitted: (value) { final emailRegex = RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'); if (!emailRegex.hasMatch(state.emailContr.text)) { EasyLoading.showError('邮箱输入错误,请重新输入!'); } else { state.pinNode.nextFocus(); } }, ), ), ); Widget get pinInput => SizedBox( width: width * 0.9, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( height: 45, width: width * 0.5, decoration: BoxDecoration( color: inputBgColor, borderRadius: BorderRadius.circular(8)), child: Obx(() => TextField( controller: state.pinContr, focusNode: state.pinNode, style: Style.normalBold, textInputAction: TextInputAction.send, keyboardType: TextInputType.phone, inputFormatters: state.countryCode.value == '86' ? [ FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), LengthLimitingTextInputFormatter(4), ] : [ FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), ], decoration: InputDecoration( border: InputBorder.none, hintText: '请输入验证码', contentPadding: EdgeInsets.symmetric(horizontal: 8), ), onSubmitted: (value) { if (value.length != 4) { EasyLoading.showError("验证码错误"); } else { logic.login(); } }, )), ), GestureDetector( onTap: () { if (!isEmail(state.emailContr.text)) { EasyLoading.showError('邮箱输入错误,请重新输入!'); } else { logic.getEmailPin(); } }, child: Container( height: 45, width: width * 0.35, alignment: Alignment.center, decoration: BoxDecoration( color: lightBlue, borderRadius: BorderRadius.circular(8)), child: Obx(() => Text( state.countDown.value == 60 ? '获取验证码' : '${state.countDown.value}S后重新获取', style: Style.normalWhiteGrey, )), ), ) ], ), ); Widget get loginBtn => GestureDetector( onTap: logic.login, child: Container( height: 45, width: width * 0.9, alignment: Alignment.center, decoration: BoxDecoration( color: blue, borderRadius: BorderRadius.circular(8)), child: Obx(() => Text( state.isWechatLogin.value ? '确定绑定' : '登录', style: Style.normalBold, )), ), ); Widget get otherLogin => Container( child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( color: white.withAlpha(30), height: 1, width: width * 0.25, ), Text( ' 其他登录方式 ', style: Style.normalSmallWhiteGrey, ), Container( color: white.withAlpha(30), height: 1, width: width * 0.25, ), ], ), Gap(15), GestureDetector( onTap: () { state.isWechatLogin.value = !state.isWechatLogin.value; }, child: Icon( Icons.wechat, size: 60, color: green, ), ), ], ), ); Widget get protocolWidget => Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ GestureDetector( onTap: () { state.protocolCheck.value = !state.protocolCheck.value; }, child: Row( children: [ Obx(() => Container( child: Icon( state.protocolCheck.value ? Icons.check_circle : Icons.radio_button_unchecked, color: state.protocolCheck.value ? blue : white, size: 16, ), )), Text( ' 我已阅读并同意', style: Style.normalSmall2, ), ], ), ), GestureDetector( onTap: () {}, child: Text( '《用户服务协议》', style: Style.normalBlueSmall2, ), ), Text( '和', style: Style.normalSmall2, ), GestureDetector( onTap: () {}, child: Text( '《用户服务协议》', style: Style.normalBlueSmall2, ), ) ], ); }