| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- import 'package:flutter/material.dart';
- import 'package:provider/provider.dart';
- import '../services/auth_provider.dart';
-
- /// 登录页面
- class LoginPage extends StatefulWidget {
- const LoginPage({super.key});
-
- @override
- State<LoginPage> createState() => _LoginPageState();
- }
-
- class _LoginPageState extends State<LoginPage> {
- final _formKey = GlobalKey<FormState>();
- final _usernameController = TextEditingController();
- final _passwordController = TextEditingController();
- bool _obscurePassword = true;
-
- @override
- void dispose() {
- _usernameController.dispose();
- _passwordController.dispose();
- super.dispose();
- }
-
- Future<void> _handleLogin() async {
- if (!_formKey.currentState!.validate()) return;
-
- final authProvider = Provider.of<AuthProvider>(context, listen: false);
- final success = await authProvider.login(
- username: _usernameController.text.trim(),
- password: _passwordController.text,
- );
-
- if (success && mounted) {
- // 登录成功后路由由 AuthGuard 自动处理
- Navigator.of(context).pushReplacementNamed('/main');
- } else if (mounted) {
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(
- content: Text(authProvider.errorMessage ?? '登录失败'),
- backgroundColor: Colors.red,
- ),
- );
- }
- }
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- body: SafeArea(
- child: Center(
- child: SingleChildScrollView(
- padding: const EdgeInsets.all(32),
- child: Form(
- key: _formKey,
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: [
- // Logo 和应用名
- const Icon(
- Icons.water_drop,
- size: 80,
- color: Color(0xFF1976D2),
- ),
- const SizedBox(height: 16),
- const Text(
- '供水管理系统',
- textAlign: TextAlign.center,
- style: TextStyle(
- fontSize: 24,
- fontWeight: FontWeight.bold,
- color: Color(0xFF1976D2),
- ),
- ),
- const SizedBox(height: 8),
- Text(
- '供水 · 巡检 · 营收',
- textAlign: TextAlign.center,
- style: TextStyle(
- fontSize: 14,
- color: Colors.grey[600],
- ),
- ),
- const SizedBox(height: 48),
-
- // 用户名输入
- TextFormField(
- controller: _usernameController,
- decoration: const InputDecoration(
- labelText: '用户名',
- prefixIcon: Icon(Icons.person),
- hintText: '请输入用户名',
- ),
- validator: (value) {
- if (value == null || value.trim().isEmpty) {
- return '请输入用户名';
- }
- return null;
- },
- ),
- const SizedBox(height: 16),
-
- // 密码输入
- TextFormField(
- controller: _passwordController,
- decoration: InputDecoration(
- labelText: '密码',
- prefixIcon: const Icon(Icons.lock),
- hintText: '请输入密码',
- suffixIcon: IconButton(
- icon: Icon(
- _obscurePassword ? Icons.visibility_off : Icons.visibility,
- ),
- onPressed: () {
- setState(() {
- _obscurePassword = !_obscurePassword;
- });
- },
- ),
- ),
- obscureText: _obscurePassword,
- validator: (value) {
- if (value == null || value.isEmpty) {
- return '请输入密码';
- }
- if (value.length < 6) {
- return '密码长度不能少于6位';
- }
- return null;
- },
- ),
- const SizedBox(height: 32),
-
- // 登录按钮
- Consumer<AuthProvider>(
- builder: (context, auth, child) {
- return ElevatedButton(
- onPressed: auth.isLoading ? null : _handleLogin,
- child: auth.isLoading
- ? const SizedBox(
- height: 20,
- width: 20,
- child: CircularProgressIndicator(
- strokeWidth: 2,
- color: Colors.white,
- ),
- )
- : const Text(
- '登 录',
- style: TextStyle(fontSize: 16),
- ),
- );
- },
- ),
- const SizedBox(height: 16),
-
- // 版本信息
- Text(
- 'v1.0.0',
- textAlign: TextAlign.center,
- style: TextStyle(color: Colors.grey[400], fontSize: 12),
- ),
- ],
- ),
- ),
- ),
- ),
- ),
- );
- }
- }
|