import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../core/network/api_client.dart'; import '../core/storage/token_store.dart'; import '../models/user_model.dart'; import '../services/user_service.dart'; /// 登录态:未登录 / 已登录(含用户信息) /// Token 本体在 TokenStore(安全存储 + 内存缓存),此处只持有用户模型与状态。 class AuthState { const AuthState({this.user, this.restored = false}); final UserModel? user; final bool restored; // 是否已完成启动恢复(避免启动期误跳登录) bool get isLoggedIn => user != null && TokenStore.hasToken; AuthState copyWith({UserModel? user, bool? restored}) => AuthState( user: user ?? this.user, restored: restored ?? this.restored, ); } class AuthNotifier extends StateNotifier { AuthNotifier() : super(const AuthState(restored: false)) { // 会话过期(401 刷新失败)→ 清空登录态 ApiClient.onSessionExpired = _onSessionExpired; } /// 启动恢复:读取安全存储中的 Token,有效则拉取用户信息 Future restore() async { await TokenStore.restore(); if (!TokenStore.hasToken) { state = state.copyWith(restored: true); return; } try { final user = await UserService.fetchMe(); state = AuthState(user: user, restored: true); } catch (_) { // Token 失效(1002 等):本地清理,回游客态 await TokenStore.clear(); state = AuthState(restored: true); } } /// 登录/注册成功:Token 已由 AuthService 写入 TokenStore,此处仅刷新用户 Future onLoginSuccess(UserModel user) async { state = AuthState(user: user, restored: true); } /// 修改资料/头像后同步当前用户(不改变登录态与 Token) void updateUser(UserModel user) => state = state.copyWith(user: user); /// 退出登录:服务端注销 + 本地清理 Future logout() async => _onSessionExpired(); Future _onSessionExpired() async { await TokenStore.clear(); state = AuthState(restored: true); } } /// 全局登录态 Provider final authProvider = StateNotifierProvider((ref) { return AuthNotifier(); });