Files
slogan/lib/core/auth/auth_provider.dart
T
adminandClaude Opus 4.7 acbe60c13c feat: app 骨架 + 网络层 + 认证(登录/注册)
- flutter create 初始化 + 依赖(riverpod 3/dio/go_router/three_dart 0.0.16)
- ApiClient:JWT 拦截器 + 统一响应解包 + 401 登出回调 + multipart 上传
- TokenStorage(shared_preferences)+ AuthNotifier 登录/登出
- 登录页(含注册对话框)+ 4 Tab 主框架
- 6 个单元测试通过(网络层 4 + 认证 2)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-31 12:39:01 +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);