Files
water-management-system/mobile/lib/pages/login/login_page.dart
T
bot_pm 778726f943 Phase 1 #24: Flutter 移动端框架(三合一 APP 骨架)
- pubspec.yaml: dio/provider/shared_preferences/flutter_map/geolocator
- main.dart: Provider 状态管理 + 登录守卫
- AuthService: Token 管理 + Dio HTTP + SharedPreferences 持久化
- LoginPage: Material Design 登录页
- HomePage: 三合一 BottomTab 导航(供水/巡检/营收)
- 预留依赖: flutter_local_notifications/image_picker/permission_handler
2026-06-14 13:19:18 +08:00

45 lines
1.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../services/auth_service.dart';
import '../home/home_page.dart';
class LoginPage extends StatefulWidget {
const LoginPage({super.key});
@override State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final _userCtrl = TextEditingController(text: 'admin');
final _passCtrl = TextEditingController(text: 'admin123');
bool _loading = false;
Future<void> _login() async {
setState(() => _loading = true);
final ok = await context.read<AuthService>().login(_userCtrl.text, _passCtrl.text);
if (!mounted) return;
setState(() => _loading = false);
if (ok) {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => const HomePage()));
} else {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('登录失败')));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Padding(padding: const EdgeInsets.all(32), child: Column(mainAxisSize: MainAxisSize.min, children: [
const Text('智慧水务', style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold, color: Colors.blue)),
const SizedBox(height: 32),
TextField(controller: _userCtrl, decoration: const InputDecoration(labelText: '用户名', prefixIcon: Icon(Icons.person))),
const SizedBox(height: 16),
TextField(controller: _passCtrl, obscureText: true, decoration: const InputDecoration(labelText: '密码', prefixIcon: Icon(Icons.lock))),
const SizedBox(height: 24),
SizedBox(width: double.infinity, height: 48, child: ElevatedButton(onPressed: _loading ? null : _login, child: Text(_loading ? '登录中...' : '登录'))),
])),
),
);
}
}