智慧水务管理系统 - 精河县供水工程综合管理平台

auth_service.dart 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import 'package:flutter/foundation.dart';
  2. import 'package:dio/dio.dart';
  3. import 'package:shared_preferences/shared_preferences.dart';
  4. /// 用户认证服务 —— 登录 / 登出 / Token 持久化
  5. class AuthService extends ChangeNotifier {
  6. // --------------- 状态 ---------------
  7. String _token = '';
  8. String _username = '';
  9. String _displayName = '';
  10. String _avatarUrl = '';
  11. bool _isLoading = false;
  12. String get token => _token;
  13. String get username => _username;
  14. String get displayName => _displayName.isNotEmpty ? _displayName : _username;
  15. String get avatarUrl => _avatarUrl;
  16. bool get isLoggedIn => _token.isNotEmpty;
  17. bool get isLoading => _isLoading;
  18. // --------------- Dio (内部使用,不依赖 ApiService 避免循环) ---------------
  19. final Dio _dio = Dio(BaseOptions(
  20. baseUrl: 'http://10.0.2.2:8080/api',
  21. connectTimeout: const Duration(seconds: 15),
  22. receiveTimeout: const Duration(seconds: 15),
  23. ));
  24. // --------------- 初始化(app 启动时恢复 session) ---------------
  25. Future<void> init() async {
  26. final prefs = await SharedPreferences.getInstance();
  27. _token = prefs.getString('token') ?? '';
  28. _username = prefs.getString('username') ?? '';
  29. _displayName = prefs.getString('displayName') ?? '';
  30. _avatarUrl = prefs.getString('avatarUrl') ?? '';
  31. notifyListeners();
  32. }
  33. // --------------- 登录 ---------------
  34. Future<bool> login(String username, String password) async {
  35. _isLoading = true;
  36. notifyListeners();
  37. try {
  38. final res = await _dio.post('/base/auth/login', data: {
  39. 'username': username,
  40. 'password': password,
  41. });
  42. // 兼容两种响应格式
  43. final data = res.data;
  44. if (data is Map && (data['code'] == 200 || data['code'] == 0)) {
  45. final payload = data['data'] ?? data;
  46. _token = payload is String ? payload : (payload['token'] ?? payload['accessToken'] ?? '').toString();
  47. _username = payload is Map ? (payload['username'] ?? username).toString() : username;
  48. _displayName = payload is Map ? (payload['displayName'] ?? payload['nickName'] ?? '').toString() : '';
  49. _avatarUrl = payload is Map ? (payload['avatar'] ?? '').toString() : '';
  50. await _persist();
  51. _isLoading = false;
  52. notifyListeners();
  53. return true;
  54. }
  55. } catch (e) {
  56. debugPrint('Login error: $e');
  57. }
  58. _isLoading = false;
  59. notifyListeners();
  60. return false;
  61. }
  62. // --------------- 登出 ---------------
  63. Future<void> logout() async {
  64. _token = '';
  65. _username = '';
  66. _displayName = '';
  67. _avatarUrl = '';
  68. final prefs = await SharedPreferences.getInstance();
  69. await prefs.remove('token');
  70. await prefs.remove('username');
  71. await prefs.remove('displayName');
  72. await prefs.remove('avatarUrl');
  73. notifyListeners();
  74. }
  75. // --------------- 刷新用户信息 ---------------
  76. Future<void> refreshProfile() async {
  77. if (_token.isEmpty) return;
  78. try {
  79. final res = await _dio.get(
  80. '/base/user/info',
  81. options: Options(headers: {'Authorization': 'Bearer $_token'}),
  82. );
  83. final data = res.data;
  84. if (data is Map && (data['code'] == 200 || data['code'] == 0)) {
  85. final payload = data['data'] ?? data;
  86. if (payload is Map) {
  87. _displayName = (payload['displayName'] ?? payload['nickName'] ?? _displayName).toString();
  88. _avatarUrl = (payload['avatar'] ?? _avatarUrl).toString();
  89. await _persist();
  90. notifyListeners();
  91. }
  92. }
  93. } catch (e) {
  94. debugPrint('refreshProfile error: $e');
  95. }
  96. }
  97. // --------------- 持久化 ---------------
  98. Future<void> _persist() async {
  99. final prefs = await SharedPreferences.getInstance();
  100. await prefs.setString('token', _token);
  101. await prefs.setString('username', _username);
  102. await prefs.setString('displayName', _displayName);
  103. await prefs.setString('avatarUrl', _avatarUrl);
  104. }
  105. }