auth_store.dart 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import 'package:chicken_farm/apis/index.dart';
  2. import 'package:chicken_farm/core/config/app_config.dart';
  3. import 'package:chicken_farm/core/services/navigation_service.dart';
  4. import 'package:chicken_farm/core/utils/jwt_token.dart';
  5. import 'package:chicken_farm/core/utils/logger.dart';
  6. import 'package:chicken_farm/modes/auth/login_model.dart';
  7. import 'package:chicken_farm/modes/user/user_model.dart';
  8. import 'package:chicken_farm/routes/app_routes.dart';
  9. import 'package:flutter_riverpod/flutter_riverpod.dart';
  10. import 'package:go_router/go_router.dart';
  11. /// 认证状态枚举
  12. enum AuthState { authenticated, unauthenticated, loading }
  13. /// 用户认证信息状态
  14. class AuthInfo {
  15. final AuthState state;
  16. final String? token;
  17. final UserModel? user;
  18. final List<String>? permissions;
  19. final List<String>? roles;
  20. AuthInfo({
  21. required this.state,
  22. this.token,
  23. this.user,
  24. this.permissions,
  25. this.roles,
  26. });
  27. /// 创建已认证状态
  28. AuthInfo.authenticated({
  29. required String token,
  30. required UserModel user,
  31. List<String>? permissions,
  32. List<String>? roles,
  33. }) : this(
  34. state: AuthState.authenticated,
  35. token: token,
  36. user: user,
  37. permissions: permissions,
  38. roles: roles,
  39. );
  40. /// 创建未认证状态
  41. AuthInfo.unauthenticated()
  42. : this(
  43. state: AuthState.unauthenticated,
  44. token: null,
  45. user: null,
  46. permissions: const [],
  47. roles: const [],
  48. );
  49. /// 创建加载状态
  50. AuthInfo.loading()
  51. : this(
  52. state: AuthState.loading,
  53. token: null,
  54. user: null,
  55. permissions: const [],
  56. roles: const [],
  57. );
  58. /// 复制对象并更新部分字段
  59. AuthInfo copyWith({
  60. AuthState? state,
  61. String? token,
  62. UserModel? user,
  63. List<String>? permissions,
  64. List<String>? roles,
  65. }) {
  66. return AuthInfo(
  67. state: state ?? this.state,
  68. token: token ?? this.token,
  69. user: user ?? this.user,
  70. permissions: permissions ?? this.permissions,
  71. roles: roles ?? this.roles,
  72. );
  73. }
  74. }
  75. class AuthStore extends StateNotifier<AuthInfo> {
  76. AuthStore() : super(AuthInfo.unauthenticated()) {
  77. _init();
  78. }
  79. /// 初始化认证状态
  80. Future<void> _init() async {
  81. state = AuthInfo.loading();
  82. try {
  83. final token = await JwtToken.getToken();
  84. if (token != null) {
  85. // 如果有token,则设置为已认证状态
  86. // 尝试获取用户信息以验证token有效性
  87. try {
  88. final userInfo = await apis.loginApi.getInfo();
  89. if (userInfo == null) {
  90. throw Exception('用户信息获取失败');
  91. }
  92. state = AuthInfo.authenticated(
  93. token: token,
  94. user: userInfo.user!,
  95. permissions: userInfo.permissions,
  96. roles: userInfo.roles,
  97. );
  98. logger.i('已登录 state: $state');
  99. } catch (e) {
  100. // Token无效,清除本地存储
  101. await JwtToken.clear();
  102. state = AuthInfo.unauthenticated();
  103. }
  104. } else {
  105. state = AuthInfo.unauthenticated();
  106. }
  107. } catch (e) {
  108. state = AuthInfo.unauthenticated();
  109. }
  110. }
  111. /// 登录操作
  112. Future<void> login(LoginModel loginModel) async {
  113. state = AuthInfo.loading();
  114. try {
  115. loginModel.clientId = AppConfig.clientId;
  116. final authResult = await apis.loginApi.login(loginModel);
  117. final token = authResult.accessToken;
  118. await JwtToken.setToken(token, authResult.refreshToken);
  119. // 获取用户信息
  120. final userInfo = await apis.loginApi.getInfo();
  121. if (userInfo == null) {
  122. throw Exception('用户信息获取失败');
  123. }
  124. state = AuthInfo.authenticated(
  125. token: token,
  126. user: userInfo.user!,
  127. permissions: userInfo.permissions,
  128. roles: userInfo.roles,
  129. );
  130. logger.i('登录成功 state: $state');
  131. } catch (e) {
  132. await JwtToken.clear();
  133. state = AuthInfo.unauthenticated();
  134. }
  135. }
  136. /// 登出操作
  137. Future<void> logout() async {
  138. try {
  139. await apis.loginApi.logout();
  140. } catch (e) {
  141. // 即使API调用失败也要清除本地状态
  142. logger.e('Logout API call failed: $e');
  143. } finally {
  144. await JwtToken.clear();
  145. state = AuthInfo.unauthenticated();
  146. if (NavigationService.navigatorKey.currentState != null &&
  147. NavigationService.navigatorKey.currentContext != null) {
  148. NavigationService.navigatorKey.currentContext!.goNamed(
  149. AppRouteNames.login,
  150. );
  151. }
  152. }
  153. }
  154. /// 刷新token
  155. Future<void> refreshToken() async {
  156. try {
  157. final refreshToken = await JwtToken.getRefreshToken();
  158. if (refreshToken != null) {
  159. final authResult = await apis.loginApi.refreshToken(refreshToken);
  160. final newToken = authResult.accessToken;
  161. await JwtToken.setToken(newToken, authResult.refreshToken);
  162. state = state.copyWith(token: newToken);
  163. }
  164. } catch (e) {
  165. // 刷新失败则登出
  166. await logout();
  167. rethrow;
  168. }
  169. }
  170. /// 重新获取用户信息
  171. Future<void> getUserInfo() async {
  172. try {
  173. final userInfo = await apis.loginApi.getInfo();
  174. if (userInfo == null) {
  175. throw Exception('用户信息获取失败');
  176. }
  177. state = state.copyWith(
  178. user: userInfo.user,
  179. permissions: userInfo.permissions,
  180. roles: userInfo.roles,
  181. );
  182. } catch (e) {
  183. rethrow;
  184. }
  185. }
  186. /// 检查是否有特定权限
  187. bool hasPermission(String permission) {
  188. return state.permissions?.contains(permission) ?? false;
  189. }
  190. /// 检查是否有特定角色
  191. bool hasRole(String role) {
  192. return state.roles?.contains(role) ?? false;
  193. }
  194. /// 是否是超级管理员
  195. bool isSuperAdmin() {
  196. if (state.user == null) return false;
  197. return state.user!.userName == "admin" ||
  198. (state.roles?.contains("super_admin") ?? false);
  199. }
  200. }
  201. // 添加 Provider 实例
  202. final authStoreProvider = StateNotifierProvider<AuthStore, AuthInfo>(
  203. (ref) => AuthStore(),
  204. );