store_controller.dart 7.3 KB

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