// // YMIAPRechargeViewController.m // YUMI // // Created by XY on 2023/2/21. // #import "XPIAPRechargeViewController.h" ///Third #import #import ///Tool #import "DJDKMIMOMColor.h" #import "YUMIMacroUitls.h" #import "YUMIHtmlUrl.h" #import "RechargeStorage.h" #import "AccountInfoStorage.h" #import "NSObject+MJExtension.h" #import "NSArray+Safe.h" #import "UIImage+Utils.h" ///Model #import "RechargeListModel.h" ///View #import "XPIAPRechargeHeaderView.h" #import "XPIAPRechargeCollectionViewCell.h" #import "XPMineRechargeNavView.h" ///P #import "XPMineRechargePresenter.h" #import "XPMineRechargeProtocol.h" ///VC #import "XPWebViewController.h" #import "XPIAPRechargeHeadCell.h" #import "SessionViewController.h" #import "ClientConfig.h" #import "Api+Main.h" #import "YuMi-swift.h" #define kHeaderViewHeight 220.0/375.0*KScreenWidth @interface XPIAPRechargeViewController () @property (nonatomic, strong) UICollectionView *collectionView; /// 头部 @property (nonatomic, strong) XPIAPRechargeHeaderView *headerView; /// 充值按钮 @property (nonatomic, strong) UIButton *rechargeBtn; /// @property (nonatomic,strong) UIStackView *stackView; ///同意 @property (nonatomic,strong) UILabel *agreeLabel; ///充值协议 @property (nonatomic,strong) UIButton *protcoloButton; /// 返回 @property (nonatomic,strong) UIButton *backBtn; /// 标题 @property (nonatomic,strong) UILabel *titleLabel; /// 数据源 @property (nonatomic, strong) NSArray *dataSource; /// 选中下标 @property (nonatomic, strong) NSIndexPath *selectedIndex; /// 订单编号 @property (nonatomic,copy) NSString *orderId; //////充值banner位 @property(nonatomic,copy) NSArray *bannerList; @end @implementation XPIAPRechargeViewController - (void)dealloc { } - (BOOL)isHiddenNavBar { return YES; } - (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; } - (XPMineRechargePresenter *)createPresenter { return [[XPMineRechargePresenter alloc] init]; } - (void)viewDidLoad { [super viewDidLoad]; if([ClientConfig shareConfig].canOpen){ [self showLoading]; [Api requestMineChannel:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { [self hideHUD]; if(code == 200){ if(data.data[@"isNative"] != nil){ BOOL is = [data.data[@"isNative"] boolValue]; [self initWebView:is]; } return; } [self initWebView:YES]; }]; return; } [self initWebView:YES]; } -(void)initWebView:(BOOL)is{ if(is == YES){ [self createUI]; [self initHttpData]; return; } XPWebViewController *vc = [[XPWebViewController alloc]init]; NSString *channel = @"p"; channel = [NSString stringWithFormat:@"%@a",channel]; channel = [NSString stringWithFormat:@"%@y",channel]; NSString *url = [NSString stringWithFormat:URLWithType(kTreasureTicketBuyURL),channel,self.type,[YYUtility deviceID]]; vc.url = url; [self addChildViewController:vc]; vc.view.frame = self.view.frame; [self.view addSubview:vc.view]; } - (void)createUI { self.view.backgroundColor = [UIColor whiteColor]; [self.view addSubview:self.headerView]; [self.view addSubview:self.collectionView]; [self.view addSubview:self.rechargeBtn]; [self.view addSubview:self.stackView]; [self.view addSubview:self.titleLabel]; [self.view addSubview:self.backBtn]; [self.stackView addArrangedSubview:self.agreeLabel]; [self.stackView addArrangedSubview:self.protcoloButton]; CGFloat height = kGetScaleWidth(123)+kNavigationHeight; [self.headerView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.top.mas_equalTo(0); make.height.mas_equalTo(height); }]; [self.stackView mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.mas_equalTo(self.view); make.bottom.mas_equalTo(-34); make.height.mas_equalTo(kGetScaleWidth(14)); }]; [self.rechargeBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.width.mas_equalTo(kGetScaleWidth(343)); make.height.mas_equalTo(kGetScaleWidth(56)); make.centerX.equalTo(self.view); make.bottom.equalTo(self.stackView.mas_top).mas_offset(-kGetScaleWidth(10)); }]; [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.headerView.mas_bottom).mas_offset(-kGetScaleWidth(22)); make.left.right.mas_equalTo(0); make.bottom.equalTo(self.rechargeBtn.mas_top).mas_offset(-kGetScaleWidth(10)); }]; [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(kStatusBarHeight); make.height.mas_equalTo(44); make.centerX.mas_equalTo(self.view); }]; [self.backBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.left.mas_equalTo(0); make.top.mas_equalTo(kStatusBarHeight); make.width.height.mas_equalTo(44); }]; } - (void)initHttpData { [self getRechargeList]; if([ClientConfig shareConfig].canOpen){ [self.presenter getBannerList]; } [self getUserWalletBalanceInfo]; [self checkTranscationIds]; } /// 返回 - (void)backBtnAction { if(self.isFairyPay){ [UIView animateWithDuration:0.5 animations:^{ self.view.frame = CGRectMake(0, KScreenHeight, KScreenWidth, KScreenHeight); }completion:^(BOOL finished) { [self.view removeFromSuperview]; [self removeFromParentViewController]; }]; return; } [self.navigationController popViewControllerAnimated:YES]; } /// 点击充值按钮 - (void)rechargeBtnAction { if(self.selectedIndex == nil){ [self showSuccessToast:YMLocalizedString(@"XPIAPRechargeViewController11")]; return; } NSInteger index = self.bannerList.count > 0 ? self.selectedIndex.row - 1 : self.selectedIndex.row; if(index < self.dataSource.count){ RechargeListModel *model = [self.dataSource safeObjectAtIndex1:index]; if (model.chargeProdId) { [XNDJTDDLoadingTool showOnlyView:kWindow]; [self.presenter requestIAPRechargeOrderWithChargeProdId:model.chargeProdId]; } } } - (void)protcoloButtonAction:(UIButton *)sender { if(self.isFairyPay){ XPWebViewController * webVC= [[XPWebViewController alloc] initWithCustomizeNav:YES]; webVC.url = URLWithType(kRechargePrivacyURL); webVC.is_Pi_FairyPay = YES; webVC.view.backgroundColor = [UIColor whiteColor]; [self addChildViewController:webVC]; [self.view addSubview:webVC.view]; webVC.view.frame = CGRectMake(0, 0, KScreenWidth, KScreenHeight); return; } XPWebViewController * webVC= [[XPWebViewController alloc] init]; webVC.url = URLWithType(kRechargePrivacyURL); [self.navigationController pushViewController:webVC animated:YES]; } - (void)getRechargeList { [self.presenter requestRechargeListWithChannel:@"8"]; } - (void)getUserWalletBalanceInfo { [self.presenter getUserWalletInfo]; } - (void)getBannerListSuccessWithList:(NSArray *)list{ self.bannerList = list; if(self.bannerList.count > 0){ self.selectedIndex = [NSIndexPath indexPathForRow:1 inSection:0]; }else{ self.selectedIndex = [NSIndexPath indexPathForRow:0 inSection:0]; } [self.collectionView reloadData]; } ///批量验证 - (void)checkTranscationIds { NSString * uid = [AccountInfoStorage instance].getUid; NSArray * array = [RechargeStorage getAllReciptsWithUid:uid]; // [self.presenter checkReceiptWithOrderId:self.orderId transcationId:transactionIdentifier]; // NSMutableArray *list = [NSMutableArray array]; // for (NSDictionary *transcationDic in array) { // NSString *transcationId = transcationDic[@"transcationId"]; // if(transcationId){ // [list addObject:transcationId]; // } // } // if(list.count > 0){ // if (@available(iOS 15.0, *)) { // PIIAPRegulate *iap = [PIIAPRegulate shared]; // [iap allTransactionWithList:list completionHandler:^{ // // }]; // // } // } for (NSDictionary *transcation in array) { NSString *orderId = transcation[@"orderId"]; NSString *transcationId = transcation[@"transcationId"]; ///二次验证 [self.presenter checkReceiptWithOrderId:orderId transcationId:transcationId errorToast:NO]; } } ///充值成功之后保存订单到钥匙串 - (void)saveRechageReciptWithTransactionIdentifier:(NSString *)transactionIdentifier { NSData *receipt = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]]; NSString *encodeStr = [receipt base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]; NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; if(transactionIdentifier != nil){ [dictionary setObject:transactionIdentifier forKey:@"transcationId"]; } if(encodeStr != nil){ [dictionary setObject:encodeStr forKey:@"recipt"]; } if(self.orderId != nil){ [dictionary setObject:self.orderId forKey:@"orderId"]; } if(dictionary.allKeys.count == 0)return; NSString *reciptJson = [dictionary toJSONString]; NSString * uid = [AccountInfoStorage instance].getUid; BOOL saveSuccess = [RechargeStorage saveTranscationId:transactionIdentifier recipt:reciptJson uid:uid]; if (!saveSuccess) { #warning to do 保存失败 需要埋点 } } ///删除本地保存的 - (void)deleteRechageReciptWithTransactionIdentifier:(NSString *)transactionIdentifier { NSString * uid = [AccountInfoStorage instance].getUid; BOOL deleteSuccess = [RechargeStorage delegateTranscationId:transactionIdentifier uid:uid]; if (deleteSuccess) { #warning to do 保存失败 需要埋点 } } #pragma mark - XPMineRechargeNavViewDelegate - (void)xPMineRechargeNavView:(XPMineRechargeNavView *)view didClickBackButton:(UIButton *)sender { [self.navigationController popViewControllerAnimated:YES]; } #pragma mark - XPIAPHelperDelegate ///当前充值的状态 - (void)rechargeNewProcessStatus:(StoreConditionResult)status { if (status == StoreConditionResultPay || status == StoreConditionResultStart || status == StoreConditionResultVerifiedServer) { }else if (status == StoreConditionResultUnowned) { [XNDJTDDLoadingTool hideHUDInView:kWindow]; [self showErrorToast:YMLocalizedString(@"XPIAPRechargeViewController1")]; }else{ [XNDJTDDLoadingTool hideHUDInView:kWindow]; [self showErrorToast:YMLocalizedString(@"XPIAPRechargeViewController0")]; } } ///充值成功回调id - (void)rechargeSuccess:(NSString *)transactionIdentifier { ///保存唯一凭证 [self saveRechageReciptWithTransactionIdentifier:transactionIdentifier]; ///二次验证 [self.presenter checkReceiptWithOrderId:self.orderId transcationId:transactionIdentifier errorToast:YES]; } #pragma mark - XPMineRechargeProtocol - (void)requestRechargeListSucccess:(NSArray *)list { self.dataSource = list; [self.collectionView reloadData]; } - (void)requestIAPRechargeOrderSuccess:(NSString *)orderId chargeProdId:(NSString *)chargeProdId uuid:(nonnull NSString *)uuid{ if (orderId.length > 0) { self.orderId = orderId; if (@available(iOS 15.0, *)) { PIIAPRegulate *iap = [PIIAPRegulate shared]; [iap demandCommodityThingWithProductId:chargeProdId uuid:uuid completionHandler:^(NSError * _Nullable error) { }]; @kWeakify(self); iap.ConditionBlock = ^(enum StoreConditionResult state, NSDictionary * _Nullable result) { @kStrongify(self); [self rechargeNewProcessStatus:state]; switch (state) { case StoreConditionResultVerifiedServer: { NSString *transactionId = result[@"transactionId"]; [self rechargeSuccess:transactionId]; } break; default: { } break; } }; } else { [XNDJTDDLoadingTool hideHUDInView:kWindow]; [self showErrorToast:YMLocalizedString(@"XPIAPRechargeViewController10")]; } }else{ [XNDJTDDLoadingTool hideHUDInView:kWindow]; } } - (void)requestIAPRechargeOrderFailWithCode:(NSInteger)code { ///获取订单失败 [XNDJTDDLoadingTool hideHUDInView:kWindow]; if(code == 50000){ TTAlertConfig *config = [[TTAlertConfig alloc]init]; config.title = YMLocalizedString(@"XPIAPRechargeViewController7"); config.message = YMLocalizedString(@"XPIAPRechargeViewController8"); TTAlertButtonConfig *confirmButtonConfig = [[TTAlertButtonConfig alloc]init]; confirmButtonConfig.title = YMLocalizedString(@"XPIAPRechargeViewController9"); UIImage *image = [UIImage gradientColorImageFromColors:@[UIColorFromRGB(0x13E2F5),UIColorFromRGB(0x9DB4FF),UIColorFromRGB(0xCC67FF)] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(200, 200)]; confirmButtonConfig.backgroundColor = [UIColor colorWithPatternImage:image]; confirmButtonConfig.cornerRadius = 38/2; config.confirmButtonConfig = confirmButtonConfig; [TTPopup alertWithConfig:config confirmHandler:^{ [self.presenter getContactCustomerService]; } cancelHandler:^{ }]; } } - (void)getContactCustomerServiceSuccessWithUid:(NSString *)uid{ [self hideHUD]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NIMSession * session = [NIMSession session:uid type:NIMSessionTypeP2P]; SessionViewController * sessionVC = [[SessionViewController alloc] initWithSession:session]; [self.navigationController pushViewController:sessionVC animated:YES]; }); } ///二次验证成功 - (void)checkReceiptSuccess:(NSString *)transcationId { [XNDJTDDLoadingTool hideHUDInView:kWindow]; if (@available(iOS 15.0, *)) { PIIAPRegulate *iap = [PIIAPRegulate shared]; [iap verifyBusinessAccomplishWithTransaction:[NSString stringWithFormat:@"%@",transcationId] completionHandler:^{ }]; } [self deleteRechageReciptWithTransactionIdentifier:transcationId]; ///刷新一下用户的💎 [self getUserWalletBalanceInfo]; self.orderId = nil; if(self.delegate && [self.delegate respondsToSelector:@selector(paySuccess)]){ [self.delegate paySuccess]; } } -(void)checkReceiptFailWithCode:(NSInteger)code transcationId:(NSString *)transcationId{ [XNDJTDDLoadingTool hideHUDInView:kWindow]; if(code == 1444){ if (@available(iOS 15.0, *)) { PIIAPRegulate *iap = [PIIAPRegulate shared]; [iap verifyBusinessAccomplishWithTransaction:[NSString stringWithFormat:@"%@",transcationId] completionHandler:^{ }]; } [self deleteRechageReciptWithTransactionIdentifier:transcationId]; } } - (void)getUserWalletInfo:(WalletInfoModel *)balanceInfo { self.headerView.walletInfo = balanceInfo; } - (void)checkTranscationIdsSuccess { NSString * uid = [AccountInfoStorage instance].getUid; [RechargeStorage delegateAllTranscationIdsWithUid:uid]; } #pragma mark - UICollectionViewDelegate - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { if(self.bannerList.count > 0){ return self.dataSource.count + 1; } return self.dataSource.count; } - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{ return self.bannerList.count > 0 && indexPath.row == 0 ? CGSizeMake(KScreenWidth, kGetScaleWidth(114)) : CGSizeMake(KScreenWidth, kGetScaleWidth(80)); } - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { if(indexPath.row == 0 && self.bannerList.count > 0){ XPIAPRechargeHeadCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([XPIAPRechargeHeadCell class]) forIndexPath:indexPath]; cell.bannerList = self.bannerList; cell.delegate = self; return cell; } XPIAPRechargeCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass(XPIAPRechargeCollectionViewCell.self) forIndexPath:indexPath]; NSInteger count = self.bannerList.count > 0 ? indexPath.item - 1 : indexPath.item; cell.rechargeModel = [self.dataSource safeObjectAtIndex1:count]; cell.selectedStyle = self.selectedIndex.item == indexPath.item; return cell; } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { if(indexPath.row == 0 && self.bannerList.count > 0)return; self.selectedIndex = indexPath; [collectionView reloadData]; } #pragma mark - XPIAPRechargeHeadCellDelegate - (void)xpIAPRechargeHeadCell:(XPIAPRechargeHeadCell *)cycleScrollView didSelectItemAtIndex:(NSInteger)index{ RechargeListModel *bannerModel = [self.bannerList safeObjectAtIndex1:index]; XPWebViewController * webVC= [[XPWebViewController alloc] init]; webVC.url = bannerModel.linkUrl; [self.navigationController pushViewController:webVC animated:YES]; } #pragma mark - 懒加载 - (UICollectionView *)collectionView { if (!_collectionView) { UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; layout.scrollDirection = UICollectionViewScrollDirectionVertical; layout.minimumLineSpacing = 0; layout.minimumInteritemSpacing = 0; layout.sectionInset = UIEdgeInsetsMake(kGetScaleWidth(16), 0, kGetScaleWidth(16), 0); _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout]; _collectionView.backgroundColor = UIColor.whiteColor; _collectionView.alwaysBounceVertical = YES; [_collectionView registerClass:[XPIAPRechargeCollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass(XPIAPRechargeCollectionViewCell.self)]; [_collectionView registerClass:[XPIAPRechargeHeadCell class] forCellWithReuseIdentifier:NSStringFromClass(XPIAPRechargeHeadCell.self)]; _collectionView.delegate = self; _collectionView.dataSource = self; _collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; _collectionView.layer.cornerRadius = kGetScaleWidth(16); _collectionView.layer.masksToBounds = YES; // _collectionView.contentInset = UIEdgeInsetsMake(kHeaderViewHeight, 0, 0, 0); } return _collectionView; } - (XPIAPRechargeHeaderView *)headerView { if (!_headerView) { _headerView = [[XPIAPRechargeHeaderView alloc] init]; } return _headerView; } - (UIButton *)rechargeBtn { if (!_rechargeBtn) { _rechargeBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_rechargeBtn setTitle:YMLocalizedString(@"XPIAPRechargeViewController2") forState:UIControlStateNormal]; [_rechargeBtn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; _rechargeBtn.titleLabel.font = kFontMedium(16); [_rechargeBtn setBackgroundImage:[UIImage gradientColorImageFromColors:@[[DJDKMIMOMColor confirmButtonGradientStartColor], [DJDKMIMOMColor confirmButtonGradientEndColor]] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(10, 10)] forState:UIControlStateNormal]; _rechargeBtn.layer.cornerRadius = kGetScaleWidth(56)/2; _rechargeBtn.clipsToBounds = YES; [_rechargeBtn addTarget:self action:@selector(rechargeBtnAction) forControlEvents:UIControlEventTouchUpInside]; } return _rechargeBtn; } - (UIStackView *)stackView { if (!_stackView) { _stackView = [[UIStackView alloc] init]; _stackView.axis = UILayoutConstraintAxisHorizontal; _stackView.distribution = UIStackViewDistributionFill; _stackView.alignment = UIStackViewAlignmentFill; _stackView.spacing = 2; } return _stackView; } - (UIButton *)protcoloButton { if (!_protcoloButton) { _protcoloButton = [UIButton buttonWithType:UIButtonTypeCustom]; [_protcoloButton setTitle:YMLocalizedString(@"XPIAPRechargeViewController3") forState:UIControlStateNormal]; [_protcoloButton setTitleColor:[DJDKMIMOMColor appMainColor] forState:UIControlStateNormal]; _protcoloButton.titleLabel.font = [UIFont systemFontOfSize:12]; [_protcoloButton addTarget:self action:@selector(protcoloButtonAction:) forControlEvents:UIControlEventTouchUpInside]; } return _protcoloButton; } - (UILabel *)agreeLabel { if (!_agreeLabel) { _agreeLabel = [[UILabel alloc] init]; _agreeLabel.text = YMLocalizedString(@"XPIAPRechargeViewController4"); _agreeLabel.font = [UIFont systemFontOfSize:12]; _agreeLabel.textColor = [DJDKMIMOMColor textThirdColor]; } return _agreeLabel; } - (UIButton *)backBtn { if (!_backBtn) { _backBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_backBtn setImage:[UIImage imageNamed:@"room_info_back"] forState:UIControlStateNormal]; [_backBtn addTarget:self action:@selector(backBtnAction) forControlEvents:UIControlEventTouchUpInside]; } return _backBtn; } - (UILabel *)titleLabel { if (!_titleLabel) { _titleLabel = [[UILabel alloc] init]; _titleLabel.text = YMLocalizedString(@"XPIAPRechargeViewController6"); _titleLabel.textColor = UIColor.whiteColor; _titleLabel.font = kFontSemibold(17); } return _titleLabel; } @end