From 111fe42782af3a46045abeb1c0873f43cfc80d47 Mon Sep 17 00:00:00 2001 From: CodeST <694468528@qq.com> Date: Thu, 11 Dec 2025 17:51:00 +0800 Subject: [PATCH] 1 --- Shared/KBAPI.h | 1 + keyBoard/Class/Shop/VC/KBShopVC.m | 8 ++--- keyBoard/Class/Shop/VC/KBSkinDetailVC.m | 46 ++++++++++++++++++++----- keyBoard/Class/Shop/VM/KBShopVM.h | 5 ++- keyBoard/Class/Shop/VM/KBShopVM.m | 36 +++++++++++++------ 5 files changed, 71 insertions(+), 25 deletions(-) diff --git a/Shared/KBAPI.h b/Shared/KBAPI.h index 509f3c3..a6fbf56 100644 --- a/Shared/KBAPI.h +++ b/Shared/KBAPI.h @@ -53,6 +53,7 @@ #define API_THEME_DETAIL @"/themes/detail" // 查询主题详情 #define API_THEME_PURCHASE @"/themes/purchase" // 购买主题 #define API_THEME_DOWNLOAD @"/themes/download" // 主题下载信息 +#define API_THEME_RECOMMENDED @"/themes/recommended" // 推荐主题列表 /// pay #define API_VALIDATE_RECEIPT @"/api/apple/validate-receipt" // 排行榜标签列表 diff --git a/keyBoard/Class/Shop/VC/KBShopVC.m b/keyBoard/Class/Shop/VC/KBShopVC.m index d7ecb42..b9ff82e 100644 --- a/keyBoard/Class/Shop/VC/KBShopVC.m +++ b/keyBoard/Class/Shop/VC/KBShopVC.m @@ -279,7 +279,7 @@ static const CGFloat JXheightForHeaderInSection = 50; [KBHUD show]; } __weak typeof(self) weakSelf = self; - [self.shopVM fetchWalletBalanceWithCompletion:^(NSNumber * _Nullable balance, NSError * _Nullable error) { + [self.shopVM fetchWalletBalanceWithCompletion:^(NSString * _Nullable balance, NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (showHUD) { [KBHUD dismiss]; @@ -289,9 +289,9 @@ static const CGFloat JXheightForHeaderInSection = 50; [KBHUD showInfo:msg]; return; } - double amountValue = balance.doubleValue; - NSString *amountString = [NSString stringWithFormat:@"%.2f", amountValue]; - [weakSelf.userHeaderView updatePoints:amountString]; +// double amountValue = balance.doubleValue; +// NSString *amountString = [NSString stringWithFormat:@"%.2f", amountValue]; + [weakSelf.userHeaderView updatePoints:balance]; }); }]; } diff --git a/keyBoard/Class/Shop/VC/KBSkinDetailVC.m b/keyBoard/Class/Shop/VC/KBSkinDetailVC.m index fb12dd0..482ab79 100644 --- a/keyBoard/Class/Shop/VC/KBSkinDetailVC.m +++ b/keyBoard/Class/Shop/VC/KBSkinDetailVC.m @@ -13,6 +13,7 @@ #import "KBSkinBottomActionView.h" #import "KBShopVM.h" #import "KBShopThemeTagModel.h" +#import "KBShopThemeModel.h" #import "KBHUD.h" #import "KBSkinService.h" @@ -33,7 +34,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { @property (nonatomic, strong) UICollectionView *collectionView; // 主列表 @property (nonatomic, strong) KBSkinBottomActionView *bottomBar; // 底部操作条 @property (nonatomic, copy) NSArray *tags; // 标签数据 -@property (nonatomic, copy) NSArray *gridData; // 底部网格数据 +@property (nonatomic, copy) NSArray *recommendedThemes; // 底部网格数据 @property (nonatomic, strong) KBShopVM *shopVM; @property (nonatomic, strong, nullable) KBShopThemeDetailModel *detailModel; //@property (nonatomic, assign) BOOL isProcessingAction; @@ -46,11 +47,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { self.view.backgroundColor = [UIColor whiteColor]; self.tags = @[]; - self.gridData = @[ - @{ @"title": @"Dopamine" }, @{ @"title": @"Dopamine" }, - @{ @"title": @"Dopamine" }, @{ @"title": @"Dopamine" }, - @{ @"title": @"Dopamine" }, @{ @"title": @"Dopamine" }, - ]; + self.recommendedThemes = @[]; // 1. 列表 [self.view addSubview:self.collectionView]; @@ -74,6 +71,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { [self updateBottomBarAppearance]; [self fetchThemeDetailIfNeeded]; + [self fetchRecommendedThemes]; } #pragma mark - UICollectionView DataSource @@ -87,7 +85,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { case KBSkinDetailSectionHeader: return 1; // 顶部大卡片 case KBSkinDetailSectionTags: return self.tags.count > 0 ? 1 : 0; case KBSkinDetailSectionTitle: return 1; // 标题 - case KBSkinDetailSectionGrid: return self.gridData.count; // 2 列网格 + case KBSkinDetailSectionGrid: return self.recommendedThemes.count; // 2 列网格 } return 0; } @@ -111,8 +109,11 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { } case KBSkinDetailSectionGrid: { KBSkinCardCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kGridCellId forIndexPath:indexPath]; - NSDictionary *d = self.gridData[indexPath.item]; - [cell configWithTitle:d[@"title"] imageURL:nil price:@"20"]; + KBShopThemeModel *model = self.recommendedThemes[indexPath.item]; + NSString *priceText = [self priceTextForTheme:model]; + [cell configWithTitle:model.themeName ?: @"" + imageURL:model.themePreviewImageUrl + price:priceText]; return cell; } } @@ -330,4 +331,31 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { return _shopVM; } +#pragma mark - Data + +- (void)fetchRecommendedThemes { + __weak typeof(self) weakSelf = self; + [self.shopVM fetchRecommendedThemesWithCompletion:^(NSArray * _Nullable themes, NSError * _Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (error) { + NSLog(@"[KBSkinDetailVC] fetch recommended failed: %@", error); + return; + } + weakSelf.recommendedThemes = themes ?: @[]; + NSIndexSet *sections = [NSIndexSet indexSetWithIndex:KBSkinDetailSectionGrid]; + [weakSelf.collectionView reloadSections:sections]; + }); + }]; +} + +- (NSString *)priceTextForTheme:(KBShopThemeModel *)model { +// if (model.isFree) { +// return KBLocalized(@"Free"); +// } + if (model.themePrice > 0.0) { + return [NSString stringWithFormat:@"%.2f", model.themePrice]; + } + return @"0"; +} + @end diff --git a/keyBoard/Class/Shop/VM/KBShopVM.h b/keyBoard/Class/Shop/VM/KBShopVM.h index a2afa1a..8d24cd5 100644 --- a/keyBoard/Class/Shop/VM/KBShopVM.h +++ b/keyBoard/Class/Shop/VM/KBShopVM.h @@ -19,7 +19,7 @@ typedef void(^KBShopStylesCompletion)(NSArray *_Nullable sty NSError *_Nullable error); typedef void(^KBShopThemesCompletion)(NSArray *_Nullable themes, NSError *_Nullable error); -typedef void(^KBShopBalanceCompletion)(NSNumber *_Nullable balance, +typedef void(^KBShopBalanceCompletion)(NSString *_Nullable balance, NSError *_Nullable error); typedef void(^KBShopDetailCompletion)(KBShopThemeDetailModel *_Nullable detail, NSError *_Nullable error); @@ -53,6 +53,9 @@ typedef void(^KBShopDownloadInfoCompletion)(NSDictionary *_Nullable info, - (void)fetchThemeDownloadInfoWithId:(nullable NSString *)themeId completion:(KBShopDownloadInfoCompletion)completion; +/// 推荐主题列表(用于皮肤详情页底部网格) +- (void)fetchRecommendedThemesWithCompletion:(KBShopThemesCompletion)completion; + @end NS_ASSUME_NONNULL_END diff --git a/keyBoard/Class/Shop/VM/KBShopVM.m b/keyBoard/Class/Shop/VM/KBShopVM.m index b9d072a..98b6470 100644 --- a/keyBoard/Class/Shop/VM/KBShopVM.m +++ b/keyBoard/Class/Shop/VM/KBShopVM.m @@ -100,17 +100,9 @@ if (completion) completion(nil, [self kb_invalidResponseError]); return; } - id balanceValue = dataObj[@"balance"]; - NSNumber *balanceNumber = nil; - if ([balanceValue isKindOfClass:[NSNumber class]]) { - balanceNumber = balanceValue; - } else if ([balanceValue isKindOfClass:[NSString class]]) { - balanceNumber = @([(NSString *)balanceValue doubleValue]); - } - if (!balanceNumber) { - balanceNumber = @(0); - } - if (completion) completion(balanceNumber, nil); + NSString * balanceValue = dataObj[@"balanceDisplay"]; + + if (completion) completion(balanceValue, nil); }]; } @@ -187,6 +179,28 @@ }]; } +- (void)fetchRecommendedThemesWithCompletion:(KBShopThemesCompletion)completion { + [[KBNetworkManager shared] GET:API_THEME_RECOMMENDED + parameters:nil + headers:nil + autoShowBusinessError:NO + completion:^(NSDictionary * _Nullable json, + NSURLResponse * _Nullable response, + NSError * _Nullable error) { + if (error) { + if (completion) completion(nil, error); + return; + } + id dataObj = json[KBData] ?: json[@"data"]; + if (![dataObj isKindOfClass:[NSArray class]]) { + if (completion) completion(nil, [self kb_invalidResponseError]); + return; + } + NSArray *list = [KBShopThemeModel mj_objectArrayWithKeyValuesArray:(NSArray *)dataObj]; + if (completion) completion(list, nil); + }]; +} + - (id)kb_themeIdParamFromString:(NSString *)themeId { if (themeId.length == 0) { return @""; } NSNumberFormatter *formatter = [NSNumberFormatter new];