// auth_provider.dart — 认证状态(JWT 令牌生命周期) import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../services/auth_api.dart'; import '../services/token_store.dart'; // ── 状态 ──────────────────────────────────────────────────────────── class AuthState { const AuthState({this.accessToken, this.isLoading = false}); final String? accessToken; final bool isLoading; bool get isLoggedIn => accessToken != null && accessToken!.isNotEmpty; AuthState copyWith({String? accessToken, bool? isLoading}) => AuthState( accessToken: accessToken ?? this.accessToken, isLoading: isLoading ?? this.isLoading, ); } // ── 状态机 ─────────────────────────────────────────────────────────── class AuthNotifier extends StateNotifier { AuthNotifier(this._store) : super(const AuthState(isLoading: true)) { _loadFromStore(); } final TokenStore _store; Future _loadFromStore() async { try { final token = await _store.loadAccessToken(); state = AuthState(accessToken: token); } catch (_) { // FlutterSecureStorage 在测试环境 / 未初始化时抛异常,视为未登录。 state = const AuthState(); } } /// 登录 / 注册成功后保存令牌。 Future saveTokens(AuthTokens tokens) async { await _store.saveTokens( access: tokens.accessToken, refresh: tokens.refreshToken, ); state = AuthState(accessToken: tokens.accessToken); } /// 退出登录:清除本地令牌。 Future logout() async { await _store.clear(); state = const AuthState(); } } // ── Providers ──────────────────────────────────────────────────────── /// 可在测试中 override,注入 stub TokenStore(避免 FlutterSecureStorage 平台依赖)。 final tokenStoreProvider = Provider((_) => const TokenStore()); final authProvider = StateNotifierProvider( (ref) => AuthNotifier(ref.watch(tokenStoreProvider)), );