new_discount_controller.dart 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. import 'dart:io';
  2. import 'package:agile_pay/flutter_pay.dart';
  3. import 'package:apple_pay/apple_pay.dart';
  4. import 'package:carousel_slider/carousel_controller.dart';
  5. import 'package:carousel_slider/carousel_options.dart';
  6. import 'package:flutter/material.dart';
  7. import 'package:injectable/injectable.dart';
  8. import 'package:keyboard/base/base_controller.dart';
  9. import 'package:get/get.dart';
  10. import 'package:keyboard/data/bean/character_info.dart';
  11. import 'package:keyboard/module/store/new_discount/member_card_bean.dart';
  12. import 'package:keyboard/widget/platform_util.dart';
  13. import '../../../data/api/response/user_info_response.dart';
  14. import '../../../data/bean/goods_info.dart';
  15. import '../../../data/bean/member_info.dart';
  16. import '../../../data/bean/pay_way_info.dart';
  17. import '../../../data/bean/wechat_payment_sign_bean.dart';
  18. import '../../../data/consts/constants.dart';
  19. import '../../../data/consts/error_code.dart';
  20. import '../../../data/consts/payment_type.dart';
  21. import '../../../data/repository/account_repository.dart';
  22. import '../../../data/repository/store_repository.dart';
  23. import '../../../dialog/alipay_qr_code_dialog.dart';
  24. import '../../../dialog/loading_dialog.dart';
  25. import '../../../dialog/login/login_dialog.dart';
  26. import '../../../dialog/member_agreement_dialog.dart';
  27. import '../../../dialog/payment_fail_dialog.dart';
  28. import '../../../dialog/payment_success_dialog.dart';
  29. import '../../../dialog/wechat_qr_code_dialog.dart';
  30. import '../../../resource/assets.gen.dart';
  31. import '../../../resource/string.gen.dart';
  32. import '../../../utils/async_util.dart';
  33. import '../../../utils/atmob_log.dart';
  34. import '../../../utils/date_util.dart';
  35. import '../../../utils/error_handler.dart';
  36. import '../../../utils/http_handler.dart';
  37. import '../../../utils/payment_status_manager.dart';
  38. import '../../../utils/toast_util.dart';
  39. import '../store_banner_bean.dart';
  40. import '../subscribe/recover_subscribe_dialog.dart';
  41. import '../suprise/surprise_dialog.dart';
  42. import '../ticket/discount_ticket_dialog.dart';
  43. import 'new_discount_page.dart';
  44. @injectable
  45. class NewDiscountController extends BaseController
  46. implements PaymentStatusCallback {
  47. final String tag = "NewDiscountController";
  48. final StoreRepository storeRepository;
  49. final AccountRepository accountRepository;
  50. final PaymentStatusManager paymentStatusManager;
  51. RxList<GoodsInfo> get goodsInfoList =>
  52. storeRepository.newDiscountGoodsInfoList;
  53. RxList<PayWayInfo> get payWayList => storeRepository.newDiscountPayWayList;
  54. final Rxn<GoodsInfo> _selectedGoodsInfoItem = Rxn<GoodsInfo>();
  55. GoodsInfo? get selectedGoodsInfoItem => _selectedGoodsInfoItem.value;
  56. final Rxn<PayWayInfo> _selectedPayWay = Rxn<PayWayInfo>();
  57. PayWayInfo? get selectedPayWay => _selectedPayWay.value;
  58. CancelableFuture? _storeDataFuture;
  59. bool get isLogin => accountRepository.isLogin.value;
  60. final isAgree = false.obs;
  61. MemberInfo? get memberStatusInfo => accountRepository.memberStatusInfo.value;
  62. UserInfoResponse? get userInfo => accountRepository.userInfo.value;
  63. final RxList<GoodsInfo> filteredGoodsList = <GoodsInfo>[].obs;
  64. RxList<CharacterInfo> get _charactersList => storeRepository.charactersList;
  65. List<CharacterInfo> get charactersList => _charactersList;
  66. final CarouselSliderController carouselSliderController =
  67. CarouselSliderController();
  68. final RxInt _currentBanner = 0.obs;
  69. int get currentBannerIndex => _currentBanner.value;
  70. /// 轮播图控制器
  71. final List<AssetGenImage> bannerList = [
  72. Assets.images.iconNewDiscountBanner1,
  73. Assets.images.iconNewDiscountBanner2,
  74. Assets.images.iconNewDiscountBanner3,
  75. ];
  76. final List<MemberCardBean> memberCardList = [
  77. MemberCardBean(
  78. imageUrl: Assets.images.iconNewDiscountMembershipCard1,
  79. title: StringName.newDiscountMemberCard1Title,
  80. desc: StringName.newDiscountMemberCard1Desc,
  81. gradient: LinearGradient(
  82. begin: Alignment(0.50, -0.00),
  83. end: Alignment(0.50, 1.00),
  84. colors: [const Color(0xFFF1EDFF), const Color(0xFFFAF8FF)],
  85. ),
  86. ),
  87. MemberCardBean(
  88. imageUrl: Assets.images.iconNewDiscountMembershipCard2,
  89. title: StringName.newDiscountMemberCard2Title,
  90. desc: StringName.newDiscountMemberCard2Desc,
  91. gradient: LinearGradient(
  92. begin: Alignment(0.50, -0.00),
  93. end: Alignment(0.50, 1.00),
  94. colors: [const Color(0xFFDCF4C0), const Color(0xFFFAFFF3)],
  95. ),
  96. ),
  97. MemberCardBean(
  98. imageUrl: Assets.images.iconNewDiscountMembershipCard3,
  99. title: StringName.newDiscountMemberCard3Title,
  100. desc: StringName.newDiscountMemberCard3Desc,
  101. gradient: LinearGradient(
  102. begin: Alignment(0.50, -0.00),
  103. end: Alignment(0.50, 1.00),
  104. colors: [const Color(0xFFF9DBFF), const Color(0xFFFFFBFE)],
  105. ),
  106. ),
  107. MemberCardBean(
  108. imageUrl: Assets.images.iconNewDiscountMembershipCard4,
  109. title: StringName.newDiscountMemberCard4Title,
  110. desc: StringName.newDiscountMemberCard4Desc,
  111. gradient: LinearGradient(
  112. begin: Alignment(0.50, -0.00),
  113. end: Alignment(0.50, 1.00),
  114. colors: [const Color(0xFFDBECFF), const Color(0xFFFBFBFF)],
  115. ),
  116. ),
  117. MemberCardBean(
  118. imageUrl: Assets.images.iconNewDiscountMembershipCard5,
  119. title: StringName.newDiscountMemberCard5Title,
  120. desc: StringName.newDiscountMemberCard5Desc,
  121. gradient: LinearGradient(
  122. begin: Alignment(0.50, -0.00),
  123. end: Alignment(0.50, 1.00),
  124. colors: [const Color(0xFFFFF7DB), const Color(0xFFFFFDFB)],
  125. ),
  126. ),
  127. ];
  128. NewDiscountController(
  129. this.storeRepository,
  130. this.accountRepository,
  131. this.paymentStatusManager,
  132. );
  133. onBannerChanged(int index, CarouselPageChangedReason reason) {
  134. _currentBanner.value = index;
  135. }
  136. void refreshStoreData() {
  137. storeRepository.refreshNewDiscountGoodsInfoList();
  138. }
  139. void updateFilteredGoodsList() {
  140. if (_selectedPayWay.value == null) {
  141. return;
  142. }
  143. _selectedGoodsInfoItem.value = null;
  144. int selectedPayWayId = _selectedPayWay.value!.id;
  145. filteredGoodsList.assignAll(
  146. goodsInfoList.where((goods) {
  147. return goods.payOptionIds == null ||
  148. goods.payOptionIds!.contains(selectedPayWayId);
  149. }).toList(),
  150. );
  151. if (filteredGoodsList.isNotEmpty) {
  152. _selectedGoodsInfoItem.value = filteredGoodsList.first;
  153. }
  154. }
  155. void onGoodsItemClick(GoodsInfo goodsInfo) {
  156. _selectedGoodsInfoItem.value = goodsInfo;
  157. debugPrint("'item: ${goodsInfo.toJson()}");
  158. }
  159. void clickPayWaySwitch() {
  160. if (payWayList.isNotEmpty) {
  161. int currentIndex = payWayList.indexOf(
  162. _selectedPayWay.value ?? payWayList.first,
  163. );
  164. int nextIndex = (currentIndex + 1) % payWayList.length;
  165. _selectedPayWay.value = payWayList[nextIndex];
  166. updateFilteredGoodsList(); // 切换支付方式后,更新商品列表
  167. }
  168. }
  169. void clickBack() {
  170. Get.back();
  171. }
  172. void clickPayNow() {
  173. if (selectedGoodsInfoItem == null) {
  174. ToastUtil.show(StringName.memberPleaseChoiceGoods);
  175. return;
  176. }
  177. if (selectedPayWay == null) {
  178. ToastUtil.show(StringName.memberPleaseChoicePayment);
  179. return;
  180. }
  181. if (!isAgree.value) {
  182. MemberAgreementDialog.show(
  183. btnConfirm: () {
  184. isAgree.value = true;
  185. clickPayNow();
  186. },
  187. );
  188. return;
  189. }
  190. AtmobLog.d(tag, 'clickPayNow: ${selectedGoodsInfoItem!.toJson()}');
  191. final buyGoods = selectedGoodsInfoItem!;
  192. final buyPayWay = selectedPayWay!;
  193. int goodsId = buyGoods.id;
  194. int payPlatform = buyPayWay.payPlatform;
  195. int payMethod = buyPayWay.payMethod;
  196. int payWayType = getPayWayType(
  197. payMethod: payMethod,
  198. payPlatform: payPlatform,
  199. );
  200. LoadingDialog.show(StringName.payLoading);
  201. storeRepository
  202. .submitAndRequestPay(
  203. goodsId: goodsId,
  204. payPlatform: payPlatform,
  205. payMethod: payMethod,
  206. )
  207. .then((response) {
  208. if (payWayType == PayWayType.paymentWayWechat) {
  209. _onWeChatPay(
  210. response.outTradeNo,
  211. response.wechatPayPrepayJson!,
  212. payMethod,
  213. buyGoods,
  214. buyPayWay,
  215. );
  216. } else if (payWayType == PayWayType.paymentWayWechatScan) {
  217. _onWechatScanPay(
  218. response.outTradeNo,
  219. response.wechatPayQrcodeUrl!,
  220. buyPayWay,
  221. buyGoods,
  222. );
  223. } else if (payWayType == PayWayType.paymentWayAlipay) {
  224. _onAliPay(
  225. response.outTradeNo,
  226. response.alipayOrderString!,
  227. payMethod,
  228. buyGoods,
  229. buyPayWay,
  230. );
  231. } else if (payWayType == PayWayType.paymentWayAlipayScan) {
  232. _onAliScanPay(
  233. response.outTradeNo,
  234. response.alipayQrcodeHtml!,
  235. buyPayWay,
  236. buyGoods,
  237. );
  238. } else if (payWayType == PayWayType.paymentWayApple) {
  239. _onApplePay(
  240. response.outTradeNo,
  241. response.appAccountToken ?? "",
  242. buyPayWay,
  243. buyGoods,
  244. );
  245. } else {
  246. ToastUtil.show(StringName.payNotSupport);
  247. }
  248. })
  249. .catchError((error) {
  250. LoadingDialog.hide();
  251. if (error is ServerErrorException) {
  252. if (error.code == ErrorCode.payOrderError) {
  253. refreshStoreData();
  254. ToastUtil.show(error.message);
  255. } else if (error.code == ErrorCode.noLoginError) {
  256. ToastUtil.show(StringName.accountNoLogin);
  257. LoginDialog.show();
  258. } else {
  259. ToastUtil.show(error.message);
  260. paymentFail();
  261. }
  262. } else {
  263. ToastUtil.show(StringName.memberPaymentFailed);
  264. paymentFail();
  265. }
  266. })
  267. .whenComplete(() {
  268. if (PlatformUtil.isAndroid) {
  269. LoadingDialog.hide();
  270. }
  271. });
  272. }
  273. void paymentFail() {
  274. PaymentFailDialog.show(
  275. btnConfirm: () {
  276. clickPayNow();
  277. },
  278. );
  279. }
  280. void _onAliScanPay(
  281. String outTradeNo,
  282. String qrHtml,
  283. PayWayInfo payWayInfo,
  284. GoodsInfo goodsInfo,
  285. ) {
  286. AlipayQrCodeDialog.show(
  287. qrCodeHtml: qrHtml,
  288. loadSuccessCallback: () {
  289. checkPaymentStatus(outTradeNo, payWayInfo, goodsInfo);
  290. },
  291. onCloseCallback: () async {
  292. //关闭后再持续查询几秒
  293. CustomLoadingDialog.show();
  294. await Future.delayed(Duration(seconds: 4));
  295. paymentStatusManager.removePollingSubscription(outTradeNo);
  296. CustomLoadingDialog.hide();
  297. },
  298. );
  299. }
  300. void _onAliPay(
  301. String outTradeNo,
  302. String payJson,
  303. int payMethod,
  304. GoodsInfo buyGoods,
  305. PayWayInfo buyPayWay,
  306. ) {
  307. final payInfo = AliPayInfo(payJson);
  308. requestSdkPay(payInfo, outTradeNo, payMethod, buyGoods, buyPayWay);
  309. }
  310. void _onWeChatPay(
  311. String outTradeNo,
  312. String payJson,
  313. int payMethod,
  314. GoodsInfo buyGoods,
  315. PayWayInfo buyPayWay,
  316. ) {
  317. final bean = WechatPaymentSignBean.stringToBean(payJson);
  318. final payInfo = WechatPayInfo(
  319. appId: bean.appId,
  320. partnerId: bean.partnerId,
  321. prepayId: bean.prepayId,
  322. package: bean.package,
  323. noncestr: bean.nonceStr,
  324. timestamp: bean.timeStamp,
  325. sign: bean.sign,
  326. );
  327. requestSdkPay(payInfo, outTradeNo, payMethod, buyGoods, buyPayWay);
  328. }
  329. void _onWechatScanPay(
  330. String outTradeNo,
  331. String qrCodeUrl,
  332. PayWayInfo payWayInfo,
  333. GoodsInfo goodsInfo,
  334. ) {
  335. WechatQrCodeDialog.show(
  336. qrCodeUrl: qrCodeUrl,
  337. loadSuccessCallback: () {
  338. checkPaymentStatus(outTradeNo, payWayInfo, goodsInfo);
  339. },
  340. onCloseCallback: () async {
  341. //关闭后再持续查询几秒
  342. CustomLoadingDialog.show();
  343. await Future.delayed(Duration(seconds: 4));
  344. paymentStatusManager.removePollingSubscription(outTradeNo);
  345. CustomLoadingDialog.hide();
  346. },
  347. );
  348. }
  349. Future<void> _onApplePay(
  350. String outTradeNo,
  351. String appAccountToken,
  352. PayWayInfo payWayInfo,
  353. GoodsInfo goodsInfo,
  354. ) async {
  355. final result = await ApplePay().purchase(
  356. productId: goodsInfo.appleGoodsId,
  357. appAccountToken: appAccountToken,
  358. );
  359. if (result["success"] == true) {
  360. var receipt = result['receipt'];
  361. print('购买成功: ${result['receipt']}');
  362. checkPaymentStatus(
  363. outTradeNo,
  364. payWayInfo,
  365. goodsInfo,
  366. receiptData: receipt,
  367. );
  368. } else {
  369. LoadingDialog.hide();
  370. ToastUtil.show("支付失败,请稍后重试");
  371. print('购买失败: ${result['error']}');
  372. }
  373. }
  374. void checkPaymentStatus(
  375. String orderNo,
  376. PayWayInfo payWayInfo,
  377. GoodsInfo goodsInfo, {
  378. String? receiptData,
  379. }) {
  380. paymentStatusManager.registerPaymentSuccessCallback(orderNo, this);
  381. paymentStatusManager.checkPaymentStatus(
  382. orderNo,
  383. payWayInfo,
  384. goodsInfo,
  385. receiptData: receiptData,
  386. );
  387. }
  388. void requestSdkPay(
  389. dynamic payInfo,
  390. String outTradeNo,
  391. int payMethod,
  392. GoodsInfo buyGoods,
  393. PayWayInfo buyPayWay,
  394. ) {
  395. AgilePay.startPay(
  396. payInfo,
  397. success: (String? result) {
  398. LoadingDialog.show(StringName.payQuerypayState);
  399. checkPaymentStatus(
  400. outTradeNo,
  401. buyPayWay,
  402. buyGoods,
  403. receiptData: result,
  404. );
  405. },
  406. payError: (int error, String? errorMessage) {
  407. debugPrint('zk---payError: $error, $errorMessage');
  408. paymentFail();
  409. errorPayToast(error);
  410. errorEventReport(payMethod);
  411. },
  412. error: (int errno, String? error) {
  413. debugPrint('zk---error: $errno, $error');
  414. errorPayToast(errno);
  415. errorEventReport(payMethod);
  416. },
  417. );
  418. }
  419. void errorEventReport(int payMethod) {
  420. if (payMethod == PayMethod.wechat) {
  421. // EventHandler.report();
  422. } else if (payMethod == PayMethod.alipay) {
  423. // EventHandler.report();
  424. } else if (payMethod == PayMethod.apple) {
  425. // EventHandler.report();
  426. }
  427. }
  428. void errorPayToast(int errno) {
  429. if (errno == AgilePayCode.payCodeNotSupport) {
  430. ToastUtil.show(StringName.payNotSupport);
  431. } else if (errno == AgilePayCode.payCodeCancelError) {
  432. ToastUtil.show(StringName.payUserCancel);
  433. } else if (errno == AgilePayCode.payCodeWxEnvError) {
  434. ToastUtil.show(StringName.payWxEvnError);
  435. } else if (errno == AgilePayCode.payCodeNotConnectStore) {
  436. ToastUtil.show(StringName.payNotConnectStore);
  437. } else {
  438. ToastUtil.show(StringName.payError);
  439. }
  440. }
  441. @override
  442. void onReady() {
  443. super.onReady();
  444. // refreshStoreData();
  445. }
  446. @override
  447. void onInit() {
  448. super.onInit();
  449. if (goodsInfoList.isNotEmpty) {
  450. _selectedGoodsInfoItem.value = goodsInfoList.first;
  451. }
  452. if (payWayList.isNotEmpty) {
  453. _selectedPayWay.value = payWayList.first;
  454. updateFilteredGoodsList();
  455. }
  456. ever<List<GoodsInfo>>(goodsInfoList, (list) {
  457. if (list.isNotEmpty) {
  458. _selectedGoodsInfoItem.value = list.first;
  459. }
  460. });
  461. ever<List<PayWayInfo>>(payWayList, (list) {
  462. if (list.isNotEmpty) {
  463. _selectedPayWay.value = list.first;
  464. updateFilteredGoodsList();
  465. }
  466. });
  467. }
  468. @override
  469. void onClose() {
  470. super.onClose();
  471. _storeDataFuture?.cancel();
  472. paymentStatusManager.unregisterPaymentSuccessCallback(this);
  473. if (!isFirstIntoDiscount() && !accountRepository.isVipUser) {
  474. if (PlatformUtil.isAndroid) {
  475. SurpriseDialog.show(
  476. clickConfirm: () {
  477. NewDiscountPage.start();
  478. },
  479. clickCancel: () {},
  480. );
  481. }
  482. if (PlatformUtil.isIOS) {
  483. DiscountTicketDialog.show(
  484. clickConfirm: () {
  485. NewDiscountPage.start();
  486. },
  487. clickCancel: () {},
  488. );
  489. }
  490. } else {
  491. setFirstIntoDiscount(false);
  492. }
  493. }
  494. @override
  495. void onPaymentSuccess(
  496. String orderNo,
  497. PayWayInfo payWayInfo,
  498. GoodsInfo goodsInfo,
  499. ) {
  500. if (PlatformUtil.isIOS) {
  501. accountRepository.refreshUserInfo();
  502. // 300ms后关闭弹窗
  503. Future.delayed(Duration(seconds: 2), () {
  504. LoadingDialog.hide();
  505. AtmobLog.d(tag, 'onPaymentSuccess: $orderNo');
  506. Get.back();
  507. PaymentSuccessDialog.show(
  508. goodsInfo: goodsInfo,
  509. btnConfirm: () {
  510. AtmobLog.d(tag, 'onGoodsItemClick: ${goodsInfo.toJson()}');
  511. },
  512. );
  513. });
  514. } else {
  515. LoadingDialog.hide();
  516. AtmobLog.d(tag, 'onPaymentSuccess: $orderNo');
  517. Get.back();
  518. PaymentSuccessDialog.show(
  519. goodsInfo: goodsInfo,
  520. btnConfirm: () {
  521. AtmobLog.d(tag, 'onGoodsItemClick: ${goodsInfo.toJson()}');
  522. },
  523. );
  524. }
  525. }
  526. @override
  527. void onPaymentError(Error error) {
  528. // TODO: implement onPaymentError
  529. if (PlatformUtil.isIOS) {
  530. LoadingDialog.hide();
  531. ErrorHandler.toastError(error);
  532. }
  533. }
  534. /// 恢复订阅
  535. Future<void> clickRestore() async {
  536. PayWayInfo? paymentWay = _selectedPayWay.value;
  537. if (paymentWay == null) {
  538. return;
  539. }
  540. int payPlatform = paymentWay.payPlatform;
  541. int payMethod = paymentWay.payMethod;
  542. CustomLoadingDialog.show();
  543. Future.delayed(const Duration(seconds: 20), () {
  544. CustomLoadingDialog.hide();
  545. ToastUtil.show("没有发现可恢复的记录");
  546. });
  547. final result = await ApplePay().restore();
  548. if (result["success"] == true) {
  549. // CustomLoadingDialog.hide();
  550. var receipt = result['receipt'];
  551. print('查找恢复记录成功: ${result['receipt']}');
  552. checkRestoreStatus(receipt);
  553. } else {
  554. CustomLoadingDialog.hide();
  555. ToastUtil.show("恢复失败");
  556. print('恢复失败: ${result['error']}');
  557. }
  558. // 显示恢复订阅弹窗
  559. // RecoverSubscribeDialog.show("周会员2025年3月6日到期。", () {
  560. // AtmobLog.d(tag, "恢复订阅弹窗 => 点击确认");
  561. // });
  562. }
  563. /// 检查恢复订阅结果
  564. Future<void> checkRestoreStatus(String? receiptData) async {
  565. PayWayInfo? paymentWay = _selectedPayWay.value;
  566. if (paymentWay == null) {
  567. // ToastUtil.showToast(StringName.storeChoicePayment.tr);
  568. return;
  569. }
  570. if (receiptData == null) {
  571. return;
  572. }
  573. int payPlatform = paymentWay.payPlatform;
  574. int payMethod = paymentWay.payMethod;
  575. // var code = await storeRepository.resume(payPlatform, payMethod, receiptData);
  576. storeRepository
  577. .subscribeResume(payPlatform, payMethod, receiptData)
  578. .then((data) {
  579. CustomLoadingDialog.hide();
  580. ToastUtil.show("恢复成功");
  581. accountRepository.getUserInfo();
  582. Get.back();
  583. })
  584. .catchError((error) {
  585. CustomLoadingDialog.hide();
  586. ToastUtil.show("恢复失败");
  587. });
  588. // if (code == 0) {
  589. // CustomLoadingDialog.hide();
  590. // ToastUtil.show("Restore success");
  591. // userRepository.getUserInfo();
  592. // Get.back();
  593. // } else {
  594. // CustomLoadingDialog.hide();
  595. // ToastUtil.show("Restore fail");
  596. // }
  597. }
  598. /// 恢复订阅
  599. Future<void> clickRestore() async {
  600. PayWayInfo? paymentWay = _selectedPayWay.value;
  601. if (paymentWay == null) {
  602. return;
  603. }
  604. int payPlatform = paymentWay.payPlatform;
  605. int payMethod = paymentWay.payMethod;
  606. CustomLoadingDialog.show();
  607. Future.delayed(const Duration(seconds: 20), () {
  608. CustomLoadingDialog.hide();
  609. ToastUtil.show("Restore record not found");
  610. });
  611. final result = await ApplePay().restore();
  612. if (result["success"] == true) {
  613. // CustomLoadingDialog.hide();
  614. var receipt = result['receipt'];
  615. print('查找恢复记录成功: ${result['receipt']}');
  616. checkRestoreStatus(receipt);
  617. } else {
  618. CustomLoadingDialog.hide();
  619. ToastUtil.show("Pay Error");
  620. print('恢复失败: ${result['error']}');
  621. }
  622. // 显示恢复订阅弹窗
  623. // RecoverSubscribeDialog.show("周会员2025年3月6日到期。", () {
  624. // AtmobLog.d(tag, "恢复订阅弹窗 => 点击确认");
  625. // });
  626. }
  627. /// 检查恢复订阅结果
  628. Future<void> checkRestoreStatus(String? receiptData) async {
  629. PayWayInfo? paymentWay = _selectedPayWay.value;
  630. if (paymentWay == null) {
  631. // ToastUtil.showToast(StringName.storeChoicePayment.tr);
  632. return;
  633. }
  634. if (receiptData == null) {
  635. return;
  636. }
  637. int payPlatform = paymentWay.payPlatform;
  638. int payMethod = paymentWay.payMethod;
  639. // var code = await storeRepository.resume(payPlatform, payMethod, receiptData);
  640. storeRepository.subscribeResume(payPlatform, payMethod, receiptData).then((data) {
  641. CustomLoadingDialog.hide();
  642. ToastUtil.show("Restore success");
  643. accountRepository.getUserInfo();
  644. Get.back();
  645. }).catchError((error) {
  646. CustomLoadingDialog.hide();
  647. ToastUtil.show("Restore fail");
  648. });
  649. // if (code == 0) {
  650. // CustomLoadingDialog.hide();
  651. // ToastUtil.show("Restore success");
  652. // userRepository.getUserInfo();
  653. // Get.back();
  654. // } else {
  655. // CustomLoadingDialog.hide();
  656. // ToastUtil.show("Restore fail");
  657. // }
  658. }
  659. /// 恢复订阅
  660. Future<void> clickRestore() async {
  661. PayWayInfo? paymentWay = _selectedPayWay.value;
  662. if (paymentWay == null) {
  663. return;
  664. }
  665. int payPlatform = paymentWay.payPlatform;
  666. int payMethod = paymentWay.payMethod;
  667. CustomLoadingDialog.show();
  668. Future.delayed(const Duration(seconds: 20), () {
  669. CustomLoadingDialog.hide();
  670. ToastUtil.show("Restore record not found");
  671. });
  672. final result = await ApplePay().restore();
  673. if (result["success"] == true) {
  674. // CustomLoadingDialog.hide();
  675. var receipt = result['receipt'];
  676. print('查找恢复记录成功: ${result['receipt']}');
  677. checkRestoreStatus(receipt);
  678. } else {
  679. CustomLoadingDialog.hide();
  680. ToastUtil.show("Pay Error");
  681. print('恢复失败: ${result['error']}');
  682. }
  683. // 显示恢复订阅弹窗
  684. // RecoverSubscribeDialog.show("周会员2025年3月6日到期。", () {
  685. // AtmobLog.d(tag, "恢复订阅弹窗 => 点击确认");
  686. // });
  687. }
  688. /// 检查恢复订阅结果
  689. Future<void> checkRestoreStatus(String? receiptData) async {
  690. PayWayInfo? paymentWay = _selectedPayWay.value;
  691. if (paymentWay == null) {
  692. // ToastUtil.showToast(StringName.storeChoicePayment.tr);
  693. return;
  694. }
  695. if (receiptData == null) {
  696. return;
  697. }
  698. int payPlatform = paymentWay.payPlatform;
  699. int payMethod = paymentWay.payMethod;
  700. // var code = await storeRepository.resume(payPlatform, payMethod, receiptData);
  701. storeRepository.subscribeResume(payPlatform, payMethod, receiptData).then((data) {
  702. CustomLoadingDialog.hide();
  703. ToastUtil.show("Restore success");
  704. accountRepository.getUserInfo();
  705. Get.back();
  706. }).catchError((error) {
  707. CustomLoadingDialog.hide();
  708. ToastUtil.show("Restore fail");
  709. });
  710. // if (code == 0) {
  711. // CustomLoadingDialog.hide();
  712. // ToastUtil.show("Restore success");
  713. // userRepository.getUserInfo();
  714. // Get.back();
  715. // } else {
  716. // CustomLoadingDialog.hide();
  717. // ToastUtil.show("Restore fail");
  718. // }
  719. }
  720. }