Files
video/app/lib/providers/auth_provider.dart
T
2026-10-15 20:36:59 +08:00

68 lines
2.2 KiB
Dart

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<AuthState> {
AuthNotifier() : super(const AuthState(restored: false)) {
// 会话过期(401 刷新失败)→ 清空登录态
ApiClient.onSessionExpired = _onSessionExpired;
}
/// 启动恢复:读取安全存储中的 Token,有效则拉取用户信息
Future<void> 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<void> onLoginSuccess(UserModel user) async {
state = AuthState(user: user, restored: true);
}
/// 修改资料/头像后同步当前用户(不改变登录态与 Token)
void updateUser(UserModel user) => state = state.copyWith(user: user);
/// 退出登录:服务端注销 + 本地清理
Future<void> logout() async => _onSessionExpired();
Future<void> _onSessionExpired() async {
await TokenStore.clear();
state = AuthState(restored: true);
}
}
/// 全局登录态 Provider
final authProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) {
return AuthNotifier();
});