1
This commit is contained in:
@@ -57,6 +57,9 @@
|
|||||||
#define API_THEME_RECOMMENDED @"/themes/recommended" // 推荐主题列表
|
#define API_THEME_RECOMMENDED @"/themes/recommended" // 推荐主题列表
|
||||||
#define API_THEME_SEARCH @"/themes/search" // 搜索主题(themeName)
|
#define API_THEME_SEARCH @"/themes/search" // 搜索主题(themeName)
|
||||||
#define API_USER_THEMES_BATCH_DELETE @"/user-themes/batch-delete" // 批量删除用户主题
|
#define API_USER_THEMES_BATCH_DELETE @"/user-themes/batch-delete" // 批量删除用户主题
|
||||||
|
#define API_THEME_PURCHASE_LIST @"/themes/purchase/list" // 查询主题购买记录
|
||||||
|
#define API_THEME_RESTORE @"/themes/restore" // 恢复已删除的主题
|
||||||
|
#define API_WALLET_TRANSACTIONS @"/wallet/transactions" // 分页查询钱包交易记录
|
||||||
|
|
||||||
/// pay
|
/// pay
|
||||||
#define API_VALIDATE_RECEIPT @"/apple/validate-receipt" // 排行榜标签列表
|
#define API_VALIDATE_RECEIPT @"/apple/validate-receipt" // 排行榜标签列表
|
||||||
|
|||||||
@@ -115,6 +115,9 @@
|
|||||||
04890A052EC0BBBB00FABA60 /* KBCategoryTitleImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04890A032EC0BBBB00FABA60 /* KBCategoryTitleImageView.m */; };
|
04890A052EC0BBBB00FABA60 /* KBCategoryTitleImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04890A032EC0BBBB00FABA60 /* KBCategoryTitleImageView.m */; };
|
||||||
04890B122EC2F00000FABA60 /* KBMyHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04890B112EC2F00000FABA60 /* KBMyHeaderView.m */; };
|
04890B122EC2F00000FABA60 /* KBMyHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04890B112EC2F00000FABA60 /* KBMyHeaderView.m */; };
|
||||||
0498BD622EDFFC12006CC1D5 /* KBMyVM.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD612EDFFC12006CC1D5 /* KBMyVM.m */; };
|
0498BD622EDFFC12006CC1D5 /* KBMyVM.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD612EDFFC12006CC1D5 /* KBMyVM.m */; };
|
||||||
|
A1F0C1B12F1234567890ABCD /* KBConsumptionRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = A1F0C1A12F1234567890ABCD /* KBConsumptionRecord.m */; };
|
||||||
|
A1F0C1B22F1234567890ABCD /* KBConsumptionRecordCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A1F0C1A32F1234567890ABCD /* KBConsumptionRecordCell.m */; };
|
||||||
|
A1F0C1B32F1234567890ABCD /* KBConsumptionRecordVC.m in Sources */ = {isa = PBXBuildFile; fileRef = A1F0C1A52F1234567890ABCD /* KBConsumptionRecordVC.m */; };
|
||||||
0498BD652EE0116D006CC1D5 /* KBEmailLoginVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD642EE0116D006CC1D5 /* KBEmailLoginVC.m */; };
|
0498BD652EE0116D006CC1D5 /* KBEmailLoginVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD642EE0116D006CC1D5 /* KBEmailLoginVC.m */; };
|
||||||
0498BD682EE01180006CC1D5 /* KBEmailRegistVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD672EE01180006CC1D5 /* KBEmailRegistVC.m */; };
|
0498BD682EE01180006CC1D5 /* KBEmailRegistVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD672EE01180006CC1D5 /* KBEmailRegistVC.m */; };
|
||||||
0498BD6B2EE025FC006CC1D5 /* KBForgetPwdVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD6A2EE025FC006CC1D5 /* KBForgetPwdVC.m */; };
|
0498BD6B2EE025FC006CC1D5 /* KBForgetPwdVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD6A2EE025FC006CC1D5 /* KBForgetPwdVC.m */; };
|
||||||
@@ -401,9 +404,15 @@
|
|||||||
05A1B2C72F5B1A2B3C4D5E60 /* KBSearchThemeModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSearchThemeModel.m; sourceTree = "<group>"; };
|
05A1B2C72F5B1A2B3C4D5E60 /* KBSearchThemeModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSearchThemeModel.m; sourceTree = "<group>"; };
|
||||||
048908DE2EBF73DC00FABA60 /* MySkinVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MySkinVC.h; sourceTree = "<group>"; };
|
048908DE2EBF73DC00FABA60 /* MySkinVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MySkinVC.h; sourceTree = "<group>"; };
|
||||||
048908DF2EBF73DC00FABA60 /* MySkinVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MySkinVC.m; sourceTree = "<group>"; };
|
048908DF2EBF73DC00FABA60 /* MySkinVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MySkinVC.m; sourceTree = "<group>"; };
|
||||||
048908E12EBF760000FABA60 /* MySkinCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MySkinCell.h; sourceTree = "<group>"; };
|
048908E12EBF760000FABA60 /* MySkinCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MySkinCell.h; sourceTree = "<group>"; };
|
||||||
048908E12EBF821700FABA60 /* KBSkinDetailVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinDetailVC.h; sourceTree = "<group>"; };
|
048908E12EBF821700FABA60 /* KBSkinDetailVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinDetailVC.h; sourceTree = "<group>"; };
|
||||||
048908E22EBF760000FABA60 /* MySkinCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MySkinCell.m; sourceTree = "<group>"; };
|
048908E22EBF760000FABA60 /* MySkinCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MySkinCell.m; sourceTree = "<group>"; };
|
||||||
|
A1F0C1A02F1234567890ABCD /* KBConsumptionRecord.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBConsumptionRecord.h; sourceTree = "<group>"; };
|
||||||
|
A1F0C1A12F1234567890ABCD /* KBConsumptionRecord.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBConsumptionRecord.m; sourceTree = "<group>"; };
|
||||||
|
A1F0C1A22F1234567890ABCD /* KBConsumptionRecordCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBConsumptionRecordCell.h; sourceTree = "<group>"; };
|
||||||
|
A1F0C1A32F1234567890ABCD /* KBConsumptionRecordCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBConsumptionRecordCell.m; sourceTree = "<group>"; };
|
||||||
|
A1F0C1A42F1234567890ABCD /* KBConsumptionRecordVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBConsumptionRecordVC.h; sourceTree = "<group>"; };
|
||||||
|
A1F0C1A52F1234567890ABCD /* KBConsumptionRecordVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBConsumptionRecordVC.m; sourceTree = "<group>"; };
|
||||||
048908E22EBF821700FABA60 /* KBSkinDetailVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinDetailVC.m; sourceTree = "<group>"; };
|
048908E22EBF821700FABA60 /* KBSkinDetailVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinDetailVC.m; sourceTree = "<group>"; };
|
||||||
048908E42EBF841B00FABA60 /* KBSkinDetailTagCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinDetailTagCell.h; sourceTree = "<group>"; };
|
048908E42EBF841B00FABA60 /* KBSkinDetailTagCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinDetailTagCell.h; sourceTree = "<group>"; };
|
||||||
048908E52EBF841B00FABA60 /* KBSkinDetailTagCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinDetailTagCell.m; sourceTree = "<group>"; };
|
048908E52EBF841B00FABA60 /* KBSkinDetailTagCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinDetailTagCell.m; sourceTree = "<group>"; };
|
||||||
@@ -1335,6 +1344,8 @@
|
|||||||
0498BD8E2EE6A3BD006CC1D5 /* KBMyMainModel.m */,
|
0498BD8E2EE6A3BD006CC1D5 /* KBMyMainModel.m */,
|
||||||
7ECBD0E320F971D0FBEDD7BC /* KBMyTheme.h */,
|
7ECBD0E320F971D0FBEDD7BC /* KBMyTheme.h */,
|
||||||
180D662EC4DB3A7FFF83FF18 /* KBMyTheme.m */,
|
180D662EC4DB3A7FFF83FF18 /* KBMyTheme.m */,
|
||||||
|
A1F0C1A02F1234567890ABCD /* KBConsumptionRecord.h */,
|
||||||
|
A1F0C1A12F1234567890ABCD /* KBConsumptionRecord.m */,
|
||||||
);
|
);
|
||||||
path = M;
|
path = M;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1346,6 +1357,8 @@
|
|||||||
049FB31C2EC21BCD00FAB05D /* KBMyKeyboardCell.m */,
|
049FB31C2EC21BCD00FAB05D /* KBMyKeyboardCell.m */,
|
||||||
048908E12EBF760000FABA60 /* MySkinCell.h */,
|
048908E12EBF760000FABA60 /* MySkinCell.h */,
|
||||||
048908E22EBF760000FABA60 /* MySkinCell.m */,
|
048908E22EBF760000FABA60 /* MySkinCell.m */,
|
||||||
|
A1F0C1A22F1234567890ABCD /* KBConsumptionRecordCell.h */,
|
||||||
|
A1F0C1A32F1234567890ABCD /* KBConsumptionRecordCell.m */,
|
||||||
048908E42EBF841B00FABA60 /* KBSkinDetailTagCell.h */,
|
048908E42EBF841B00FABA60 /* KBSkinDetailTagCell.h */,
|
||||||
048908E52EBF841B00FABA60 /* KBSkinDetailTagCell.m */,
|
048908E52EBF841B00FABA60 /* KBSkinDetailTagCell.m */,
|
||||||
048908E72EBF843000FABA60 /* KBSkinDetailHeaderCell.h */,
|
048908E72EBF843000FABA60 /* KBSkinDetailHeaderCell.h */,
|
||||||
@@ -1379,6 +1392,8 @@
|
|||||||
049FB2192EC20A9E00FAB05D /* KBMyKeyBoardVC.m */,
|
049FB2192EC20A9E00FAB05D /* KBMyKeyBoardVC.m */,
|
||||||
048908DE2EBF73DC00FABA60 /* MySkinVC.h */,
|
048908DE2EBF73DC00FABA60 /* MySkinVC.h */,
|
||||||
048908DF2EBF73DC00FABA60 /* MySkinVC.m */,
|
048908DF2EBF73DC00FABA60 /* MySkinVC.m */,
|
||||||
|
A1F0C1A42F1234567890ABCD /* KBConsumptionRecordVC.h */,
|
||||||
|
A1F0C1A52F1234567890ABCD /* KBConsumptionRecordVC.m */,
|
||||||
049FB2212EC311F900FAB05D /* KBPersonInfoVC.h */,
|
049FB2212EC311F900FAB05D /* KBPersonInfoVC.h */,
|
||||||
049FB2222EC311F900FAB05D /* KBPersonInfoVC.m */,
|
049FB2222EC311F900FAB05D /* KBPersonInfoVC.m */,
|
||||||
04791F902ED48010004E8522 /* KBNoticeVC.h */,
|
04791F902ED48010004E8522 /* KBNoticeVC.h */,
|
||||||
@@ -1990,6 +2005,9 @@
|
|||||||
048908BC2EBE1FCB00FABA60 /* BaseViewController.m in Sources */,
|
048908BC2EBE1FCB00FABA60 /* BaseViewController.m in Sources */,
|
||||||
0498BD902EE6A3BD006CC1D5 /* KBMyMainModel.m in Sources */,
|
0498BD902EE6A3BD006CC1D5 /* KBMyMainModel.m in Sources */,
|
||||||
471CAD3574798685B72ADD55 /* KBMyTheme.m in Sources */,
|
471CAD3574798685B72ADD55 /* KBMyTheme.m in Sources */,
|
||||||
|
A1F0C1B12F1234567890ABCD /* KBConsumptionRecord.m in Sources */,
|
||||||
|
A1F0C1B22F1234567890ABCD /* KBConsumptionRecordCell.m in Sources */,
|
||||||
|
A1F0C1B32F1234567890ABCD /* KBConsumptionRecordVC.m in Sources */,
|
||||||
04FC95D72EB1EA16007BD342 /* BaseTableView.m in Sources */,
|
04FC95D72EB1EA16007BD342 /* BaseTableView.m in Sources */,
|
||||||
0498BD712EE02A41006CC1D5 /* KBForgetPwdNewPwdVC.m in Sources */,
|
0498BD712EE02A41006CC1D5 /* KBForgetPwdNewPwdVC.m in Sources */,
|
||||||
048908EF2EBF861800FABA60 /* KBSkinSectionTitleCell.m in Sources */,
|
048908EF2EBF861800FABA60 /* KBSkinSectionTitleCell.m in Sources */,
|
||||||
|
|||||||
22
keyBoard/Assets.xcassets/My/my_chongzhi_bg.imageset/Contents.json
vendored
Normal file
22
keyBoard/Assets.xcassets/My/my_chongzhi_bg.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "my_chongzhi_bg@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "my_chongzhi_bg@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
keyBoard/Assets.xcassets/My/my_chongzhi_bg.imageset/my_chongzhi_bg@2x.png
vendored
Normal file
BIN
keyBoard/Assets.xcassets/My/my_chongzhi_bg.imageset/my_chongzhi_bg@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.2 KiB |
BIN
keyBoard/Assets.xcassets/My/my_chongzhi_bg.imageset/my_chongzhi_bg@3x.png
vendored
Normal file
BIN
keyBoard/Assets.xcassets/My/my_chongzhi_bg.imageset/my_chongzhi_bg@3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
22
keyBoard/Assets.xcassets/My/my_record_icon.imageset/Contents.json
vendored
Normal file
22
keyBoard/Assets.xcassets/My/my_record_icon.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "my_record_icon@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "my_record_icon@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
keyBoard/Assets.xcassets/My/my_record_icon.imageset/my_record_icon@2x.png
vendored
Normal file
BIN
keyBoard/Assets.xcassets/My/my_record_icon.imageset/my_record_icon@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
BIN
keyBoard/Assets.xcassets/My/my_record_icon.imageset/my_record_icon@3x.png
vendored
Normal file
BIN
keyBoard/Assets.xcassets/My/my_record_icon.imageset/my_record_icon@3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
25
keyBoard/Class/Me/M/KBConsumptionRecord.h
Normal file
25
keyBoard/Class/Me/M/KBConsumptionRecord.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// KBConsumptionRecord.h
|
||||||
|
// keyBoard
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/// 消费/购买记录模型 1 消费 2充值
|
||||||
|
typedef NS_ENUM(NSInteger, KBConsumptionRecordType) {
|
||||||
|
KBConsumptionRecordTypeConsumption = 1,
|
||||||
|
KBConsumptionRecordTypeRecharge = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
@interface KBConsumptionRecord : NSObject
|
||||||
|
@property (nonatomic, strong, nullable) NSNumber *amount;
|
||||||
|
@property (nonatomic, assign) KBConsumptionRecordType type;
|
||||||
|
@property (nonatomic, strong, nullable) NSNumber *beforeBalance;
|
||||||
|
@property (nonatomic, strong, nullable) NSNumber *afterBalance;
|
||||||
|
@property (nonatomic, copy, nullable) NSString *kbdescription;
|
||||||
|
@property (nonatomic, copy, nullable) NSString *createdAt;
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
16
keyBoard/Class/Me/M/KBConsumptionRecord.m
Normal file
16
keyBoard/Class/Me/M/KBConsumptionRecord.m
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// KBConsumptionRecord.m
|
||||||
|
// keyBoard
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "KBConsumptionRecord.h"
|
||||||
|
|
||||||
|
@implementation KBConsumptionRecord
|
||||||
|
+ (NSDictionary *)mj_replacedKeyFromPropertyName {
|
||||||
|
// JSON: { "id": 0, "tagName": "xxx" }
|
||||||
|
// Model: tagId / tagName
|
||||||
|
return @{
|
||||||
|
@"kbdescription" : @"description",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@end
|
||||||
16
keyBoard/Class/Me/V/KBConsumptionRecordCell.h
Normal file
16
keyBoard/Class/Me/V/KBConsumptionRecordCell.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// KBConsumptionRecordCell.h
|
||||||
|
// keyBoard
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "BaseCell.h"
|
||||||
|
@class KBConsumptionRecord;
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface KBConsumptionRecordCell : BaseCell
|
||||||
|
+ (NSString *)reuseId;
|
||||||
|
- (void)configWithRecord:(KBConsumptionRecord *)record;
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
123
keyBoard/Class/Me/V/KBConsumptionRecordCell.m
Normal file
123
keyBoard/Class/Me/V/KBConsumptionRecordCell.m
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
//
|
||||||
|
// KBConsumptionRecordCell.m
|
||||||
|
// keyBoard
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "KBConsumptionRecordCell.h"
|
||||||
|
#import "KBConsumptionRecord.h"
|
||||||
|
#import <Masonry/Masonry.h>
|
||||||
|
#import "UIColor+Extension.h"
|
||||||
|
|
||||||
|
@interface KBConsumptionRecordCell ()
|
||||||
|
@property (nonatomic, strong) UILabel *titleLabel;
|
||||||
|
@property (nonatomic, strong) UILabel *timeLabel;
|
||||||
|
@property (nonatomic, strong) UILabel *amountLabel;
|
||||||
|
@property (nonatomic, strong) UIView *lineView;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation KBConsumptionRecordCell
|
||||||
|
|
||||||
|
- (void)setupUI {
|
||||||
|
self.contentView.backgroundColor = [UIColor whiteColor];
|
||||||
|
[self.contentView addSubview:self.titleLabel];
|
||||||
|
[self.contentView addSubview:self.timeLabel];
|
||||||
|
[self.contentView addSubview:self.amountLabel];
|
||||||
|
[self.contentView addSubview:self.lineView];
|
||||||
|
|
||||||
|
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self.contentView).offset(16);
|
||||||
|
make.top.equalTo(self.contentView).offset(14);
|
||||||
|
make.right.lessThanOrEqualTo(self.amountLabel.mas_left).offset(-12);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self.titleLabel);
|
||||||
|
make.top.equalTo(self.titleLabel.mas_bottom).offset(6);
|
||||||
|
make.bottom.equalTo(self.contentView).offset(-14);
|
||||||
|
make.right.lessThanOrEqualTo(self.amountLabel.mas_left).offset(-12);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.amountLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.right.equalTo(self.contentView).offset(-16);
|
||||||
|
make.centerY.equalTo(self.titleLabel);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.lineView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self.contentView).offset(16);
|
||||||
|
make.right.equalTo(self.contentView).offset(-16);
|
||||||
|
make.bottom.equalTo(self.contentView);
|
||||||
|
make.height.mas_equalTo(KB_ONE_PIXEL);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)configWithRecord:(KBConsumptionRecord *)record {
|
||||||
|
NSString *title = record.kbdescription.length ? record.kbdescription : KBLocalized(@"Consumption");
|
||||||
|
self.titleLabel.text = title;
|
||||||
|
|
||||||
|
self.timeLabel.text = record.createdAt.length ? record.createdAt : @"--";
|
||||||
|
|
||||||
|
NSString *displayAmount = [self kb_formatAmountText:record.amount];
|
||||||
|
self.amountLabel.text = displayAmount;
|
||||||
|
|
||||||
|
UIColor *incomeColor = [UIColor colorWithHex:0x66CD7C];
|
||||||
|
UIColor *expenseColor = [UIColor colorWithHex:0xCD2853];
|
||||||
|
self.amountLabel.textColor = (record.type == KBConsumptionRecordTypeRecharge) ? incomeColor : expenseColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)kb_formatAmountText:(NSNumber *)amount {
|
||||||
|
if (![amount isKindOfClass:NSNumber.class]) { return @"--"; }
|
||||||
|
static NSNumberFormatter *formatter;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
formatter = [[NSNumberFormatter alloc] init];
|
||||||
|
formatter.numberStyle = NSNumberFormatterDecimalStyle;
|
||||||
|
formatter.minimumFractionDigits = 2;
|
||||||
|
formatter.maximumFractionDigits = 2;
|
||||||
|
formatter.minimumIntegerDigits = 1;
|
||||||
|
formatter.positivePrefix = @"+";
|
||||||
|
});
|
||||||
|
return [formatter stringFromNumber:amount] ?: @"--";
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Lazy
|
||||||
|
|
||||||
|
- (UILabel *)titleLabel {
|
||||||
|
if (!_titleLabel) {
|
||||||
|
_titleLabel = [UILabel new];
|
||||||
|
_titleLabel.font = [KBFont medium:15];
|
||||||
|
_titleLabel.textColor = [UIColor colorWithHex:KBBlackValue];
|
||||||
|
_titleLabel.text = KBLocalized(@"Consumption");
|
||||||
|
}
|
||||||
|
return _titleLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)timeLabel {
|
||||||
|
if (!_timeLabel) {
|
||||||
|
_timeLabel = [UILabel new];
|
||||||
|
_timeLabel.font = [KBFont regular:12];
|
||||||
|
_timeLabel.textColor = [UIColor colorWithHex:0x9FA5B5];
|
||||||
|
_timeLabel.text = @"--";
|
||||||
|
}
|
||||||
|
return _timeLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)amountLabel {
|
||||||
|
if (!_amountLabel) {
|
||||||
|
_amountLabel = [UILabel new];
|
||||||
|
_amountLabel.font = [KBFont medium:16];
|
||||||
|
_amountLabel.textColor = [UIColor colorWithHex:0xE36464];
|
||||||
|
_amountLabel.textAlignment = NSTextAlignmentRight;
|
||||||
|
_amountLabel.text = @"--";
|
||||||
|
}
|
||||||
|
return _amountLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIView *)lineView {
|
||||||
|
if (!_lineView) {
|
||||||
|
_lineView = [UIView new];
|
||||||
|
_lineView.backgroundColor = [UIColor colorWithHex:0xEFEFF1];
|
||||||
|
}
|
||||||
|
return _lineView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
14
keyBoard/Class/Me/VC/KBConsumptionRecordVC.h
Normal file
14
keyBoard/Class/Me/VC/KBConsumptionRecordVC.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// KBConsumptionRecordVC.h
|
||||||
|
// keyBoard
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "BaseViewController.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface KBConsumptionRecordVC : BaseViewController
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
337
keyBoard/Class/Me/VC/KBConsumptionRecordVC.m
Normal file
337
keyBoard/Class/Me/VC/KBConsumptionRecordVC.m
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
//
|
||||||
|
// KBConsumptionRecordVC.m
|
||||||
|
// keyBoard
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "KBConsumptionRecordVC.h"
|
||||||
|
#import "KBConsumptionRecord.h"
|
||||||
|
#import "KBConsumptionRecordCell.h"
|
||||||
|
#import "KBMyVM.h"
|
||||||
|
#import "KBShopVM.h"
|
||||||
|
#import "KBJfPay.h"
|
||||||
|
#import <Masonry/Masonry.h>
|
||||||
|
#import "UIColor+Extension.h"
|
||||||
|
#import "KBHUD.h"
|
||||||
|
#import <MJRefresh/MJRefresh.h>
|
||||||
|
|
||||||
|
@interface KBConsumptionRecordVC () <UITableViewDataSource, UITableViewDelegate>
|
||||||
|
@property (nonatomic, strong) BaseTableView *tableView;
|
||||||
|
@property (nonatomic, strong) UIView *headerView;
|
||||||
|
@property (nonatomic, strong) UIView *cardView;
|
||||||
|
@property (nonatomic, strong) UILabel *pointsTitleLabel;
|
||||||
|
@property (nonatomic, strong) UILabel *pointsLabel;
|
||||||
|
@property (nonatomic, strong) UIImageView *pointsIconView;
|
||||||
|
@property (nonatomic, strong) UIButton *rechargeButton;
|
||||||
|
@property (nonatomic, strong) UIImageView *sectionIconView;
|
||||||
|
@property (nonatomic, strong) UILabel *sectionTitleLabel;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) NSMutableArray<KBConsumptionRecord *> *records;
|
||||||
|
@property (nonatomic, strong) KBMyVM *viewModel;
|
||||||
|
@property (nonatomic, strong) KBShopVM *shopVM;
|
||||||
|
@property (nonatomic, strong) UIImageView *bgImageView; // 全屏背景图
|
||||||
|
@property (nonatomic, assign) NSInteger pageNumber;
|
||||||
|
@property (nonatomic, assign) NSInteger pageSize;
|
||||||
|
@property (nonatomic, assign) BOOL isLoading;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation KBConsumptionRecordVC
|
||||||
|
|
||||||
|
- (void)viewDidLoad {
|
||||||
|
[super viewDidLoad];
|
||||||
|
self.view.backgroundColor = [UIColor whiteColor];
|
||||||
|
self.kb_titleLabel.text = KBLocalized(@"Consumption Record");
|
||||||
|
self.kb_navView.backgroundColor = [UIColor clearColor];
|
||||||
|
self.bgImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"my_bg_icon"]];
|
||||||
|
self.bgImageView.contentMode = UIViewContentModeScaleAspectFill;
|
||||||
|
[self.view insertSubview:self.bgImageView belowSubview:self.kb_navView];
|
||||||
|
[self.bgImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.edges.equalTo(self.view);
|
||||||
|
}];
|
||||||
|
self.records = [NSMutableArray array];
|
||||||
|
[self.view addSubview:self.tableView];
|
||||||
|
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.right.bottom.equalTo(self.view);
|
||||||
|
make.top.equalTo(self.view).offset(KB_NAV_TOTAL_HEIGHT);
|
||||||
|
}];
|
||||||
|
|
||||||
|
self.tableView.tableHeaderView = self.headerView;
|
||||||
|
|
||||||
|
self.pageNumber = 1;
|
||||||
|
self.pageSize = 10;
|
||||||
|
[self setupRefresh];
|
||||||
|
[self fetchWalletBalance];
|
||||||
|
[self.tableView.mj_header beginRefreshing];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Data
|
||||||
|
|
||||||
|
- (void)fetchWalletBalance {
|
||||||
|
__weak typeof(self) weakSelf = self;
|
||||||
|
[self.shopVM fetchWalletBalanceWithCompletion:^(NSString * _Nullable balance, NSError * _Nullable error) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if (!error && balance.length > 0) {
|
||||||
|
weakSelf.pointsLabel.text = balance;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setupRefresh {
|
||||||
|
__weak typeof(self) weakSelf = self;
|
||||||
|
self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
|
||||||
|
[weakSelf refreshRecords];
|
||||||
|
}];
|
||||||
|
self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
|
||||||
|
[weakSelf loadMoreRecords];
|
||||||
|
}];
|
||||||
|
self.tableView.mj_footer.hidden = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)refreshRecords {
|
||||||
|
if (self.isLoading) {
|
||||||
|
[self.tableView.mj_header endRefreshing];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.pageNumber = 1;
|
||||||
|
[self.tableView.mj_footer resetNoMoreData];
|
||||||
|
[self fetchPurchaseRecordsIsRefresh:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)loadMoreRecords {
|
||||||
|
if (self.isLoading || self.tableView.mj_footer.state == MJRefreshStateNoMoreData) {
|
||||||
|
[self.tableView.mj_footer endRefreshing];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.pageNumber += 1;
|
||||||
|
[self fetchPurchaseRecordsIsRefresh:NO];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)fetchPurchaseRecordsIsRefresh:(BOOL)isRefresh {
|
||||||
|
self.isLoading = YES;
|
||||||
|
BOOL showHUD = !self.tableView.mj_header.isRefreshing && !self.tableView.mj_footer.isRefreshing;
|
||||||
|
if (showHUD) {
|
||||||
|
[KBHUD show];
|
||||||
|
}
|
||||||
|
__weak typeof(self) weakSelf = self;
|
||||||
|
[self.viewModel fetchWalletTransactionsWithPage:self.pageNumber
|
||||||
|
pageSize:self.pageSize
|
||||||
|
completion:^(NSArray<KBConsumptionRecord *> * _Nullable records, NSError * _Nullable error) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
weakSelf.isLoading = NO;
|
||||||
|
if (showHUD) {
|
||||||
|
[KBHUD dismiss];
|
||||||
|
}
|
||||||
|
if (isRefresh) {
|
||||||
|
[weakSelf.tableView.mj_header endRefreshing];
|
||||||
|
} else {
|
||||||
|
[weakSelf.tableView.mj_footer endRefreshing];
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
if (!isRefresh) {
|
||||||
|
weakSelf.pageNumber = MAX(1, weakSelf.pageNumber - 1);
|
||||||
|
}
|
||||||
|
NSString *msg = error.localizedDescription ?: KBLocalized(@"Network error");
|
||||||
|
[KBHUD showInfo:msg];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isRefresh) {
|
||||||
|
[weakSelf.records removeAllObjects];
|
||||||
|
}
|
||||||
|
if (records.count > 0) {
|
||||||
|
[weakSelf.records addObjectsFromArray:records];
|
||||||
|
}
|
||||||
|
[weakSelf.tableView reloadData];
|
||||||
|
weakSelf.tableView.mj_footer.hidden = (weakSelf.records.count == 0);
|
||||||
|
if (records.count < weakSelf.pageSize) {
|
||||||
|
[weakSelf.tableView.mj_footer endRefreshingWithNoMoreData];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - UITableView
|
||||||
|
|
||||||
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||||
|
return self.records.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
return KBFit(78);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
KBConsumptionRecordCell *cell = [tableView dequeueReusableCellWithIdentifier:[KBConsumptionRecordCell reuseId]
|
||||||
|
forIndexPath:indexPath];
|
||||||
|
if (indexPath.row < self.records.count) {
|
||||||
|
[cell configWithRecord:self.records[indexPath.row]];
|
||||||
|
}
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Actions
|
||||||
|
|
||||||
|
- (void)onRecharge {
|
||||||
|
KBJfPay *vc = [[KBJfPay alloc] init];
|
||||||
|
[self.navigationController pushViewController:vc animated:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Lazy
|
||||||
|
|
||||||
|
- (BaseTableView *)tableView {
|
||||||
|
if (!_tableView) {
|
||||||
|
_tableView = [[BaseTableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
|
||||||
|
_tableView.backgroundColor = [UIColor clearColor];
|
||||||
|
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||||
|
_tableView.dataSource = self;
|
||||||
|
_tableView.delegate = self;
|
||||||
|
[_tableView registerClass:KBConsumptionRecordCell.class forCellReuseIdentifier:[KBConsumptionRecordCell reuseId]];
|
||||||
|
}
|
||||||
|
return _tableView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIView *)headerView {
|
||||||
|
if (!_headerView) {
|
||||||
|
CGFloat headerHeight = KBFit(210);
|
||||||
|
_headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KB_SCREEN_WIDTH, headerHeight)];
|
||||||
|
_headerView.backgroundColor = [UIColor clearColor];
|
||||||
|
|
||||||
|
[_headerView addSubview:self.cardView];
|
||||||
|
[_headerView addSubview:self.sectionIconView];
|
||||||
|
[_headerView addSubview:self.sectionTitleLabel];
|
||||||
|
|
||||||
|
[self.cardView addSubview:self.pointsTitleLabel];
|
||||||
|
[self.cardView addSubview:self.pointsIconView];
|
||||||
|
[self.cardView addSubview:self.pointsLabel];
|
||||||
|
[self.cardView addSubview:self.rechargeButton];
|
||||||
|
|
||||||
|
[self.cardView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(_headerView).offset(16);
|
||||||
|
make.right.equalTo(_headerView).offset(-16);
|
||||||
|
make.top.equalTo(_headerView).offset(24);
|
||||||
|
make.height.mas_equalTo(KBFit(126));
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.pointsTitleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self.cardView).offset(16);
|
||||||
|
make.top.equalTo(self.cardView).offset(18);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.pointsIconView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self.cardView).offset(16);
|
||||||
|
make.centerY.equalTo(self.cardView);
|
||||||
|
make.width.height.mas_equalTo(38);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.pointsLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self.pointsIconView.mas_right).offset(8);
|
||||||
|
make.centerY.equalTo(self.pointsIconView).offset(5);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.rechargeButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.right.equalTo(self.cardView).offset(-16);
|
||||||
|
make.centerY.equalTo(self.pointsIconView);
|
||||||
|
make.width.mas_equalTo(114);
|
||||||
|
make.height.mas_equalTo(42);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.sectionIconView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(_headerView).offset(16);
|
||||||
|
make.top.equalTo(self.cardView.mas_bottom).offset(18);
|
||||||
|
make.width.height.mas_equalTo(24);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.sectionTitleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.centerY.equalTo(self.sectionIconView);
|
||||||
|
make.left.equalTo(self.sectionIconView.mas_right).offset(8);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
return _headerView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIView *)cardView {
|
||||||
|
if (!_cardView) {
|
||||||
|
_cardView = [UIView new];
|
||||||
|
_cardView.backgroundColor = [UIColor colorWithHex:0xC5FFF6];
|
||||||
|
_cardView.layer.cornerRadius = 20;
|
||||||
|
_cardView.layer.masksToBounds = YES;
|
||||||
|
}
|
||||||
|
return _cardView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)pointsTitleLabel {
|
||||||
|
if (!_pointsTitleLabel) {
|
||||||
|
_pointsTitleLabel = [UILabel new];
|
||||||
|
_pointsTitleLabel.text = KBLocalized(@"My Points");
|
||||||
|
_pointsTitleLabel.font = [KBFont medium:14];
|
||||||
|
_pointsTitleLabel.textColor = [UIColor colorWithHex:0x6B7A7A];
|
||||||
|
}
|
||||||
|
return _pointsTitleLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)pointsLabel {
|
||||||
|
if (!_pointsLabel) {
|
||||||
|
_pointsLabel = [UILabel new];
|
||||||
|
_pointsLabel.text = @"0";
|
||||||
|
_pointsLabel.font = [KBFont bold:40];
|
||||||
|
_pointsLabel.textColor = [UIColor colorWithHex:0x02BEAC];
|
||||||
|
}
|
||||||
|
return _pointsLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIImageView *)pointsIconView {
|
||||||
|
if (!_pointsIconView) {
|
||||||
|
_pointsIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"shop_jb_icon"]];
|
||||||
|
_pointsIconView.contentMode = UIViewContentModeScaleAspectFit;
|
||||||
|
}
|
||||||
|
return _pointsIconView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)rechargeButton {
|
||||||
|
if (!_rechargeButton) {
|
||||||
|
_rechargeButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||||
|
[_rechargeButton setTitle:KBLocalized(@"Recharge") forState:UIControlStateNormal];
|
||||||
|
_rechargeButton.titleLabel.font = [KBFont medium:13];
|
||||||
|
[_rechargeButton setTitleColor:[UIColor colorWithHex:0x1B1F1A] forState:UIControlStateNormal];
|
||||||
|
// _rechargeButton.backgroundColor = [UIColor colorWithHex:0xCFF7EA];
|
||||||
|
[_rechargeButton setBackgroundImage:[UIImage imageNamed:@"my_chongzhi_bg"] forState:UIControlStateNormal];
|
||||||
|
_rechargeButton.layer.cornerRadius = 21;
|
||||||
|
_rechargeButton.layer.masksToBounds = YES;
|
||||||
|
[_rechargeButton addTarget:self action:@selector(onRecharge) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
return _rechargeButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIImageView *)sectionIconView {
|
||||||
|
if (!_sectionIconView) {
|
||||||
|
_sectionIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"shop_jb_icon"]];
|
||||||
|
_sectionIconView.contentMode = UIViewContentModeScaleAspectFit;
|
||||||
|
}
|
||||||
|
return _sectionIconView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)sectionTitleLabel {
|
||||||
|
if (!_sectionTitleLabel) {
|
||||||
|
_sectionTitleLabel = [UILabel new];
|
||||||
|
_sectionTitleLabel.text = KBLocalized(@"Consumption Details");
|
||||||
|
_sectionTitleLabel.font = [KBFont medium:14];
|
||||||
|
_sectionTitleLabel.textColor = [UIColor colorWithHex:KBBlackValue];
|
||||||
|
}
|
||||||
|
return _sectionTitleLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (KBMyVM *)viewModel {
|
||||||
|
if (!_viewModel) {
|
||||||
|
_viewModel = [[KBMyVM alloc] init];
|
||||||
|
}
|
||||||
|
return _viewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (KBShopVM *)shopVM {
|
||||||
|
if (!_shopVM) {
|
||||||
|
_shopVM = [[KBShopVM alloc] init];
|
||||||
|
}
|
||||||
|
return _shopVM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
#import "KBNoticeVC.h"
|
#import "KBNoticeVC.h"
|
||||||
#import "KBFeedBackVC.h"
|
#import "KBFeedBackVC.h"
|
||||||
#import "KBMyVM.h"
|
#import "KBMyVM.h"
|
||||||
|
#import "KBConsumptionRecordVC.h"
|
||||||
|
|
||||||
|
|
||||||
@interface MyVC () <UITableViewDelegate, UITableViewDataSource>
|
@interface MyVC () <UITableViewDelegate, UITableViewDataSource>
|
||||||
@property (nonatomic, strong) BaseTableView *tableView; // 列表
|
@property (nonatomic, strong) BaseTableView *tableView; // 列表
|
||||||
@@ -37,8 +39,9 @@
|
|||||||
make.edges.equalTo(self.view);
|
make.edges.equalTo(self.view);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 数据源(title + SF Symbols 名称 + 色值),分两组
|
// 数据源(title + SF Symbols 名称 + 色值),分两组 my_record_icon
|
||||||
self.data = @[
|
self.data = @[
|
||||||
|
@[@{ @"title": KBLocalized(@"Consumption record"), @"icon": @"my_record_icon", @"color": @(0x60A3FF),@"id":@"8" }],
|
||||||
@[@{ @"title": KBLocalized(@"Notice"), @"icon": @"my_notice_icon", @"color": @(0x60A3FF),@"id":@"1" }],
|
@[@{ @"title": KBLocalized(@"Notice"), @"icon": @"my_notice_icon", @"color": @(0x60A3FF),@"id":@"1" }],
|
||||||
@[@{ @"title": KBLocalized(@"Share App"), @"icon": @"my_share_icon", @"color": @(0xF5A623),@"id":@"2" }],
|
@[@{ @"title": KBLocalized(@"Share App"), @"icon": @"my_share_icon", @"color": @(0xF5A623),@"id":@"2" }],
|
||||||
@[@{ @"title": KBLocalized(@"Feedback"), @"icon": @"my_feedback_icon", @"color": @(0xB06AFD),@"id":@"3" },
|
@[@{ @"title": KBLocalized(@"Feedback"), @"icon": @"my_feedback_icon", @"color": @(0xB06AFD),@"id":@"3" },
|
||||||
@@ -130,6 +133,9 @@
|
|||||||
|
|
||||||
}else if ([itemID isEqualToString:@"6"]){
|
}else if ([itemID isEqualToString:@"6"]){
|
||||||
|
|
||||||
|
}else if ([itemID isEqualToString:@"8"]){
|
||||||
|
KBConsumptionRecordVC *vc = [[KBConsumptionRecordVC alloc] init];
|
||||||
|
[self.navigationController pushViewController:vc animated:true];
|
||||||
}else if ([itemID isEqualToString:@"7"]){
|
}else if ([itemID isEqualToString:@"7"]){
|
||||||
KBTestVC *vc = [[KBTestVC alloc] init];
|
KBTestVC *vc = [[KBTestVC alloc] init];
|
||||||
[self.navigationController pushViewController:vc animated:true];
|
[self.navigationController pushViewController:vc animated:true];
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "KBCharacter.h"
|
#import "KBCharacter.h"
|
||||||
#import "KBMyTheme.h"
|
#import "KBMyTheme.h"
|
||||||
|
#import "KBConsumptionRecord.h"
|
||||||
@class KBUser;
|
@class KBUser;
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
@@ -26,6 +27,7 @@ typedef void(^KBDeleteUserCharacterCompletion)(BOOL success, NSError * _Nullable
|
|||||||
typedef void(^KBMyPurchasedThemesCompletion)(NSArray<KBMyTheme *> *_Nullable themes, NSError *_Nullable error);
|
typedef void(^KBMyPurchasedThemesCompletion)(NSArray<KBMyTheme *> *_Nullable themes, NSError *_Nullable error);
|
||||||
typedef void(^KBDeleteThemesCompletion)(BOOL success, NSError *_Nullable error);
|
typedef void(^KBDeleteThemesCompletion)(BOOL success, NSError *_Nullable error);
|
||||||
typedef void(^KBSubmitFeedbackCompletion)(BOOL success, NSError *_Nullable error);
|
typedef void(^KBSubmitFeedbackCompletion)(BOOL success, NSError *_Nullable error);
|
||||||
|
typedef void(^KBMyPurchaseRecordCompletion)(NSArray<KBConsumptionRecord *> *_Nullable records, NSError *_Nullable error);
|
||||||
|
|
||||||
@interface KBMyVM : NSObject
|
@interface KBMyVM : NSObject
|
||||||
|
|
||||||
@@ -39,6 +41,10 @@ typedef void(^KBSubmitFeedbackCompletion)(BOOL success, NSError *_Nullable error
|
|||||||
/// 批量删除用户主题(/user-themes/batch-delete)
|
/// 批量删除用户主题(/user-themes/batch-delete)
|
||||||
- (void)deletePurchasedThemesWithIds:(NSArray<NSString *> *)themeIds
|
- (void)deletePurchasedThemesWithIds:(NSArray<NSString *> *)themeIds
|
||||||
completion:(KBDeleteThemesCompletion)completion;
|
completion:(KBDeleteThemesCompletion)completion;
|
||||||
|
/// 分页查询钱包交易记录(/wallet/transactions)
|
||||||
|
- (void)fetchWalletTransactionsWithPage:(NSInteger)pageNum
|
||||||
|
pageSize:(NSInteger)pageSize
|
||||||
|
completion:(KBMyPurchaseRecordCompletion)completion;
|
||||||
/// 本地已下载主题列表
|
/// 本地已下载主题列表
|
||||||
- (void)fetchDownloadedThemesWithCompletion:(KBMyPurchasedThemesCompletion)completion;
|
- (void)fetchDownloadedThemesWithCompletion:(KBMyPurchasedThemesCompletion)completion;
|
||||||
/// 删除本地主题资源
|
/// 删除本地主题资源
|
||||||
|
|||||||
@@ -158,6 +158,47 @@ NSString * const KBUserCharacterDeletedNotification = @"KBUserCharacterDeletedNo
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)fetchWalletTransactionsWithPage:(NSInteger)pageNum
|
||||||
|
pageSize:(NSInteger)pageSize
|
||||||
|
completion:(KBMyPurchaseRecordCompletion)completion {
|
||||||
|
NSInteger safePageNum = pageNum > 0 ? pageNum : 1;
|
||||||
|
NSInteger safePageSize = pageSize > 0 ? pageSize : 10;
|
||||||
|
NSDictionary *body = @{
|
||||||
|
@"pageNum": @(safePageNum),
|
||||||
|
@"pageSize": @(safePageSize)
|
||||||
|
};
|
||||||
|
[[KBNetworkManager shared] POST:API_WALLET_TRANSACTIONS
|
||||||
|
jsonBody:body
|
||||||
|
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:[NSDictionary class]]) {
|
||||||
|
NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain
|
||||||
|
code:KBNetworkErrorInvalidResponse
|
||||||
|
userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Invalid response")}];
|
||||||
|
if (completion) completion(nil, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
id recordsObj = [(NSDictionary *)dataObj objectForKey:@"records"];
|
||||||
|
if (![recordsObj isKindOfClass:[NSArray class]]) {
|
||||||
|
NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain
|
||||||
|
code:KBNetworkErrorInvalidResponse
|
||||||
|
userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Invalid response")}];
|
||||||
|
if (completion) completion(nil, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NSArray<KBConsumptionRecord *> *records = [KBConsumptionRecord mj_objectArrayWithKeyValuesArray:(NSArray *)recordsObj];
|
||||||
|
if (completion) completion(records, nil);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)fetchDownloadedThemesWithCompletion:(KBMyPurchasedThemesCompletion)completion {
|
- (void)fetchDownloadedThemesWithCompletion:(KBMyPurchasedThemesCompletion)completion {
|
||||||
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
|
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
|
||||||
NSArray<KBSkinDownloadRecord *> *records = [KBSkinInstallBridge installedSkinRecords];
|
NSArray<KBSkinDownloadRecord *> *records = [KBSkinInstallBridge installedSkinRecords];
|
||||||
|
|||||||
@@ -293,7 +293,10 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) {
|
|||||||
mode:KBSkinSourceModeRemoteZip
|
mode:KBSkinSourceModeRemoteZip
|
||||||
completion:^(BOOL success) {
|
completion:^(BOOL success) {
|
||||||
if (success) {
|
if (success) {
|
||||||
// [KBHUD showSuccess:KBLocalized(@"已开始下载")];
|
NSString *themeId = self.detailModel.themeId;
|
||||||
|
if (themeId.length > 0) {
|
||||||
|
[self.shopVM restoreThemeWithId:themeId completion:nil];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
[KBHUD showInfo:KBLocalized(@"下载失败")];
|
[KBHUD showInfo:KBLocalized(@"下载失败")];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ typedef void(^KBShopPurchaseCompletion)(BOOL success,
|
|||||||
NSError *_Nullable error);
|
NSError *_Nullable error);
|
||||||
typedef void(^KBShopDownloadInfoCompletion)(NSDictionary *_Nullable info,
|
typedef void(^KBShopDownloadInfoCompletion)(NSDictionary *_Nullable info,
|
||||||
NSError *_Nullable error);
|
NSError *_Nullable error);
|
||||||
|
typedef void(^KBShopRestoreCompletion)(BOOL success,
|
||||||
|
NSError *_Nullable error);
|
||||||
|
|
||||||
@interface KBShopVM : NSObject
|
@interface KBShopVM : NSObject
|
||||||
@property (nonatomic, copy, readonly, nullable) NSArray<KBShopStyleModel *> *styles;
|
@property (nonatomic, copy, readonly, nullable) NSArray<KBShopStyleModel *> *styles;
|
||||||
@@ -56,6 +58,10 @@ typedef void(^KBShopDownloadInfoCompletion)(NSDictionary *_Nullable info,
|
|||||||
/// 推荐主题列表(用于皮肤详情页底部网格)
|
/// 推荐主题列表(用于皮肤详情页底部网格)
|
||||||
- (void)fetchRecommendedThemesWithCompletion:(KBShopThemesCompletion)completion;
|
- (void)fetchRecommendedThemesWithCompletion:(KBShopThemesCompletion)completion;
|
||||||
|
|
||||||
|
/// 恢复已删除的主题(/themes/restore)
|
||||||
|
- (void)restoreThemeWithId:(nullable NSString *)themeId
|
||||||
|
completion:(nullable KBShopRestoreCompletion)completion;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|||||||
@@ -201,6 +201,24 @@
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)restoreThemeWithId:(nullable NSString *)themeId
|
||||||
|
completion:(nullable KBShopRestoreCompletion)completion {
|
||||||
|
if (themeId.length == 0) {
|
||||||
|
if (completion) completion(NO, [self kb_invalidParameterError]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NSDictionary *body = @{@"themeId": [self kb_themeIdParamFromString:themeId]};
|
||||||
|
[[KBNetworkManager shared] POST:API_THEME_RESTORE
|
||||||
|
jsonBody:body
|
||||||
|
headers:nil
|
||||||
|
autoShowBusinessError:NO
|
||||||
|
completion:^(NSDictionary * _Nullable json,
|
||||||
|
NSURLResponse * _Nullable response,
|
||||||
|
NSError * _Nullable error) {
|
||||||
|
if (completion) completion(error == nil, error);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
- (id)kb_themeIdParamFromString:(NSString *)themeId {
|
- (id)kb_themeIdParamFromString:(NSString *)themeId {
|
||||||
if (themeId.length == 0) { return @""; }
|
if (themeId.length == 0) { return @""; }
|
||||||
NSNumberFormatter *formatter = [NSNumberFormatter new];
|
NSNumberFormatter *formatter = [NSNumberFormatter new];
|
||||||
|
|||||||
Reference in New Issue
Block a user