|
|
@ -4,7 +4,6 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; |
|
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; |
|
|
import '../controllers/login_controller.dart'; |
|
|
import '../controllers/login_controller.dart'; |
|
|
import '../../common/webview_page.dart'; |
|
|
import '../../common/webview_page.dart'; |
|
|
import 'package:get_storage/get_storage.dart'; |
|
|
|
|
|
|
|
|
|
|
|
class LoginView extends GetView<LoginController> { |
|
|
class LoginView extends GetView<LoginController> { |
|
|
const LoginView({Key? key}) : super(key: key); |
|
|
const LoginView({Key? key}) : super(key: key); |
|
|
@ -20,9 +19,7 @@ class LoginView extends GetView<LoginController> { |
|
|
child: Scaffold( |
|
|
child: Scaffold( |
|
|
backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], |
|
|
backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], |
|
|
body: SafeArea( |
|
|
body: SafeArea( |
|
|
child: Obx(() => controller.viewState == LoginViewState.welcome |
|
|
child: _buildWelcomeView(isDarkMode), |
|
|
? _buildWelcomeView(isDarkMode) |
|
|
|
|
|
: _buildVerificationView(context, isDarkMode)), |
|
|
|
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
); |
|
|
); |
|
|
@ -66,44 +63,6 @@ class LoginView extends GetView<LoginController> { |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 验证码页面 |
|
|
|
|
|
Widget _buildVerificationView(BuildContext context, bool isDarkMode) { |
|
|
|
|
|
return Padding( |
|
|
|
|
|
padding: EdgeInsets.all(24.w), |
|
|
|
|
|
child: SingleChildScrollView( |
|
|
|
|
|
physics: const BouncingScrollPhysics(), |
|
|
|
|
|
child: Column( |
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
|
|
|
|
children: [ |
|
|
|
|
|
// 返回按钮 |
|
|
|
|
|
_buildBackButton(isDarkMode), |
|
|
|
|
|
|
|
|
|
|
|
// 验证码标题 |
|
|
|
|
|
SizedBox(height: 24.h), |
|
|
|
|
|
_buildVerificationTitle(isDarkMode), |
|
|
|
|
|
|
|
|
|
|
|
// 验证码输入框 |
|
|
|
|
|
SizedBox(height: 32.h), |
|
|
|
|
|
_buildVerificationInputs(context, isDarkMode), |
|
|
|
|
|
|
|
|
|
|
|
// 重新发送验证码 |
|
|
|
|
|
SizedBox(height: 16.h), |
|
|
|
|
|
_buildResendButton(isDarkMode), |
|
|
|
|
|
|
|
|
|
|
|
// 登录按钮 |
|
|
|
|
|
SizedBox(height: 32.h), |
|
|
|
|
|
_buildLoginButton(isDarkMode), |
|
|
|
|
|
|
|
|
|
|
|
// 使用密码登录 |
|
|
|
|
|
SizedBox(height: 16.h), |
|
|
|
|
|
_buildUsePasswordButton(isDarkMode), |
|
|
|
|
|
SizedBox(height: 24.h), |
|
|
|
|
|
], |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 应用标志和标题 |
|
|
// 应用标志和标题 |
|
|
Widget _buildAppLogo(bool isDarkMode) { |
|
|
Widget _buildAppLogo(bool isDarkMode) { |
|
|
return Column( |
|
|
return Column( |
|
|
@ -684,185 +643,4 @@ class LoginView extends GetView<LoginController> { |
|
|
], |
|
|
], |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 返回按钮 |
|
|
|
|
|
Widget _buildBackButton(bool isDarkMode) { |
|
|
|
|
|
return Container( |
|
|
|
|
|
width: 40.w, |
|
|
|
|
|
height: 40.w, |
|
|
|
|
|
decoration: BoxDecoration( |
|
|
|
|
|
color: isDarkMode ? Colors.grey[800] : Colors.grey.withOpacity(0.1), |
|
|
|
|
|
borderRadius: BorderRadius.circular(20.r), |
|
|
|
|
|
), |
|
|
|
|
|
child: IconButton( |
|
|
|
|
|
icon: Icon( |
|
|
|
|
|
Icons.arrow_back, |
|
|
|
|
|
color: isDarkMode ? Colors.grey[400] : Colors.grey[600], |
|
|
|
|
|
size: 20.sp, |
|
|
|
|
|
), |
|
|
|
|
|
onPressed: () => controller.showWelcomeView(), |
|
|
|
|
|
), |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 验证码标题 |
|
|
|
|
|
Widget _buildVerificationTitle(bool isDarkMode) { |
|
|
|
|
|
return Column( |
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
|
|
|
|
children: [ |
|
|
|
|
|
Text( |
|
|
|
|
|
'enterVerificationCode'.tr, // 输入验证码 |
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
fontSize: 20.sp, |
|
|
|
|
|
fontWeight: FontWeight.w600, |
|
|
|
|
|
color: isDarkMode ? Colors.white : Colors.black, |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
|
|
|
SizedBox(height: 8.h), |
|
|
|
|
|
Obx(() => Text( |
|
|
|
|
|
'${'verificationCodeSentTo'.tr} ${controller.displayContact}', // 验证码已发送至 |
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
fontSize: 14.sp, |
|
|
|
|
|
color: isDarkMode ? Colors.grey[400] : Colors.grey[600], |
|
|
|
|
|
), |
|
|
|
|
|
)), |
|
|
|
|
|
], |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 验证码输入框 |
|
|
|
|
|
Widget _buildVerificationInputs(BuildContext context, bool isDarkMode) { |
|
|
|
|
|
return Row( |
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|
|
|
|
|
children: List.generate( |
|
|
|
|
|
4, (index) => _buildVerificationInput(index, context, isDarkMode)), |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 单个验证码输入框 |
|
|
|
|
|
Widget _buildVerificationInput( |
|
|
|
|
|
int index, BuildContext context, bool isDarkMode) { |
|
|
|
|
|
return Container( |
|
|
|
|
|
width: 60.w, |
|
|
|
|
|
height: 60.w, |
|
|
|
|
|
decoration: BoxDecoration( |
|
|
|
|
|
color: isDarkMode |
|
|
|
|
|
? Colors.grey[900]!.withOpacity(0.3) |
|
|
|
|
|
: Colors.grey.withOpacity(0.1), |
|
|
|
|
|
borderRadius: BorderRadius.circular(12.r), |
|
|
|
|
|
border: Border.all( |
|
|
|
|
|
color: isDarkMode ? Colors.grey[700]! : Colors.grey[300]!, |
|
|
|
|
|
width: 1, |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
|
|
|
child: Center( |
|
|
|
|
|
child: TextField( |
|
|
|
|
|
textAlign: TextAlign.center, |
|
|
|
|
|
keyboardType: TextInputType.number, |
|
|
|
|
|
maxLength: 1, |
|
|
|
|
|
onChanged: (value) { |
|
|
|
|
|
controller.updateVerificationCode(index, value); |
|
|
|
|
|
if (value.isNotEmpty && index < 3) { |
|
|
|
|
|
FocusScope.of(context).nextFocus(); |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
decoration: InputDecoration( |
|
|
|
|
|
counterText: '', |
|
|
|
|
|
border: InputBorder.none, |
|
|
|
|
|
fillColor: Colors.transparent, |
|
|
|
|
|
filled: true, |
|
|
|
|
|
), |
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
fontSize: 24.sp, |
|
|
|
|
|
fontWeight: FontWeight.w600, |
|
|
|
|
|
color: isDarkMode ? Colors.white : Colors.black, |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 重新发送验证码按钮 |
|
|
|
|
|
Widget _buildResendButton(bool isDarkMode) { |
|
|
|
|
|
return Center( |
|
|
|
|
|
child: Obx(() => TextButton.icon( |
|
|
|
|
|
onPressed: controller.countdownSeconds > 0 |
|
|
|
|
|
? null |
|
|
|
|
|
: controller.resendVerificationCode, |
|
|
|
|
|
icon: Icon( |
|
|
|
|
|
Icons.refresh, |
|
|
|
|
|
size: 14.sp, |
|
|
|
|
|
color: controller.countdownSeconds > 0 |
|
|
|
|
|
? (isDarkMode ? Colors.grey[600] : Colors.grey[500]) |
|
|
|
|
|
: const Color(0xFF3B82F6), |
|
|
|
|
|
), |
|
|
|
|
|
label: Text( |
|
|
|
|
|
controller.countdownSeconds > 0 |
|
|
|
|
|
? '${'resendVerificationCode'.tr} (${controller.countdownSeconds}s)' // 重新发送验证码 (倒计时) |
|
|
|
|
|
: 'resendVerificationCode'.tr, // 重新发送验证码 |
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
fontSize: 14.sp, |
|
|
|
|
|
color: controller.countdownSeconds > 0 |
|
|
|
|
|
? (isDarkMode ? Colors.grey[600] : Colors.grey[500]) |
|
|
|
|
|
: const Color(0xFF3B82F6), |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
|
|
|
)), |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 登录按钮 |
|
|
|
|
|
Widget _buildLoginButton(bool isDarkMode) { |
|
|
|
|
|
return SizedBox( |
|
|
|
|
|
width: double.infinity, |
|
|
|
|
|
child: Obx(() => ElevatedButton( |
|
|
|
|
|
onPressed: controller.isLoading ? null : () => controller.login(), |
|
|
|
|
|
style: ElevatedButton.styleFrom( |
|
|
|
|
|
backgroundColor: const Color(0xFF3B82F6), |
|
|
|
|
|
foregroundColor: Colors.white, |
|
|
|
|
|
padding: EdgeInsets.symmetric(vertical: 14.h), |
|
|
|
|
|
shape: RoundedRectangleBorder( |
|
|
|
|
|
borderRadius: BorderRadius.circular(16.r), |
|
|
|
|
|
), |
|
|
|
|
|
elevation: 0, |
|
|
|
|
|
disabledBackgroundColor: const Color(0xFF3B82F6).withOpacity(0.7), |
|
|
|
|
|
disabledForegroundColor: Colors.white, |
|
|
|
|
|
), |
|
|
|
|
|
child: controller.isLoading |
|
|
|
|
|
? SizedBox( |
|
|
|
|
|
height: 20.h, |
|
|
|
|
|
width: 20.h, |
|
|
|
|
|
child: CircularProgressIndicator( |
|
|
|
|
|
strokeWidth: 2.w, |
|
|
|
|
|
valueColor: |
|
|
|
|
|
const AlwaysStoppedAnimation<Color>(Colors.white), |
|
|
|
|
|
), |
|
|
|
|
|
) |
|
|
|
|
|
: Text( |
|
|
|
|
|
'login'.tr, // 登录 |
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
fontSize: 16.sp, |
|
|
|
|
|
fontWeight: FontWeight.w600, |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
|
|
|
)), |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 使用密码登录按钮 |
|
|
|
|
|
Widget _buildUsePasswordButton(bool isDarkMode) { |
|
|
|
|
|
return Center( |
|
|
|
|
|
child: TextButton( |
|
|
|
|
|
onPressed: controller.usePasswordLogin, |
|
|
|
|
|
child: Text( |
|
|
|
|
|
'usePasswordLogin'.tr, // 使用密码登录 |
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
fontSize: 14.sp, |
|
|
|
|
|
color: |
|
|
|
|
|
isDarkMode ? const Color(0xFF3B82F6) : const Color(0xFF3B82F6), |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|