| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482 |
- //
- // 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
|