新增聊天记录
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
#import "KBPersonaChatCell.h"
|
||||
#import "KBChatTableView.h"
|
||||
#import "KBAiChatMessage.h"
|
||||
#import "KBChatHistoryPageModel.h"
|
||||
#import "AiVM.h"
|
||||
#import <Masonry/Masonry.h>
|
||||
#import <SDWebImage/SDWebImage.h>
|
||||
|
||||
@@ -34,6 +36,18 @@
|
||||
/// 是否已加载数据
|
||||
@property (nonatomic, assign) BOOL hasLoadedData;
|
||||
|
||||
/// 是否正在加载
|
||||
@property (nonatomic, assign) BOOL isLoading;
|
||||
|
||||
/// 当前页码
|
||||
@property (nonatomic, assign) NSInteger currentPage;
|
||||
|
||||
/// 是否还有更多历史消息
|
||||
@property (nonatomic, assign) BOOL hasMoreHistory;
|
||||
|
||||
/// AiVM 实例
|
||||
@property (nonatomic, strong) AiVM *aiVM;
|
||||
|
||||
@end
|
||||
|
||||
@implementation KBPersonaChatCell
|
||||
@@ -102,7 +116,11 @@
|
||||
|
||||
// 重置状态
|
||||
self.hasLoadedData = NO;
|
||||
self.isLoading = NO;
|
||||
self.currentPage = 1;
|
||||
self.hasMoreHistory = YES;
|
||||
self.messages = [NSMutableArray array];
|
||||
self.aiVM = [[AiVM alloc] init];
|
||||
|
||||
// 设置 UI
|
||||
[self.backgroundImageView sd_setImageWithURL:[NSURL URLWithString:persona.coverImageUrl]
|
||||
@@ -118,20 +136,113 @@
|
||||
#pragma mark - 2:数据加载
|
||||
|
||||
- (void)preloadDataIfNeeded {
|
||||
if (self.hasLoadedData) {
|
||||
if (self.hasLoadedData || self.isLoading) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: 这里后续需要用 chatId 去请求聊天记录
|
||||
// 目前先添加开场白作为第一条消息
|
||||
self.hasLoadedData = YES;
|
||||
|
||||
if (self.persona.introText.length > 0) {
|
||||
KBAiChatMessage *openingMsg = [KBAiChatMessage assistantMessageWithText:self.persona.introText];
|
||||
openingMsg.isComplete = YES;
|
||||
[self.messages addObject:openingMsg];
|
||||
[self.tableView reloadData];
|
||||
[self loadChatHistory];
|
||||
}
|
||||
|
||||
- (void)loadChatHistory {
|
||||
if (self.isLoading || !self.hasMoreHistory) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.isLoading = YES;
|
||||
|
||||
// 使用 persona.personaId 作为 companionId
|
||||
NSInteger companionId = self.persona.personaId;
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[self.aiVM fetchChatHistoryWithCompanionId:companionId
|
||||
pageNum:self.currentPage
|
||||
pageSize:20
|
||||
completion:^(KBChatHistoryPageModel *pageModel, NSError *error) {
|
||||
weakSelf.isLoading = NO;
|
||||
|
||||
if (error) {
|
||||
NSLog(@"[KBPersonaChatCell] 加载聊天记录失败:%@", error.localizedDescription);
|
||||
|
||||
// 如果是第一次加载失败,显示开场白
|
||||
if (weakSelf.currentPage == 1 && weakSelf.persona.introText.length > 0) {
|
||||
[weakSelf showOpeningMessage];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
weakSelf.hasLoadedData = YES;
|
||||
weakSelf.hasMoreHistory = pageModel.hasMore;
|
||||
|
||||
// 转换为 KBAiChatMessage
|
||||
NSMutableArray *newMessages = [NSMutableArray array];
|
||||
for (KBChatHistoryModel *item in pageModel.records) {
|
||||
KBAiChatMessage *message;
|
||||
if (item.isUserMessage) {
|
||||
message = [KBAiChatMessage userMessageWithText:item.content];
|
||||
} else {
|
||||
message = [KBAiChatMessage assistantMessageWithText:item.content];
|
||||
}
|
||||
message.isComplete = YES;
|
||||
[newMessages addObject:message];
|
||||
}
|
||||
|
||||
// 插入到顶部(历史消息)
|
||||
if (weakSelf.currentPage == 1) {
|
||||
// 第一页,直接赋值
|
||||
weakSelf.messages = newMessages;
|
||||
} else {
|
||||
// 后续页,插入到顶部
|
||||
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, newMessages.count)];
|
||||
[weakSelf.messages insertObjects:newMessages atIndexes:indexSet];
|
||||
}
|
||||
|
||||
// 刷新 UI
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (weakSelf.currentPage == 1) {
|
||||
[weakSelf.tableView reloadData];
|
||||
|
||||
// 滚动到底部(最新消息)
|
||||
if (weakSelf.messages.count > 0) {
|
||||
NSIndexPath *lastIndexPath = [NSIndexPath indexPathForRow:weakSelf.messages.count - 1 inSection:0];
|
||||
[weakSelf.tableView scrollToRowAtIndexPath:lastIndexPath
|
||||
atScrollPosition:UITableViewScrollPositionBottom
|
||||
animated:NO];
|
||||
}
|
||||
} else {
|
||||
// 保持滚动位置
|
||||
CGFloat oldContentHeight = weakSelf.tableView.contentSize.height;
|
||||
[weakSelf.tableView reloadData];
|
||||
CGFloat newContentHeight = weakSelf.tableView.contentSize.height;
|
||||
CGFloat offsetY = newContentHeight - oldContentHeight;
|
||||
[weakSelf.tableView setContentOffset:CGPointMake(0, offsetY) animated:NO];
|
||||
}
|
||||
});
|
||||
|
||||
NSLog(@"[KBPersonaChatCell] 加载成功:第 %ld 页,%ld 条消息,还有更多:%@",
|
||||
(long)weakSelf.currentPage,
|
||||
(long)newMessages.count,
|
||||
pageModel.hasMore ? @"是" : @"否");
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)loadMoreHistory {
|
||||
if (!self.hasMoreHistory || self.isLoading) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.currentPage++;
|
||||
[self loadChatHistory];
|
||||
}
|
||||
|
||||
- (void)showOpeningMessage {
|
||||
// 显示开场白作为第一条消息
|
||||
KBAiChatMessage *openingMsg = [KBAiChatMessage assistantMessageWithText:self.persona.introText];
|
||||
openingMsg.isComplete = YES;
|
||||
[self.messages addObject:openingMsg];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.tableView reloadData];
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
@@ -159,6 +270,17 @@
|
||||
return UITableViewAutomaticDimension;
|
||||
}
|
||||
|
||||
#pragma mark - UIScrollViewDelegate
|
||||
|
||||
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
|
||||
CGFloat offsetY = scrollView.contentOffset.y;
|
||||
|
||||
// 下拉到顶部,加载历史消息
|
||||
if (offsetY <= -50 && !self.isLoading) {
|
||||
[self loadMoreHistory];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Lazy Load
|
||||
|
||||
- (UIImageView *)backgroundImageView {
|
||||
|
||||
Reference in New Issue
Block a user