Commit a6797435 authored by DatHV's avatar DatHV
Browse files

refactor print, log, request

parent f0334970
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:mypoint_flutter_app/base/app_navigator.dart'; import 'package:mypoint_flutter_app/base/app_navigator.dart';
import 'package:mypoint_flutter_app/resources/base_color.dart'; import 'package:mypoint_flutter_app/resources/base_color.dart';
...@@ -40,14 +39,6 @@ class MyApp extends StatelessWidget { ...@@ -40,14 +39,6 @@ class MyApp extends StatelessWidget {
primaryColor: BaseColor.primary500, primaryColor: BaseColor.primary500,
), ),
locale: const Locale('vi'), locale: const Locale('vi'),
supportedLocales: const [
Locale('vi', 'VN'), // Vietnamese
],
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
home: SplashScreen(), home: SplashScreen(),
getPages: RouterPage.pages(), getPages: RouterPage.pages(),
); );
......
import 'package:mypoint_flutter_app/base/base_response_model.dart';
import 'package:mypoint_flutter_app/configs/api_paths.dart';
import 'package:mypoint_flutter_app/configs/callbacks.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client.dart';
import 'package:mypoint_flutter_app/preference/data_preference.dart';
import '../../screen/affiliate/model/affiliate_brand_model.dart';
import '../../screen/affiliate/model/affiliate_category_model.dart';
import '../../screen/affiliate/model/affiliate_product_top_sale_model.dart';
import '../../screen/affiliate/model/cashback_overview_model.dart';
import '../../screen/affiliate_brand_detail/models/affiliate_brand_detail_model.dart';
class AffiliateApi {
AffiliateApi(this.client);
final RestfulAPIClient client;
Future<BaseResponseModel<List<AffiliateCategoryModel>>>
affiliateCategoryGetList() async {
final token = DataPreference.instance.token ?? "";
final body = {"access_token": token};
return client.requestNormal(
APIPaths.affiliateCategoryGetList,
Method.POST,
body,
(data) {
final list = data as List<dynamic>;
return list.map((e) => AffiliateCategoryModel.fromJson(e)).toList();
},
);
}
Future<BaseResponseModel<List<AffiliateBrandModel>>> affiliateBrandGetList({
String? categoryCode,
}) async {
final token = DataPreference.instance.token ?? "";
final body = {"access_token": token};
if ((categoryCode ?? '').isNotEmpty) {
body['category_code'] = categoryCode!;
}
return client.requestNormal(
APIPaths.affiliateBrandGetList,
Method.POST,
body,
(data) {
final list = data as List<dynamic>;
return list.map((e) => AffiliateBrandModel.fromJson(e)).toList();
},
);
}
Future<BaseResponseModel<List<AffiliateProductTopSaleModel>>>
affiliateProductTopSale() async {
final token = DataPreference.instance.token ?? "";
final body = {"access_token": token};
return client.requestNormal(
APIPaths.affiliateProductTopSale,
Method.POST,
body,
(data) {
final list = data as List<dynamic>;
return list
.map((e) => AffiliateProductTopSaleModel.fromJson(e))
.toList();
},
);
}
Future<BaseResponseModel<CashbackOverviewModel>> getCashBackOverview() async {
return client.requestNormal(APIPaths.getCashbackOverview, Method.GET, {}, (
data,
) {
return CashbackOverviewModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<AffiliateBrandDetailModel>> getAffiliateBrandDetail(
String brandId,
) async {
final token = DataPreference.instance.token ?? "";
final body = {"access_token": token, "brand_id": brandId};
return client.requestNormal(
APIPaths.affiliateBrandGetDetail,
Method.POST,
body,
(data) {
return AffiliateBrandDetailModel.fromJson(data as Json);
},
);
}
}
import '../../base/base_response_model.dart';
import '../../configs/api_paths.dart';
import '../../configs/callbacks.dart';
import '../restful_api_client.dart';
import '../../screen/game/models/game_bundle_item_model.dart';
import '../../screen/game/models/game_bundle_response.dart';
class GameApi {
GameApi(this.client);
final RestfulAPIClient client;
Future<BaseResponseModel<GameBundleResponse>> getGames() {
return client.requestNormal(
APIPaths.getGames,
Method.GET,
const {},
(data) => GameBundleResponse.fromJson(data as Json),
);
}
Future<BaseResponseModel<GameBundleItemModel>> getGameDetail(String id) {
final path = APIPaths.getGameDetail.replaceAll('%@', id);
return client.requestNormal(
path,
Method.POST,
const {},
(data) => GameBundleItemModel.fromJson(data as Json),
);
}
Future<BaseResponseModel<GameBundleItemModel>> submitGameCard(
String gameId,
String itemId,
) {
final path = APIPaths.submitGameCard
.replaceFirst('%@', gameId)
.replaceFirst('%@', itemId);
return client.requestNormal(
path,
Method.POST,
const {},
(data) => GameBundleItemModel.fromJson(data as Json),
);
}
}
import '../../base/base_response_model.dart';
import '../../configs/api_paths.dart';
import '../../configs/callbacks.dart';
import '../../networking/restful_api_client.dart';
import '../../preference/data_preference.dart';
import '../../screen/location_address/models/district_address_model.dart';
import '../../screen/location_address/models/province_address_model.dart';
class LocationApi {
LocationApi(this.client);
final RestfulAPIClient client;
Future<BaseResponseModel<ProvinceAddressResponse>> locationProvinceGetList() {
final token = DataPreference.instance.token ?? '';
final body = {'access_token': token, 'country_code2': 'VN'};
return client.requestNormal(
APIPaths.locationProvinceGetList,
Method.POST,
body,
(data) => ProvinceAddressResponse.fromJson(data as Json),
);
}
Future<BaseResponseModel<DistrictAddressResponse>> locationDistrictGetList(
String provinceCode,
) {
final token = DataPreference.instance.token ?? '';
final body = {'access_token': token, 'province_code': provinceCode};
return client.requestNormal(
APIPaths.locationDistrictGetList,
Method.POST,
body,
(data) => DistrictAddressResponse.fromJson(data as Json),
);
}
}
import '../../base/base_response_model.dart';
import '../../configs/api_paths.dart';
import '../../configs/callbacks.dart';
import '../../networking/restful_api_client.dart';
import '../../preference/data_preference.dart';
import '../../screen/home/models/notification_unread_model.dart';
import '../../screen/notification/models/category_notify_item_model.dart';
import '../../screen/notification/models/notification_detail_model.dart';
import '../../screen/notification/models/notification_list_data_model.dart';
class NotificationApi {
NotificationApi(this.client);
final RestfulAPIClient client;
Future<BaseResponseModel<List<CategoryNotifyItemModel>>> getNotificationCategories() {
return client.requestNormal(APIPaths.getNotificationCategories, Method.GET, const {}, (data) {
final list = data as List<dynamic>;
return list.map((item) => CategoryNotifyItemModel.fromJson(item)).toList();
});
}
Future<BaseResponseModel<NotificationListDataModel>> getNotifications(Json body) {
return client.requestNormal(
APIPaths.getNotifications,
Method.POST,
body,
(data) => NotificationListDataModel.fromJson(data as Json),
);
}
Future<BaseResponseModel<EmptyCodable>> deleteNotification(String id) {
final token = DataPreference.instance.token ?? '';
return client.requestNormal(APIPaths.deleteNotification, Method.POST, {
'notification_id': id,
'lang': 'vi',
'access_token': token,
}, (data) => EmptyCodable.fromJson(data as Json));
}
Future<BaseResponseModel<EmptyCodable>> deleteAllNotifications() {
final token = DataPreference.instance.token ?? '';
final body = {'access_token': token};
return client.requestNormal(
APIPaths.deleteAllNotifications,
Method.POST,
body,
(data) => EmptyCodable.fromJson(data as Json),
);
}
Future<BaseResponseModel<EmptyCodable>> notificationMarkAsSeen() {
final token = DataPreference.instance.token ?? '';
final body = {'access_token': token};
return client.requestNormal(
APIPaths.notificationMarkAsSeen,
Method.POST,
body,
(data) => EmptyCodable.fromJson(data as Json),
);
}
Future<BaseResponseModel<NotificationDetailResponseModel>> getNotificationDetail(String id) {
final token = DataPreference.instance.token ?? '';
final body = {'notification_id': id, 'mark_as_seen': '1', 'access_token': token};
return client.requestNormal(
APIPaths.notificationGetDetail,
Method.POST,
body,
(data) => NotificationDetailResponseModel.fromJson(data as Json),
);
}
Future<BaseResponseModel<NotificationUnreadData>> getNotificationUnread() {
final token = DataPreference.instance.token ?? '';
final body = {'access_token': token};
return client.requestNormal(
APIPaths.getNotificationUnread,
Method.POST,
body,
(data) => NotificationUnreadData.fromJson(data as Json),
);
}
}
import '../../base/base_response_model.dart';
import '../../configs/api_paths.dart';
import '../../configs/callbacks.dart';
import '../../networking/restful_api_client.dart';
import '../../preference/data_preference.dart';
import '../../screen/data_network_service/product_network_data_model.dart';
import '../../screen/home/models/my_product_model.dart';
import '../../screen/mobile_card/models/mobile_service_redeem_data.dart';
import '../../screen/mobile_card/models/product_mobile_card_model.dart';
import '../../screen/mobile_card/models/usable_voucher_model.dart';
import '../../screen/topup/models/brand_network_model.dart';
import '../../screen/traffic_service/traffic_service_model.dart';
import '../../screen/transaction/model/order_product_payment_response_model.dart';
import '../../screen/transaction/model/payment_bank_account_info_model.dart';
import '../../screen/transaction/model/payment_method_model.dart';
import '../../screen/transaction/model/preview_order_payment_model.dart';
import '../../screen/voucher/models/like_product_response_model.dart';
import '../../screen/voucher/models/my_mobile_card_response.dart';
import '../../screen/voucher/models/my_product_status_type.dart';
import '../../screen/voucher/models/product_brand_model.dart';
import '../../screen/voucher/models/product_model.dart';
import '../../screen/voucher/models/product_store_model.dart';
import '../../screen/voucher/models/product_type.dart';
import '../../screen/voucher/models/search_product_response_model.dart';
class ProductApi {
ProductApi(this.client);
final RestfulAPIClient client;
Future<BaseResponseModel<List<ProductModel>>> getProducts(Json body) {
return client.requestNormal(APIPaths.getProducts, Method.GET, body, (data) {
final list = data as List<dynamic>;
return list.map((e) => ProductModel.fromJson(e)).toList();
});
}
Future<BaseResponseModel<SearchProductResponseModel>> getSearchProducts(Json body) {
return client.requestNormal(
APIPaths.getSearchProducts,
Method.POST,
body,
(data) => SearchProductResponseModel.fromJson(data as Json),
);
}
Future<BaseResponseModel<List<ProductModel>>> productsCustomerLikes(Json body) {
return client.requestNormal(APIPaths.productsCustomerLikes, Method.GET, body, (data) {
final list = data as List<dynamic>;
return list.map((e) => ProductModel.fromJson(e)).toList();
});
}
Future<BaseResponseModel<ProductModel>> getProduct(int id) {
final path = APIPaths.getProductDetail.replaceAll('%@', id.toString());
return client.requestNormal(path, Method.GET, const {}, (data) => ProductModel.fromJson(data as Json));
}
Future<BaseResponseModel<ProductModel>> getCustomerProductDetail(int id) {
final path = APIPaths.getCustomerProductDetail.replaceAll('%@', id.toString());
return client.requestNormal(path, Method.GET, const {}, (data) => ProductModel.fromJson(data as Json));
}
Future<BaseResponseModel<List<ProductStoreModel>>> getProductStores(int id) {
final body = {'product_id': id, 'size': 20, 'index': 0};
return client.requestNormal(APIPaths.getProductStores, Method.GET, body, (data) {
final list = data as List<dynamic>;
return list.map((e) => ProductStoreModel.fromJson(e)).toList();
});
}
Future<BaseResponseModel<LikeProductResponseModel>> likeProduct(int id) {
final body = {'product_id': id};
return client.requestNormal(APIPaths.productCustomerLikes, Method.POST, body, (data) {
return LikeProductResponseModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<EmptyCodable>> unlikeProduct(int id) {
final path = APIPaths.productCustomerUnlikes.replaceAll('%@', id.toString());
return client.requestNormal(path, Method.DELETE, const {}, (data) => EmptyCodable.fromJson(data as Json));
}
Future<BaseResponseModel<List<EmptyCodable>>> verifyOrderProduct(Json body) {
return client.requestNormal(APIPaths.verifyOrderProduct, Method.POST, body, (data) {
final list = data as List<dynamic>;
return list.map((e) => EmptyCodable.fromJson(e)).toList();
});
}
Future<BaseResponseModel<PreviewOrderPaymentModel>> getPreviewOrderInfo(Json body) {
return client.requestNormal(
APIPaths.getPreviewOrderInfo,
Method.POST,
body,
(data) => PreviewOrderPaymentModel.fromJson(data as Json),
);
}
Future<BaseResponseModel<List<PaymentBankAccountInfoModel>>> getPreviewOrderBankAccounts() {
return client.requestNormal(APIPaths.getPreviewOrderBankAccounts, Method.GET, const {}, (data) {
final list = data as List<dynamic>;
return list.map((e) => PaymentBankAccountInfoModel.fromJson(e)).toList();
});
}
Future<BaseResponseModel<List<PaymentMethodModel>>> getPreviewPaymentMethods() {
return client.requestNormal(APIPaths.getPreviewPaymentMethods, Method.GET, const {}, (data) {
final list = data as List<dynamic>;
return list.map((e) => PaymentMethodModel.fromJson(e)).toList();
});
}
Future<BaseResponseModel<OrderProductPaymentResponseModel>> orderSubmitPayment({
required List<ProductModel> products,
required int quantity,
required String requestId,
int? point,
int? cash,
PaymentMethodModel? method,
int? paymentTokenId,
bool? saveToken,
String? metadata,
String? targetPhoneNumber,
}) {
final items =
products.map((product) {
return {
'product_id': product.id,
'product_type': product.type ?? '',
'quantity': quantity,
'target_phone_number': targetPhoneNumber ?? '',
};
}).toList();
final Map<String, dynamic> params = {'request_id': requestId, 'items': items, 'flow': '21'};
final firstProduct = products.first;
if (firstProduct.previewFlashSale?.isFlashSalePrice == true && firstProduct.previewFlashSale?.id != null) {
params['flash_sale_id'] = firstProduct.previewFlashSale!.id;
}
if (method != null) {
params['payment_method'] = method.code;
}
if (point != null && point != 0) {
params['pay_point'] = point;
}
if (cash != null && cash != 0) {
params['pay_cash'] = cash;
}
if (paymentTokenId != null) {
params['payment_token_id'] = paymentTokenId;
}
if (saveToken != null) {
params['save_token'] = saveToken;
}
if (metadata != null) {
params['metadata'] = metadata;
}
return client.requestNormal(APIPaths.orderSubmitPayment, Method.POST, params, (data) {
return OrderProductPaymentResponseModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<List<MyProductModel>>> getCustomerProducts(Json body) {
return client.requestNormal(APIPaths.getCustomerProducts, Method.GET, body, (data) {
final list = data as List<dynamic>;
return list.map((e) => MyProductModel.fromJson(e)).toList();
});
}
Future<BaseResponseModel<List<ProductBrandModel>>> getTopUpBrands(ProductType type) {
final body = {'type': type.value};
return client.requestNormal(APIPaths.getTopUpBrands, Method.GET, body, (data) {
final list = data as List<dynamic>;
return list.map((e) => ProductBrandModel.fromJson(e)).toList();
});
}
Future<BaseResponseModel<List<ProductBrandModel>>> productTopUpBrands() {
final body = {'topup_type': 'PRODUCT_MODEL_MOBILE_SERVICE', 'page_size': '999', 'page_index': 0};
return client.requestNormal(APIPaths.productTopUpsBrands, Method.GET, body, (data) {
final list = data as List<dynamic>;
return list.map((e) => ProductBrandModel.fromJson(e)).toList();
});
}
Future<BaseResponseModel<BrandNameCheckResponse>> checkMobileNetwork(String phone) {
final body = {'phone': phone};
return client.requestNormal(APIPaths.checkMobileNetwork, Method.GET, body, (data) {
return BrandNameCheckResponse.fromJson(data as Json);
});
}
Future<BaseResponseModel<ProductMobileCardResponse>> productMobileCardGetList() {
final token = DataPreference.instance.token ?? '';
final body = {'start': 0, 'limit': 200, 'access_token': token};
return client.requestNormal(APIPaths.productMobileCardGetList, Method.POST, body, (data) {
return ProductMobileCardResponse.fromJson(data as Json);
});
}
Future<BaseResponseModel<MobileServiceRedeemData>> redeemMobileCard(String productId) {
final token = DataPreference.instance.token ?? '';
final body = {'product_id': productId, 'get_customer_balance': '1', 'access_token': token};
return client.requestNormal(APIPaths.redeemMobileCard, Method.POST, body, (data) {
return MobileServiceRedeemData.fromJson(data as Json);
});
}
Future<BaseResponseModel<RedeemProductResponseModel>> getMobileCardCode(String itemId) {
final token = DataPreference.instance.token ?? '';
final body = {'product_item_id': itemId, 'access_token': token};
return client.requestNormal(APIPaths.getMobileCardCode, Method.POST, body, (data) {
return RedeemProductResponseModel.fromJson(data as Json);
});
}
Future<BaseResponseModel<List<TopUpNetworkDataModel>>> getNetworkProducts(String brandId) {
final body = {
'brand_id': brandId,
'topup_type': 'PRODUCT_MODEL_MOBILE_SERVICE',
'page_size': '999',
'page_index': 0,
};
return client.requestNormal(APIPaths.getNetworkProducts, Method.GET, body, (data) {
final list = data as List<dynamic>;
return list.map((e) => TopUpNetworkDataModel.fromJson(e)).toList();
});
}
Future<BaseResponseModel<EmptyCodable>> redeemProductTopUps(int productId, String phoneNumber) {
final token = DataPreference.instance.token ?? '';
final body = {
'access_token': token,
'product_id': productId,
'quantity': 1,
'phone_number': phoneNumber,
'lang': 'vi',
};
return client.requestNormal(APIPaths.redeemProductTopUps, Method.POST, body, (data) {
return EmptyCodable.fromJson(data as Json);
});
}
Future<BaseResponseModel<MyVoucherResponse>> getMyMobileCards(MyProductStatusType status, Json body) {
final token = DataPreference.instance.token ?? '';
body['access_token'] = token;
body['product_model_code'] = 'PRODUCT_MODEL_MOBILE_CARD';
body['list_order'] = 'DESC';
var path = '';
switch (status) {
case MyProductStatusType.waiting:
path = APIPaths.getMyProductGetWaitingList;
case MyProductStatusType.used:
path = APIPaths.getMyProductGetUsedList;
case MyProductStatusType.expired:
path = APIPaths.getMyProductGetExpiredList;
}
return client.requestNormal(path, Method.POST, body, (data) {
return MyVoucherResponse.fromJson(data as Json);
});
}
Future<BaseResponseModel<EmptyCodable>> myProductMarkAsUsed(String id) {
final token = DataPreference.instance.token ?? '';
final body = {'product_item_id': id, 'lang': 'vi', 'access_token': token};
return client.requestNormal(APIPaths.myProductMarkAsUsed, Method.POST, body, (data) {
return EmptyCodable.fromJson(data as Json);
});
}
Future<BaseResponseModel<EmptyCodable>> myProductMarkAsNotUsedYet(String id) {
final token = DataPreference.instance.token ?? '';
final body = {'product_item_id': id, 'lang': 'vi', 'access_token': token};
return client.requestNormal(APIPaths.myProductMarkAsNotUsedYet, Method.POST, body, (data) {
return EmptyCodable.fromJson(data as Json);
});
}
Future<BaseResponseModel<TrafficServiceResponseModel>> getProductVnTraSold(Json body) {
return client.requestNormal(APIPaths.getProductVnTraSold, Method.GET, body, (data) {
return TrafficServiceResponseModel.fromJson(data as Json);
});
}
}
import '../../base/base_response_model.dart';
import '../../configs/api_paths.dart';
import '../../configs/callbacks.dart';
import '../../networking/restful_api_client.dart';
import '../../preference/data_preference.dart';
import '../../screen/faqs/faqs_model.dart';
import '../../screen/pageDetail/model/campaign_detail_model.dart';
import '../../screen/pageDetail/model/detail_page_rule_type.dart';
class WebsiteApi {
WebsiteApi(this.client);
final RestfulAPIClient client;
Future<BaseResponseModel<CampaignDetailResponseModel>> websitePageGetDetail(String id) {
final token = DataPreference.instance.token ?? '';
final body = {'website_page_id': id, 'access_token': token};
return client.requestNormal(
APIPaths.websitePageGetDetail,
Method.POST,
body,
(data) => CampaignDetailResponseModel.fromJson(data as Json),
);
}
Future<BaseResponseModel<CampaignDetailResponseModel>> websitePage(DetailPageRuleType rule) {
final body = {'code': rule.key};
return client.requestNormal(
APIPaths.websitePage,
Method.GET,
body,
(data) => CampaignDetailResponseModel.fromJson(data as Json),
);
}
Future<BaseResponseModel<FAQItemModelResponse>> websiteFolderGetPageList(Json body) {
return client.requestNormal(
APIPaths.websiteFolderGetPageList,
Method.POST,
body,
(data) => FAQItemModelResponse.fromJson(data as Json),
);
}
}
...@@ -20,6 +20,7 @@ class AuthInterceptor extends Interceptor { ...@@ -20,6 +20,7 @@ class AuthInterceptor extends Interceptor {
APIPaths.login, APIPaths.login,
APIPaths.refreshToken, APIPaths.refreshToken,
APIPaths.logout, APIPaths.logout,
APIPaths.deleteNotification,
'assets', 'assets',
]; ];
......
import 'dart:async'; import 'dart:async';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:mypoint_flutter_app/base/app_loading.dart'; import 'package:mypoint_flutter_app/base/app_loading.dart';
import '../../base/app_navigator.dart'; import '../../base/app_navigator.dart';
import '../dio_http_service.dart'; import '../dio_http_service.dart';
...@@ -14,17 +15,17 @@ class ExceptionInterceptor extends Interceptor { ...@@ -14,17 +15,17 @@ class ExceptionInterceptor extends Interceptor {
final apiError = ErrorMapper.map(err); final apiError = ErrorMapper.map(err);
err.requestOptions.extra['mapped_error'] = apiError; err.requestOptions.extra['mapped_error'] = apiError;
// return handler.next(err); // return handler.next(err);
print('ExceptionInterceptor: onError: $apiError'); debugPrint('ExceptionInterceptor: onError: $apiError');
final extra = err.requestOptions.extra; final extra = err.requestOptions.extra;
final silent = extra['silent'] == true; final silent = extra['silent'] == true;
// Nếu không phải network error hoặc không thể retry -> forward // Nếu không phải network error hoặc không thể retry -> forward
if (!ErrorMapper.isNetworkError(err)) return handler.next(err); if (!ErrorMapper.isNetworkError(err)) return handler.next(err);
if (silent) return handler.next(err); if (silent) return handler.next(err);
print('ExceptionInterceptor: onError: $apiError'); debugPrint('ExceptionInterceptor: onError: $apiError');
// Chỉ cho phép retry với GET hoặc request được mark allow_retry // Chỉ cho phép retry với GET hoặc request được mark allow_retry
final allowRetry = _shouldAllowRetry(err.requestOptions); final allowRetry = _shouldAllowRetry(err.requestOptions);
if (!allowRetry) return handler.next(err); if (!allowRetry) return handler.next(err);
print('ExceptionInterceptor: onError: $_isPrompting'); debugPrint('ExceptionInterceptor: onError: $_isPrompting');
if (_isPrompting) return handler.next(err); if (_isPrompting) return handler.next(err);
_isPrompting = true; _isPrompting = true;
// ask user retry // ask user retry
......
import 'dart:convert'; import 'dart:convert';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:logger/logger.dart'; import 'package:logger/logger.dart';
......
...@@ -72,9 +72,7 @@ class RequestInterceptor extends Interceptor { ...@@ -72,9 +72,7 @@ class RequestInterceptor extends Interceptor {
} }
options.data = jsonEncode(body); options.data = jsonEncode(body);
} catch (e) { } catch (e) {
if (kDebugMode) { debugPrint('⚠️ RequestInterceptor: failed to normalize JSON body - $e');
print('⚠️ RequestInterceptor: failed to normalize JSON body - $e');
}
} }
} }
} }
...@@ -118,8 +118,6 @@ class RestfulAPIClient { ...@@ -118,8 +118,6 @@ class RestfulAPIClient {
} }
void _debug(Object e) { void _debug(Object e) {
if (kDebugMode) { debugPrint('=== API DEBUG === $e');
print('=== API DEBUG === $e');
}
} }
} }
...@@ -23,9 +23,7 @@ class DataPreference { ...@@ -23,9 +23,7 @@ class DataPreference {
try { try {
_loginToken = LoginTokenResponseModel.fromJson(jsonDecode(tokenJson)); _loginToken = LoginTokenResponseModel.fromJson(jsonDecode(tokenJson));
} catch (e) { } catch (e) {
if (kDebugMode) { debugPrint('Failed to parse login token: $e');
print('Failed to parse login token: $e');
}
// Clear invalid token // Clear invalid token
await prefs.remove('login_token'); await prefs.remove('login_token');
} }
...@@ -36,17 +34,13 @@ class DataPreference { ...@@ -36,17 +34,13 @@ class DataPreference {
_profile = ProfileResponseModel.fromJson(jsonDecode(profileJson)); _profile = ProfileResponseModel.fromJson(jsonDecode(profileJson));
phoneNumberUsedForLoginScreen = _profile?.workerSite?.phoneNumber ?? ""; phoneNumberUsedForLoginScreen = _profile?.workerSite?.phoneNumber ?? "";
} catch (e) { } catch (e) {
if (kDebugMode) { debugPrint('Failed to parse user profile: $e');
print('Failed to parse user profile: $e');
}
// Clear invalid profile // Clear invalid profile
await prefs.remove('user_profile'); await prefs.remove('user_profile');
} }
} }
} catch (e) { } catch (e) {
if (kDebugMode) { debugPrint('DataPreference init failed: $e');
print('DataPreference init failed: $e');
}
} }
} }
String get displayName { String get displayName {
...@@ -109,9 +103,7 @@ class DataPreference { ...@@ -109,9 +103,7 @@ class DataPreference {
try { try {
return jsonDecode(jsonString) as String?; return jsonDecode(jsonString) as String?;
} catch (e) { } catch (e) {
if (kDebugMode) { debugPrint('Failed to parse bio token for $phone: $e');
print('Failed to parse bio token for $phone: $e');
}
// Clear invalid bio token // Clear invalid bio token
await prefs.remove('biometric_login_token_$phone'); await prefs.remove('biometric_login_token_$phone');
return null; return null;
...@@ -119,9 +111,7 @@ class DataPreference { ...@@ -119,9 +111,7 @@ class DataPreference {
} }
return null; return null;
} catch (e) { } catch (e) {
if (kDebugMode) { debugPrint('getBioToken failed for $phone: $e');
print('getBioToken failed for $phone: $e');
}
return null; return null;
} }
} }
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
class AffiliateOverviewPopup extends StatelessWidget { class AffiliateOverviewPopup extends StatelessWidget {
final List<String> descriptions; final List<String> descriptions;
......
import 'package:get/get_rx/src/rx_types/rx_types.dart'; import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart'; import 'package:mypoint_flutter_app/networking/api/affiliate_api.dart' deferred as affiliate_api;
import '../../base/base_response_model.dart';
import '../../networking/restful_api_viewmodel.dart'; import '../../networking/restful_api_viewmodel.dart';
import 'model/affiliate_brand_model.dart'; import 'model/affiliate_brand_model.dart';
import 'model/affiliate_category_model.dart'; import 'model/affiliate_category_model.dart';
...@@ -16,10 +17,22 @@ class AffiliateTabViewModel extends RestfulApiViewModel { ...@@ -16,10 +17,22 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
final Rxn<CashbackOverviewModel> overview = Rxn<CashbackOverviewModel>(); final Rxn<CashbackOverviewModel> overview = Rxn<CashbackOverviewModel>();
void Function((List<AffiliateBrandModel>, String) data)? onShowAffiliateBrandPopup; void Function((List<AffiliateBrandModel>, String) data)? onShowAffiliateBrandPopup;
bool _affiliateLibLoaded = false;
Future<void> _ensureAffiliateLibraryLoaded() async {
if (_affiliateLibLoaded) return;
await affiliate_api.loadLibrary();
_affiliateLibLoaded = true;
}
Future<BaseResponseModel<T>> _callAffiliate<T>(Future<BaseResponseModel<T>> Function(dynamic api) fn) async {
await _ensureAffiliateLibraryLoaded();
final api = affiliate_api.AffiliateApi(client);
return fn(api);
}
bool get isDataAvailable { bool get isDataAvailable {
return affiliateBrands.isNotEmpty || return affiliateBrands.isNotEmpty || affiliateCategories.isNotEmpty || affiliateProducts.isNotEmpty;
affiliateCategories.isNotEmpty ||
affiliateProducts.isNotEmpty;
} }
Future<void> refreshData({bool isShowLoading = true}) async { Future<void> refreshData({bool isShowLoading = true}) async {
...@@ -36,7 +49,7 @@ class AffiliateTabViewModel extends RestfulApiViewModel { ...@@ -36,7 +49,7 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
Future<void> _getAffiliateBrandGetList() async { Future<void> _getAffiliateBrandGetList() async {
await callApi<List<AffiliateBrandModel>>( await callApi<List<AffiliateBrandModel>>(
request: () => client.affiliateBrandGetList(), request: () => _callAffiliate((api) => api.affiliateBrandGetList()),
onSuccess: (data, _) { onSuccess: (data, _) {
affiliateBrands.assignAll(data); affiliateBrands.assignAll(data);
}, },
...@@ -49,12 +62,9 @@ class AffiliateTabViewModel extends RestfulApiViewModel { ...@@ -49,12 +62,9 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
Future<void> _getAffiliateCategoryGetList() async { Future<void> _getAffiliateCategoryGetList() async {
await callApi<List<AffiliateCategoryModel>>( await callApi<List<AffiliateCategoryModel>>(
request: () => client.affiliateCategoryGetList(), request: () => _callAffiliate((api) => api.affiliateCategoryGetList()),
onSuccess: (data, _) { onSuccess: (data, _) {
final category = AffiliateCategoryModel( final category = AffiliateCategoryModel(code: AffiliateCategoryType.other, name: "Khác");
code: AffiliateCategoryType.other,
name: "Khác",
);
final results = data; final results = data;
allAffiliateCategories.assignAll(results); allAffiliateCategories.assignAll(results);
...@@ -72,11 +82,11 @@ class AffiliateTabViewModel extends RestfulApiViewModel { ...@@ -72,11 +82,11 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
Future<void> _getAffiliateProductTopSale() async { Future<void> _getAffiliateProductTopSale() async {
await callApi<List<AffiliateProductTopSaleModel>>( await callApi<List<AffiliateProductTopSaleModel>>(
request: () => client.affiliateProductTopSale(), request: () => _callAffiliate((api) => api.affiliateProductTopSale()),
onSuccess: (data, _) { onSuccess: (data, _) {
affiliateProducts.assignAll(data); affiliateProducts.assignAll(data);
}, },
onFailure: (msg, _, __) async { onFailure: (msg, _, _) async {
affiliateProducts.clear(); affiliateProducts.clear();
}, },
withLoading: false, withLoading: false,
...@@ -85,7 +95,7 @@ class AffiliateTabViewModel extends RestfulApiViewModel { ...@@ -85,7 +95,7 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
Future<void> _getAffiliateOverview() async { Future<void> _getAffiliateOverview() async {
await callApi<CashbackOverviewModel>( await callApi<CashbackOverviewModel>(
request: () => client.getCashBackOverview(), request: () => _callAffiliate((api) => api.getCashBackOverview()),
onSuccess: (data, _) { onSuccess: (data, _) {
overview.value = data; overview.value = data;
}, },
...@@ -98,7 +108,10 @@ class AffiliateTabViewModel extends RestfulApiViewModel { ...@@ -98,7 +108,10 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
Future<void> affiliateBrandGetListBuyCategory(AffiliateCategoryModel category) async { Future<void> affiliateBrandGetListBuyCategory(AffiliateCategoryModel category) async {
await callApi<List<AffiliateBrandModel>>( await callApi<List<AffiliateBrandModel>>(
request: () => client.affiliateBrandGetList(categoryCode: AffiliateCategoryModel.codeToJson(category.code)), request:
() => _callAffiliate(
(api) => api.affiliateBrandGetList(categoryCode: AffiliateCategoryModel.codeToJson(category.code)),
),
onSuccess: (data, _) { onSuccess: (data, _) {
if (data.isNotEmpty) { if (data.isNotEmpty) {
onShowAffiliateBrandPopup?.call((data, category.name ?? '')); onShowAffiliateBrandPopup?.call((data, category.name ?? ''));
...@@ -106,4 +119,4 @@ class AffiliateTabViewModel extends RestfulApiViewModel { ...@@ -106,4 +119,4 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
}, },
); );
} }
} }
\ No newline at end of file
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:mypoint_flutter_app/configs/constants.dart'; import 'package:mypoint_flutter_app/configs/constants.dart';
import 'package:mypoint_flutter_app/networking/api/affiliate_api.dart'
deferred as affiliate_api;
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart'; import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import '../../networking/restful_api_viewmodel.dart'; import '../../networking/restful_api_viewmodel.dart';
import 'models/affiliate_brand_detail_model.dart'; import 'models/affiliate_brand_detail_model.dart';
class AffiliateBrandDetailViewModel extends RestfulApiViewModel { class AffiliateBrandDetailViewModel extends RestfulApiViewModel {
final String brandId; final String brandId;
AffiliateBrandDetailViewModel(this.brandId); AffiliateBrandDetailViewModel(this.brandId);
void Function(String message)? onShowAlertError; void Function(String message)? onShowAlertError;
final Rxn<AffiliateBrandDetailModel> brandDetailData = Rxn<AffiliateBrandDetailModel>(); final Rxn<AffiliateBrandDetailModel> brandDetailData =
Rxn<AffiliateBrandDetailModel>();
bool _affiliateLibLoaded = false;
Future<void> _ensureAffiliateLibraryLoaded() async {
if (_affiliateLibLoaded) return;
await affiliate_api.loadLibrary();
_affiliateLibLoaded = true;
}
@override @override
void onInit() { void onInit() {
...@@ -19,7 +32,11 @@ class AffiliateBrandDetailViewModel extends RestfulApiViewModel { ...@@ -19,7 +32,11 @@ class AffiliateBrandDetailViewModel extends RestfulApiViewModel {
Future<void> _fetchDetail() async { Future<void> _fetchDetail() async {
await callApi<AffiliateBrandDetailModel>( await callApi<AffiliateBrandDetailModel>(
request: () => client.getAffiliateBrandDetail(brandId), request: () async {
await _ensureAffiliateLibraryLoaded();
final api = affiliate_api.AffiliateApi(client);
return api.getAffiliateBrandDetail(brandId);
},
onSuccess: (data, _) { onSuccess: (data, _) {
brandDetailData.value = data; brandDetailData.value = data;
}, },
......
import 'package:get/get_rx/src/rx_types/rx_types.dart'; import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:mypoint_flutter_app/configs/constants.dart'; import 'package:mypoint_flutter_app/configs/constants.dart';
import 'package:mypoint_flutter_app/networking/api/affiliate_api.dart'
deferred as affiliate_api;
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart'; import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import '../../networking/restful_api_viewmodel.dart'; import '../../networking/restful_api_viewmodel.dart';
import '../affiliate/model/affiliate_brand_model.dart'; import '../affiliate/model/affiliate_brand_model.dart';
import '../affiliate/model/affiliate_category_model.dart'; import '../affiliate/model/affiliate_category_model.dart';
class AffiliateCategoryGridViewModel extends RestfulApiViewModel { class AffiliateCategoryGridViewModel extends RestfulApiViewModel {
void Function((List<AffiliateBrandModel>, String) data)? onShowAffiliateBrandPopup; void Function((List<AffiliateBrandModel>, String) data)?
onShowAffiliateBrandPopup;
void Function(String message)? onShowAlertError; void Function(String message)? onShowAlertError;
Future<void> affiliateBrandGetListBuyCategory(AffiliateCategoryModel category) async { bool _affiliateLibLoaded = false;
Future<void> _ensureAffiliateLibraryLoaded() async {
if (_affiliateLibLoaded) return;
await affiliate_api.loadLibrary();
_affiliateLibLoaded = true;
}
Future<void> affiliateBrandGetListBuyCategory(
AffiliateCategoryModel category,
) async {
await callApi<List<AffiliateBrandModel>>( await callApi<List<AffiliateBrandModel>>(
request: () => client.affiliateBrandGetList( request: () async {
categoryCode: AffiliateCategoryModel.codeToJson(category.code), await _ensureAffiliateLibraryLoaded();
), final api = affiliate_api.AffiliateApi(client);
return api.affiliateBrandGetList(
categoryCode: AffiliateCategoryModel.codeToJson(category.code),
);
},
onSuccess: (data, _) { onSuccess: (data, _) {
if (data.isNotEmpty) { if (data.isNotEmpty) {
onShowAffiliateBrandPopup?.call((data, category.name ?? '')); onShowAffiliateBrandPopup?.call((data, category.name ?? ''));
...@@ -24,4 +41,4 @@ class AffiliateCategoryGridViewModel extends RestfulApiViewModel { ...@@ -24,4 +41,4 @@ class AffiliateCategoryGridViewModel extends RestfulApiViewModel {
}, },
); );
} }
} }
\ No newline at end of file
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:mypoint_flutter_app/widgets/custom_empty_widget.dart'; import 'package:mypoint_flutter_app/widgets/custom_empty_widget.dart';
...@@ -35,7 +36,7 @@ class _BankAccountManagerScreenState extends State<BankAccountManagerScreen> { ...@@ -35,7 +36,7 @@ class _BankAccountManagerScreenState extends State<BankAccountManagerScreen> {
await Get.to(() => BankAccountDetailScreen( await Get.to(() => BankAccountDetailScreen(
model: viewModel.bankAccounts.value[index], model: viewModel.bankAccounts.value[index],
)); ));
print("reload getBankAccountList"); debugPrint("reload getBankAccountList");
viewModel.getBankAccountList(); viewModel.getBankAccountList();
}), }),
), ),
......
import 'package:flutter/foundation.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:local_auth/local_auth.dart'; import 'package:local_auth/local_auth.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart'; import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
...@@ -27,7 +28,7 @@ class BiometricViewModel extends RestfulApiViewModel { ...@@ -27,7 +28,7 @@ class BiometricViewModel extends RestfulApiViewModel {
biometricType.value = BiometricType.fingerprint; biometricType.value = BiometricType.fingerprint;
} }
} catch (e) { } catch (e) {
print("Lỗi kiểm tra sinh trắc học: $e"); debugPrint("Lỗi kiểm tra sinh trắc học: $e");
} }
} }
......
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