You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
4.4 KiB

import 'dart:developer';
import 'package:dio/dio.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:problem_check_system/data/models/auth_model.dart';
import 'package:problem_check_system/data/providers/connectivity_provider.dart';
import 'package:problem_check_system/data/providers/http_provider.dart';
class AuthRepository extends GetxService {
final HttpProvider httpProvider;
final GetStorage storage;
final ConnectivityProvider connectivityProvider;
AuthRepository({
required this.httpProvider,
required this.storage,
required this.connectivityProvider,
});
static const String _tokenKey = 'token';
static const String _refreshTokenKey = 'refresh_token';
static const String _loginKey = 'user';
static const String _rememberPassword = 'remember_password';
void saveToken(String token) {
storage.write(_tokenKey, token);
}
String? getToken() {
return storage.read(_tokenKey);
}
void saveRefreshToken(String refreshToken) {
storage.write(_refreshTokenKey, refreshToken);
}
String? getRefreshToken() {
return storage.read(_refreshTokenKey);
}
void addLoginKey(LoginRequest login) {
storage.write(_loginKey, login.toJson());
}
/// 登录请求
LoginRequest getLoginKey() {
final loginData = storage.read(_loginKey);
// 检查是否找到数据,并进行反序列化
if (loginData != null) {
// 确保类型正确,然后进行反序列化
return LoginRequest.fromJson(Map<String, dynamic>.from(loginData));
}
// 如果没有找到数据,返回一个默认的空对象
return LoginRequest(username: '', password: '');
}
void removeLoginKey() {
storage.remove(_loginKey);
}
void addRememberPassword(bool remembered) {
storage.write(_rememberPassword, remembered);
}
bool getRememberPassword() {
return storage.read(_rememberPassword);
}
void clearAuthData() {
storage.remove(_tokenKey);
storage.remove(_refreshTokenKey);
}
// 是否在线
bool get isOnline {
return connectivityProvider.isOnline.value;
}
/// Check if a user is currently logged in by verifying the existence of a token.
bool isLoggedIn() {
final token = getToken();
return token != null && token.isNotEmpty;
}
/// Handles the user login process by calling the API and saving the response.
Future<LoginResponse> login(LoginRequest request) async {
try {
final response = await httpProvider.post(
'/api/Accounts/SignIn',
data: request.toJson(),
);
final loginResponse = LoginResponse.fromJson(response.data);
return loginResponse;
} catch (e) {
throw Exception(e);
}
}
/// 从 API 获取用户个人资料
Future<Profile> getUserProfile() async {
try {
final response = await httpProvider.get('/api/Accounts/Profile');
// 将 JSON 数据反序列化为 Profile 模型
return Profile.fromJson(response.data);
} on DioException catch (e) {
// 专门处理网络错误,例如无网络连接、超时等
// DioException 包含了更详细的错误信息
throw Exception('Network error: ${e.message}');
} catch (e) {
// 捕获所有其他未知错误
rethrow; // 重新抛出异常,让调用者来处理
}
}
/// Refreshes the authentication token using the refresh token.
Future<LoginResponse> refreshToken() async {
final refreshToken = getRefreshToken();
if (refreshToken == null || refreshToken.isEmpty) {
throw Exception('没有可用的刷新token');
}
try {
final response = await httpProvider.post(
'/auth/refresh',
data: {'refresh_token': refreshToken},
);
final authResponse = LoginResponse.fromJson(response.data);
saveToken(authResponse.token);
saveRefreshToken(authResponse.refreshToken);
return authResponse;
} catch (e) {
throw Exception(e);
}
}
/// Logs the user out by calling the API and then clearing local data.
Future<void> logout() async {
try {
// Attempt to call the API, but even if it fails, continue to clear local data.
await httpProvider.post('/auth/logout');
} on DioException catch (e) {
log('退出登录API调用失败: ${e.message}');
} finally {
// Regardless of API success or failure, always clear local storage.
clearAuthData();
}
}
}