Files
slogan/app/lib/core/auth/auth_provider.dart
T
admin b53c57e02d Add 'app/' from commit 'a11a66886941bba128d89c1124115e1b1c87a128'
git-subtree-dir: app
git-subtree-mainline: 6ebd902c6b
git-subtree-split: a11a668869
2026-08-04 14:59:55 +08:00

65 lines
1.8 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../network/api_client.dart';
import '../storage/token_storage.dart';
class AuthState {
final bool authenticated;
final int? userId;
final String? name;
const AuthState({
this.authenticated = false,
this.userId,
this.name,
});
}
final tokenStorageProvider = Provider<TokenStorage>((ref) => TokenStorage());
final apiClientProvider = Provider<ApiClient>((ref) {
final client = ApiClient(tokenStorage: ref.watch(tokenStorageProvider));
client.onUnauthorized = () {
ref.read(authProvider.notifier).logout();
};
return client;
});
class AuthNotifier extends AsyncNotifier<AuthState> {
@override
Future<AuthState> build() async {
final storage = ref.watch(tokenStorageProvider);
await storage.load();
return AuthState(authenticated: storage.hasToken);
}
Future<void> login(String account, String password) async {
state = const AsyncLoading();
try {
final client = ref.read(apiClientProvider);
final data = await client.post<Map<String, dynamic>>('/user/login', {
'account': account,
'password': password,
});
final token = data['token'] as String? ?? '';
final user = data['user'] as Map<String, dynamic>? ?? {};
await ref.read(tokenStorageProvider).save(token);
state = AsyncData(AuthState(
authenticated: true,
userId: (user['id'] as num?)?.toInt(),
name: user['name'] as String?,
));
} catch (e) {
state = AsyncError(e, StackTrace.current);
}
}
Future<void> logout() async {
await ref.read(tokenStorageProvider).clear();
state = const AsyncData(AuthState());
}
}
final authProvider =
AsyncNotifierProvider<AuthNotifier, AuthState>(AuthNotifier.new);