account_repository.dart 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import 'package:get/get.dart';
  2. import 'package:injectable/injectable.dart';
  3. import 'package:keyboard/data/api/atmob_api.dart';
  4. import '../../di/get_it.dart';
  5. import '../../utils/atmob_log.dart';
  6. import '../../utils/http_handler.dart';
  7. import '../../utils/mmkv_util.dart';
  8. import '../api/request/login_request.dart';
  9. import '../api/request/send_code_request.dart';
  10. import '../api/response/login_response.dart';
  11. import '../consts/error_code.dart';
  12. @lazySingleton
  13. class AccountRepository {
  14. final AtmobApi atmobApi;
  15. final String tag = "AccountRepository";
  16. static final String keyAccountLoginPhoneNum = 'key_account_login_phone_num';
  17. static final String keyAccountLoginToken = 'key_account_login_token';
  18. RxnString loginPhoneNum = RxnString();
  19. RxBool isLogin = RxBool(false);
  20. int? _lastRequestCodeTime;
  21. int _errorCodeTimes = 0;
  22. static String? token = KVUtil.getString(keyAccountLoginToken, null);
  23. AccountRepository(this.atmobApi) {
  24. AtmobLog.d(tag, '$tag....init');
  25. isLogin.bindStream(
  26. loginPhoneNum.map((value) {
  27. return value?.isNotEmpty == true;
  28. }),
  29. );
  30. loginPhoneNum.value = KVUtil.getString(keyAccountLoginPhoneNum, null);
  31. }
  32. // 检查是否在 60 秒内重复请求
  33. Future<void> loginSendCode(String phoneNum) {
  34. final currentTime = DateTime.now().millisecondsSinceEpoch;
  35. if (currentTime - (_lastRequestCodeTime ?? 0) < 60 * 1000) {
  36. throw RequestCodeTooOftenException();
  37. }
  38. return atmobApi
  39. .loginSendCode(SendCodeRequest(phoneNum))
  40. .then(HttpHandler.handle(true))
  41. .then((value) {
  42. _lastRequestCodeTime = currentTime;
  43. _errorCodeTimes = 0;
  44. });
  45. }
  46. Future<LoginResponse> loginUserLogin(
  47. String phoneNum,
  48. String verificationCode,
  49. ) {
  50. if (_errorCodeTimes >= 5) {
  51. throw LoginTooOftenException();
  52. }
  53. return atmobApi
  54. .loginUserLogin(LoginRequest(phoneNum, verificationCode))
  55. .then(HttpHandler.handle(true))
  56. .then((response) {
  57. _errorCodeTimes = 0;
  58. onLoginSuccess(phoneNum, response.authToken);
  59. return response;
  60. })
  61. .catchError((error) {
  62. if (error is ServerErrorException &&
  63. error.code == ErrorCode.verificationCodeError) {
  64. _errorCodeTimes++;
  65. }
  66. throw error;
  67. });
  68. }
  69. void onLoginSuccess(String phoneNum, String authToken) {
  70. AccountRepository.token = authToken;
  71. loginPhoneNum.value = phoneNum;
  72. KVUtil.putString(keyAccountLoginPhoneNum, phoneNum);
  73. KVUtil.putString(keyAccountLoginToken, authToken);
  74. }
  75. void logout() {
  76. token = null;
  77. KVUtil.putString(keyAccountLoginPhoneNum, null);
  78. KVUtil.putString(keyAccountLoginToken, null);
  79. loginPhoneNum.value = null;
  80. }
  81. static AccountRepository getInstance() {
  82. return getIt.get<AccountRepository>();
  83. }
  84. }
  85. class RequestCodeTooOftenException implements Exception {
  86. final String message;
  87. /// 可选的构造函数,支持自定义错误信息
  88. RequestCodeTooOftenException([this.message = '请求验证码过于频繁']);
  89. @override
  90. String toString() => message;
  91. }
  92. class LoginTooOftenException implements Exception {
  93. final String message;
  94. /// 可选的构造函数,支持自定义错误信息
  95. LoginTooOftenException([this.message = '登录过于频繁']);
  96. @override
  97. String toString() => message;
  98. }