store_controller.dart 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. import 'dart:io';
  2. import 'package:apple_pay/apple_pay.dart';
  3. import 'package:classify_photo/classify_photo.dart';
  4. import 'package:clean/data/repositories/user_repository.dart';
  5. import 'package:clean/module/store/payment_status_manager.dart';
  6. import 'package:clean/router/app_pages.dart';
  7. import 'package:clean/utils/error_handler.dart';
  8. import 'package:flutter/Material.dart';
  9. import 'package:get/get.dart';
  10. import 'package:in_app_purchase/in_app_purchase.dart';
  11. import '../../base/base_controller.dart';
  12. import '../../data/api/response/order_pay_response.dart';
  13. import '../../data/bean/payment_way.dart';
  14. import '../../data/bean/store_item.dart';
  15. import '../../data/consts/constants.dart';
  16. import '../../data/consts/event_report_id.dart';
  17. import '../../data/repositories/store_repository.dart';
  18. import '../../dialog/loading_dialog.dart';
  19. import '../../handler/event_handler.dart';
  20. import '../../sdk/pay/agile_pay.dart';
  21. import '../../sdk/pay/applepay/apple_pay_info.dart';
  22. import '../../sdk/pay/assist/product_type.dart';
  23. import '../../utils/toast_util.dart';
  24. class StoreController extends BaseController implements PaymentStatusCallback {
  25. final RxList<StoreItem> storeItems = <StoreItem>[].obs;
  26. final RxList<PaymentWay> paymentWays = <PaymentWay>[].obs;
  27. final Rxn<StoreItem> currentSelectedStoreItem = Rxn<StoreItem>();
  28. final Rxn<PaymentWay> currentSelectedPaymentWay = Rxn<PaymentWay>();
  29. var freeAppleId = "";
  30. RxBool isFree = false.obs;
  31. @override
  32. Future<void> onInit() async {
  33. super.onInit();
  34. initStoreIndexData();
  35. }
  36. @override
  37. void onReady() {
  38. EventHandler.report(EventId.event_02001);
  39. super.onReady();
  40. }
  41. @override
  42. void onClose() {
  43. // TODO: implement onClose
  44. super.onClose();
  45. if (isFirstIntoStore() && !userRepository.isVip()) {
  46. Get.toNamed(RoutePath.discount);
  47. setFirstIntoStore(false);
  48. }
  49. }
  50. void initStoreIndexData() {
  51. LoadingDialog.show();
  52. storeRepository.storeIndex().then((indexData) async {
  53. storeItems.clear();
  54. storeItems.addAll(indexData.items);
  55. currentSelectedStoreItem.value =
  56. storeItems.isNotEmpty ? storeItems.first : null;
  57. paymentWays.clear();
  58. paymentWays.addAll(indexData.paymentWays);
  59. currentSelectedPaymentWay.value =
  60. paymentWays.isNotEmpty ? paymentWays.first : null;
  61. var freeAppleId = "";
  62. for (var item in storeItems) {
  63. if (item.freeTrialName != null) {
  64. freeAppleId = item.appleGoodsId;
  65. }
  66. }
  67. isFree.value = await ApplePay().check(freeAppleId);
  68. LoadingDialog.hide();
  69. });
  70. }
  71. Future<void> onRestoreClick() async {
  72. EventHandler.report(EventId.event_02004);
  73. PaymentWay? paymentWay = currentSelectedPaymentWay.value;
  74. if (paymentWay == null) {
  75. // ToastUtil.showToast(StringName.storeChoicePayment.tr);
  76. return;
  77. }
  78. int payPlatform = paymentWay.payPlatform;
  79. int payMethod = paymentWay.payMethod;
  80. LoadingDialog.show();
  81. Future.delayed(const Duration(seconds: 20), () {
  82. LoadingDialog.hide();
  83. ToastUtil.show("Restore record not found");
  84. });
  85. final result = await ApplePay().restore();
  86. if (result["success"] == true) {
  87. // LoadingDialog.hide();
  88. var receipt = result['receipt'];
  89. print('查找恢复记录成功: ${result['receipt']}');
  90. checkRestoreStatus(receipt);
  91. } else {
  92. LoadingDialog.hide();
  93. ToastUtil.show("Pay Error");
  94. print('恢复失败: ${result['error']}');
  95. }
  96. }
  97. void onBuyClick() async {
  98. EventHandler.report(EventId.event_02002);
  99. StoreItem? storeItem = currentSelectedStoreItem.value;
  100. if (storeItem == null) {
  101. // ToastUtil.showToast(StringName.storeChoiceGoods.tr);
  102. return;
  103. }
  104. PaymentWay? paymentWay = currentSelectedPaymentWay.value;
  105. if (paymentWay == null) {
  106. // ToastUtil.showToast(StringName.storeChoicePayment.tr);
  107. return;
  108. }
  109. int payPlatform = paymentWay.payPlatform;
  110. int payMethod = paymentWay.payMethod;
  111. LoadingDialog.show();
  112. try {
  113. // OrderPayResponse response =
  114. storeRepository.orderPay(storeItem.id, payPlatform, payMethod).then((response) async {
  115. dynamic payInfo;
  116. String outTradeNo = response.outTradeNo;
  117. if (payPlatform == PayPlatform.apple) {
  118. payInfo = ApplePayInfo(
  119. storeItem.appleGoodsId,
  120. storeItem.subscribable == 1
  121. ? ProductType.nonConsumable
  122. : ProductType.consumable,
  123. response.appAccountToken);
  124. }
  125. final result = await ApplePay().purchase(productId: storeItem.appleGoodsId, appAccountToken: response.appAccountToken);
  126. if (result["success"] == true) {
  127. var receipt = result['receipt'];
  128. print('购买成功: ${result['receipt']}');
  129. checkPaymentStatus(outTradeNo, paymentWay, storeItem, receiptData: receipt);
  130. } else {
  131. LoadingDialog.hide();
  132. ToastUtil.show("Pay Error, Please try again");
  133. print('购买失败: ${result['error']}');
  134. }
  135. }).catchError((error) {
  136. LoadingDialog.hide();
  137. ErrorHandler.toastError(error);
  138. });
  139. } catch (error) {
  140. LoadingDialog.hide();
  141. // ToastUtil.showToast(StringName.storePayError.tr);
  142. }
  143. }
  144. void closeBackClick(){
  145. EventHandler.report(EventId.event_02003);
  146. Get.back();
  147. }
  148. // 检查恢复订阅结果
  149. Future<void> checkRestoreStatus(String? receiptData) async {
  150. PaymentWay? paymentWay = currentSelectedPaymentWay.value;
  151. if (paymentWay == null) {
  152. // ToastUtil.showToast(StringName.storeChoicePayment.tr);
  153. return;
  154. }
  155. if (receiptData == null) {
  156. return;
  157. }
  158. int payPlatform = paymentWay.payPlatform;
  159. int payMethod = paymentWay.payMethod;
  160. // var code = await storeRepository.resume(payPlatform, payMethod, receiptData);
  161. storeRepository.resume(payPlatform, payMethod, receiptData).then((data) {
  162. LoadingDialog.hide();
  163. ToastUtil.show("Restore success");
  164. userRepository.getUserInfo();
  165. Get.back();
  166. }).catchError((error) {
  167. LoadingDialog.hide();
  168. ToastUtil.show("Restore fail");
  169. });
  170. // if (code == 0) {
  171. // LoadingDialog.hide();
  172. // ToastUtil.show("Restore success");
  173. // userRepository.getUserInfo();
  174. // Get.back();
  175. // } else {
  176. // LoadingDialog.hide();
  177. // ToastUtil.show("Restore fail");
  178. // }
  179. }
  180. void checkPaymentStatus(
  181. String orderNo, PaymentWay paymentWay, StoreItem storeItemBean,
  182. {String? receiptData}) {
  183. paymentStatusManager.registerPaymentSuccessCallback(orderNo, this);
  184. paymentStatusManager.checkPaymentStatus(orderNo, paymentWay, storeItemBean,
  185. receiptData: receiptData);
  186. }
  187. @override
  188. void onPaymentSuccess(String orderNo, PaymentWay paymentWay, StoreItem storeItemBean) {
  189. // TODO: implement onPaymentSuccess
  190. LoadingDialog.hide();
  191. ToastUtil.show("Pay success");
  192. // 300ms后关闭弹窗
  193. Future.delayed(Duration(seconds: 3), () {
  194. userRepository.getUserInfo();
  195. });
  196. Get.back();
  197. }
  198. @override
  199. void onPaymentError(Error error) {
  200. // TODO: implement onPaymentError
  201. LoadingDialog.hide();
  202. ErrorHandler.toastError(error);
  203. }
  204. }