| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- import 'dart:async';
- import 'package:get/get.dart';
- import 'package:injectable/injectable.dart';
- import 'package:location/base/app_base_request.dart';
- import 'package:location/data/api/atmob_api.dart';
- import 'package:location/data/api/request/login_request.dart';
- import 'package:location/data/api/request/send_code_request.dart';
- import 'package:location/data/bean/location_info.dart';
- import 'package:location/data/bean/member_status_info.dart';
- import 'package:location/data/bean/user_info.dart';
- import 'package:location/data/consts/constants.dart';
- import 'package:location/data/consts/error_code.dart';
- import 'package:location/data/repositories/friends_repository.dart';
- import 'package:location/data/repositories/message_repository.dart';
- import 'package:location/data/repositories/phone_event_repository.dart';
- import 'package:location/data/repositories/urgent_contact_repository.dart';
- import 'package:location/di/get_it.dart';
- import 'package:location/module/main/today_track_helper.dart';
- import 'package:location/push_notification/ios_push_notification_service.dart';
- import 'package:location/resource/string.gen.dart';
- import 'package:location/sdk/gravity/gravity_helper.dart';
- import 'package:location/socket/atmob_location_client.dart';
- import 'package:location/utils/async_util.dart';
- import 'package:location/utils/atmob_log.dart';
- import 'package:location/utils/http_handler.dart';
- import 'package:location/utils/mmkv_util.dart';
- import '../../sdk/map/map_helper.dart';
- import '../api/request/notification_report_request.dart';
- import '../api/request/one_click_login_request.dart';
- import '../api/request/user_avatar_update_request.dart';
- import '../api/response/login_response.dart';
- import '../api/response/member_status_response.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';
- static final String keyAccountLoginUserId = 'key_account_login_user_id';
- RxnString loginPhoneNum = RxnString();
- RxBool isLogin = RxBool(false);
- Rxn<MemberStatusInfo> memberStatusInfo = Rxn<MemberStatusInfo>();
- int? _lastRequestCodeTime;
- int _errorCodeTimes = 0;
- Timer? refreshMemberHandler;
- CancelableFuture? memberStatusFuture;
- static String? token = KVUtil.getString(keyAccountLoginToken, null);
- late final FriendsRepository friendsRepository;
- late final MessageRepository messageRepository;
- late final UrgentContactRepository urgentContactRepository;
- late final PhoneEventRepository phoneEventRepository;
- final Rx<UserInfo> mineUserInfo = Rx<UserInfo>(UserInfo(
- id: Constants.mineLocationId,
- phoneNumber: "我",
- isMine: true));
- AccountRepository(this.atmobApi) {
- AtmobLog.d(tag, '$tag....init');
- friendsRepository = FriendsRepository.getInstance();
- messageRepository = MessageRepository.getInstance();
- urgentContactRepository = UrgentContactRepository.getInstance();
- phoneEventRepository = PhoneEventRepository.getInstance();
- isLogin.bindStream(
- loginPhoneNum.map((value) {
- return value?.isNotEmpty == true;
- }),
- );
- loginPhoneNum.value = KVUtil.getString(keyAccountLoginPhoneNum, null);
- refreshMemberStatus();
- MapHelper.addLocationListener((location) {
- mineUserInfo.value.lastLocation.value =
- LocationInfo.fromMapLocation(location);
- });
- }
- static AccountRepository getInstance() {
- return getIt.get<AccountRepository>();
- }
- Future<void> loginSendCode(String phoneNum) {
- final currentTime = DateTime.now().millisecondsSinceEpoch;
- // 检查是否在 60 秒内重复请求
- if (currentTime - (_lastRequestCodeTime ?? 0) < 60 * 1000) {
- throw RequestCodeTooOftenException();
- }
- return atmobApi
- .loginSendCode(SendCodeRequest(phoneNum))
- .then(HttpHandler.handle(true))
- .then((value) {
- _lastRequestCodeTime = currentTime;
- _errorCodeTimes = 0;
- });
- }
- Future<LoginResponse> loginUserLogin(
- String phoneNum, String verificationCode) {
- if (_errorCodeTimes >= 5) {
- return Future.error(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);
- AtmobLocationClient.connectWebSocket();
- refreshMemberStatus();
- friendsRepository.refreshFriends();
- messageRepository.refreshFriendWaitingCount();
- messageRepository.refreshUnreadMessage();
- urgentContactRepository.requestUrgentContactList();
- //上传推送token
- onRequestNotificationReport();
- //上报事件
- phoneEventRepository.startReportPhoneEvent();
- TodayTrackHelper.getInstance().clear();
- GravityHelper.onLogin();
- }
- void logout() {
- token = null;
- refreshMemberHandler?.cancel();
- AtmobLocationClient.disConnectWebSocket();
- KVUtil.putString(keyAccountLoginPhoneNum, null);
- KVUtil.putString(keyAccountLoginToken, null);
- KVUtil.putString(keyAccountLoginUserId, null);
- KVUtil.putString(Constants.keyLastSelectFriendId, null);
- loginPhoneNum.value = null;
- memberStatusInfo.value = null;
- friendsRepository.clearFriends();
- messageRepository.clearMessage();
- urgentContactRepository.clearContactList();
- phoneEventRepository.stopReportPhoneEvent();
- GravityHelper.onLogout();
- }
- void refreshMemberStatus() {
- memberStatusFuture?.cancel();
- memberStatusFuture = AsyncUtil.retryWithExponentialBackoff(
- () => getMemberStatus(), 10, predicate: (error) {
- if (error is ServerErrorException) {
- return error.code != ErrorCode.noLoginError;
- }
- return true;
- });
- memberStatusFuture?.then((data) {
- AtmobLog.d(tag, "getMemberStatus success: ${memberStatusInfo.value}");
- }).catchError((error) {
- AtmobLog.e(tag, "getMemberStatus error: $error");
- });
- }
- Future<MemberStatusResponse> getMemberStatus() {
- return atmobApi
- .getMemberStatus(AppBaseRequest())
- .then(HttpHandler.handle(false))
- .then((response) {
- refreshMemberHandler?.cancel();
- updateAvatar(response.avatar);
- KVUtil.putString(keyAccountLoginUserId, response.deviceId);
- if (!response.permanent && !response.expired) {
- refreshMemberHandler = Timer(
- Duration(
- milliseconds: response.endTimestamp - response.serverTimestamp),
- () => refreshMemberStatus());
- }
- return response;
- }).then((response) {
- MemberStatusInfo memberStatusInfo = MemberStatusInfo(
- level: response.level,
- endTimestamp: response.endTimestamp,
- expired: response.expired,
- permanent: response.permanent,
- trialed: response.trialed,
- avatar: response.avatar,
- trialEndTimestamp: response.trialEndTimestamp);
- this.memberStatusInfo.value = memberStatusInfo;
- return response;
- });
- }
- void updateAvatar(String? avatar) {
- mineUserInfo.value.avatar = avatar;
- mineUserInfo.refresh();
- }
- Future<bool> userAvatarUpdate(String avatar) {
- if (avatar == mineUserInfo.value.avatar) {
- return Future.value(true);
- }
- return atmobApi
- .userAvatarUpdate(UserAvatarUpdateRequest(avatar))
- .then(HttpHandler.handle(true))
- .then((_) {
- updateAvatar(avatar);
- AtmobLog.d(tag, "userAvatarUpdate success: $avatar");
- return true;
- });
- }
- Future<void> oneClickLogin(
- {required String token, required String accessToken}) {
- return atmobApi
- .oneClickLogin(OneClickLoginRequest(token, accessToken))
- .then(HttpHandler.handle(false))
- .then((response) {
- onLoginSuccess(response.phone ?? '', response.authToken);
- });
- }
- bool memberIsExpired() {
- return memberStatusInfo.value == null ||
- memberStatusInfo.value?.expired == true;
- }
- Future<void> userClear() {
- return atmobApi.userClear(AppBaseRequest()).then(HttpHandler.handle(true));
- }
- ///请求推送的数据
- Future<void> onRequestNotificationReport() async {
- // 初始化推送服务
- var tokenStr = await IosPushNotificationService.getDeviceToken();
- print("tokenStrsfsdf---${tokenStr}");
- return atmobApi
- .notificationReport(
- NotificationReportRequest(deviceToken: tokenStr as String))
- .then(HttpHandler.handle(false))
- .then((response) {})
- .catchError((_) {});
- }
- }
- 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;
- }
|