This commit is contained in:
sjk
2025-11-17 13:39:05 +08:00
commit d4cfe2b9de
479 changed files with 109324 additions and 0 deletions

View File

@@ -0,0 +1,312 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/models/user_model.dart';
import '../../../core/services/auth_service.dart';
import '../../../core/services/storage_service.dart';
import '../../../core/network/api_client.dart';
import '../../../core/errors/app_exception.dart';
/// 认证状态
class AuthState {
final User? user;
final bool isAuthenticated;
final bool isLoading;
final String? error;
const AuthState({
this.user,
this.isAuthenticated = false,
this.isLoading = false,
this.error,
});
AuthState copyWith({
User? user,
bool? isAuthenticated,
bool? isLoading,
String? error,
}) {
return AuthState(
user: user ?? this.user,
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
isLoading: isLoading ?? this.isLoading,
error: error,
);
}
}
/// 认证状态管理器
class AuthNotifier extends StateNotifier<AuthState> {
final AuthService _authService;
final StorageService _storageService;
AuthNotifier(this._authService, this._storageService) : super(const AuthState()) {
_checkAuthStatus();
}
/// 检查认证状态
Future<void> _checkAuthStatus() async {
try {
final token = await _storageService.getToken();
if (token != null && token.isNotEmpty) {
// 获取真实用户信息
try {
final user = await _authService.getUserInfo();
state = state.copyWith(
user: user,
isAuthenticated: true,
);
} catch (e) {
// Token可能已过期清除token
await _storageService.clearTokens();
}
}
} catch (e) {
// 忽略错误,保持未认证状态
}
}
/// 登录
Future<void> login({
required String account, // 用户名或邮箱
required String password,
bool rememberMe = false,
}) async {
state = state.copyWith(isLoading: true, error: null);
try {
// 调用真实API
final authResponse = await _authService.login(
account: account,
password: password,
rememberMe: rememberMe,
);
// 保存token
await _storageService.saveToken(authResponse.token);
if (rememberMe && authResponse.refreshToken != null) {
await _storageService.saveRefreshToken(authResponse.refreshToken!);
}
// 更新状态
state = state.copyWith(
user: authResponse.user,
isAuthenticated: true,
isLoading: false,
);
} catch (e) {
state = state.copyWith(
isLoading: false,
error: e.toString(),
);
rethrow;
}
}
/// 注册
Future<void> register({
required String email,
required String password,
required String username,
required String nickname,
}) async {
state = state.copyWith(isLoading: true, error: null);
try {
// 调用真实API
final authResponse = await _authService.register(
email: email,
password: password,
username: username,
nickname: nickname,
);
// 保存token
await _storageService.saveToken(authResponse.token);
if (authResponse.refreshToken != null) {
await _storageService.saveRefreshToken(authResponse.refreshToken!);
}
// 更新状态
state = state.copyWith(
user: authResponse.user,
isAuthenticated: true,
isLoading: false,
);
} catch (e) {
state = state.copyWith(
isLoading: false,
error: e.toString(),
);
rethrow;
}
}
/// 登出
Future<void> logout() async {
state = state.copyWith(isLoading: true, error: null);
try {
// 模拟网络延迟
await Future.delayed(const Duration(milliseconds: 500));
await _storageService.clearTokens();
state = const AuthState();
} catch (e) {
state = state.copyWith(
isLoading: false,
error: e.toString(),
);
rethrow;
}
}
/// 忘记密码
Future<void> forgotPassword(String email) async {
state = state.copyWith(isLoading: true, error: null);
try {
// 模拟网络延迟
await Future.delayed(const Duration(milliseconds: 1000));
if (email.isEmpty) {
throw Exception('邮箱地址不能为空');
}
// 模拟发送重置邮件成功
state = state.copyWith(isLoading: false);
} catch (e) {
state = state.copyWith(
isLoading: false,
error: e.toString(),
);
rethrow;
}
}
/// 重置密码
Future<void> resetPassword({
required String token,
required String newPassword,
}) async {
state = state.copyWith(isLoading: true, error: null);
try {
// 模拟网络延迟
await Future.delayed(const Duration(milliseconds: 1000));
if (newPassword.length < 6) {
throw Exception('密码长度不能少于6位');
}
state = state.copyWith(isLoading: false);
} catch (e) {
state = state.copyWith(
isLoading: false,
error: e.toString(),
);
rethrow;
}
}
/// 更新用户信息
Future<void> updateProfile({
String? username,
String? email,
String? phone,
String? avatar,
}) async {
if (state.user == null) return;
state = state.copyWith(isLoading: true, error: null);
try {
// 模拟网络延迟
await Future.delayed(const Duration(milliseconds: 1000));
final updatedUser = state.user!.copyWith(
username: username ?? state.user!.username,
email: email ?? state.user!.email,
phone: phone ?? state.user!.phone,
avatar: avatar ?? state.user!.avatar,
updatedAt: DateTime.now(),
);
state = state.copyWith(
user: updatedUser,
isLoading: false,
);
} catch (e) {
state = state.copyWith(
isLoading: false,
error: e.toString(),
);
rethrow;
}
}
/// 修改密码
Future<void> changePassword({
required String currentPassword,
required String newPassword,
}) async {
state = state.copyWith(isLoading: true, error: null);
try {
// 模拟网络延迟
await Future.delayed(const Duration(milliseconds: 1000));
if (currentPassword.isEmpty || newPassword.isEmpty) {
throw Exception('当前密码和新密码不能为空');
}
if (newPassword.length < 6) {
throw Exception('新密码长度不能少于6位');
}
state = state.copyWith(isLoading: false);
} catch (e) {
state = state.copyWith(
isLoading: false,
error: e.toString(),
);
rethrow;
}
}
/// 清除错误
void clearError() {
state = state.copyWith(error: null);
}
}
/// 认证服务提供者
final authServiceProvider = Provider<AuthService>((ref) {
return AuthService(ApiClient.instance);
});
/// 存储服务提供者 - 改为同步Provider因为StorageService已在main中初始化
final storageServiceProvider = Provider<StorageService>((ref) {
// StorageService已经在main.dart中初始化直接获取实例
// 这里使用一个技巧通过Future.value包装已初始化的实例
throw UnimplementedError('Use storageServiceInstanceProvider instead');
});
/// 认证状态提供者 - 改为StateNotifierProvider以保持状态
final authProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) {
final authService = ref.watch(authServiceProvider);
// 直接使用已初始化的StorageService实例
final storageService = StorageService.instance;
return AuthNotifier(authService, storageService);
});
/// 是否已认证的提供者
final isAuthenticatedProvider = Provider<bool>((ref) {
return ref.watch(authProvider).isAuthenticated;
});
/// 当前用户提供者
final currentUserProvider = Provider<User?>((ref) {
return ref.watch(authProvider).user;
});