Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Hoàng Văn Đạt
mypoint_flutter_app
Commits
a6797435
Commit
a6797435
authored
Nov 05, 2025
by
DatHV
Browse files
refactor print, log, request
parent
f0334970
Changes
117
Expand all
Show whitespace changes
Inline
Side-by-side
lib/main.dart
View file @
a6797435
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_localizations/flutter_localizations.dart'
;
import
'package:get/get.dart'
;
import
'package:mypoint_flutter_app/base/app_navigator.dart'
;
import
'package:mypoint_flutter_app/resources/base_color.dart'
;
...
...
@@ -40,14 +39,6 @@ class MyApp extends StatelessWidget {
primaryColor:
BaseColor
.
primary500
,
),
locale:
const
Locale
(
'vi'
),
supportedLocales:
const
[
Locale
(
'vi'
,
'VN'
),
// Vietnamese
],
localizationsDelegates:
const
[
GlobalMaterialLocalizations
.
delegate
,
GlobalWidgetsLocalizations
.
delegate
,
GlobalCupertinoLocalizations
.
delegate
,
],
home:
SplashScreen
(),
getPages:
RouterPage
.
pages
(),
);
...
...
lib/networking/api/affiliate_api.dart
0 → 100644
View file @
a6797435
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
);
},
);
}
}
lib/networking/api/game_api.dart
0 → 100644
View file @
a6797435
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
),
);
}
}
lib/networking/api/location_api.dart
0 → 100644
View file @
a6797435
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
),
);
}
}
lib/networking/api/notification_api.dart
0 → 100644
View file @
a6797435
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
),
);
}
}
lib/networking/api/product_api.dart
0 → 100644
View file @
a6797435
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
);
});
}
}
lib/networking/api/website_api.dart
0 → 100644
View file @
a6797435
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
),
);
}
}
lib/networking/interceptor/auth_interceptor.dart
View file @
a6797435
...
...
@@ -20,6 +20,7 @@ class AuthInterceptor extends Interceptor {
APIPaths
.
login
,
APIPaths
.
refreshToken
,
APIPaths
.
logout
,
APIPaths
.
deleteNotification
,
'assets'
,
];
...
...
lib/networking/interceptor/exception_interceptor.dart
View file @
a6797435
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'
;
...
...
@@ -14,17 +15,17 @@ class ExceptionInterceptor extends Interceptor {
final
apiError
=
ErrorMapper
.
map
(
err
);
err
.
requestOptions
.
extra
[
'mapped_error'
]
=
apiError
;
// return handler.next(err);
p
rint
(
'ExceptionInterceptor: onError:
$apiError
'
);
debugP
rint
(
'ExceptionInterceptor: onError:
$apiError
'
);
final
extra
=
err
.
requestOptions
.
extra
;
final
silent
=
extra
[
'silent'
]
==
true
;
// Nếu không phải network error hoặc không thể retry -> forward
if
(!
ErrorMapper
.
isNetworkError
(
err
))
return
handler
.
next
(
err
);
if
(
silent
)
return
handler
.
next
(
err
);
p
rint
(
'ExceptionInterceptor: onError:
$apiError
'
);
debugP
rint
(
'ExceptionInterceptor: onError:
$apiError
'
);
// Chỉ cho phép retry với GET hoặc request được mark allow_retry
final
allowRetry
=
_shouldAllowRetry
(
err
.
requestOptions
);
if
(!
allowRetry
)
return
handler
.
next
(
err
);
p
rint
(
'ExceptionInterceptor: onError:
$_isPrompting
'
);
debugP
rint
(
'ExceptionInterceptor: onError:
$_isPrompting
'
);
if
(
_isPrompting
)
return
handler
.
next
(
err
);
_isPrompting
=
true
;
// ask user retry
...
...
lib/networking/interceptor/logger_interceptor.dart
View file @
a6797435
import
'dart:convert'
;
import
'package:dio/dio.dart'
;
import
'package:logger/logger.dart'
;
...
...
lib/networking/interceptor/request_interceptor.dart
View file @
a6797435
...
...
@@ -72,9 +72,7 @@ class RequestInterceptor extends Interceptor {
}
options
.
data
=
jsonEncode
(
body
);
}
catch
(
e
)
{
if
(
kDebugMode
)
{
print
(
'⚠️ RequestInterceptor: failed to normalize JSON body -
$e
'
);
}
debugPrint
(
'⚠️ RequestInterceptor: failed to normalize JSON body -
$e
'
);
}
}
}
lib/networking/restful_api_client.dart
View file @
a6797435
...
...
@@ -118,8 +118,6 @@ class RestfulAPIClient {
}
void
_debug
(
Object
e
)
{
if
(
kDebugMode
)
{
print
(
'=== API DEBUG ===
$e
'
);
}
debugPrint
(
'=== API DEBUG ===
$e
'
);
}
}
lib/networking/restful_api_client_all_request.dart
View file @
a6797435
This diff is collapsed.
Click to expand it.
lib/preference/data_preference.dart
View file @
a6797435
...
...
@@ -23,9 +23,7 @@ class DataPreference {
try
{
_loginToken
=
LoginTokenResponseModel
.
fromJson
(
jsonDecode
(
tokenJson
));
}
catch
(
e
)
{
if
(
kDebugMode
)
{
print
(
'Failed to parse login token:
$e
'
);
}
debugPrint
(
'Failed to parse login token:
$e
'
);
// Clear invalid token
await
prefs
.
remove
(
'login_token'
);
}
...
...
@@ -36,17 +34,13 @@ class DataPreference {
_profile
=
ProfileResponseModel
.
fromJson
(
jsonDecode
(
profileJson
));
phoneNumberUsedForLoginScreen
=
_profile
?.
workerSite
?.
phoneNumber
??
""
;
}
catch
(
e
)
{
if
(
kDebugMode
)
{
print
(
'Failed to parse user profile:
$e
'
);
}
debugPrint
(
'Failed to parse user profile:
$e
'
);
// Clear invalid profile
await
prefs
.
remove
(
'user_profile'
);
}
}
}
catch
(
e
)
{
if
(
kDebugMode
)
{
print
(
'DataPreference init failed:
$e
'
);
}
debugPrint
(
'DataPreference init failed:
$e
'
);
}
}
String
get
displayName
{
...
...
@@ -109,9 +103,7 @@ class DataPreference {
try
{
return
jsonDecode
(
jsonString
)
as
String
?;
}
catch
(
e
)
{
if
(
kDebugMode
)
{
print
(
'Failed to parse bio token for
$phone
:
$e
'
);
}
debugPrint
(
'Failed to parse bio token for
$phone
:
$e
'
);
// Clear invalid bio token
await
prefs
.
remove
(
'biometric_login_token_
$phone
'
);
return
null
;
...
...
@@ -119,9 +111,7 @@ class DataPreference {
}
return
null
;
}
catch
(
e
)
{
if
(
kDebugMode
)
{
print
(
'getBioToken failed for
$phone
:
$e
'
);
}
debugPrint
(
'getBioToken failed for
$phone
:
$e
'
);
return
null
;
}
}
...
...
lib/screen/affiliate/affiliate_overview.dart
View file @
a6797435
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
{
final
List
<
String
>
descriptions
;
...
...
lib/screen/affiliate/affiliate_tab_viewmodel.dart
View file @
a6797435
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
'model/affiliate_brand_model.dart'
;
import
'model/affiliate_category_model.dart'
;
...
...
@@ -16,10 +17,22 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
final
Rxn
<
CashbackOverviewModel
>
overview
=
Rxn
<
CashbackOverviewModel
>();
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
{
return
affiliateBrands
.
isNotEmpty
||
affiliateCategories
.
isNotEmpty
||
affiliateProducts
.
isNotEmpty
;
return
affiliateBrands
.
isNotEmpty
||
affiliateCategories
.
isNotEmpty
||
affiliateProducts
.
isNotEmpty
;
}
Future
<
void
>
refreshData
({
bool
isShowLoading
=
true
})
async
{
...
...
@@ -36,7 +49,7 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
Future
<
void
>
_getAffiliateBrandGetList
()
async
{
await
callApi
<
List
<
AffiliateBrandModel
>>(
request:
()
=>
client
.
affiliateBrandGetList
(),
request:
()
=>
_callAffiliate
((
api
)
=>
api
.
affiliateBrandGetList
()
)
,
onSuccess:
(
data
,
_
)
{
affiliateBrands
.
assignAll
(
data
);
},
...
...
@@ -49,12 +62,9 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
Future
<
void
>
_getAffiliateCategoryGetList
()
async
{
await
callApi
<
List
<
AffiliateCategoryModel
>>(
request:
()
=>
client
.
affiliateCategoryGetList
(),
request:
()
=>
_callAffiliate
((
api
)
=>
api
.
affiliateCategoryGetList
()
)
,
onSuccess:
(
data
,
_
)
{
final
category
=
AffiliateCategoryModel
(
code:
AffiliateCategoryType
.
other
,
name:
"Khác"
,
);
final
category
=
AffiliateCategoryModel
(
code:
AffiliateCategoryType
.
other
,
name:
"Khác"
);
final
results
=
data
;
allAffiliateCategories
.
assignAll
(
results
);
...
...
@@ -72,11 +82,11 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
Future
<
void
>
_getAffiliateProductTopSale
()
async
{
await
callApi
<
List
<
AffiliateProductTopSaleModel
>>(
request:
()
=>
client
.
affiliateProductTopSale
(),
request:
()
=>
_callAffiliate
((
api
)
=>
api
.
affiliateProductTopSale
()
)
,
onSuccess:
(
data
,
_
)
{
affiliateProducts
.
assignAll
(
data
);
},
onFailure:
(
msg
,
_
,
_
_
)
async
{
onFailure:
(
msg
,
_
,
_
)
async
{
affiliateProducts
.
clear
();
},
withLoading:
false
,
...
...
@@ -85,7 +95,7 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
Future
<
void
>
_getAffiliateOverview
()
async
{
await
callApi
<
CashbackOverviewModel
>(
request:
()
=>
client
.
getCashBackOverview
(),
request:
()
=>
_callAffiliate
((
api
)
=>
api
.
getCashBackOverview
()
)
,
onSuccess:
(
data
,
_
)
{
overview
.
value
=
data
;
},
...
...
@@ -98,7 +108,10 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
Future
<
void
>
affiliateBrandGetListBuyCategory
(
AffiliateCategoryModel
category
)
async
{
await
callApi
<
List
<
AffiliateBrandModel
>>(
request:
()
=>
client
.
affiliateBrandGetList
(
categoryCode:
AffiliateCategoryModel
.
codeToJson
(
category
.
code
)),
request:
()
=>
_callAffiliate
(
(
api
)
=>
api
.
affiliateBrandGetList
(
categoryCode:
AffiliateCategoryModel
.
codeToJson
(
category
.
code
)),
),
onSuccess:
(
data
,
_
)
{
if
(
data
.
isNotEmpty
)
{
onShowAffiliateBrandPopup
?.
call
((
data
,
category
.
name
??
''
));
...
...
lib/screen/affiliate_brand_detail/affiliate_brand_detail_viewmodel.dart
View file @
a6797435
import
'package:get/get.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
'../../networking/restful_api_viewmodel.dart'
;
import
'models/affiliate_brand_detail_model.dart'
;
class
AffiliateBrandDetailViewModel
extends
RestfulApiViewModel
{
final
String
brandId
;
AffiliateBrandDetailViewModel
(
this
.
brandId
);
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
void
onInit
()
{
...
...
@@ -19,7 +32,11 @@ class AffiliateBrandDetailViewModel extends RestfulApiViewModel {
Future
<
void
>
_fetchDetail
()
async
{
await
callApi
<
AffiliateBrandDetailModel
>(
request:
()
=>
client
.
getAffiliateBrandDetail
(
brandId
),
request:
()
async
{
await
_ensureAffiliateLibraryLoaded
();
final
api
=
affiliate_api
.
AffiliateApi
(
client
);
return
api
.
getAffiliateBrandDetail
(
brandId
);
},
onSuccess:
(
data
,
_
)
{
brandDetailData
.
value
=
data
;
},
...
...
lib/screen/affiliate_brand_detail/affiliate_category_grid_viewmodel.dart
View file @
a6797435
import
'package:get/get_rx/src/rx_types/rx_types.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
'../../networking/restful_api_viewmodel.dart'
;
import
'../affiliate/model/affiliate_brand_model.dart'
;
import
'../affiliate/model/affiliate_category_model.dart'
;
class
AffiliateCategoryGridViewModel
extends
RestfulApiViewModel
{
void
Function
((
List
<
AffiliateBrandModel
>,
String
)
data
)?
onShowAffiliateBrandPopup
;
void
Function
((
List
<
AffiliateBrandModel
>,
String
)
data
)?
onShowAffiliateBrandPopup
;
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
>>(
request:
()
=>
client
.
affiliateBrandGetList
(
request:
()
async
{
await
_ensureAffiliateLibraryLoaded
();
final
api
=
affiliate_api
.
AffiliateApi
(
client
);
return
api
.
affiliateBrandGetList
(
categoryCode:
AffiliateCategoryModel
.
codeToJson
(
category
.
code
),
),
);
},
onSuccess:
(
data
,
_
)
{
if
(
data
.
isNotEmpty
)
{
onShowAffiliateBrandPopup
?.
call
((
data
,
category
.
name
??
''
));
...
...
lib/screen/bank_account_manager/bank_account_manager_screen.dart
View file @
a6797435
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:get/get.dart'
;
import
'package:mypoint_flutter_app/widgets/custom_empty_widget.dart'
;
...
...
@@ -35,7 +36,7 @@ class _BankAccountManagerScreenState extends State<BankAccountManagerScreen> {
await
Get
.
to
(()
=>
BankAccountDetailScreen
(
model:
viewModel
.
bankAccounts
.
value
[
index
],
));
p
rint
(
"reload getBankAccountList"
);
debugP
rint
(
"reload getBankAccountList"
);
viewModel
.
getBankAccountList
();
}),
),
...
...
lib/screen/biometric/biometric_viewmodel.dart
View file @
a6797435
import
'package:flutter/foundation.dart'
;
import
'package:get/get.dart'
;
import
'package:local_auth/local_auth.dart'
;
import
'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart'
;
...
...
@@ -27,7 +28,7 @@ class BiometricViewModel extends RestfulApiViewModel {
biometricType
.
value
=
BiometricType
.
fingerprint
;
}
}
catch
(
e
)
{
p
rint
(
"Lỗi kiểm tra sinh trắc học:
$e
"
);
debugP
rint
(
"Lỗi kiểm tra sinh trắc học:
$e
"
);
}
}
...
...
Prev
1
2
3
4
5
6
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment