// // JXMemberPromptViewController.m // AICity // // Feature: 003-ios-api-https // Task: T055 - iOS会员购买跳转 // Created on 2025-10-14. // #import "JXMemberPromptViewController.h" #import "JXMemberService.h" @interface JXMemberPromptViewController () // UI组件 @property (nonatomic, strong) UIView *containerView; @property (nonatomic, strong) UIButton *closeButton; @property (nonatomic, strong) UIImageView *contentIcon; @property (nonatomic, strong) UILabel *titleLabel; @property (nonatomic, strong) UILabel *descriptionLabel; @property (nonatomic, strong) UILabel *currentStatusLabel; @property (nonatomic, strong) UILabel *requiredStatusLabel; @property (nonatomic, strong) UILabel *benefitsLabel; @property (nonatomic, strong) UIButton *purchaseButton; @property (nonatomic, strong) UIButton *trialButton; @property (nonatomic, strong) UIButton *cancelButton; // 服务 @property (nonatomic, strong) JXMemberService *memberService; @end @implementation JXMemberPromptViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.8]; self.memberService = [JXMemberService sharedService]; [self setupUI]; [self updateUI]; } - (void)setupUI { // 容器视图 self.containerView = [[UIView alloc] init]; self.containerView.backgroundColor = [UIColor whiteColor]; self.containerView.layer.cornerRadius = 12.0; self.containerView.layer.masksToBounds = YES; [self.view addSubview:self.containerView]; // 关闭按钮 self.closeButton = [UIButton buttonWithType:UIButtonTypeSystem]; [self.closeButton setTitle:@"✕" forState:UIControlStateNormal]; self.closeButton.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightMedium]; [self.closeButton setTitleColor:[UIColor grayColor] forState:UIControlStateNormal]; [self.closeButton addTarget:self action:@selector(closeButtonTapped) forControlEvents:UIControlEventTouchUpInside]; [self.containerView addSubview:self.closeButton]; // 内容图标 self.contentIcon = [[UIImageView alloc] init]; self.contentIcon.image = [UIImage systemImageNamed:@"crown.fill"]; self.contentIcon.tintColor = [UIColor systemOrangeColor]; self.contentIcon.contentMode = UIViewContentModeScaleAspectFit; [self.containerView addSubview:self.contentIcon]; // 标题 self.titleLabel = [[UILabel alloc] init]; self.titleLabel.font = [UIFont systemFontOfSize:20 weight:UIFontWeightBold]; self.titleLabel.textColor = [UIColor blackColor]; self.titleLabel.textAlignment = NSTextAlignmentCenter; self.titleLabel.numberOfLines = 0; [self.containerView addSubview:self.titleLabel]; // 描述 self.descriptionLabel = [[UILabel alloc] init]; self.descriptionLabel.font = [UIFont systemFontOfSize:16]; self.descriptionLabel.textColor = [UIColor darkGrayColor]; self.descriptionLabel.textAlignment = NSTextAlignmentCenter; self.descriptionLabel.numberOfLines = 0; [self.containerView addSubview:self.descriptionLabel]; // 当前状态 self.currentStatusLabel = [[UILabel alloc] init]; self.currentStatusLabel.font = [UIFont systemFontOfSize:14]; self.currentStatusLabel.textColor = [UIColor grayColor]; self.currentStatusLabel.textAlignment = NSTextAlignmentCenter; [self.containerView addSubview:self.currentStatusLabel]; // 所需状态 self.requiredStatusLabel = [[UILabel alloc] init]; self.requiredStatusLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium]; self.requiredStatusLabel.textColor = [UIColor systemOrangeColor]; self.requiredStatusLabel.textAlignment = NSTextAlignmentCenter; [self.containerView addSubview:self.requiredStatusLabel]; // 权益说明 self.benefitsLabel = [[UILabel alloc] init]; self.benefitsLabel.font = [UIFont systemFontOfSize:14]; self.benefitsLabel.textColor = [UIColor darkGrayColor]; self.benefitsLabel.numberOfLines = 0; [self.containerView addSubview:self.benefitsLabel]; // 购买按钮 self.purchaseButton = [UIButton buttonWithType:UIButtonTypeSystem]; self.purchaseButton.backgroundColor = [UIColor systemOrangeColor]; [self.purchaseButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; self.purchaseButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium]; self.purchaseButton.layer.cornerRadius = 8.0; [self.purchaseButton addTarget:self action:@selector(purchaseButtonTapped) forControlEvents:UIControlEventTouchUpInside]; [self.containerView addSubview:self.purchaseButton]; // 试看按钮 self.trialButton = [UIButton buttonWithType:UIButtonTypeSystem]; [self.trialButton setTitle:@"免费试看3分钟" forState:UIControlStateNormal]; [self.trialButton setTitleColor:[UIColor systemBlueColor] forState:UIControlStateNormal]; self.trialButton.titleLabel.font = [UIFont systemFontOfSize:14]; self.trialButton.layer.borderWidth = 1.0; self.trialButton.layer.borderColor = [UIColor systemBlueColor].CGColor; self.trialButton.layer.cornerRadius = 6.0; [self.trialButton addTarget:self action:@selector(trialButtonTapped) forControlEvents:UIControlEventTouchUpInside]; [self.containerView addSubview:self.trialButton]; // 取消按钮 self.cancelButton = [UIButton buttonWithType:UIButtonTypeSystem]; [self.cancelButton setTitle:@"取消" forState:UIControlStateNormal]; [self.cancelButton setTitleColor:[UIColor grayColor] forState:UIControlStateNormal]; self.cancelButton.titleLabel.font = [UIFont systemFontOfSize:16]; [self.cancelButton addTarget:self action:@selector(cancelButtonTapped) forControlEvents:UIControlEventTouchUpInside]; [self.containerView addSubview:self.cancelButton]; [self setupConstraints]; } - (void)setupConstraints { // 使用Auto Layout设置约束 self.containerView.translatesAutoresizingMaskIntoConstraints = NO; self.closeButton.translatesAutoresizingMaskIntoConstraints = NO; self.contentIcon.translatesAutoresizingMaskIntoConstraints = NO; self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO; self.descriptionLabel.translatesAutoresizingMaskIntoConstraints = NO; self.currentStatusLabel.translatesAutoresizingMaskIntoConstraints = NO; self.requiredStatusLabel.translatesAutoresizingMaskIntoConstraints = NO; self.benefitsLabel.translatesAutoresizingMaskIntoConstraints = NO; self.purchaseButton.translatesAutoresizingMaskIntoConstraints = NO; self.trialButton.translatesAutoresizingMaskIntoConstraints = NO; self.cancelButton.translatesAutoresizingMaskIntoConstraints = NO; [NSLayoutConstraint activateConstraints:@[ // 容器视图 [self.containerView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor], [self.containerView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor], [self.containerView.widthAnchor constraintEqualToConstant:320], // 关闭按钮 [self.closeButton.topAnchor constraintEqualToAnchor:self.containerView.topAnchor constant:16], [self.closeButton.trailingAnchor constraintEqualToAnchor:self.containerView.trailingAnchor constant:-16], [self.closeButton.widthAnchor constraintEqualToConstant:30], [self.closeButton.heightAnchor constraintEqualToConstant:30], // 内容图标 [self.contentIcon.topAnchor constraintEqualToAnchor:self.containerView.topAnchor constant:24], [self.contentIcon.centerXAnchor constraintEqualToAnchor:self.containerView.centerXAnchor], [self.contentIcon.widthAnchor constraintEqualToConstant:48], [self.contentIcon.heightAnchor constraintEqualToConstant:48], // 标题 [self.titleLabel.topAnchor constraintEqualToAnchor:self.contentIcon.bottomAnchor constant:16], [self.titleLabel.leadingAnchor constraintEqualToAnchor:self.containerView.leadingAnchor constant:20], [self.titleLabel.trailingAnchor constraintEqualToAnchor:self.containerView.trailingAnchor constant:-20], // 描述 [self.descriptionLabel.topAnchor constraintEqualToAnchor:self.titleLabel.bottomAnchor constant:12], [self.descriptionLabel.leadingAnchor constraintEqualToAnchor:self.containerView.leadingAnchor constant:20], [self.descriptionLabel.trailingAnchor constraintEqualToAnchor:self.containerView.trailingAnchor constant:-20], // 当前状态 [self.currentStatusLabel.topAnchor constraintEqualToAnchor:self.descriptionLabel.bottomAnchor constant:16], [self.currentStatusLabel.leadingAnchor constraintEqualToAnchor:self.containerView.leadingAnchor constant:20], [self.currentStatusLabel.trailingAnchor constraintEqualToAnchor:self.containerView.trailingAnchor constant:-20], // 所需状态 [self.requiredStatusLabel.topAnchor constraintEqualToAnchor:self.currentStatusLabel.bottomAnchor constant:4], [self.requiredStatusLabel.leadingAnchor constraintEqualToAnchor:self.containerView.leadingAnchor constant:20], [self.requiredStatusLabel.trailingAnchor constraintEqualToAnchor:self.containerView.trailingAnchor constant:-20], // 权益说明 [self.benefitsLabel.topAnchor constraintEqualToAnchor:self.requiredStatusLabel.bottomAnchor constant:16], [self.benefitsLabel.leadingAnchor constraintEqualToAnchor:self.containerView.leadingAnchor constant:20], [self.benefitsLabel.trailingAnchor constraintEqualToAnchor:self.containerView.trailingAnchor constant:-20], // 购买按钮 [self.purchaseButton.topAnchor constraintEqualToAnchor:self.benefitsLabel.bottomAnchor constant:24], [self.purchaseButton.leadingAnchor constraintEqualToAnchor:self.containerView.leadingAnchor constant:20], [self.purchaseButton.trailingAnchor constraintEqualToAnchor:self.containerView.trailingAnchor constant:-20], [self.purchaseButton.heightAnchor constraintEqualToConstant:44], // 试看按钮 [self.trialButton.topAnchor constraintEqualToAnchor:self.purchaseButton.bottomAnchor constant:12], [self.trialButton.leadingAnchor constraintEqualToAnchor:self.containerView.leadingAnchor constant:20], [self.trialButton.trailingAnchor constraintEqualToAnchor:self.containerView.trailingAnchor constant:-20], [self.trialButton.heightAnchor constraintEqualToConstant:36], // 取消按钮 [self.cancelButton.topAnchor constraintEqualToAnchor:self.trialButton.bottomAnchor constant:12], [self.cancelButton.centerXAnchor constraintEqualToAnchor:self.containerView.centerXAnchor], [self.cancelButton.bottomAnchor constraintEqualToAnchor:self.containerView.bottomAnchor constant:-20], [self.cancelButton.heightAnchor constraintEqualToConstant:32] ]]; } - (void)updateUI { // 更新标题和描述 NSString *requiredMemberType = [self getRequiredMemberType:self.requiredLevel]; self.titleLabel.text = [NSString stringWithFormat:@"观看此内容需要%@权限", [self getMemberTypeDisplayName:requiredMemberType]]; switch (self.requiredLevel) { case 1: self.descriptionLabel.text = @"此为付费内容,需要开通会员才能观看完整视频"; break; case 2: self.descriptionLabel.text = @"此为高级内容,需要高级会员或VIP会员权限"; break; case 3: self.descriptionLabel.text = @"此为VIP专享内容,需要VIP会员权限"; break; default: self.descriptionLabel.text = @"此内容需要会员权限才能观看"; break; } // 更新当前状态 self.currentStatusLabel.text = [NSString stringWithFormat:@"当前状态:%@", [self getMemberTypeDisplayName:self.memberStatus.localMemberType]]; // 更新所需状态 self.requiredStatusLabel.text = [NSString stringWithFormat:@"所需权限:%@", [self getMemberTypeDisplayName:requiredMemberType]]; // 更新权益说明 [self updateBenefitsText:requiredMemberType]; // 更新按钮状态 [self updateButtonStates:requiredMemberType]; } - (void)updateBenefitsText:(NSString *)requiredMemberType { NSString *benefits; if ([requiredMemberType isEqualToString:@"basic"]) { benefits = @"• 观看所有付费内容\n• 无广告播放\n• 高清画质"; } else if ([requiredMemberType isEqualToString:@"premium"]) { benefits = @"• 观看所有付费和高级内容\n• 无广告播放\n• 超高清画质\n• 离线下载"; } else if ([requiredMemberType isEqualToString:@"vip"]) { benefits = @"• 观看所有内容包括VIP专享\n• 无广告播放\n• 4K超高清画质\n• 离线下载\n• 优先客服支持"; } else { benefits = @"• 观看付费内容\n• 更好的观看体验"; } self.benefitsLabel.text = benefits; } - (void)updateButtonStates:(NSString *)requiredMemberType { // 根据当前会员状态和所需权限更新按钮显示 BOOL canUpgrade = [self canUpgradeToRequiredLevel:self.memberStatus.localMemberType requiredType:requiredMemberType]; self.purchaseButton.enabled = canUpgrade; if ([self.memberStatus.localMemberType isEqualToString:@"free"]) { [self.purchaseButton setTitle:[NSString stringWithFormat:@"开通%@", [self getMemberTypeDisplayName:requiredMemberType]] forState:UIControlStateNormal]; } else if (canUpgrade) { [self.purchaseButton setTitle:[NSString stringWithFormat:@"升级到%@", [self getMemberTypeDisplayName:requiredMemberType]] forState:UIControlStateNormal]; } else { [self.purchaseButton setTitle:[NSString stringWithFormat:@"已是%@", [self getMemberTypeDisplayName:self.memberStatus.localMemberType]] forState:UIControlStateNormal]; } // 试看按钮(某些内容可能支持试看) self.trialButton.hidden = ![self supportsTrial:self.requiredLevel]; } #pragma mark - Button Actions - (void)closeButtonTapped { if (self.onCancel) { self.onCancel(); } [self dismissViewControllerAnimated:YES completion:nil]; } - (void)purchaseButtonTapped { [self navigateToMemberPurchase]; } - (void)trialButtonTapped { if (self.onTrialPlay) { self.onTrialPlay(3 * 60); // 3分钟试看 } [self dismissViewControllerAnimated:YES completion:nil]; } - (void)cancelButtonTapped { if (self.onCancel) { self.onCancel(); } [self dismissViewControllerAnimated:YES completion:nil]; } - (void)navigateToMemberPurchase { // 跳转到本APP的会员购买页面 // 这里需要根据实际的会员购买页面进行调整 // 方式1: 使用URL Scheme跳转 NSString *urlString = [NSString stringWithFormat:@"aicity://member/purchase?type=%@&source=juxing&episode=%@", [self getRequiredMemberType:self.requiredLevel], self.episodeId]; NSURL *url = [NSURL URLWithString:urlString]; if ([[UIApplication sharedApplication] canOpenURL:url]) { [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) { if (success) { // 跳转成功,监听会员购买结果 [self startMonitoringMemberPurchase]; } else { [self showFallbackPurchaseOptions]; } }]; } else { // 方式2: 发送通知跳转到主页面的会员购买Tab [[NSNotificationCenter defaultCenter] postNotificationName:@"ShowMemberPurchase" object:nil userInfo:@{ @"required_type": [self getRequiredMemberType:self.requiredLevel], @"source": @"juxing_player", @"episode_id": self.episodeId ?: @"" }]; [self showFallbackPurchaseOptions]; } } - (void)showFallbackPurchaseOptions { UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"开通会员" message:@"请前往主页面开通会员" preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"前往主页" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { // 跳转到主页面 [[NSNotificationCenter defaultCenter] postNotificationName:@"NavigateToMainPage" object:nil]; if (self.onCancel) { self.onCancel(); } [self dismissViewControllerAnimated:YES completion:nil]; }]]; [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]]; [self presentViewController:alert animated:YES completion:nil]; } - (void)startMonitoringMemberPurchase { // 监听会员购买成功通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(memberPurchaseSuccessNotification:) name:@"MemberPurchaseSuccess" object:nil]; // 设置超时监听(30秒后停止监听) dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(30.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] removeObserver:self name:@"MemberPurchaseSuccess" object:nil]; }); } - (void)memberPurchaseSuccessNotification:(NSNotification *)notification { [[NSNotificationCenter defaultCenter] removeObserver:self name:@"MemberPurchaseSuccess" object:nil]; // 刷新会员状态 [self refreshMemberStatusAndPlay]; } - (void)refreshMemberStatusAndPlay { [self.memberService getCurrentMemberStatusWithForceRefresh:YES completion:^(JXMemberStatus * _Nullable memberStatus, NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (error) { [self showAlert:@"获取会员状态失败" message:error.localizedDescription]; return; } // 检查是否现在有权限 if (memberStatus.accessLevel >= self.requiredLevel) { [self showAlert:@"会员开通成功!" message:@"即将开始播放"]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ if (self.onMemberPurchaseSuccess) { self.onMemberPurchaseSuccess(); } [self dismissViewControllerAnimated:YES completion:nil]; }); } else { [self showAlert:@"会员权限不足" message:@"请升级会员"]; // 更新UI显示最新状态 self.memberStatus = memberStatus; [self updateUI]; } }); }]; } #pragma mark - Helper Methods - (NSString *)getRequiredMemberType:(NSInteger)level { switch (level) { case 0: return @"free"; case 1: return @"basic"; case 2: return @"premium"; case 3: return @"vip"; default: return @"basic"; } } - (NSString *)getMemberTypeDisplayName:(NSString *)memberType { if ([memberType isEqualToString:@"free"]) { return @"免费用户"; } else if ([memberType isEqualToString:@"basic"]) { return @"基础会员"; } else if ([memberType isEqualToString:@"premium"]) { return @"高级会员"; } else if ([memberType isEqualToString:@"vip"]) { return @"VIP会员"; } else { return @"未知类型"; } } - (BOOL)canUpgradeToRequiredLevel:(NSString *)currentType requiredType:(NSString *)requiredType { NSInteger currentLevel = [self getMemberLevel:currentType]; NSInteger requiredLevel = [self getMemberLevel:requiredType]; return currentLevel < requiredLevel; } - (NSInteger)getMemberLevel:(NSString *)memberType { if ([memberType isEqualToString:@"free"]) { return 0; } else if ([memberType isEqualToString:@"basic"]) { return 1; } else if ([memberType isEqualToString:@"premium"]) { return 2; } else if ([memberType isEqualToString:@"vip"]) { return 3; } else { return 0; } } - (BOOL)supportsTrial:(NSInteger)requiredLevel { // 某些内容可能支持试看功能 return requiredLevel <= 2; // 只有基础和高级内容支持试看,VIP内容不支持 } - (void)showAlert:(NSString *)title message:(NSString *)message { UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]]; [self presentViewController:alert animated:YES completion:nil]; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } @end