You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
6.8 KiB
219 lines
6.8 KiB
import 'package:flutter/material.dart'; |
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|
import 'package:get/get.dart'; |
|
import 'package:problem_check_system/modules/auth/controllers/auth_controller.dart'; |
|
|
|
class LoginPage extends StatelessWidget { |
|
const LoginPage({super.key}); |
|
|
|
@override |
|
Widget build(BuildContext context) { |
|
final AuthController controller = Get.find<AuthController>(); |
|
|
|
// 在 build 方法中创建并初始化 TextEditingController |
|
final TextEditingController usernameController = TextEditingController( |
|
text: controller.username.value, |
|
); |
|
final TextEditingController passwordController = TextEditingController( |
|
text: controller.password.value, |
|
); |
|
|
|
// 监听 AuthController 的响应式变量,以防它们在其他地方被修改 |
|
// 并更新到 TextEditingController。 |
|
// 这里使用 once() 或 ever() 都可以,但为了代码简洁, |
|
// 我们主要关注初始同步。用户输入后,值会通过 onChanged 更新。 |
|
usernameController.text = controller.username.value; |
|
passwordController.text = controller.password.value; |
|
|
|
return Scaffold( |
|
resizeToAvoidBottomInset: false, |
|
body: Stack( |
|
children: [ |
|
_buildBackground(), |
|
_buildLoginCard(controller, usernameController, passwordController), |
|
], |
|
), |
|
); |
|
} |
|
|
|
Widget _buildBackground() { |
|
// ... 此部分代码不变 ... |
|
return Stack( |
|
children: [ |
|
Container( |
|
decoration: const BoxDecoration( |
|
image: DecorationImage( |
|
image: AssetImage('assets/images/background.png'), |
|
fit: BoxFit.fitWidth, |
|
), |
|
), |
|
), |
|
Positioned( |
|
left: 28.5.w, |
|
top: 89.5.h, |
|
child: Image.asset( |
|
'assets/images/label.png', |
|
width: 171.5.w, |
|
height: 23.5.h, |
|
fit: BoxFit.fitWidth, |
|
), |
|
), |
|
Positioned( |
|
left: 28.5.w, |
|
top: 128.5.h, |
|
child: Image.asset( |
|
'assets/images/label1.png', |
|
width: 296.5.w, |
|
height: 35.5.h, |
|
fit: BoxFit.fitWidth, |
|
), |
|
), |
|
], |
|
); |
|
} |
|
|
|
// 修改 _buildLoginCard 方法签名,传入控制器 |
|
Widget _buildLoginCard( |
|
AuthController controller, |
|
TextEditingController usernameController, |
|
TextEditingController passwordController, |
|
) { |
|
return Positioned( |
|
left: 20.5.w, |
|
top: 220.5.h, |
|
child: Container( |
|
width: 334.w, |
|
height: 574.5.h, |
|
decoration: BoxDecoration( |
|
color: const Color(0xFFFFFFFF).withOpacity(0.6), // 使用 withOpacity 更清晰 |
|
borderRadius: BorderRadius.all(Radius.circular(23.5.r)), |
|
), |
|
padding: EdgeInsets.all(24.w), |
|
child: Column( |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
children: [ |
|
const SizedBox(height: 16), |
|
// 使用新版 _buildTextFieldSection |
|
_buildTextFieldSection( |
|
label: '账号', |
|
hintText: '请输入您的账号', |
|
controller: usernameController, |
|
onChanged: controller.updateUsername, // onChanged 保留,用于实时同步 |
|
), |
|
const SizedBox(height: 22), |
|
_buildTextFieldSection( |
|
label: '密码', |
|
hintText: '请输入您的密码', |
|
obscureText: true, |
|
controller: passwordController, |
|
onChanged: controller.updatePassword, |
|
), |
|
const SizedBox(height: 9.5), |
|
_buildRememberPasswordRow(controller), |
|
const SizedBox(height: 138.5), |
|
_buildLoginButton(controller), |
|
], |
|
), |
|
), |
|
); |
|
} |
|
|
|
// 修改 _buildTextFieldSection 以接受 TextEditingController |
|
Widget _buildTextFieldSection({ |
|
required String label, |
|
required String hintText, |
|
required TextEditingController controller, |
|
bool obscureText = false, |
|
required Function(String) onChanged, |
|
}) { |
|
return Column( |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
children: [ |
|
Text( |
|
label, |
|
style: TextStyle(fontSize: 16.5.sp, color: Colors.black), |
|
), |
|
const SizedBox(height: 10.5), |
|
TextField( |
|
controller: controller, // 使用传入的控制器 |
|
onChanged: onChanged, |
|
obscureText: obscureText, |
|
style: const TextStyle(color: Colors.black), |
|
decoration: InputDecoration( |
|
hintText: hintText, |
|
hintStyle: const TextStyle(color: Colors.grey), |
|
border: const OutlineInputBorder(), |
|
), |
|
), |
|
], |
|
); |
|
} |
|
|
|
Widget _buildRememberPasswordRow(AuthController controller) { |
|
// ... 此部分代码不变 ... |
|
return Row( |
|
mainAxisAlignment: MainAxisAlignment.end, |
|
children: [ |
|
Obx( |
|
() => Checkbox( |
|
value: controller.rememberPassword.value, |
|
onChanged: (value) => controller.rememberPassword.value = value!, |
|
), |
|
), |
|
Text( |
|
'记住密码', |
|
style: TextStyle(color: const Color(0xFF959595), fontSize: 14.sp), |
|
), |
|
], |
|
); |
|
} |
|
|
|
Widget _buildLoginButton(AuthController controller) { |
|
// ... 此部分代码不变 ... |
|
return SizedBox( |
|
width: double.infinity, |
|
child: ElevatedButton( |
|
onPressed: controller.login, |
|
style: ElevatedButton.styleFrom( |
|
padding: EdgeInsets.zero, |
|
backgroundColor: Colors.transparent, |
|
shadowColor: Colors.transparent, |
|
shape: RoundedRectangleBorder( |
|
borderRadius: BorderRadius.circular(8.r), |
|
), |
|
minimumSize: Size(double.infinity, 48.h), |
|
), |
|
child: Ink( |
|
decoration: BoxDecoration( |
|
gradient: const LinearGradient( |
|
colors: [Color(0xFF418CFC), Color(0xFF3DBFFC)], |
|
begin: Alignment.centerLeft, |
|
end: Alignment.centerRight, |
|
), |
|
borderRadius: BorderRadius.circular(8.r), |
|
), |
|
child: Container( |
|
constraints: BoxConstraints(minHeight: 48.h), |
|
alignment: Alignment.center, |
|
padding: EdgeInsets.symmetric(vertical: 12.h, horizontal: 24.w), |
|
child: Obx(() { |
|
if (controller.isLoading.value) { |
|
return const CircularProgressIndicator( |
|
valueColor: AlwaysStoppedAnimation<Color>(Colors.white), |
|
); |
|
} |
|
return Text( |
|
'登录', |
|
style: TextStyle( |
|
color: Colors.white, |
|
fontSize: 16.sp, |
|
fontWeight: FontWeight.w500, |
|
), |
|
); |
|
}), |
|
), |
|
), |
|
), |
|
); |
|
} |
|
}
|
|
|