import 'package:get/get.dart'; import 'package:injectable/injectable.dart'; import 'package:keyboard/data/api/atmob_api.dart'; import '../../di/get_it.dart'; import '../../utils/atmob_log.dart'; import '../../utils/http_handler.dart'; import '../../utils/mmkv_util.dart'; import '../api/request/login_request.dart'; import '../api/request/send_code_request.dart'; import '../api/response/login_response.dart'; import '../consts/error_code.dart'; @lazySingleton class AccountRepository { final AtmobApi atmobApi; final String tag = "AccountRepository"; static final String keyAccountLoginPhoneNum = 'key_account_login_phone_num'; static final String keyAccountLoginToken = 'key_account_login_token'; RxnString loginPhoneNum = RxnString(); RxBool isLogin = RxBool(false); int? _lastRequestCodeTime; int _errorCodeTimes = 0; static String? token = KVUtil.getString(keyAccountLoginToken, null); AccountRepository(this.atmobApi) { AtmobLog.d(tag, '$tag....init'); isLogin.bindStream( loginPhoneNum.map((value) { return value?.isNotEmpty == true; }), ); loginPhoneNum.value = KVUtil.getString(keyAccountLoginPhoneNum, null); } // 检查是否在 60 秒内重复请求 Future loginSendCode(String phoneNum) { final currentTime = DateTime.now().millisecondsSinceEpoch; if (currentTime - (_lastRequestCodeTime ?? 0) < 60 * 1000) { throw RequestCodeTooOftenException(); } return atmobApi .loginSendCode(SendCodeRequest(phoneNum)) .then(HttpHandler.handle(true)) .then((value) { _lastRequestCodeTime = currentTime; _errorCodeTimes = 0; }); } Future loginUserLogin( String phoneNum, String verificationCode, ) { if (_errorCodeTimes >= 5) { throw LoginTooOftenException(); } return atmobApi .loginUserLogin(LoginRequest(phoneNum, verificationCode)) .then(HttpHandler.handle(true)) .then((response) { _errorCodeTimes = 0; onLoginSuccess(phoneNum, response.authToken); return response; }) .catchError((error) { if (error is ServerErrorException && error.code == ErrorCode.verificationCodeError) { _errorCodeTimes++; } throw error; }); } void onLoginSuccess(String phoneNum, String authToken) { AccountRepository.token = authToken; loginPhoneNum.value = phoneNum; KVUtil.putString(keyAccountLoginPhoneNum, phoneNum); KVUtil.putString(keyAccountLoginToken, authToken); } void logout() { token = null; KVUtil.putString(keyAccountLoginPhoneNum, null); KVUtil.putString(keyAccountLoginToken, null); loginPhoneNum.value = null; } static AccountRepository getInstance() { return getIt.get(); } } class RequestCodeTooOftenException implements Exception { final String message; /// 可选的构造函数,支持自定义错误信息 RequestCodeTooOftenException([this.message = '请求验证码过于频繁']); @override String toString() => message; } class LoginTooOftenException implements Exception { final String message; /// 可选的构造函数,支持自定义错误信息 LoginTooOftenException([this.message = '登录过于频繁']); @override String toString() => message; }