Commit 6b980613 authored by DatHV's avatar DatHV
Browse files

update project structure

parent bfff9e47
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:mypoint_flutter_app/base/app_loading.dart';
import '../../base/app_navigator.dart';
import '../dio_http_service.dart';
import 'package:mypoint_flutter_app/shared/widgets/loading/app_loading.dart';
import '../../../app/routing/app_navigator.dart';
import '../error_mapper.dart';
import '../dio_http_service.dart';
class ExceptionInterceptor extends Interceptor {
static Completer<bool>? _currentRetryPrompt;
......
import 'dart:convert';
import 'dart:typed_data';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:mypoint_flutter_app/preference/data_preference.dart';
import 'package:mypoint_flutter_app/shared/preferences/data_preference.dart';
import 'package:uuid/uuid.dart';
class RequestInterceptor extends Interceptor {
......
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:mypoint_flutter_app/base/base_response_model.dart';
import '../configs/callbacks.dart';
import '../configs/constants.dart';
import 'package:mypoint_flutter_app/shared/widgets/base_view/base_response_model.dart';
import '../../app/config/callbacks.dart';
import '../../app/config/constants.dart';
enum Method { GET, POST, PUT, DELETE }
......
import 'dart:io';
import 'package:mypoint_flutter_app/configs/api_paths.dart';
import 'package:mypoint_flutter_app/base/base_response_model.dart';
import 'package:mypoint_flutter_app/configs/constants.dart';
import 'package:mypoint_flutter_app/extensions/string_extension.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client.dart';
import 'package:mypoint_flutter_app/preference/data_preference.dart';
import 'package:mypoint_flutter_app/screen/voucher/models/product_model.dart';
import '../configs/callbacks.dart';
import '../configs/device_info.dart';
import '../directional/directional_screen.dart';
import '../model/auth/biometric_register_response_model.dart';
import '../model/auth/login_token_response_model.dart';
import '../model/auth/profile_response_model.dart';
import '../preference/package_info.dart';
import '../screen/health_book/health_book_model.dart';
import '../screen/history_point/models/history_point_models.dart';
import '../screen/history_point/models/transaction_summary_by_date_model.dart';
import '../screen/register_campaign/model/verify_register_model.dart';
import '../screen/splash/models/update_response_model.dart';
import '../preference/point/header_home_model.dart';
import '../screen/bank_account_manager/bank_account_info_model.dart';
import '../screen/campaign7day/models/campaign_7day_info_model.dart';
import '../screen/campaign7day/models/campaign_7day_mission_model.dart';
import '../screen/campaign7day/models/campaign_7day_reward_model.dart';
import '../screen/daily_checkin/daily_checkin_models.dart';
import '../screen/device_manager/device_manager_model.dart';
import '../screen/electric_payment/models/customer_contract_object_model.dart';
import '../screen/electric_payment/models/electric_payment_response_model.dart';
import '../screen/flash_sale/models/flash_sale_category_model.dart';
import '../screen/flash_sale/models/flash_sale_detail_response.dart';
import '../screen/history_point_cashback/models/history_point_cashback_model.dart';
import '../screen/home/models/achievement_model.dart';
import '../screen/home/models/hover_data_model.dart';
import '../screen/home/models/main_section_config_model.dart';
import '../screen/home/models/pipi_detail_model.dart';
import '../screen/interested_categories/models/interested_categories_model.dart';
import '../screen/invite_friend_campaign/models/invite_friend_campaign_model.dart';
import '../screen/membership/models/membership_info_response.dart';
import '../screen/onboarding/model/check_phone_response_model.dart';
import '../screen/onboarding/model/onboarding_info_model.dart';
import '../screen/otp/model/create_otp_response_model.dart';
import '../screen/otp/model/otp_verify_response_model.dart';
import '../screen/popup_manager/popup_manager_model.dart';
import '../screen/quiz_campaign/quiz_campaign_model.dart';
import '../screen/register_campaign/model/registration_form_package_model.dart';
import '../screen/traffic_service/traffic_service_model.dart';
import '../screen/transaction/history/transaction_category_model.dart';
import '../screen/transaction/history/transaction_history_model.dart';
import '../screen/transaction/history/transaction_history_response_model.dart';
export 'api/affiliate_api.dart';
export 'api/website_api.dart';
export 'api/notification_api.dart';
export 'api/location_api.dart';
export 'api/product_api.dart';
import 'package:mypoint_flutter_app/app/config/api_paths.dart';
import 'package:mypoint_flutter_app/shared/widgets/base_view/base_response_model.dart';
import 'package:mypoint_flutter_app/app/config/constants.dart';
import 'package:mypoint_flutter_app/core/utils/extensions/string_extension.dart';
import 'package:mypoint_flutter_app/core/network/restful_api_client.dart';
import 'package:mypoint_flutter_app/shared/preferences/data_preference.dart';
import 'package:mypoint_flutter_app/features/voucher/models/product_model.dart';
import '../../app/config/callbacks.dart';
import '../services/device_info.dart';
import '../../shared/navigation/directional_screen.dart';
import '../../features/home/models/header_home_model.dart';
import '../../features/biometric/model/biometric_register_response_model.dart';
import '../../features/login/model/login_token_response_model.dart';
import '../../features/personal/model/profile_response_model.dart';
import '../services/package_info.dart';
import '../../features/health_book/health_book_model.dart';
import '../../features/history_point/models/history_point_models.dart';
import '../../features/history_point/models/transaction_summary_by_date_model.dart';
import '../../features/register_campaign/model/verify_register_model.dart';
import '../../features/splash/models/update_response_model.dart';
import '../../features/bank_account_manager/bank_account_info_model.dart';
import '../../features/campaign7day/models/campaign_7day_info_model.dart';
import '../../features/campaign7day/models/campaign_7day_mission_model.dart';
import '../../features/campaign7day/models/campaign_7day_reward_model.dart';
import '../../features/daily_checkin/daily_checkin_models.dart';
import '../../features/device_manager/device_manager_model.dart';
import '../../features/electric_payment/models/customer_contract_object_model.dart';
import '../../features/electric_payment/models/electric_payment_response_model.dart';
import '../../features/flash_sale/models/flash_sale_category_model.dart';
import '../../features/flash_sale/models/flash_sale_detail_response.dart';
import '../../features/history_point_cashback/models/history_point_cashback_model.dart';
import '../../features/achievement/model/achievement_model.dart';
import '../../features/home/models/hover_data_model.dart';
import '../../features/home/models/main_section_config_model.dart';
import '../../features/pipi/model/pipi_detail_model.dart';
import '../../features/interested_categories/models/interested_categories_model.dart';
import '../../features/invite_friend_campaign/models/invite_friend_campaign_model.dart';
import '../../features/membership/models/membership_info_response.dart';
import '../../features/onboarding/model/check_phone_response_model.dart';
import '../../features/onboarding/model/onboarding_info_model.dart';
import '../../features/otp/model/create_otp_response_model.dart';
import '../../features/otp/model/otp_verify_response_model.dart';
import '../../features/popup_manager/popup_manager_model.dart';
import '../../features/quiz_campaign/quiz_campaign_model.dart';
import '../../features/register_campaign/model/registration_form_package_model.dart';
import '../../features/traffic_service/traffic_service_model.dart';
import '../../features/transaction/history/transaction_category_model.dart';
import '../../features/transaction/history/transaction_history_model.dart';
import '../../features/transaction/history/transaction_history_response_model.dart';
extension RestfulAPIClientAllRequest on RestfulAPIClient {
Future<BaseResponseModel<UpdateResponseModel>> checkUpdateApp() async {
......@@ -65,12 +61,7 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
"version": version,
"build_number": buildNumber,
};
return requestNormal(
APIPaths.checkUpdate,
Method.POST,
body,
(data) => UpdateResponseModel.fromJson(data as Json),
);
return requestNormal(APIPaths.checkUpdate, Method.POST, body, (data) => UpdateResponseModel.fromJson(data as Json));
}
Future<BaseResponseModel<OnboardingInfoModel>> getOnboardingInfo() async {
......@@ -82,16 +73,10 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
);
}
Future<BaseResponseModel<CheckPhoneResponseModel>> checkPhoneNumber(
String phone,
) async {
Future<BaseResponseModel<CheckPhoneResponseModel>> checkPhoneNumber(String phone) async {
var deviceKey = await DeviceInfo.getDeviceId();
var key = "$phone+_=$deviceKey/*8854";
final body = {
"device_key": deviceKey,
"phone_number": phone,
"key": key.toSha256(),
};
final body = {"device_key": deviceKey, "phone_number": phone, "key": key.toSha256()};
return requestNormal(
APIPaths.checkPhoneNumber,
Method.POST,
......@@ -100,10 +85,7 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
);
}
Future<BaseResponseModel<OTPVerifyResponseModel>> verifyOTP(
String otp,
String mfaToken,
) async {
Future<BaseResponseModel<OTPVerifyResponseModel>> verifyOTP(String otp, String mfaToken) async {
final body = {"otp": otp, "mfaToken": mfaToken};
return requestNormal(
APIPaths.verifyOtpWithAction,
......@@ -113,9 +95,7 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
);
}
Future<BaseResponseModel<OTPResendResponseModel>> resendOTP(
String mfaToken,
) async {
Future<BaseResponseModel<OTPResendResponseModel>> resendOTP(String mfaToken) async {
final body = {"mfaToken": mfaToken};
return requestNormal(
APIPaths.retryOtpWithAction,
......@@ -125,8 +105,7 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
);
}
Future<BaseResponseModel<CreateOTPResponseModel>>
requestOtpDeleteAccount() async {
Future<BaseResponseModel<CreateOTPResponseModel>> requestOtpDeleteAccount() async {
return requestNormal(
APIPaths.otpDeleteAccountRequest,
Method.POST,
......@@ -135,39 +114,19 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
);
}
Future<BaseResponseModel<CreateOTPResponseModel>> verifyDeleteAccount(
String otp,
) async {
return requestNormal(
APIPaths.verifyDeleteAccount,
Method.POST,
{"otp": otp},
(data) => CreateOTPResponseModel.fromJson(data as Json),
);
Future<BaseResponseModel<CreateOTPResponseModel>> verifyDeleteAccount(String otp) async {
return requestNormal(APIPaths.verifyDeleteAccount, Method.POST, {
"otp": otp,
}, (data) => CreateOTPResponseModel.fromJson(data as Json));
}
Future<BaseResponseModel<EmptyCodable>> signup(
String phone,
String password,
) async {
Future<BaseResponseModel<EmptyCodable>> signup(String phone, String password) async {
var deviceKey = await DeviceInfo.getDeviceId();
final body = {
"username": phone,
"password": password.toSha256(),
"device_key": deviceKey,
};
return requestNormal(
APIPaths.signup,
Method.POST,
body,
(data) => EmptyCodable.fromJson(data as Json),
);
final body = {"username": phone, "password": password.toSha256(), "device_key": deviceKey};
return requestNormal(APIPaths.signup, Method.POST, body, (data) => EmptyCodable.fromJson(data as Json));
}
Future<BaseResponseModel<LoginTokenResponseModel>> login(
String phone,
String password,
) async {
Future<BaseResponseModel<LoginTokenResponseModel>> login(String phone, String password) async {
var deviceKey = await DeviceInfo.getDeviceId();
final body = {
"username": phone,
......@@ -175,37 +134,20 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
"device_key": deviceKey,
"workspace_code": "8854",
};
return requestNormal(
APIPaths.login,
Method.POST,
body,
(data) => LoginTokenResponseModel.fromJson(data as Json),
);
return requestNormal(APIPaths.login, Method.POST, body, (data) => LoginTokenResponseModel.fromJson(data as Json));
}
Future<BaseResponseModel<EmptyCodable>> logout() async {
var deviceKey = await DeviceInfo.getDeviceId();
var phone = DataPreference.instance.phone ?? "";
final body = {"username": phone, "device_key": deviceKey, "lang": "vi"};
return requestNormal(
APIPaths.logout,
Method.POST,
body,
(data) => EmptyCodable.fromJson(data as Json),
);
return requestNormal(APIPaths.logout, Method.POST, body, (data) => EmptyCodable.fromJson(data as Json));
}
Future<BaseResponseModel<LoginTokenResponseModel>> loginWithBiometric(
String phone,
) async {
Future<BaseResponseModel<LoginTokenResponseModel>> loginWithBiometric(String phone) async {
var deviceKey = await DeviceInfo.getDeviceId();
var bioToken = await DataPreference.instance.getBioToken(phone) ?? "";
final body = {
"username": phone,
"bioToken": bioToken,
"deviceKey": deviceKey,
"workspaceCode": "8854",
};
final body = {"username": phone, "bioToken": bioToken, "deviceKey": deviceKey, "workspaceCode": "8854"};
return requestNormal(
APIPaths.loginWithBiometric,
Method.POST,
......@@ -215,22 +157,13 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
}
Future<BaseResponseModel<ProfileResponseModel>> getUserProfile() async {
return requestNormal(
APIPaths.getUserInfo,
Method.GET,
{},
(data) => ProfileResponseModel.fromJson(data as Json),
);
return requestNormal(APIPaths.getUserInfo, Method.GET, {}, (data) => ProfileResponseModel.fromJson(data as Json));
}
Future<BaseResponseModel<TokenRefreshResponseModel>> refreshToken() async {
String? token = DataPreference.instance.token ?? "";
String? refreshToken = DataPreference.instance.refreshToken ?? "";
final body = {
"access_token_old": token,
"refresh_token": refreshToken,
'lang': 'vi',
};
final body = {"access_token_old": token, "refresh_token": refreshToken, 'lang': 'vi'};
return requestNormal(
APIPaths.refreshToken,
Method.POST,
......@@ -239,15 +172,8 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
);
}
Future<BaseResponseModel<CreateOTPResponseModel>> otpCreateNew(
String ownerId,
) async {
final body = {
"owner_id": ownerId,
"ttl": Constants.otpTtl,
"resend_after_second": Constants.otpTtl,
'lang': 'vi',
};
Future<BaseResponseModel<CreateOTPResponseModel>> otpCreateNew(String ownerId) async {
final body = {"owner_id": ownerId, "ttl": Constants.otpTtl, "resend_after_second": Constants.otpTtl, 'lang': 'vi'};
return requestNormal(
APIPaths.otpCreateNew,
Method.POST,
......@@ -276,10 +202,7 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
);
}
Future<BaseResponseModel<EmptyCodable>> accountPasswordReset(
String phone,
String password,
) async {
Future<BaseResponseModel<EmptyCodable>> accountPasswordReset(String phone, String password) async {
final body = {"login_name": phone, "password": password.toSha256()};
return requestNormal(
APIPaths.accountPasswordReset,
......@@ -289,16 +212,9 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
);
}
Future<BaseResponseModel<EmptyCodable>> accountPasswordChange(
String phone,
String password,
) async {
Future<BaseResponseModel<EmptyCodable>> accountPasswordChange(String phone, String password) async {
String? token = DataPreference.instance.token ?? "";
final body = {
"login_name": phone,
"password": password.toSha256(),
"access_token": token,
};
final body = {"login_name": phone, "password": password.toSha256(), "access_token": token};
return requestNormal(
APIPaths.accountPasswordChange,
Method.POST,
......@@ -307,16 +223,9 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
);
}
Future<BaseResponseModel<EmptyCodable>> accountLoginForPasswordChange(
String phone,
String password,
) async {
Future<BaseResponseModel<EmptyCodable>> accountLoginForPasswordChange(String phone, String password) async {
String? token = DataPreference.instance.token ?? "";
final body = {
"login_name": phone,
"password": password.toSha256(),
"access_token": token,
};
final body = {"login_name": phone, "password": password.toSha256(), "access_token": token};
return requestNormal(
APIPaths.accountLoginForPasswordChange,
Method.POST,
......@@ -325,8 +234,7 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
);
}
Future<BaseResponseModel<BiometricRegisterResponseModel>>
accountBioCredential() async {
Future<BaseResponseModel<BiometricRegisterResponseModel>> accountBioCredential() async {
var deviceKey = await DeviceInfo.getDeviceId();
final body = {"deviceKey": deviceKey};
return requestNormal(
......@@ -337,8 +245,7 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
);
}
Future<BaseResponseModel<BiometricRegisterResponseModel>>
registerBiometric() async {
Future<BaseResponseModel<BiometricRegisterResponseModel>> registerBiometric() async {
var deviceKey = await DeviceInfo.getDeviceId();
final body = {"deviceKey": deviceKey};
return requestNormal(
......@@ -353,35 +260,21 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
var deviceKey = await DeviceInfo.getDeviceId();
final path = "${APIPaths.unRegisterBiometric}/$deviceKey";
final body = {"deviceKey": deviceKey};
return requestNormal(
path,
Method.POST,
body,
(data) => EmptyCodable.fromJson(data as Json),
);
return requestNormal(path, Method.POST, body, (data) => EmptyCodable.fromJson(data as Json));
}
Future<BaseResponseModel<HeaderHomeModel>> getHomeHeaderData() async {
return requestNormal(
APIPaths.headerHome,
Method.GET,
{},
(data) => HeaderHomeModel.fromJson(data as Json),
);
return requestNormal(APIPaths.headerHome, Method.GET, {}, (data) => HeaderHomeModel.fromJson(data as Json));
}
Future<BaseResponseModel<RegistrationFormPackageModel>> getRegistrationForm(
String id,
) async {
Future<BaseResponseModel<RegistrationFormPackageModel>> getRegistrationForm(String id) async {
final path = APIPaths.getRegistrationForm.replaceAll("%@", id);
return requestNormal(path, Method.GET, {}, (data) {
return RegistrationFormPackageModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<TransactionHistoryModel>> getTransactionHistoryDetail(
String id,
) async {
Future<BaseResponseModel<TransactionHistoryModel>> getTransactionHistoryDetail(String id) async {
final path = APIPaths.getTransactionHistoryDetail.replaceAll("%@", id);
return requestNormal(path, Method.GET, {}, (data) {
return TransactionHistoryModel.fromJson(data as Json);
......@@ -396,20 +289,15 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
});
}
Future<BaseResponseModel<List<MainSectionConfigModel>>>
getSectionLayoutHome() async {
Future<BaseResponseModel<List<MainSectionConfigModel>>> getSectionLayoutHome() async {
return requestNormal(APIPaths.getSectionLayoutHome, Method.GET, {}, (data) {
final list = data as List<dynamic>;
return list.map((e) => MainSectionConfigModel.fromJson(e)).toList();
});
}
Future<BaseResponseModel<AchievementListResponse>> getAchievementList(
Json body,
) async {
return requestNormal(APIPaths.achievementGetList, Method.POST, body, (
data,
) {
Future<BaseResponseModel<AchievementListResponse>> getAchievementList(Json body) async {
return requestNormal(APIPaths.achievementGetList, Method.POST, body, (data) {
return AchievementListResponse.fromJson(data as Json);
});
}
......@@ -426,65 +314,47 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
});
}
Future<BaseResponseModel<EmptyCodable>> updateWorkerSiteProfile(
Json body,
) async {
Future<BaseResponseModel<EmptyCodable>> updateWorkerSiteProfile(Json body) async {
String? token = DataPreference.instance.token ?? "";
body["access_token"] = token;
return requestNormal(APIPaths.updateWorkerSiteProfile, Method.POST, body, (
data,
) {
return requestNormal(APIPaths.updateWorkerSiteProfile, Method.POST, body, (data) {
return EmptyCodable.fromJson(data as Json);
});
}
Future<BaseResponseModel<MembershipInfoResponse>>
getMembershipLevelInfo() async {
Future<BaseResponseModel<MembershipInfoResponse>> getMembershipLevelInfo() async {
String? token = DataPreference.instance.token ?? "";
final body = {"access_token": token, "lang": "vi"};
return requestNormal(APIPaths.getMembershipLevelInfo, Method.POST, body, (
data,
) {
return requestNormal(APIPaths.getMembershipLevelInfo, Method.POST, body, (data) {
return MembershipInfoResponse.fromJson(data as Json);
});
}
Future<BaseResponseModel<HistoryPointCashBackResponse>>
historyPointCashBackRequest(Json body) async {
Future<BaseResponseModel<HistoryPointCashBackResponse>> historyPointCashBackRequest(Json body) async {
String? token = DataPreference.instance.token ?? "";
body["access_token"] = token;
return requestNormal(APIPaths.historyCashBackPoint, Method.GET, body, (
data,
) {
return requestNormal(APIPaths.historyCashBackPoint, Method.GET, body, (data) {
return HistoryPointCashBackResponse.fromJson(data as Json);
});
}
Future<BaseResponseModel<InviteFriendDetailModel>>
getCampaignInviteFriend() async {
Future<BaseResponseModel<InviteFriendDetailModel>> getCampaignInviteFriend() async {
String? token = DataPreference.instance.token ?? "";
final body = {"access_token": token};
return requestNormal(APIPaths.campaignInviteFriend, Method.GET, body, (
data,
) {
return requestNormal(APIPaths.campaignInviteFriend, Method.GET, body, (data) {
return InviteFriendDetailModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<CampaignInviteFriendDetail>>
getDetailCampaignInviteFriend() async {
Future<BaseResponseModel<CampaignInviteFriendDetail>> getDetailCampaignInviteFriend() async {
String? token = DataPreference.instance.token ?? "";
final body = {"access_token": token};
return requestNormal(APIPaths.inviteFriendCampaigns, Method.GET, body, (
data,
) {
return requestNormal(APIPaths.inviteFriendCampaigns, Method.GET, body, (data) {
return CampaignInviteFriendDetail.fromJson(data as Json);
});
}
Future<BaseResponseModel<InviteFriendResponse>> phoneInviteFriend(
String phone,
) async {
Future<BaseResponseModel<InviteFriendResponse>> phoneInviteFriend(String phone) async {
String? token = DataPreference.instance.token ?? "";
final body = {"access_token": token, 'username': phone};
return requestNormal(APIPaths.phoneInviteFriend, Method.POST, body, (data) {
......@@ -495,9 +365,7 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
Future<BaseResponseModel<CheckInDataModel>> rewardOpportunityGetList() async {
String? token = DataPreference.instance.token ?? "";
final body = {"access_token": token, 'number_day': '7'};
return requestNormal(APIPaths.rewardOpportunityGetList, Method.POST, body, (
data,
) {
return requestNormal(APIPaths.rewardOpportunityGetList, Method.POST, body, (data) {
return CheckInDataModel.fromJson(data as Json);
});
}
......@@ -505,119 +373,79 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
Future<BaseResponseModel<SubmitCheckInData>> submitCheckIn() async {
String? token = DataPreference.instance.token ?? "";
final body = {"access_token": token};
return requestNormal(
APIPaths.rewardOpportunityOpenRequest,
Method.POST,
body,
(data) {
return SubmitCheckInData.fromJson(data as Json);
},
);
return requestNormal(APIPaths.rewardOpportunityOpenRequest, Method.POST, body, (data) {
return SubmitCheckInData.fromJson(data as Json);
});
}
Future<BaseResponseModel<TransactionHistoryResponse>>
getTransactionHistoryResponse(Json body) async {
return requestNormal(
APIPaths.getTransactionOrderHistory,
Method.GET,
body,
(data) {
return TransactionHistoryResponse.fromJson(data as Json);
},
);
Future<BaseResponseModel<TransactionHistoryResponse>> getTransactionHistoryResponse(Json body) async {
await Future.delayed(Duration(milliseconds: 3500));
return requestNormal(APIPaths.getTransactionOrderHistory, Method.GET, body, (data) {
return TransactionHistoryResponse.fromJson(data as Json);
});
}
Future<BaseResponseModel<List<TransactionCategoryModel>>>
getTransactionHistoryCategories() async {
return requestNormal(APIPaths.orderHistoryCategories, Method.GET, {}, (
data,
) {
Future<BaseResponseModel<List<TransactionCategoryModel>>> getTransactionHistoryCategories() async {
return requestNormal(APIPaths.orderHistoryCategories, Method.GET, {}, (data) {
final list = data as List<dynamic>;
return list.map((e) => TransactionCategoryModel.fromJson(e)).toList();
});
}
Future<BaseResponseModel<CustomerContractModel>>
customerContractRequestSearch(String maKH) async {
Future<BaseResponseModel<CustomerContractModel>> customerContractRequestSearch(String maKH) async {
String? token = DataPreference.instance.token ?? "";
final body = {"access_token": token, 'ma_khang': maKH};
return requestNormal(
APIPaths.customerContractRequestSearch,
Method.POST,
body,
(data) {
return CustomerContractModel.fromJson(data as Json);
},
);
return requestNormal(APIPaths.customerContractRequestSearch, Method.POST, body, (data) {
return CustomerContractModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<List<CustomerContractModel>>>
customerContractSearchHistoryGetList() async {
Future<BaseResponseModel<List<CustomerContractModel>>> customerContractSearchHistoryGetList() async {
String? token = DataPreference.instance.token ?? "";
final body = {"access_token": token};
return requestNormal(
APIPaths.customerContractSearchHistoryGetList,
Method.POST,
body,
(data) {
final list = data as List<dynamic>;
return list.map((e) => CustomerContractModel.fromJson(e)).toList();
},
);
return requestNormal(APIPaths.customerContractSearchHistoryGetList, Method.POST, body, (data) {
final list = data as List<dynamic>;
return list.map((e) => CustomerContractModel.fromJson(e)).toList();
});
}
Future<BaseResponseModel<bool>> customerContractDelete(String maKHs) async {
String? token = DataPreference.instance.token ?? "";
final body = {"access_token": token, 'ma_khang': maKHs};
return requestNormal(APIPaths.customerContractDelete, Method.POST, body, (
data,
) {
return requestNormal(APIPaths.customerContractDelete, Method.POST, body, (data) {
return data == true;
});
}
Future<BaseResponseModel<HealthBookResponseModel>> getHealthBookCards(
Json body,
) async {
Future<BaseResponseModel<HealthBookResponseModel>> getHealthBookCards(Json body) async {
return requestNormal(APIPaths.getHealthBookCards, Method.GET, body, (data) {
return HealthBookResponseModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<HealthBookCardItemModel>> getDetailHealthBookCard(
String id,
) async {
Future<BaseResponseModel<HealthBookCardItemModel>> getDetailHealthBookCard(String id) async {
final path = APIPaths.detailHealthBookCardDetail.replaceAll("%@", id);
return requestNormal(path, Method.GET, {}, (data) {
return HealthBookCardItemModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<TrafficServiceDetailModel>> getDetailMyPackageVnTra(
String id,
) async {
Future<BaseResponseModel<TrafficServiceDetailModel>> getDetailMyPackageVnTra(String id) async {
final path = APIPaths.detailMyPackageVnTra.replaceAll("%@", id);
return requestNormal(path, Method.GET, {}, (data) {
return TrafficServiceDetailModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<EmptyCodable>> submitPerformMission(
Campaign7DayMissionModel mission,
String id,
) async {
final path = APIPaths.submitCampaignMission
.replaceFirst('%@', id)
.replaceFirst('%@', mission.id.toString());
Future<BaseResponseModel<EmptyCodable>> submitPerformMission(Campaign7DayMissionModel mission, String id) async {
final path = APIPaths.submitCampaignMission.replaceFirst('%@', id).replaceFirst('%@', mission.id.toString());
return requestNormal(path, Method.POST, {}, (data) {
return EmptyCodable.fromJson(data as Json);
});
}
Future<BaseResponseModel<List<Campaign7DayRewardModel>>> getCampaignRewards(
String id,
) async {
Future<BaseResponseModel<List<Campaign7DayRewardModel>>> getCampaignRewards(String id) async {
final path = APIPaths.getCampaignReward.replaceFirst('%@', id);
return requestNormal(path, Method.GET, {}, (data) {
final list = data as List<dynamic>;
......@@ -625,9 +453,7 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
});
}
Future<BaseResponseModel<List<String>>> getCampaignLiveTransactions(
String id,
) async {
Future<BaseResponseModel<List<String>>> getCampaignLiveTransactions(String id) async {
final path = APIPaths.getCampaignLiveTransactions.replaceFirst('%@', id);
return requestNormal(path, Method.GET, {}, (data) {
if (data is List) {
......@@ -637,56 +463,40 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
});
}
Future<BaseResponseModel<Campaign7DayInfoModel>> getCampaignMissions(
String id,
) async {
Future<BaseResponseModel<Campaign7DayInfoModel>> getCampaignMissions(String id) async {
final path = APIPaths.getCampaignMissions.replaceFirst('%@', id);
return requestNormal(path, Method.GET, {}, (data) {
return Campaign7DayInfoModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<SurveyCampaignInfoModel>> getCampaignQuizSurvey(
String id,
) async {
Future<BaseResponseModel<SurveyCampaignInfoModel>> getCampaignQuizSurvey(String id) async {
final path = APIPaths.getQuizCampaign.replaceFirst('%@', id);
return requestNormal(path, Method.GET, {}, (data) {
return SurveyCampaignInfoModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<QuizCampaignSubmitResponseModel>> quizSubmitCampaign(
String id,
Json body,
) async {
Future<BaseResponseModel<QuizCampaignSubmitResponseModel>> quizSubmitCampaign(String id, Json body) async {
final path = APIPaths.quizSubmitCampaign.replaceFirst('%@', id);
return requestNormal(path, Method.POST, body, (data) {
return QuizCampaignSubmitResponseModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<List<FlashSaleCategoryModel>>>
getFlashSaleCategories(String groupId) async {
Future<BaseResponseModel<List<FlashSaleCategoryModel>>> getFlashSaleCategories(String groupId) async {
final path = APIPaths.getFlashSaleGroup.replaceFirst('%@', groupId);
return requestNormal(path, Method.GET, const {}, (data) {
if (data is List) {
return data
.whereType<Map<String, dynamic>>()
.map(FlashSaleCategoryModel.fromJson)
.toList();
return data.whereType<Map<String, dynamic>>().map(FlashSaleCategoryModel.fromJson).toList();
}
if (data is Map<String, dynamic>) {
final categories = data['categories'] ?? data['data'] ?? data['items'];
if (categories is List) {
return categories
.whereType<Map<String, dynamic>>()
.map(FlashSaleCategoryModel.fromJson)
.toList();
return categories.whereType<Map<String, dynamic>>().map(FlashSaleCategoryModel.fromJson).toList();
}
if (data.containsKey('_id')) {
return [
FlashSaleCategoryModel.fromJson(Map<String, dynamic>.from(data)),
];
return [FlashSaleCategoryModel.fromJson(Map<String, dynamic>.from(data))];
}
}
return <FlashSaleCategoryModel>[];
......@@ -700,11 +510,7 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
int? categoryId,
}) async {
final path = APIPaths.getFlashSaleDetail.replaceFirst('%@', groupId);
final params = <String, dynamic>{
'index': index,
'size': size,
if (categoryId != null) 'category_id': categoryId,
};
final params = <String, dynamic>{'index': index, 'size': size, if (categoryId != null) 'category_id': categoryId};
return requestNormal(path, Method.GET, params, (data) {
if (data is Map<String, dynamic>) {
return FlashSaleDetailResponse.fromJson(data);
......@@ -725,9 +531,7 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
});
}
Future<BaseResponseModel<DevicesLogoutListResponse>> getLogoutDevices(
Json body,
) async {
Future<BaseResponseModel<DevicesLogoutListResponse>> getLogoutDevices(Json body) async {
return requestNormal(APIPaths.getLogoutDevices, Method.GET, body, (data) {
return DevicesLogoutListResponse.fromJson(data as Json);
});
......@@ -738,43 +542,31 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
return requestNormal(path, Method.DELETE, {}, (data) => data as String);
}
Future<BaseResponseModel<InterestedCategoriesResponse>>
categoryTopLevelGetList() async {
Future<BaseResponseModel<InterestedCategoriesResponse>> categoryTopLevelGetList() async {
String? token = DataPreference.instance.token ?? "";
final body = {"access_token": token, "lang": "vi"};
return requestNormal(APIPaths.categoryTopLevelGetList, Method.POST, body, (
data,
) {
return requestNormal(APIPaths.categoryTopLevelGetList, Method.POST, body, (data) {
return InterestedCategoriesResponse.fromJson(data as Json);
});
}
Future<BaseResponseModel<EmptyCodable>> submitCategorySubscribe(
String code,
) async {
Future<BaseResponseModel<EmptyCodable>> submitCategorySubscribe(String code) async {
String? token = DataPreference.instance.token ?? "";
final body = {"access_token": token, 'category_codes': code};
return requestNormal(APIPaths.categorySubscribeList, Method.POST, body, (
data,
) {
return requestNormal(APIPaths.categorySubscribeList, Method.POST, body, (data) {
return EmptyCodable.fromJson(data as Json);
});
}
Future<BaseResponseModel<EmptyCodable>> submitCategoryUnsubscribeList(
String code,
) async {
Future<BaseResponseModel<EmptyCodable>> submitCategoryUnsubscribeList(String code) async {
String? token = DataPreference.instance.token ?? "";
final body = {"access_token": token, 'category_codes': code};
return requestNormal(APIPaths.categoryUnsubscribeList, Method.POST, body, (
data,
) {
return requestNormal(APIPaths.categoryUnsubscribeList, Method.POST, body, (data) {
return EmptyCodable.fromJson(data as Json);
});
}
Future<BaseResponseModel<ElectricPaymentResponseModel>>
customerEvnPaymentGatewayRequest(
Future<BaseResponseModel<ElectricPaymentResponseModel>> customerEvnPaymentGatewayRequest(
CustomerContractModel contract,
String paymentMethod,
) async {
......@@ -786,18 +578,12 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
'amount': contract.amount ?? 0,
'payment_method': paymentMethod,
};
return requestNormal(
APIPaths.customerEvnPaymentGatewayRequest,
Method.POST,
body,
(data) {
return ElectricPaymentResponseModel.fromJson(data as Json);
},
);
return requestNormal(APIPaths.customerEvnPaymentGatewayRequest, Method.POST, body, (data) {
return ElectricPaymentResponseModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<List<PopupManagerModel>>>
getPopupManagerCommonScreen() async {
Future<BaseResponseModel<List<PopupManagerModel>>> getPopupManagerCommonScreen() async {
String? token = DataPreference.instance.token ?? "";
final body = {"access_token": token, "lang": "vi"};
return requestNormal(APIPaths.getPopup, Method.POST, body, (data) {
......@@ -806,20 +592,14 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
});
}
Future<BaseResponseModel<List<BankAccountInfoModel>>>
getOrderPaymentMyAccounts() async {
return requestNormal(APIPaths.orderPaymentMyAccounts, Method.GET, {}, (
data,
) {
Future<BaseResponseModel<List<BankAccountInfoModel>>> getOrderPaymentMyAccounts() async {
return requestNormal(APIPaths.orderPaymentMyAccounts, Method.GET, {}, (data) {
final list = data as List<dynamic>;
return list.map((e) => BankAccountInfoModel.fromJson(e)).toList();
});
}
Future<BaseResponseModel<String>> setDefaultBankAccount(
String id,
bool isDefault,
) async {
Future<BaseResponseModel<String>> setDefaultBankAccount(String id, bool isDefault) async {
final path = APIPaths.bankAccountSetDefault.replaceFirst('%@', id);
final body = {"is_default": isDefault ? 1 : 0};
return requestNormal(path, Method.POST, body, (data) => data as String);
......@@ -830,47 +610,30 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
return requestNormal(path, Method.DELETE, {}, (data) => data as String);
}
Future<BaseResponseModel<TransactionSummaryByDateModel>>
transactionGetSummaryByDate(Json body) async {
Future<BaseResponseModel<TransactionSummaryByDateModel>> transactionGetSummaryByDate(Json body) async {
String? token = DataPreference.instance.token ?? "";
body["access_token"] = token;
return requestNormal(
APIPaths.transactionGetSummaryByDate,
Method.POST,
body,
(data) {
return TransactionSummaryByDateModel.fromJson(data as Json);
},
);
return requestNormal(APIPaths.transactionGetSummaryByDate, Method.POST, body, (data) {
return TransactionSummaryByDateModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<ListHistoryResponseModel>> transactionHistoryGetList(
Json body,
) async {
Future<BaseResponseModel<ListHistoryResponseModel>> transactionHistoryGetList(Json body) async {
String? token = DataPreference.instance.token ?? "";
body["access_token"] = token;
return requestNormal(
APIPaths.transactionHistoryGetList,
Method.POST,
body,
(data) {
return ListHistoryResponseModel.fromJson(data as Json);
},
);
return requestNormal(APIPaths.transactionHistoryGetList, Method.POST, body, (data) {
return ListHistoryResponseModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<DirectionalScreen>> getDirectionOfflineBrand(
String id,
) async {
Future<BaseResponseModel<DirectionalScreen>> getDirectionOfflineBrand(String id) async {
final body = {"bank_account": id};
return requestNormal(APIPaths.getOfflineBrand, Method.GET, body, (data) {
return DirectionalScreen.fromJson(data as Json);
});
}
Future<BaseResponseModel<EmptyCodable>> pushNotificationDeviceUpdateToken(
String token,
) async {
Future<BaseResponseModel<EmptyCodable>> pushNotificationDeviceUpdateToken(String token) async {
var deviceKey = await DeviceInfo.getDeviceId();
final details = await DeviceInfo.getDetails();
String? accessToken = DataPreference.instance.token ?? "";
......@@ -881,53 +644,35 @@ extension RestfulAPIClientAllRequest on RestfulAPIClient {
body["lang"] = 'vi';
body["software_type"] = "Application";
body["software_model"] = "MyPoint";
return requestNormal(
APIPaths.pushNotificationDeviceUpdateToken,
Method.POST,
body,
(data) {
return EmptyCodable.fromJson(data as Json);
},
);
return requestNormal(APIPaths.pushNotificationDeviceUpdateToken, Method.POST, body, (data) {
return EmptyCodable.fromJson(data as Json);
});
}
Future<BaseResponseModel<DirectionalScreen>> getDirectionScreen(
String path,
) async {
Future<BaseResponseModel<DirectionalScreen>> getDirectionScreen(String path) async {
var path_ = path.startsWith('/') ? path : '/$path';
return requestNormal(path_, Method.GET, {}, (data) {
return DirectionalScreen.fromJson(data as Json);
});
}
Future<BaseResponseModel<EmptyCodable>> submitShareContent(
String path,
) async {
Future<BaseResponseModel<EmptyCodable>> submitShareContent(String path) async {
var path_ = path.startsWith('/') ? path : '/$path';
return requestNormal(path_, Method.GET, {}, (data) {
return EmptyCodable.fromJson(data as Json);
});
}
Future<BaseResponseModel<VerifyRegisterCampaignModel>> verifyRegisterForm(
String path,
Json body,
) async {
Future<BaseResponseModel<VerifyRegisterCampaignModel>> verifyRegisterForm(String path, Json body) async {
var path_ = path.startsWith('/') ? path : '/$path';
return requestNormal(path_, Method.POST, body, (data) {
return VerifyRegisterCampaignModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<SubmitViewVoucherCompletedResponse>>
submitCampaignViewVoucherComplete() async {
return requestNormal(
APIPaths.submitCampaignViewVoucherComplete,
Method.POST,
{},
(data) {
return SubmitViewVoucherCompletedResponse.fromJson(data as Json);
},
);
Future<BaseResponseModel<SubmitViewVoucherCompletedResponse>> submitCampaignViewVoucherComplete() async {
return requestNormal(APIPaths.submitCampaignViewVoucherComplete, Method.POST, {}, (data) {
return SubmitViewVoucherCompletedResponse.fromJson(data as Json);
});
}
}
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client.dart';
import '../base/base_response_model.dart';
import '../base/base_view_model.dart';
import '../configs/constants.dart';
import '../base/app_navigator.dart';
import 'package:mypoint_flutter_app/core/network/restful_api_client.dart';
import '../../shared/widgets/base_view/base_response_model.dart';
import '../../shared/widgets/base_view/base_view_model.dart';
import '../../app/config/constants.dart';
import '../../app/routing/app_navigator.dart';
import 'interceptor/network_error_gate.dart';
import 'dio_extra_keys.dart';
import 'dio_http_service.dart';
import 'error_mapper.dart';
import 'interceptor/network_error_gate.dart';
typedef ApiCall<T> = Future<BaseResponseModel<T>> Function();
typedef OnSuccess<T> =
......@@ -33,9 +33,11 @@ class RestfulApiViewModel extends BaseViewModel {
OnComplete? onComplete,
bool showAppNavigatorDialog = false,
bool withLoading = true,
bool trackLoading = true,
String defaultError = ErrorCodes.commonError,
}) async {
if (withLoading) showLoading();
if (trackLoading) beginTrackedLoading();
BaseResponseModel<T>? res;
try {
res = await request();
......@@ -86,6 +88,7 @@ class RestfulApiViewModel extends BaseViewModel {
}
} finally {
if (withLoading) hideLoading();
if (trackLoading) endTrackedLoading();
onComplete?.call();
}
}
......
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:local_auth/local_auth.dart';
import '../resources/base_color.dart';
import '../widgets/alert/custom_alert_dialog.dart';
import '../widgets/alert/data_alert_model.dart';
import '../theme/base_color.dart';
import '../../shared/widgets/alert/custom_alert_dialog.dart';
import '../../shared/widgets/alert/data_alert_model.dart';
enum BiometricTypeEnum {
none,
......
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter_branch_sdk/flutter_branch_sdk.dart';
import 'package:mypoint_flutter_app/extensions/string_extension.dart';
import 'package:mypoint_flutter_app/core/utils/extensions/string_extension.dart';
import 'package:uni_links/uni_links.dart';
import 'package:mypoint_flutter_app/directional/directional_screen.dart';
import 'package:mypoint_flutter_app/extensions/crypto.dart' as mycrypto;
import '../directional/directional_action_type.dart';
import 'package:mypoint_flutter_app/shared/navigation/directional_screen.dart';
import 'package:mypoint_flutter_app/core/utils/crypto.dart' as mycrypto;
import '../../app/routing/directional_action_type.dart';
class DeepLinkService {
DeepLinkService._internal();
......@@ -17,6 +17,7 @@ class DeepLinkService {
bool _initialized = false;
Future<void> initialize() async {
if (kIsWeb) return;
if (_initialized) return;
_initialized = true;
debugPrint('🔗 Initializing DeepLinkService...');
......@@ -57,6 +58,10 @@ class DeepLinkService {
} catch (_) {}
}
bool handleIncomingUri(String uri) {
return _routeFromUriString(uri) ?? false;
}
void _listenLinkStream() {
try {
_linkSub = linkStream.listen((uri) {
......@@ -67,10 +72,10 @@ class DeepLinkService {
}
// Firebase Dynamic Links removed due to version constraints.
void _routeFromUriString(String uriStr) {
bool? _routeFromUriString(String uriStr) {
debugPrint('🔗 Deep link received: $uriStr');
final uri = Uri.tryParse(uriStr);
if (uri == null) return;
if (uri == null) return false;
final type = uri.queryParameters[Defines.actionType] ?? uri.queryParameters['action_type'];
final param = uri.queryParameters[Defines.actionParams] ?? uri.queryParameters['action_param'];
......@@ -91,13 +96,12 @@ class DeepLinkService {
direction?.extraData = {
'password': param,
};
direction?.begin();
return; // Use if you need to attach to userInfo later
return direction?.begin(); // Use if you need to attach to userInfo later
}
}
}
final screen = DirectionalScreen.build(clickActionType: type, clickActionParam: param);
screen?.begin();
return screen?.begin();
}
void _handleBranchSession(Map<dynamic, dynamic> data) {
......
import 'package:flutter/foundation.dart';
import 'package:mypoint_flutter_app/base/base_response_model.dart';
import 'package:mypoint_flutter_app/configs/constants.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import 'package:mypoint_flutter_app/preference/data_preference.dart';
import 'package:mypoint_flutter_app/shared/widgets/base_view/base_response_model.dart';
import 'package:mypoint_flutter_app/app/config/constants.dart';
import 'package:mypoint_flutter_app/core/network/restful_api_client_all_request.dart';
import 'package:mypoint_flutter_app/shared/preferences/data_preference.dart';
import '../firebase/push_token_service.dart';
import '../model/auth/login_token_response_model.dart';
import '../networking/restful_api_viewmodel.dart';
import '../../features/login/model/login_token_response_model.dart';
import '../network/restful_api_viewmodel.dart';
/// Login result enum để handle các trạng thái khác nhau
enum LoginResult {
......@@ -43,15 +43,12 @@ class LoginService extends RestfulApiViewModel {
try {
// Step 1: Authenticate user
final authResponse = await client.login(phone, password);
if (!authResponse.isSuccess || authResponse.data == null) {
debugPrint('Login failed: ${authResponse.errorMessage}');
return _handleAuthError(authResponse);
}
// Step 2: Save token
await DataPreference.instance.saveLoginToken(authResponse.data!);
// Step 3: Get user profile (critical step)
final profileResult = await _getUserProfileWithRetry();
if (profileResult.result != LoginResult.success) {
......@@ -62,16 +59,13 @@ class LoginService extends RestfulApiViewModel {
message: profileResult.message ?? Constants.commonError,
);
}
// Step 4: Upload FCM token (non-critical, don't fail login if this fails)
await _uploadFCMTokenSafely();
return LoginResponse(result: LoginResult.success);
} catch (e) {
return LoginResponse(
result: LoginResult.networkError,
message: 'Đăng nhập thất bại: ${e.toString()}',
message: ErrorCodes.commonError,
);
}
}
......@@ -120,12 +114,10 @@ class LoginService extends RestfulApiViewModel {
for (int attempt = 1; attempt <= maxRetries; attempt++) {
try {
final response = await client.getUserProfile();
if (response.isSuccess && response.data != null) {
await DataPreference.instance.saveUserProfile(response.data!);
return LoginResponse(result: LoginResult.success);
}
// If not last attempt, wait before retry
if (attempt < maxRetries) {
await Future.delayed(Duration(seconds: attempt * 2));
......@@ -134,16 +126,16 @@ class LoginService extends RestfulApiViewModel {
if (attempt == maxRetries) {
return LoginResponse(
result: LoginResult.networkError,
message: 'Không thể tải thông tin người dùng: ${e.toString()}',
message: ErrorCodes.commonError,
);
}
await Future.delayed(Duration(seconds: attempt * 2));
}
}
debugPrint('Failed to fetch user profile after $maxRetries attempts');
return LoginResponse(
result: LoginResult.networkError,
message: 'Không thể tải thông tin người dùng sau $maxRetries lần thử',
message: ErrorCodes.commonError,
);
}
......@@ -161,13 +153,10 @@ class LoginService extends RestfulApiViewModel {
Future<LoginResponse> biometricLogin(String phone) async {
try {
final response = await client.loginWithBiometric(phone);
if (!response.isSuccess || response.data == null) {
return _handleAuthError(response);
}
await DataPreference.instance.saveLoginToken(response.data!);
final profileResult = await _getUserProfileWithRetry();
if (profileResult.result != LoginResult.success) {
await DataPreference.instance.clearLoginToken();
......@@ -176,14 +165,12 @@ class LoginService extends RestfulApiViewModel {
message: profileResult.message ?? Constants.commonError,
);
}
await _uploadFCMTokenSafely();
return LoginResponse(result: LoginResult.success);
} catch (e) {
return LoginResponse(
result: LoginResult.networkError,
message: 'Đăng nhập sinh trắc thất bại: ${e.toString()}',
message: ErrorCodes.commonError,
);
}
}
......
import 'package:flutter/foundation.dart';
import '../networking/dio_http_service.dart';
import '../networking/restful_api_client.dart';
import '../networking/restful_api_client_all_request.dart';
import '../preference/data_preference.dart';
import '../network/dio_http_service.dart';
import '../network/restful_api_client.dart';
import '../network/restful_api_client_all_request.dart';
import '../../shared/preferences/data_preference.dart';
class LogoutService {
LogoutService._();
......
import 'package:flutter/widgets.dart';
import 'package:mypoint_flutter_app/extensions/string_extension.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import '../configs/constants.dart';
import '../model/auth/login_token_response_model.dart';
import '../networking/restful_api_viewmodel.dart';
import '../preference/data_preference.dart';
import '../base/app_navigator.dart';
import 'package:mypoint_flutter_app/core/utils/extensions/string_extension.dart';
import 'package:mypoint_flutter_app/core/network/restful_api_client_all_request.dart';
import '../../app/config/constants.dart';
import '../../features/login/model/login_token_response_model.dart';
import '../network/restful_api_viewmodel.dart';
import '../../shared/preferences/data_preference.dart';
import '../../app/routing/app_navigator.dart';
class TokenRefreshService extends RestfulApiViewModel {
static final TokenRefreshService _instance = TokenRefreshService._internal();
......
......@@ -41,6 +41,10 @@ void webResetSDK() {
// no-op on non-web
}
void webNotifySplashScreenReady() {
// no-op on non-web
}
Future<dynamic> webConfigUIApp(Map<String, dynamic> config) async {
return null;
}
......
// Web-specific implementations for x-app-sdk
import 'dart:html' as html;
import 'package:flutter/foundation.dart';
import 'x_app_sdk_service.dart';
......@@ -81,6 +82,14 @@ void webResetSDK() {
}
}
void webNotifySplashScreenReady() {
try {
html.window.dispatchEvent(html.CustomEvent('mypoint-splash-ready'));
} catch (e) {
debugPrint('❌ Error notifying splash readiness: $e');
}
}
Future<dynamic> webConfigUIApp(Map<String, dynamic> config) async {
try {
return await XAppSDKService().configUIApp(config);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment