添加评论
This commit is contained in:
83
keyBoard/Class/AiTalk/M/KBAICommentModel.h
Normal file
83
keyBoard/Class/AiTalk/M/KBAICommentModel.h
Normal file
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// KBAICommentModel.h
|
||||
// keyBoard
|
||||
//
|
||||
// Created by Mac on 2026/1/16.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class KBAIReplyModel;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/// Footer 状态枚举
|
||||
typedef NS_ENUM(NSInteger, KBAIReplyFooterState) {
|
||||
KBAIReplyFooterStateHidden, // 无二级评论,不显示
|
||||
KBAIReplyFooterStateExpand, // 显示"展开x条回复"(初始折叠状态)
|
||||
KBAIReplyFooterStateLoadMore, // 显示"加载更多"(已展开部分)
|
||||
KBAIReplyFooterStateCollapse // 显示"收起"(全部展开后)
|
||||
};
|
||||
|
||||
/// 一级评论模型
|
||||
@interface KBAICommentModel : NSObject
|
||||
|
||||
/// 评论ID
|
||||
@property(nonatomic, copy) NSString *commentId;
|
||||
|
||||
/// 用户ID
|
||||
@property(nonatomic, copy) NSString *userId;
|
||||
|
||||
/// 用户名
|
||||
@property(nonatomic, copy) NSString *userName;
|
||||
|
||||
/// 用户头像
|
||||
@property(nonatomic, copy) NSString *avatarUrl;
|
||||
|
||||
/// 评论内容
|
||||
@property(nonatomic, copy) NSString *content;
|
||||
|
||||
/// 点赞数
|
||||
@property(nonatomic, assign) NSInteger likeCount;
|
||||
|
||||
/// 是否已点赞
|
||||
@property(nonatomic, assign) BOOL isLiked;
|
||||
|
||||
/// 创建时间(时间戳)
|
||||
@property(nonatomic, assign) NSTimeInterval createTime;
|
||||
|
||||
#pragma mark - 二级评论相关
|
||||
|
||||
/// 所有二级评论(从服务器获取的完整数据)
|
||||
@property(nonatomic, strong) NSArray<KBAIReplyModel *> *replies;
|
||||
|
||||
/// 当前显示的二级评论(分页展开用)
|
||||
@property(nonatomic, strong) NSMutableArray<KBAIReplyModel *> *displayedReplies;
|
||||
|
||||
/// 二级评论总数
|
||||
@property(nonatomic, assign) NSInteger totalReplyCount;
|
||||
|
||||
/// 是否还有更多回复未展开
|
||||
@property(nonatomic, assign) BOOL hasMoreReplies;
|
||||
|
||||
/// 回复是否已展开
|
||||
@property(nonatomic, assign) BOOL isRepliesExpanded;
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
/// 格式化后的时间字符串
|
||||
- (NSString *)formattedTime;
|
||||
|
||||
/// 获取当前 Footer 状态
|
||||
- (KBAIReplyFooterState)footerState;
|
||||
|
||||
/// 展开更多回复(每次加载指定数量)
|
||||
/// @param count 本次加载的数量
|
||||
- (void)loadMoreReplies:(NSInteger)count;
|
||||
|
||||
/// 收起所有回复
|
||||
- (void)collapseReplies;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
100
keyBoard/Class/AiTalk/M/KBAICommentModel.m
Normal file
100
keyBoard/Class/AiTalk/M/KBAICommentModel.m
Normal file
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// KBAICommentModel.m
|
||||
// keyBoard
|
||||
//
|
||||
// Created by Mac on 2026/1/16.
|
||||
//
|
||||
|
||||
#import "KBAICommentModel.h"
|
||||
#import "KBAIReplyModel.h"
|
||||
#import <MJExtension/MJExtension.h>
|
||||
|
||||
@implementation KBAICommentModel
|
||||
|
||||
+ (NSDictionary *)mj_replacedKeyFromPropertyName {
|
||||
return @{
|
||||
@"commentId" : @"id",
|
||||
@"userName" : @[ @"userName", @"nickname", @"name" ],
|
||||
@"avatarUrl" : @[ @"avatarUrl", @"avatar" ],
|
||||
};
|
||||
}
|
||||
|
||||
+ (NSDictionary *)mj_objectClassInArray {
|
||||
return @{@"replies" : [KBAIReplyModel class]};
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_displayedReplies = [NSMutableArray array];
|
||||
_isRepliesExpanded = NO;
|
||||
_hasMoreReplies = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setReplies:(NSArray<KBAIReplyModel *> *)replies {
|
||||
_replies = replies;
|
||||
_totalReplyCount = replies.count;
|
||||
_hasMoreReplies = replies.count > 0;
|
||||
}
|
||||
|
||||
- (NSString *)formattedTime {
|
||||
NSDate *date = [NSDate dateWithTimeIntervalSince1970:self.createTime];
|
||||
NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:date];
|
||||
|
||||
if (interval < 60) {
|
||||
return @"刚刚";
|
||||
} else if (interval < 3600) {
|
||||
return [NSString stringWithFormat:@"%.0f分钟前", interval / 60];
|
||||
} else if (interval < 86400) {
|
||||
return [NSString stringWithFormat:@"%.0f小时前", interval / 3600];
|
||||
} else if (interval < 86400 * 30) {
|
||||
return [NSString stringWithFormat:@"%.0f天前", interval / 86400];
|
||||
} else {
|
||||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||||
formatter.dateFormat = @"MM-dd";
|
||||
return [formatter stringFromDate:date];
|
||||
}
|
||||
}
|
||||
|
||||
- (KBAIReplyFooterState)footerState {
|
||||
// 无二级评论
|
||||
if (self.totalReplyCount == 0) {
|
||||
return KBAIReplyFooterStateHidden;
|
||||
}
|
||||
|
||||
// 未展开(初始状态)
|
||||
if (!self.isRepliesExpanded) {
|
||||
return KBAIReplyFooterStateExpand;
|
||||
}
|
||||
|
||||
// 已展开但还有更多
|
||||
if (self.displayedReplies.count < self.totalReplyCount) {
|
||||
return KBAIReplyFooterStateLoadMore;
|
||||
}
|
||||
|
||||
// 全部展开,显示收起
|
||||
return KBAIReplyFooterStateCollapse;
|
||||
}
|
||||
|
||||
- (void)loadMoreReplies:(NSInteger)count {
|
||||
self.isRepliesExpanded = YES;
|
||||
|
||||
NSInteger currentCount = self.displayedReplies.count;
|
||||
NSInteger endIndex = MIN(currentCount + count, self.replies.count);
|
||||
|
||||
for (NSInteger i = currentCount; i < endIndex; i++) {
|
||||
[self.displayedReplies addObject:self.replies[i]];
|
||||
}
|
||||
|
||||
self.hasMoreReplies = (self.displayedReplies.count < self.totalReplyCount);
|
||||
}
|
||||
|
||||
- (void)collapseReplies {
|
||||
self.isRepliesExpanded = NO;
|
||||
[self.displayedReplies removeAllObjects];
|
||||
self.hasMoreReplies = self.totalReplyCount > 0;
|
||||
}
|
||||
|
||||
@end
|
||||
47
keyBoard/Class/AiTalk/M/KBAIReplyModel.h
Normal file
47
keyBoard/Class/AiTalk/M/KBAIReplyModel.h
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// KBAIReplyModel.h
|
||||
// keyBoard
|
||||
//
|
||||
// Created by Mac on 2026/1/16.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/// 二级评论(回复)模型
|
||||
@interface KBAIReplyModel : NSObject
|
||||
|
||||
/// 回复ID
|
||||
@property(nonatomic, copy) NSString *replyId;
|
||||
|
||||
/// 用户ID
|
||||
@property(nonatomic, copy) NSString *userId;
|
||||
|
||||
/// 用户名
|
||||
@property(nonatomic, copy) NSString *userName;
|
||||
|
||||
/// 用户头像
|
||||
@property(nonatomic, copy) NSString *avatarUrl;
|
||||
|
||||
/// 回复内容
|
||||
@property(nonatomic, copy) NSString *content;
|
||||
|
||||
/// 被回复的用户名(@xxx)
|
||||
@property(nonatomic, copy, nullable) NSString *replyToUserName;
|
||||
|
||||
/// 点赞数
|
||||
@property(nonatomic, assign) NSInteger likeCount;
|
||||
|
||||
/// 是否已点赞
|
||||
@property(nonatomic, assign) BOOL isLiked;
|
||||
|
||||
/// 创建时间(时间戳)
|
||||
@property(nonatomic, assign) NSTimeInterval createTime;
|
||||
|
||||
/// 格式化后的时间字符串
|
||||
- (NSString *)formattedTime;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
40
keyBoard/Class/AiTalk/M/KBAIReplyModel.m
Normal file
40
keyBoard/Class/AiTalk/M/KBAIReplyModel.m
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// KBAIReplyModel.m
|
||||
// keyBoard
|
||||
//
|
||||
// Created by Mac on 2026/1/16.
|
||||
//
|
||||
|
||||
#import "KBAIReplyModel.h"
|
||||
#import <MJExtension/MJExtension.h>
|
||||
|
||||
@implementation KBAIReplyModel
|
||||
|
||||
+ (NSDictionary *)mj_replacedKeyFromPropertyName {
|
||||
return @{
|
||||
@"replyId" : @"id",
|
||||
@"userName" : @[ @"userName", @"nickname", @"name" ],
|
||||
@"avatarUrl" : @[ @"avatarUrl", @"avatar" ],
|
||||
};
|
||||
}
|
||||
|
||||
- (NSString *)formattedTime {
|
||||
NSDate *date = [NSDate dateWithTimeIntervalSince1970:self.createTime];
|
||||
NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:date];
|
||||
|
||||
if (interval < 60) {
|
||||
return @"刚刚";
|
||||
} else if (interval < 3600) {
|
||||
return [NSString stringWithFormat:@"%.0f分钟前", interval / 60];
|
||||
} else if (interval < 86400) {
|
||||
return [NSString stringWithFormat:@"%.0f小时前", interval / 3600];
|
||||
} else if (interval < 86400 * 30) {
|
||||
return [NSString stringWithFormat:@"%.0f天前", interval / 86400];
|
||||
} else {
|
||||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||||
formatter.dateFormat = @"MM-dd";
|
||||
return [formatter stringFromDate:date];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
207
keyBoard/Class/AiTalk/M/comments_mock.json
Normal file
207
keyBoard/Class/AiTalk/M/comments_mock.json
Normal file
@@ -0,0 +1,207 @@
|
||||
{
|
||||
"totalCount": 1258,
|
||||
"comments": [
|
||||
{
|
||||
"id": "comment_001",
|
||||
"userId": "user_101",
|
||||
"userName": "小明同学",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=1",
|
||||
"content": "这个功能太棒了!期待更多更新",
|
||||
"likeCount": 328,
|
||||
"isLiked": false,
|
||||
"createTime": 1737010800,
|
||||
"replies": [
|
||||
{
|
||||
"id": "reply_001_1",
|
||||
"userId": "user_102",
|
||||
"userName": "科技达人",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=2",
|
||||
"content": "同意!这个设计真的很用心",
|
||||
"likeCount": 45,
|
||||
"isLiked": false,
|
||||
"createTime": 1737014400
|
||||
},
|
||||
{
|
||||
"id": "reply_001_2",
|
||||
"userId": "user_103",
|
||||
"userName": "程序员小李",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=3",
|
||||
"content": "感谢支持,会继续努力的!",
|
||||
"replyToUserName": "科技达人",
|
||||
"likeCount": 23,
|
||||
"isLiked": true,
|
||||
"createTime": 1737018000
|
||||
},
|
||||
{
|
||||
"id": "reply_001_3",
|
||||
"userId": "user_104",
|
||||
"userName": "产品经理",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=4",
|
||||
"content": "下个版本会有更多惊喜",
|
||||
"likeCount": 12,
|
||||
"isLiked": false,
|
||||
"createTime": 1737021600
|
||||
},
|
||||
{
|
||||
"id": "reply_001_4",
|
||||
"userId": "user_105",
|
||||
"userName": "UI设计师",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=5",
|
||||
"content": "细节决定品质",
|
||||
"likeCount": 8,
|
||||
"isLiked": false,
|
||||
"createTime": 1737025200
|
||||
},
|
||||
{
|
||||
"id": "reply_001_5",
|
||||
"userId": "user_106",
|
||||
"userName": "测试工程师",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=6",
|
||||
"content": "已经测试通过了,稳定性很好",
|
||||
"likeCount": 5,
|
||||
"isLiked": false,
|
||||
"createTime": 1737028800
|
||||
},
|
||||
{
|
||||
"id": "reply_001_6",
|
||||
"userId": "user_107",
|
||||
"userName": "运营妹子",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=7",
|
||||
"content": "用户反馈都很正面",
|
||||
"likeCount": 3,
|
||||
"isLiked": false,
|
||||
"createTime": 1737032400
|
||||
},
|
||||
{
|
||||
"id": "reply_001_7",
|
||||
"userId": "user_108",
|
||||
"userName": "后端大神",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=8",
|
||||
"content": "接口性能优化了30%",
|
||||
"likeCount": 15,
|
||||
"isLiked": false,
|
||||
"createTime": 1737036000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "comment_002",
|
||||
"userId": "user_201",
|
||||
"userName": "热心网友",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=10",
|
||||
"content": "请问这个键盘支持哪些语言输入?想知道有没有日语输入法。",
|
||||
"likeCount": 89,
|
||||
"isLiked": false,
|
||||
"createTime": 1736924400,
|
||||
"replies": [
|
||||
{
|
||||
"id": "reply_002_1",
|
||||
"userId": "user_202",
|
||||
"userName": "官方客服",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=11",
|
||||
"content": "目前支持中文、英文,日语输入法正在开发中,预计下月上线",
|
||||
"likeCount": 32,
|
||||
"isLiked": false,
|
||||
"createTime": 1736928000
|
||||
},
|
||||
{
|
||||
"id": "reply_002_2",
|
||||
"userId": "user_201",
|
||||
"userName": "热心网友",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=10",
|
||||
"content": "太好了,期待!",
|
||||
"replyToUserName": "官方客服",
|
||||
"likeCount": 5,
|
||||
"isLiked": false,
|
||||
"createTime": 1736931600
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "comment_003",
|
||||
"userId": "user_301",
|
||||
"userName": "设计爱好者",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=12",
|
||||
"content": "这个UI设计太精美了,配色方案很舒服,是哪位设计师的作品?",
|
||||
"likeCount": 256,
|
||||
"isLiked": true,
|
||||
"createTime": 1736838000,
|
||||
"replies": []
|
||||
},
|
||||
{
|
||||
"id": "comment_004",
|
||||
"userId": "user_401",
|
||||
"userName": "效率达人",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=13",
|
||||
"content": "自从用了这个键盘,打字速度提升了一倍!强烈推荐给大家",
|
||||
"likeCount": 512,
|
||||
"isLiked": false,
|
||||
"createTime": 1736751600,
|
||||
"replies": [
|
||||
{
|
||||
"id": "reply_004_1",
|
||||
"userId": "user_402",
|
||||
"userName": "新用户",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=14",
|
||||
"content": "真的吗?那我也要试试",
|
||||
"likeCount": 18,
|
||||
"isLiked": false,
|
||||
"createTime": 1736755200
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "comment_005",
|
||||
"userId": "user_501",
|
||||
"userName": "数码博主",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=15",
|
||||
"content": "做了一期评测视频,这款键盘在同类产品中确实是顶尖水平",
|
||||
"likeCount": 1024,
|
||||
"isLiked": false,
|
||||
"createTime": 1736665200,
|
||||
"replies": [
|
||||
{
|
||||
"id": "reply_005_1",
|
||||
"userId": "user_502",
|
||||
"userName": "粉丝A",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=16",
|
||||
"content": "博主的评测视频太专业了",
|
||||
"likeCount": 56,
|
||||
"isLiked": false,
|
||||
"createTime": 1736668800
|
||||
},
|
||||
{
|
||||
"id": "reply_005_2",
|
||||
"userId": "user_503",
|
||||
"userName": "粉丝B",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=17",
|
||||
"content": "已经去看了,确实很详细",
|
||||
"likeCount": 23,
|
||||
"isLiked": false,
|
||||
"createTime": 1736672400
|
||||
},
|
||||
{
|
||||
"id": "reply_005_3",
|
||||
"userId": "user_504",
|
||||
"userName": "路人甲",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=18",
|
||||
"content": "求链接",
|
||||
"likeCount": 8,
|
||||
"isLiked": false,
|
||||
"createTime": 1736676000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "comment_006",
|
||||
"userId": "user_601",
|
||||
"userName": "老用户",
|
||||
"avatarUrl": "https://picsum.photos/100/100?random=19",
|
||||
"content": "用了三年了,一直很稳定,希望能出个暗黑主题",
|
||||
"likeCount": 178,
|
||||
"isLiked": false,
|
||||
"createTime": 1736578800,
|
||||
"replies": []
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user