member_activity_controller.dart 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import 'dart:io';
  2. import 'package:apple_pay/apple_pay.dart';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:get/get.dart';
  5. import 'package:get/get_core/src/get_main.dart';
  6. import 'package:injectable/injectable.dart';
  7. import 'package:location/base/base_controller.dart';
  8. import 'package:location/data/repositories/account_repository.dart';
  9. import 'package:location/data/repositories/member_repository.dart';
  10. import '../../../data/bean/goods_bean.dart';
  11. import '../../../data/bean/member_status_info.dart';
  12. import '../../../data/bean/pay_item_bean.dart';
  13. import '../../../data/consts/web_url.dart';
  14. import '../../../dialog/loading_dialog.dart';
  15. import '../../../handler/error_handler.dart';
  16. import '../../../helper/member_pay_helper.dart';
  17. import '../../../resource/assets.gen.dart';
  18. import '../../../resource/string.gen.dart';
  19. import '../../../utils/async_util.dart';
  20. import '../../../utils/toast_util.dart';
  21. import '../../browser/browser_view.dart';
  22. import '../../main/main_page.dart';
  23. @injectable
  24. class MemberActivityController extends BaseController {
  25. final Rxn<GoodsBean> _selectedGoods = Rxn<GoodsBean>();
  26. GoodsBean? get selectedGoods => _selectedGoods.value;
  27. MemberStatusInfo? get memberStatusInfo =>
  28. accountRepository.memberStatusInfo.value;
  29. final List<ImageProvider> funImages = [
  30. Assets.images.imgMemberActivityBanner1.provider(),
  31. Assets.images.imgMemberActivityBanner2.provider(),
  32. Assets.images.imgMemberActivityBanner3.provider(),
  33. Assets.images.imgMemberActivityBanner4.provider(),
  34. ];
  35. final RxList<GoodsBean> goodsList = <GoodsBean>[].obs;
  36. final List<PayItemBean> payItemList = <PayItemBean>[];
  37. CancelableFuture? _memberDataFuture;
  38. final AccountRepository accountRepository;
  39. final MemberRepository memberRepository;
  40. final MemberPayHelper memberPayHelper;
  41. Duration? get activityDuration => memberRepository.activityDuration.value;
  42. MemberActivityController(
  43. this.accountRepository, this.memberRepository, this.memberPayHelper);
  44. @override
  45. void onReady() {
  46. super.onReady();
  47. refreshMemberData();
  48. precacheImage(
  49. Assets.images.iconMemberSpecialProductsSelect.provider(), Get.context!);
  50. precacheImage(
  51. Assets.images.iconMemberSpecialProductsNormal.provider(), Get.context!);
  52. }
  53. void refreshMemberData() {
  54. _memberDataFuture?.cancel();
  55. _memberDataFuture =
  56. AsyncUtil.retryWithExponentialBackoff(() => _requestMemberData(), 4);
  57. _memberDataFuture?.catchError((error) {
  58. ErrorHandler.toastError(error);
  59. });
  60. }
  61. Future<void> _requestMemberData() {
  62. return memberRepository
  63. .guideItemList(itemListType: Platform.isIOS ? 2 : 0)
  64. .then((response) {
  65. goodsList.clear();
  66. payItemList.clear();
  67. _selectedGoods.value = null;
  68. if (response.payInfoList?.isNotEmpty == true) {
  69. payItemList.addAll(response.payInfoList!);
  70. }
  71. if (response.goodsList?.isNotEmpty == true) {
  72. goodsList.addAll(response.goodsList!);
  73. _selectedGoods.value = goodsList.first;
  74. }
  75. if (goodsList.isNotEmpty && payItemList.isNotEmpty) {
  76. memberRepository.setLastSelectedMember(
  77. goodsList.first, payItemList.first);
  78. }
  79. }).catchError((error) {
  80. ErrorHandler.toastError(error);
  81. });
  82. }
  83. void onBack() {
  84. if (Get.key.currentState?.canPop() == true) {
  85. Get.back();
  86. } else {
  87. MainPage.start();
  88. }
  89. }
  90. void onBuyClick() {
  91. if (payItemList.isEmpty) {
  92. ToastUtil.show(StringName.memberActivityNoPayway);
  93. return;
  94. }
  95. memberPayHelper.launchPay(selectedGoods, payItemList.first);
  96. }
  97. void onGoodsItemClick(GoodsBean goodsInfo) {
  98. _selectedGoods.value = goodsInfo;
  99. onBuyClick();
  100. }
  101. void onPrivacyPolicyClick() {
  102. BrowserPage.start(WebUrl.privacyPolicy);
  103. }
  104. void onTermOfServiceClick() {
  105. BrowserPage.start(WebUrl.userAgreement);
  106. }
  107. void onRenewalAgreementClick() {
  108. BrowserPage.start(WebUrl.renewalAgreement);
  109. }
  110. void onRecoverClick() async {
  111. if (payItemList.isNotEmpty) {
  112. ToastUtil.show(StringName.memberActivityNoPayway);
  113. return;
  114. }
  115. PayItemBean paymentWay = payItemList.first;
  116. CustomLoadingDialog.show();
  117. Future.delayed(const Duration(seconds: 20), () {
  118. CustomLoadingDialog.hide();
  119. });
  120. final result = await ApplePay().restore();
  121. if (result["success"] == true) {
  122. var receipt = result['receipt'];
  123. print('查找恢复记录成功: ${result['receipt']}');
  124. checkRestoreStatus(receipt, paymentWay);
  125. } else {
  126. CustomLoadingDialog.hide();
  127. ToastUtil.show("恢复失败");
  128. print('恢复失败: ${result['error']}');
  129. }
  130. }
  131. Future<void> checkRestoreStatus(
  132. String? receiptData, PayItemBean paymentWay) async {
  133. if (receiptData == null) {
  134. return;
  135. }
  136. memberRepository.subscriptionResume(3, receiptData).then((data) async {
  137. CustomLoadingDialog.hide();
  138. ToastUtil.show("恢复成功");
  139. await AccountRepository.getInstance().getMemberStatus();
  140. Get.back();
  141. }).catchError((error) {
  142. CustomLoadingDialog.hide();
  143. ToastUtil.show("恢复失败");
  144. });
  145. }
  146. @override
  147. void onClose() {
  148. super.onClose();
  149. _memberDataFuture?.cancel();
  150. }
  151. }