| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- import 'package:chicken_farm/apis/index.dart';
- import 'package:chicken_farm/core/config/app_config.dart';
- import 'package:chicken_farm/core/services/connectivity_service.dart';
- import 'package:chicken_farm/core/services/navigation_service.dart';
- import 'package:chicken_farm/core/utils/jwt_token.dart';
- import 'package:chicken_farm/core/utils/logger.dart';
- import 'package:chicken_farm/modes/auth/login_model.dart';
- import 'package:chicken_farm/modes/user/user_model.dart';
- import 'package:chicken_farm/routes/app_routes.dart';
- import 'package:flutter_riverpod/flutter_riverpod.dart';
- import 'package:go_router/go_router.dart';
- /// 认证状态枚举
- enum AuthState { authenticated, unauthenticated, loading }
- /// 用户认证信息状态
- class AuthInfo {
- final AuthState state;
- final String? token;
- final UserModel? user;
- final List<String>? permissions;
- final List<String>? roles;
- AuthInfo({
- required this.state,
- this.token,
- this.user,
- this.permissions,
- this.roles,
- });
- /// 创建已认证状态
- AuthInfo.authenticated({
- required String token,
- required UserModel user,
- List<String>? permissions,
- List<String>? roles,
- }) : this(
- state: AuthState.authenticated,
- token: token,
- user: user,
- permissions: permissions,
- roles: roles,
- );
- /// 创建未认证状态
- AuthInfo.unauthenticated()
- : this(
- state: AuthState.unauthenticated,
- token: null,
- user: null,
- permissions: const [],
- roles: const [],
- );
- /// 创建加载状态
- AuthInfo.loading()
- : this(
- state: AuthState.loading,
- token: null,
- user: null,
- permissions: const [],
- roles: const [],
- );
- /// 复制对象并更新部分字段
- AuthInfo copyWith({
- AuthState? state,
- String? token,
- UserModel? user,
- List<String>? permissions,
- List<String>? roles,
- }) {
- return AuthInfo(
- state: state ?? this.state,
- token: token ?? this.token,
- user: user ?? this.user,
- permissions: permissions ?? this.permissions,
- roles: roles ?? this.roles,
- );
- }
- }
- class AuthStore extends StateNotifier<AuthInfo> {
- AuthStore() : super(AuthInfo.unauthenticated()) {
- _init();
- }
- /// 初始化认证状态
- Future<void> _init() async {
- state = AuthInfo.loading();
- try {
- final token = await JwtToken.getToken();
- if (token != null) {
- // 检查网络连接状态
- final container = ProviderContainer();
- final isConnected = await container.read(isConnectedProvider.future);
- if (isConnected) {
- // 有网络连接,强制获取最新用户信息
- try {
- final userInfo = await apis.loginApi.getInfo();
- if (userInfo == null) {
- throw Exception('用户信息获取失败');
- }
- // 保存用户信息到本地存储,供离线时使用
- await JwtToken.saveUserInfo(userInfo);
- state = AuthInfo.authenticated(
- token: token,
- user: userInfo.user!,
- permissions: userInfo.permissions,
- roles: userInfo.roles,
- );
- logger.i('在线模式下已登录 state: $state');
- } catch (e) {
- // 网络连接但是获取用户信息失败,可能是token过期
- logger.e('在线模式下获取用户信息失败: $e');
- await JwtToken.clear();
- state = AuthInfo.unauthenticated();
- }
- } else {
- // 无网络连接,使用离线模式
- try {
- // 尝试从本地存储获取上次登录的用户信息
- final cachedUserInfo = await JwtToken.getUserInfo();
- if (cachedUserInfo != null && cachedUserInfo.user != null) {
- state = AuthInfo.authenticated(
- token: token,
- user: cachedUserInfo.user!,
- permissions: cachedUserInfo.permissions ?? [],
- roles: cachedUserInfo.roles ?? [],
- );
- logger.i('离线模式下使用缓存用户信息: $state');
- } else {
- // 没有缓存的用户信息,不能进行离线认证
- logger.w('离线模式下无缓存用户信息,无法进行离线认证');
- state = AuthInfo.unauthenticated();
- }
- } catch (e) {
- logger.e('离线模式初始化失败: $e');
- state = AuthInfo.unauthenticated();
- }
- }
- } else {
- state = AuthInfo.unauthenticated();
- }
- } catch (e) {
- logger.e('认证初始化失败: $e');
- state = AuthInfo.unauthenticated();
- }
- }
- /// 登录操作
- Future<void> login(LoginModel loginModel) async {
- state = AuthInfo.loading();
- try {
- loginModel.clientId = AppConfig.clientId;
- final authResult = await apis.loginApi.login(loginModel);
- final token = authResult.accessToken;
- await JwtToken.setToken(token, authResult.refreshToken);
- // 获取用户信息
- final userInfo = await apis.loginApi.getInfo();
- if (userInfo == null) {
- throw Exception('用户信息获取失败');
- }
- // 保存用户信息到本地存储,供离线时使用
- await JwtToken.saveUserInfo(userInfo);
- state = AuthInfo.authenticated(
- token: token,
- user: userInfo.user!,
- permissions: userInfo.permissions,
- roles: userInfo.roles,
- );
- logger.i('登录成功 state: $state');
- } catch (e) {
- await JwtToken.clear();
- state = AuthInfo.unauthenticated();
- }
- }
- /// 登出操作
- Future<void> logout() async {
- try {
- await apis.loginApi.logout();
- } catch (e) {
- // 即使API调用失败也要清除本地状态
- logger.e('Logout API call failed: $e');
- } finally {
- await JwtToken.clear();
- state = AuthInfo.unauthenticated();
- if (NavigationService.navigatorKey.currentState != null &&
- NavigationService.navigatorKey.currentContext != null) {
- NavigationService.navigatorKey.currentContext!.goNamed(
- AppRouteNames.login,
- );
- }
- }
- }
- /// 刷新token
- Future<void> refreshToken() async {
- try {
- final refreshToken = await JwtToken.getRefreshToken();
- if (refreshToken != null) {
- final authResult = await apis.loginApi.refreshToken(refreshToken);
- final newToken = authResult.accessToken;
- await JwtToken.setToken(newToken, authResult.refreshToken);
- state = state.copyWith(token: newToken);
- }
- } catch (e) {
- // 刷新失败则登出
- await logout();
- rethrow;
- }
- }
- /// 重新获取用户信息
- Future<void> getUserInfo() async {
- try {
- final userInfo = await apis.loginApi.getInfo();
- if (userInfo == null) {
- throw Exception('用户信息获取失败');
- }
- // 更新本地存储的用户信息
- await JwtToken.saveUserInfo(userInfo);
- state = state.copyWith(
- user: userInfo.user,
- permissions: userInfo.permissions,
- roles: userInfo.roles,
- );
- } catch (e) {
- rethrow;
- }
- }
- /// 检查是否有特定权限
- bool hasPermission(String permission) {
- return state.permissions?.contains(permission) ?? false;
- }
- /// 检查是否有特定角色
- bool hasRole(String role) {
- return state.roles?.contains(role) ?? false;
- }
- /// 是否是超级管理员
- bool isSuperAdmin() {
- if (state.user == null) return false;
- return state.user!.userName == "admin" ||
- (state.roles?.contains("super_admin") ?? false);
- }
- }
- // 添加 Provider 实例
- final authStoreProvider = StateNotifierProvider<AuthStore, AuthInfo>(
- (ref) => AuthStore(),
- );
|