diff --git a/Shared/KBAPI.h b/Shared/KBAPI.h index da520d6..b0c4fc3 100644 --- a/Shared/KBAPI.h +++ b/Shared/KBAPI.h @@ -20,6 +20,7 @@ #define API_APPLE_LOGIN @"/user/appleLogin" // Apple 登录 #define API_LOGOUT @"/user/logout" // 退出登录 #define KB_API_CHARACTER_LIST @"/character/list" // 排行榜角色列表 +#define KB_API_TAG_LIST @"/tag/list" // 排行榜标签列表 // 应用配置 #ifndef KB_API_APP_CONFIG diff --git a/keyBoard.xcodeproj/project.pbxproj b/keyBoard.xcodeproj/project.pbxproj index 1dd486e..bdac235 100644 --- a/keyBoard.xcodeproj/project.pbxproj +++ b/keyBoard.xcodeproj/project.pbxproj @@ -107,6 +107,7 @@ 0498BD742EE02E3D006CC1D5 /* KBRegistVerEmailVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD732EE02E3D006CC1D5 /* KBRegistVerEmailVC.m */; }; 0498BD782EE04286006CC1D5 /* KBHomeVM.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD772EE04286006CC1D5 /* KBHomeVM.m */; }; 0498BD7B2EE04518006CC1D5 /* KBCharacter.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD7A2EE04518006CC1D5 /* KBCharacter.m */; }; + 0498BD7E2EE04F9C006CC1D5 /* KBTag.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD7D2EE04F9C006CC1D5 /* KBTag.m */; }; 049FB20B2EC1C13800FAB05D /* KBSkinBottomActionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */; }; 049FB20E2EC1CD2800FAB05D /* KBAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB20D2EC1CD2800FAB05D /* KBAlert.m */; }; 049FB2112EC1F72F00FAB05D /* KBMyListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2102EC1F72F00FAB05D /* KBMyListCell.m */; }; @@ -391,6 +392,8 @@ 0498BD772EE04286006CC1D5 /* KBHomeVM.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBHomeVM.m; sourceTree = ""; }; 0498BD792EE04518006CC1D5 /* KBCharacter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBCharacter.h; sourceTree = ""; }; 0498BD7A2EE04518006CC1D5 /* KBCharacter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBCharacter.m; sourceTree = ""; }; + 0498BD7C2EE04F9C006CC1D5 /* KBTag.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBTag.h; sourceTree = ""; }; + 0498BD7D2EE04F9C006CC1D5 /* KBTag.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBTag.m; sourceTree = ""; }; 049FB2092EC1C13800FAB05D /* KBSkinBottomActionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinBottomActionView.h; sourceTree = ""; }; 049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinBottomActionView.m; sourceTree = ""; }; 049FB20C2EC1CD2800FAB05D /* KBAlert.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBAlert.h; sourceTree = ""; }; @@ -1032,6 +1035,8 @@ children = ( 0498BD792EE04518006CC1D5 /* KBCharacter.h */, 0498BD7A2EE04518006CC1D5 /* KBCharacter.m */, + 0498BD7C2EE04F9C006CC1D5 /* KBTag.h */, + 0498BD7D2EE04F9C006CC1D5 /* KBTag.m */, ); path = M; sourceTree = ""; @@ -1784,6 +1789,7 @@ 049FB2232EC311F900FAB05D /* KBPersonInfoVC.m in Sources */, 0498BD6B2EE025FC006CC1D5 /* KBForgetPwdVC.m in Sources */, 048908FE2EC0CC2400FABA60 /* UIScrollView+KBEmptyView.m in Sources */, + 0498BD7E2EE04F9C006CC1D5 /* KBTag.m in Sources */, 04791F922ED48010004E8522 /* KBNoticeVC.m in Sources */, 04FC970F2EB334F8007BD342 /* KBWebImageManager.m in Sources */, 04FC95CF2EB1E7A1007BD342 /* HomeVC.m in Sources */, diff --git a/keyBoard/Class/Home/M/KBTag.h b/keyBoard/Class/Home/M/KBTag.h new file mode 100644 index 0000000..3552895 --- /dev/null +++ b/keyBoard/Class/Home/M/KBTag.h @@ -0,0 +1,27 @@ +// +// KBTag.h +// 排行榜标签模型 +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/// 首页排行榜标签模型 +/// 对应后端 /tag/list 返回的单个元素: +/// { +/// "id": 0, +/// "tagName": "" +/// } +@interface KBTag : NSObject + +/// 标签 id(后端字段 id) +@property (nonatomic, copy, nullable) NSString *tagId; + +/// 标签名称(后端字段 tagName) +@property (nonatomic, copy, nullable) NSString *tagName; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/keyBoard/Class/Home/M/KBTag.m b/keyBoard/Class/Home/M/KBTag.m new file mode 100644 index 0000000..73a902d --- /dev/null +++ b/keyBoard/Class/Home/M/KBTag.m @@ -0,0 +1,17 @@ +// +// KBTag.m +// + +#import "KBTag.h" +#import + +@implementation KBTag + ++ (NSDictionary *)mj_replacedKeyFromPropertyName { + return @{ + @"tagId": @"id", + }; +} + +@end + diff --git a/keyBoard/Class/Home/VC/HomeRankVC.m b/keyBoard/Class/Home/VC/HomeRankVC.m index 4f3a531..86510f4 100644 --- a/keyBoard/Class/Home/VC/HomeRankVC.m +++ b/keyBoard/Class/Home/VC/HomeRankVC.m @@ -8,13 +8,16 @@ #import "HomeRankVC.h" #import "HomeRankContentVC.h" #import "KBCategoryTitleImageView.h" +#import "KBHomeVM.h" +#import "KBTag.h" @interface HomeRankVC () -@property (nonatomic, strong) NSArray *titles; +@property (nonatomic, strong) NSArray *titles; +@property (nonatomic, strong) NSArray *tags; @property (nonatomic, strong) JXCategoryTitleImageView *myCategoryView; @property (nonatomic, strong) JXCategoryListContainerView *listContainerView; @property (nonatomic, assign) JXCategoryTitleImageType currentType; - +@property (nonatomic, strong) KBHomeVM *homeVM; @end @implementation HomeRankVC @@ -23,21 +26,12 @@ [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor clearColor]; - self.titles = @[KBLocalized(@"螃蟹啊斯柯达积分卡"), - KBLocalized(@"小龙虾"), - KBLocalized(@"苹果"), - KBLocalized(@"胡萝卜"), - KBLocalized(@"葡萄"), - KBLocalized(@"西瓜")]; + self.titles = @[]; [self.view addSubview:self.myCategoryView]; [self.view addSubview:self.listContainerView]; self.listContainerView.scrollView.scrollEnabled = false; - NSArray *imageNames = @[@"home_item_normal", @"home_item_normal", @"home_item_normal", @"home_item_normal", @"home_item_normal", @"home_item_normal"]; - NSArray *selectedImageNames = @[@"home_item_selected", @"home_item_selected", @"home_item_selected", @"home_item_selected", @"home_item_selected", @"home_item_selected"]; - self.myCategoryView.titles = self.titles; -// self.myCategoryView.titleColorGradientEnabled = YES; - self.myCategoryView.imageInfoArray = imageNames; + // 静态样式配置(与数据无关) self.myCategoryView.cellBackgroundSelectedColor = [UIColor blackColor]; self.myCategoryView.cellBackgroundUnselectedColor = [UIColor colorWithHex:0xEAF8F4]; self.myCategoryView.titleColor = [UIColor colorWithHex:0x1B1F1A]; @@ -48,35 +42,50 @@ self.myCategoryView.titleLabelZoomScale = 1.0; self.myCategoryView.cellWidthZoomEnabled = NO; // 关闭cell宽度缩放 self.myCategoryView.cellWidthZoomScale = 1.0; - - self.myCategoryView.selectedImageInfoArray = selectedImageNames; - self.myCategoryView.loadImageBlock = ^(UIImageView *imageView, id info) { - NSString *imageName = info; - imageView.image = [UIImage imageNamed:imageName]; - }; self.myCategoryView.imageZoomEnabled = false; self.myCategoryView.imageZoomScale = 1.3; self.myCategoryView.averageCellSpacingEnabled = NO; - self.myCategoryView.cellBackgroundColorGradientEnabled = true; self.myCategoryView.cellWidthIncrement = 20; -// JXCategoryIndicatorLineView *lineView = [[JXCategoryIndicatorLineView alloc] init]; -// lineView.indicatorWidth = 20; -// self.myCategoryView.indicators = @[lineView]; -// JXCategoryIndicatorLineView *indicatorlineView = [[JXCategoryIndicatorLineView alloc]init]; -// indicatorlineView.indicatorHeight = 30; -// indicatorlineView.indicatorColor = UIColor.blackColor; -// indicatorlineView.verticalMargin = 10; -// indicatorlineView.indicatorWidthIncrement = 20; -// indicatorlineView.indicatorCornerRadius = 4; -// UIImage *bgImage = [UIImage kb_imageWithColor:[UIColor blackColor] size:CGSizeMake(30, 30)]; -//// UIImage *bgImage = [UIImage imageNamed:@"get_ppd_btn"]; -// UIImageView *imageV = [[UIImageView alloc]initWithImage:bgImage]; -// imageV.frame = indicatorlineView.bounds; -// imageV.contentMode = UIViewContentModeScaleToFill; -// [indicatorlineView addSubview:imageV]; -// self.myCategoryView.indicators = @[indicatorlineView]; -// [self configCategoryViewWithType:JXCategoryTitleImageType_LeftImage]; + + // 加载标签列表 + self.homeVM = [KBHomeVM new]; + KBWeakSelf + [self.homeVM fetchTagListWithParams:nil + needShow:YES + completion:^(NSArray * _Nullable list, NSError * _Nullable error) { + if (error) { + return; + } + weakSelf.tags = list ?: @[]; + + // titles 使用后端返回的 tagName(不再本地化) + NSMutableArray *titles = [NSMutableArray array]; + for (KBTag *tag in weakSelf.tags) { + NSString *name = tag.tagName ?: @""; + [titles addObject:name]; + } + weakSelf.titles = [titles copy]; + + // 根据返回数量构造图片数组 + NSMutableArray *imageNames = [NSMutableArray array]; + NSMutableArray *selectedImageNames = [NSMutableArray array]; + for (NSInteger i = 0; i < weakSelf.titles.count; i++) { + [imageNames addObject:@"home_item_normal"]; + [selectedImageNames addObject:@"home_item_selected"]; + } + + weakSelf.myCategoryView.titles = weakSelf.titles; + weakSelf.myCategoryView.imageInfoArray = imageNames; + weakSelf.myCategoryView.selectedImageInfoArray = selectedImageNames; + weakSelf.myCategoryView.loadImageBlock = ^(UIImageView *imageView, id info) { + NSString *imageName = info; + imageView.image = [UIImage imageNamed:imageName]; + }; + + [weakSelf.myCategoryView reloadData]; + [weakSelf.listContainerView reloadData]; + }]; } - (void)viewDidLayoutSubviews { diff --git a/keyBoard/Class/Home/VM/KBHomeVM.h b/keyBoard/Class/Home/VM/KBHomeVM.h index b33a09a..cd8d7e7 100644 --- a/keyBoard/Class/Home/VM/KBHomeVM.h +++ b/keyBoard/Class/Home/VM/KBHomeVM.h @@ -10,16 +10,24 @@ NS_ASSUME_NONNULL_BEGIN @class KBCharacter; +@class KBTag; /// 首页排行榜回调 typedef void(^KBHomeRankCompletion)(NSArray * _Nullable list, NSError * _Nullable error); +/// 首页标签回调 +typedef void(^KBHomeTagCompletion)(NSArray * _Nullable list, + NSError * _Nullable error); + @interface KBHomeVM : NSObject /// 最近一次成功请求到的排行榜数据 @property (nonatomic, copy, readonly, nullable) NSArray *rankList; +/// 最近一次成功请求到的标签数据 +@property (nonatomic, copy, readonly, nullable) NSArray *tagList; + /// 请求排行榜列表(GET /character/list) /// - Parameters: /// - params: 额外查询参数(可为空),例如分页、筛选 tag 等; @@ -29,6 +37,15 @@ typedef void(^KBHomeRankCompletion)(NSArray * _Nullable list, needShow:(BOOL)needShow completion:(KBHomeRankCompletion)completion; +/// 请求排行榜标签列表(GET /tag/list) +/// - Parameters: +/// - params: 额外查询参数(可为空); +/// - needShow: 是否在请求期间显示加载 HUD; +/// - completion: 回调,list 为解析后的标签数组,error 非空表示失败。 +- (void)fetchTagListWithParams:(nullable NSDictionary *)params + needShow:(BOOL)needShow + completion:(KBHomeTagCompletion)completion; + @end NS_ASSUME_NONNULL_END diff --git a/keyBoard/Class/Home/VM/KBHomeVM.m b/keyBoard/Class/Home/VM/KBHomeVM.m index e13a7fa..b681078 100644 --- a/keyBoard/Class/Home/VM/KBHomeVM.m +++ b/keyBoard/Class/Home/VM/KBHomeVM.m @@ -7,12 +7,14 @@ #import "KBHomeVM.h" #import "KBCharacter.h" +#import "KBTag.h" #import "KBNetworkManager.h" #import "KBHUD.h" #import "KBBizCode.h" @interface KBHomeVM () @property (nonatomic, copy, readwrite, nullable) NSArray *rankList; +@property (nonatomic, copy, readwrite, nullable) NSArray *tagList; @end @implementation KBHomeVM @@ -65,4 +67,50 @@ }]; } +- (void)fetchTagListWithParams:(nullable NSDictionary *)params + needShow:(BOOL)needShow + completion:(KBHomeTagCompletion)completion { + if (needShow) { + [KBHUD show]; + } + + [[KBNetworkManager shared] GET:KB_API_TAG_LIST + parameters:params + headers:nil + autoShowBusinessError:NO + completion:^(NSDictionary * _Nullable json, NSURLResponse * _Nullable response, NSError * _Nullable error) { + if (needShow) { + [KBHUD dismiss]; + } + + if (error) { + NSString *msg = KBBizMessageFromJSONObject(json) ?: error.localizedDescription ?: KBLocalized(@"Network error"); + [KBHUD showInfo:msg]; + if (completion) { + completion(nil, error); + } + return; + } + + id dataObj = json[KBData] ?: json[@"data"]; + if (![dataObj isKindOfClass:[NSArray class]]) { + NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain + code:KBNetworkErrorInvalidResponse + userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Invalid response")}]; + [KBHUD showInfo:e.localizedDescription]; + if (completion) { + completion(nil, e); + } + return; + } + + NSArray *list = [KBTag mj_objectArrayWithKeyValuesArray:(NSArray *)dataObj]; + self.tagList = list; + + if (completion) { + completion(list, nil); + } + }]; +} + @end