这是CaiYouHui前端,一个关于flutter的安卓app,前端使用flutter实现

login_screen.dart 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. import 'package:flutter/material.dart';
  2. import 'package:provider/provider.dart';
  3. import '../../providers/auth_provider.dart';
  4. import '../../../core/constants/route_constants.dart';
  5. import '../../providers/user_provider.dart';
  6. import '../../widgets/common/app_button.dart';
  7. import '../../widgets/common/app_text_field.dart';
  8. import '../../widgets/common/loading_indicator.dart';
  9. class LoginScreen extends StatefulWidget {
  10. final VoidCallback? onSuccess;
  11. const LoginScreen({
  12. super.key,
  13. this.onSuccess,
  14. });
  15. @override
  16. State<LoginScreen> createState() => _LoginScreenState();
  17. }
  18. class _LoginScreenState extends State<LoginScreen> {
  19. final _formKey = GlobalKey<FormState>();
  20. final _emailController = TextEditingController(text: 'aaa');
  21. final _passwordController = TextEditingController(text: 'Heweidabangzi77!');
  22. @override
  23. void dispose() {
  24. _emailController.dispose();
  25. _passwordController.dispose();
  26. super.dispose();
  27. }
  28. @override
  29. Widget build(BuildContext context) {
  30. final authProvider = Provider.of<AuthProvider>(context);
  31. return Scaffold(
  32. appBar: AppBar(
  33. title: const Text('登录'),
  34. ),
  35. body: SingleChildScrollView(
  36. child: Padding(
  37. padding: const EdgeInsets.all(24.0),
  38. child: Form(
  39. key: _formKey,
  40. child: Column(
  41. crossAxisAlignment: CrossAxisAlignment.start,
  42. children: [
  43. const SizedBox(height: 40),
  44. const Center(
  45. child: Text(
  46. '欢迎回来',
  47. style: TextStyle(
  48. fontSize: 28,
  49. fontWeight: FontWeight.bold,
  50. ),
  51. ),
  52. ),
  53. const SizedBox(height: 8),
  54. const Center(
  55. child: Text(
  56. '请输入您的账号信息',
  57. style: TextStyle(
  58. fontSize: 16,
  59. color: Colors.grey,
  60. ),
  61. ),
  62. ),
  63. const SizedBox(height: 40),
  64. AppTextField(
  65. controller: _emailController, // 改为username
  66. labelText: '用户名',
  67. hintText: '请输入用户名',
  68. prefixIcon: const Icon(Icons.person_outline),
  69. validator: (value) {
  70. if (value == null || value.isEmpty) {
  71. return '请输入用户名';
  72. }
  73. return null;
  74. },
  75. ),
  76. const SizedBox(height: 20),
  77. AppTextField(
  78. controller: _passwordController,
  79. labelText: '密码',
  80. hintText: '请输入密码',
  81. obscureText: true,
  82. prefixIcon: const Icon(Icons.lock_outline),
  83. validator: (value) {
  84. if (value == null || value.isEmpty) {
  85. return '请输入密码';
  86. }
  87. if (value.length < 6) {
  88. return '密码至少需要6位字符';
  89. }
  90. return null;
  91. },
  92. ),
  93. const SizedBox(height: 30),
  94. if (authProvider.error != null)
  95. Padding(
  96. padding: const EdgeInsets.only(bottom: 16),
  97. child: Text(
  98. authProvider.error!,
  99. style: const TextStyle(
  100. color: Colors.red,
  101. fontSize: 14,
  102. ),
  103. ),
  104. ),
  105. if (authProvider.isLoading)
  106. const LoadingIndicator()
  107. else
  108. AppButton(
  109. text: '登录',
  110. onPressed: () async {
  111. if (_formKey.currentState!.validate()) {
  112. await authProvider.login(
  113. _emailController.text.trim(),
  114. _passwordController.text,
  115. );
  116. if (authProvider.isAuthenticated) {
  117. // ✅ 同时更新 userProvider
  118. final userProvider = Provider.of<UserProvider>(context, listen: false);
  119. userProvider.updateUser(authProvider.user);
  120. // widget.onSuccess?.call();
  121. Navigator.of(context).pushReplacementNamed(RouteConstants.home);
  122. // Navigator.of(context).pushNamedAndRemoveUntil(RouteConstants.home);
  123. }
  124. }
  125. },
  126. ),
  127. const SizedBox(height: 20),
  128. Center(
  129. child: TextButton(
  130. onPressed: () {
  131. Navigator.of(context).pushNamed(RouteConstants.register);
  132. },
  133. child: const Text(
  134. '还没有账号?立即注册',
  135. style: TextStyle(
  136. fontSize: 14,
  137. color: Colors.blue,
  138. ),
  139. ),
  140. ),
  141. ),
  142. const SizedBox(height: 30),
  143. const Row(
  144. children: [
  145. Expanded(child: Divider()),
  146. Padding(
  147. padding: EdgeInsets.symmetric(horizontal: 16),
  148. child: Text('或'),
  149. ),
  150. Expanded(child: Divider()),
  151. ],
  152. ),
  153. const SizedBox(height: 20),
  154. Row(
  155. mainAxisAlignment: MainAxisAlignment.center,
  156. children: [
  157. IconButton(
  158. onPressed: () {},
  159. icon: Container(
  160. padding: const EdgeInsets.all(10),
  161. decoration: BoxDecoration(
  162. color: Colors.grey[100],
  163. borderRadius: BorderRadius.circular(50),
  164. ),
  165. child: const Icon(Icons.wechat, color: Colors.green),
  166. ),
  167. ),
  168. IconButton(
  169. onPressed: () {},
  170. icon: Container(
  171. padding: const EdgeInsets.all(10),
  172. decoration: BoxDecoration(
  173. color: Colors.grey[100],
  174. borderRadius: BorderRadius.circular(50),
  175. ),
  176. child: const Icon(Icons.wechat, color: Colors.blue),
  177. ),
  178. ),
  179. ],
  180. ),
  181. ],
  182. ),
  183. ),
  184. ),
  185. ),
  186. );
  187. }
  188. }