342 lines
11 KiB
Dart
342 lines
11 KiB
Dart
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/widgets.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:starwork_flutter/common/constant/login_type.dart';
|
|
|
|
import 'package:starwork_flutter/routes/app_routes.dart';
|
|
|
|
import 'login_controller.dart';
|
|
|
|
class LoginView extends GetView<LoginController> {
|
|
const LoginView({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return GestureDetector(
|
|
onTap: () {
|
|
// 收起键盘
|
|
FocusScope.of(context).unfocus();
|
|
},
|
|
child: Scaffold(
|
|
resizeToAvoidBottomInset: true,
|
|
body: SafeArea(
|
|
child: SingleChildScrollView(
|
|
child: _buildBody(),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildBody() {
|
|
return SizedBox(
|
|
height: 0.9.sh,
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
_buildTop(),
|
|
_buildPrivacyPolicy(),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
_buildTop() {
|
|
return Container(
|
|
margin: EdgeInsets.symmetric(horizontal: 40.w, vertical: 40.h),
|
|
child: Column(
|
|
children: [
|
|
_buildTitle(),
|
|
SizedBox(height: 20.h),
|
|
_buildPhoneInputAndLoginButton(),
|
|
SizedBox(height: 20.h),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildTitle() {
|
|
return SizedBox(
|
|
width: double.infinity,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
'欢迎使用斯凯签勤'.tr,
|
|
style: TextStyle(
|
|
fontSize: 22.sp,
|
|
fontWeight: FontWeight.w500,
|
|
),
|
|
),
|
|
Text(
|
|
'未注册手机号验证后将自动创建账号'.tr,
|
|
style: TextStyle(
|
|
fontSize: 14.sp,
|
|
fontWeight: FontWeight.w500,
|
|
color: Colors.grey,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
_buildPhoneInputAndLoginButton() {
|
|
return Obx(
|
|
() => Column(
|
|
children: [
|
|
TextField(
|
|
controller: controller.phoneController,
|
|
keyboardType: TextInputType.phone,
|
|
textInputAction: TextInputAction.done,
|
|
maxLength: controller.phoneNumberSize,
|
|
decoration: InputDecoration(
|
|
counterText: '',
|
|
hintText: '请输入手机号码'.tr,
|
|
border: const UnderlineInputBorder(),
|
|
suffixIcon: controller.phoneController.text.isNotEmpty
|
|
? IconButton(
|
|
icon: const Icon(Icons.clear, color: Colors.grey),
|
|
onPressed: () {
|
|
controller.phoneController.clear(); // 清空输入
|
|
},
|
|
)
|
|
: null,
|
|
// 如果没有内容,就不显示清除按钮,
|
|
// 获取焦点时的边框
|
|
focusedBorder: UnderlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: controller.isFormValid.value
|
|
? Colors.blue
|
|
: Colors.blue.withOpacity(0.5),
|
|
), //
|
|
),
|
|
),
|
|
),
|
|
Visibility(
|
|
visible: controller.loginType.value == LoginType.phonePassword,
|
|
child: SizedBox(
|
|
height: 18.h,
|
|
),
|
|
),
|
|
Visibility(
|
|
visible: controller.loginType.value == LoginType.phonePassword,
|
|
child: TextField(
|
|
controller: controller.passwordController,
|
|
keyboardType: TextInputType.visiblePassword,
|
|
textInputAction: TextInputAction.done,
|
|
obscureText: controller.isPasswordVisible.value,
|
|
decoration: InputDecoration(
|
|
counterText: '',
|
|
hintText: '请输入密码'.tr,
|
|
border: const UnderlineInputBorder(),
|
|
suffixIcon: IconButton(
|
|
icon: Icon(
|
|
controller.isPasswordVisible.value
|
|
? Icons.visibility
|
|
: Icons.visibility_off,
|
|
),
|
|
onPressed: () => controller.isPasswordVisible.value =
|
|
!controller.isPasswordVisible.value,
|
|
),
|
|
focusedBorder: UnderlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: controller.isFormValid.value
|
|
? Colors.blue
|
|
: Colors.blue.withOpacity(0.5),
|
|
), //
|
|
),
|
|
),
|
|
),
|
|
),
|
|
SizedBox(
|
|
height: 48.h,
|
|
),
|
|
ElevatedButton(
|
|
onPressed: controller.isFormValid.value
|
|
? controller.requestPhoneCode
|
|
: null,
|
|
style: ButtonStyle(
|
|
minimumSize:
|
|
MaterialStateProperty.all(Size(double.infinity, 44.h)),
|
|
shape: MaterialStateProperty.all(
|
|
RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(8.r),
|
|
),
|
|
),
|
|
backgroundColor: MaterialStateProperty.all(
|
|
controller.isFormValid.value
|
|
? Colors.blue
|
|
: Colors.blue.withOpacity(0.5),
|
|
),
|
|
),
|
|
child: Text(
|
|
controller.loginType.value == LoginType.phoneCodeLogin
|
|
? '获取验证码'.tr
|
|
: '登录'.tr,
|
|
style: TextStyle(
|
|
fontSize: 16.sp,
|
|
fontWeight: FontWeight.w500,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 20.h),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Visibility(
|
|
visible: LoginType.phoneCodeLogin == controller.loginType.value,
|
|
child: TextButton(
|
|
onPressed: () {
|
|
controller.loginType.value = LoginType.phonePassword;
|
|
},
|
|
child: Text(
|
|
'密码登录'.tr,
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(
|
|
fontSize: 16.sp,
|
|
fontWeight: FontWeight.w500,
|
|
color: Colors.grey,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
Visibility(
|
|
visible: LoginType.phonePassword == controller.loginType.value,
|
|
child: TextButton(
|
|
onPressed: () {
|
|
controller.loginType.value = LoginType.phoneCodeLogin;
|
|
},
|
|
child: Text(
|
|
'验证码登录'.tr,
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(
|
|
fontSize: 16.sp,
|
|
fontWeight: FontWeight.w500,
|
|
color: Colors.grey,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
Visibility(
|
|
visible: LoginType.phonePassword == controller.loginType.value,
|
|
child: Text(
|
|
'|',
|
|
style: TextStyle(
|
|
fontSize: 16.sp,
|
|
fontWeight: FontWeight.w500,
|
|
color: Colors.grey,
|
|
),
|
|
),
|
|
),
|
|
Visibility(
|
|
visible: LoginType.phonePassword == controller.loginType.value,
|
|
child: TextButton(
|
|
style: ButtonStyle(
|
|
overlayColor:
|
|
MaterialStateProperty.all(Colors.transparent), // 墨水覆盖
|
|
side: MaterialStateProperty.all(null), // 取消边框
|
|
),
|
|
onPressed: () {
|
|
Get.toNamed(
|
|
AppRoutes.forgotPassword,
|
|
parameters: {
|
|
'phone': controller.phoneController.text,
|
|
},
|
|
);
|
|
},
|
|
child: Text(
|
|
'忘记密码'.tr,
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(
|
|
fontSize: 16.sp,
|
|
fontWeight: FontWeight.w500,
|
|
color: Colors.grey,
|
|
),
|
|
),
|
|
),
|
|
)
|
|
],
|
|
)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
_handleLoginButtonText() {
|
|
if (controller.loginType.value == LoginType.phoneCodeLogin) {
|
|
return;
|
|
} else if (controller.loginType.value == LoginType.phonePassword) {
|
|
return '验证码登录'.tr + ' | '.tr + '忘记密码'.tr;
|
|
}
|
|
}
|
|
|
|
_buildPrivacyPolicy() {
|
|
return GestureDetector(
|
|
onTap: () {
|
|
controller.isPrivacyAgreementValid.value =
|
|
controller.isPrivacyAgreementValid.value == 1 ? 0 : 1;
|
|
},
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
Obx(
|
|
() => Checkbox(
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(4.r),
|
|
),
|
|
activeColor: Colors.blue,
|
|
value: controller.isPrivacyAgreementValid.value == 1,
|
|
// 转换为 bool
|
|
onChanged: (bool? value) {
|
|
controller.isPrivacyAgreementValid.value =
|
|
value == true ? 1 : 0;
|
|
},
|
|
),
|
|
),
|
|
RichText(
|
|
textAlign: TextAlign.center,
|
|
text: TextSpan(
|
|
children: [
|
|
TextSpan(
|
|
text: '我已阅读并同意'.tr,
|
|
style: TextStyle(
|
|
fontSize: 13.sp,
|
|
color: Colors.grey,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '《用户协议》'.tr,
|
|
style: TextStyle(
|
|
fontSize: 13.sp,
|
|
color: Colors.blue,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '和'.tr,
|
|
style: TextStyle(
|
|
fontSize: 13.sp,
|
|
color: Colors.grey,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '《隐私政策》'.tr,
|
|
style: TextStyle(
|
|
fontSize: 13.sp,
|
|
color: Colors.blue,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|