1
This commit is contained in:
@@ -154,6 +154,7 @@
|
|||||||
048FFD372F29F410005D62AE /* KBAIMessageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 048FFD392F29F410005D62AE /* KBAIMessageCell.m */; };
|
048FFD372F29F410005D62AE /* KBAIMessageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 048FFD392F29F410005D62AE /* KBAIMessageCell.m */; };
|
||||||
048FFD3C2F29F500005D62AE /* KBLikedCompanionModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 048FFD3B2F29F500005D62AE /* KBLikedCompanionModel.m */; };
|
048FFD3C2F29F500005D62AE /* KBLikedCompanionModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 048FFD3B2F29F500005D62AE /* KBLikedCompanionModel.m */; };
|
||||||
048FFD3F2F29F600005D62AE /* KBChattedCompanionModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 048FFD3E2F29F600005D62AE /* KBChattedCompanionModel.m */; };
|
048FFD3F2F29F600005D62AE /* KBChattedCompanionModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 048FFD3E2F29F600005D62AE /* KBChattedCompanionModel.m */; };
|
||||||
|
048FFD422F29F700005D62AE /* KBChatSessionResetModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 048FFD412F29F700005D62AE /* KBChatSessionResetModel.m */; };
|
||||||
0498BD622EDFFC12006CC1D5 /* KBMyVM.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD612EDFFC12006CC1D5 /* KBMyVM.m */; };
|
0498BD622EDFFC12006CC1D5 /* KBMyVM.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD612EDFFC12006CC1D5 /* KBMyVM.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 */; };
|
||||||
@@ -574,6 +575,8 @@
|
|||||||
048FFD3B2F29F500005D62AE /* KBLikedCompanionModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBLikedCompanionModel.m; sourceTree = "<group>"; };
|
048FFD3B2F29F500005D62AE /* KBLikedCompanionModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBLikedCompanionModel.m; sourceTree = "<group>"; };
|
||||||
048FFD3D2F29F600005D62AE /* KBChattedCompanionModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBChattedCompanionModel.h; sourceTree = "<group>"; };
|
048FFD3D2F29F600005D62AE /* KBChattedCompanionModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBChattedCompanionModel.h; sourceTree = "<group>"; };
|
||||||
048FFD3E2F29F600005D62AE /* KBChattedCompanionModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBChattedCompanionModel.m; sourceTree = "<group>"; };
|
048FFD3E2F29F600005D62AE /* KBChattedCompanionModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBChattedCompanionModel.m; sourceTree = "<group>"; };
|
||||||
|
048FFD402F29F700005D62AE /* KBChatSessionResetModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBChatSessionResetModel.h; sourceTree = "<group>"; };
|
||||||
|
048FFD412F29F700005D62AE /* KBChatSessionResetModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBChatSessionResetModel.m; sourceTree = "<group>"; };
|
||||||
0498BD5E2EDF2157006CC1D5 /* KBBizCode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBBizCode.h; sourceTree = "<group>"; };
|
0498BD5E2EDF2157006CC1D5 /* KBBizCode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBBizCode.h; sourceTree = "<group>"; };
|
||||||
0498BD602EDFFC12006CC1D5 /* KBMyVM.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBMyVM.h; sourceTree = "<group>"; };
|
0498BD602EDFFC12006CC1D5 /* KBMyVM.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBMyVM.h; sourceTree = "<group>"; };
|
||||||
0498BD612EDFFC12006CC1D5 /* KBMyVM.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBMyVM.m; sourceTree = "<group>"; };
|
0498BD612EDFFC12006CC1D5 /* KBMyVM.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBMyVM.m; sourceTree = "<group>"; };
|
||||||
@@ -1039,6 +1042,8 @@
|
|||||||
048FFD3B2F29F500005D62AE /* KBLikedCompanionModel.m */,
|
048FFD3B2F29F500005D62AE /* KBLikedCompanionModel.m */,
|
||||||
048FFD3D2F29F600005D62AE /* KBChattedCompanionModel.h */,
|
048FFD3D2F29F600005D62AE /* KBChattedCompanionModel.h */,
|
||||||
048FFD3E2F29F600005D62AE /* KBChattedCompanionModel.m */,
|
048FFD3E2F29F600005D62AE /* KBChattedCompanionModel.m */,
|
||||||
|
048FFD402F29F700005D62AE /* KBChatSessionResetModel.h */,
|
||||||
|
048FFD412F29F700005D62AE /* KBChatSessionResetModel.m */,
|
||||||
);
|
);
|
||||||
path = M;
|
path = M;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -2340,6 +2345,7 @@
|
|||||||
048FFD372F29F410005D62AE /* KBAIMessageCell.m in Sources */,
|
048FFD372F29F410005D62AE /* KBAIMessageCell.m in Sources */,
|
||||||
048FFD3C2F29F500005D62AE /* KBLikedCompanionModel.m in Sources */,
|
048FFD3C2F29F500005D62AE /* KBLikedCompanionModel.m in Sources */,
|
||||||
048FFD3F2F29F600005D62AE /* KBChattedCompanionModel.m in Sources */,
|
048FFD3F2F29F600005D62AE /* KBChattedCompanionModel.m in Sources */,
|
||||||
|
048FFD422F29F700005D62AE /* KBChatSessionResetModel.m in Sources */,
|
||||||
04791F952ED48028004E8522 /* KBFeedBackVC.m in Sources */,
|
04791F952ED48028004E8522 /* KBFeedBackVC.m in Sources */,
|
||||||
04890A042EC0BBBB00FABA60 /* KBCategoryTitleImageCell.m in Sources */,
|
04890A042EC0BBBB00FABA60 /* KBCategoryTitleImageCell.m in Sources */,
|
||||||
04890A052EC0BBBB00FABA60 /* KBCategoryTitleImageView.m in Sources */,
|
04890A052EC0BBBB00FABA60 /* KBCategoryTitleImageView.m in Sources */,
|
||||||
|
|||||||
49
keyBoard/Class/AiTalk/M/KBAIChatMessageCacheManager.h
Normal file
49
keyBoard/Class/AiTalk/M/KBAIChatMessageCacheManager.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// KBAIChatMessageCacheManager.h
|
||||||
|
// keyBoard
|
||||||
|
//
|
||||||
|
// Created by Mac on 2026/1/28.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
@class KBAiChatMessage;
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/// 聊天消息缓存管理器
|
||||||
|
/// 用于避免重复请求消息数据,提升性能
|
||||||
|
@interface KBAIChatMessageCacheManager : NSObject
|
||||||
|
|
||||||
|
/// 单例
|
||||||
|
+ (instancetype)shared;
|
||||||
|
|
||||||
|
/// 保存消息到缓存
|
||||||
|
/// @param messages 消息数组
|
||||||
|
/// @param companionId 人设 ID
|
||||||
|
- (void)saveMessages:(NSArray<KBAiChatMessage *> *)messages forCompanionId:(NSInteger)companionId;
|
||||||
|
|
||||||
|
/// 从缓存获取消息
|
||||||
|
/// @param companionId 人设 ID
|
||||||
|
/// @return 消息数组,如果缓存中没有则返回 nil
|
||||||
|
- (NSArray<KBAiChatMessage *> * _Nullable)messagesForCompanionId:(NSInteger)companionId;
|
||||||
|
|
||||||
|
/// 追加消息到缓存(用于上拉加载更多历史消息)
|
||||||
|
/// @param messages 新消息数组
|
||||||
|
/// @param companionId 人设 ID
|
||||||
|
- (void)appendMessages:(NSArray<KBAiChatMessage *> *)messages forCompanionId:(NSInteger)companionId;
|
||||||
|
|
||||||
|
/// 清空指定人设的消息缓存
|
||||||
|
/// @param companionId 人设 ID
|
||||||
|
- (void)clearMessagesForCompanionId:(NSInteger)companionId;
|
||||||
|
|
||||||
|
/// 清空所有消息缓存
|
||||||
|
- (void)clearAllMessages;
|
||||||
|
|
||||||
|
/// 获取缓存状态
|
||||||
|
/// @param companionId 人设 ID
|
||||||
|
/// @return 是否有缓存
|
||||||
|
- (BOOL)hasCacheForCompanionId:(NSInteger)companionId;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
123
keyBoard/Class/AiTalk/M/KBAIChatMessageCacheManager.m
Normal file
123
keyBoard/Class/AiTalk/M/KBAIChatMessageCacheManager.m
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
//
|
||||||
|
// KBAIChatMessageCacheManager.m
|
||||||
|
// keyBoard
|
||||||
|
//
|
||||||
|
// Created by Mac on 2026/1/28.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "KBAIChatMessageCacheManager.h"
|
||||||
|
#import "KBAiChatMessage.h"
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface KBAIChatMessageCacheManager ()
|
||||||
|
/// 消息缓存:Key = companionId,Value = messages 数组
|
||||||
|
@property (nonatomic, strong) NSCache<NSNumber *, NSMutableArray<KBAiChatMessage *> *> *messageCache;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation KBAIChatMessageCacheManager
|
||||||
|
|
||||||
|
#pragma mark - Singleton
|
||||||
|
|
||||||
|
+ (instancetype)shared {
|
||||||
|
static KBAIChatMessageCacheManager *instance = nil;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
instance = [[self alloc] init];
|
||||||
|
});
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
_messageCache = [[NSCache alloc] init];
|
||||||
|
|
||||||
|
// 设置缓存上限,防止内存过大
|
||||||
|
_messageCache.countLimit = 20; // 最多缓存 20 个人设的消息
|
||||||
|
_messageCache.totalCostLimit = 10 * 1024 * 1024; // 最大 10MB
|
||||||
|
|
||||||
|
// 监听内存警告,自动清理缓存
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
|
selector:@selector(handleMemoryWarning)
|
||||||
|
name:UIApplicationDidReceiveMemoryWarningNotification
|
||||||
|
object:nil];
|
||||||
|
|
||||||
|
NSLog(@"[MessageCache] 缓存管理器初始化成功,限制:20个人设,最大10MB");
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Public Methods
|
||||||
|
|
||||||
|
- (void)saveMessages:(NSArray<KBAiChatMessage *> *)messages forCompanionId:(NSInteger)companionId {
|
||||||
|
if (!messages || messages.count == 0) {
|
||||||
|
NSLog(@"[MessageCache] 警告:尝试保存空消息数组,companionId=%ld", (long)companionId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSNumber *key = @(companionId);
|
||||||
|
NSMutableArray *mutableMessages = [messages mutableCopy];
|
||||||
|
[self.messageCache setObject:mutableMessages forKey:key];
|
||||||
|
|
||||||
|
NSLog(@"[MessageCache] 保存成功:companionId=%ld, 消息数=%ld", (long)companionId, (long)messages.count);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray<KBAiChatMessage *> *)messagesForCompanionId:(NSInteger)companionId {
|
||||||
|
NSNumber *key = @(companionId);
|
||||||
|
NSMutableArray *messages = [self.messageCache objectForKey:key];
|
||||||
|
|
||||||
|
if (messages) {
|
||||||
|
NSLog(@"[MessageCache] 缓存命中:companionId=%ld, 消息数=%ld", (long)companionId, (long)messages.count);
|
||||||
|
} else {
|
||||||
|
NSLog(@"[MessageCache] 缓存未命中:companionId=%ld", (long)companionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)appendMessages:(NSArray<KBAiChatMessage *> *)messages forCompanionId:(NSInteger)companionId {
|
||||||
|
if (!messages || messages.count == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSNumber *key = @(companionId);
|
||||||
|
NSMutableArray *existingMessages = [self.messageCache objectForKey:key];
|
||||||
|
|
||||||
|
if (existingMessages) {
|
||||||
|
// 追加到现有消息数组
|
||||||
|
[existingMessages addObjectsFromArray:messages];
|
||||||
|
NSLog(@"[MessageCache] 追加消息:companionId=%ld, 新增=%ld, 总计=%ld",
|
||||||
|
(long)companionId, (long)messages.count, (long)existingMessages.count);
|
||||||
|
} else {
|
||||||
|
// 如果缓存中没有,直接保存
|
||||||
|
[self saveMessages:messages forCompanionId:companionId];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)clearMessagesForCompanionId:(NSInteger)companionId {
|
||||||
|
NSNumber *key = @(companionId);
|
||||||
|
[self.messageCache removeObjectForKey:key];
|
||||||
|
NSLog(@"[MessageCache] 清空缓存:companionId=%ld", (long)companionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)clearAllMessages {
|
||||||
|
[self.messageCache removeAllObjects];
|
||||||
|
NSLog(@"[MessageCache] 清空所有缓存");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)hasCacheForCompanionId:(NSInteger)companionId {
|
||||||
|
NSNumber *key = @(companionId);
|
||||||
|
return [self.messageCache objectForKey:key] != nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Memory Warning
|
||||||
|
|
||||||
|
- (void)handleMemoryWarning {
|
||||||
|
NSLog(@"[MessageCache] ⚠️ 收到内存警告,清空所有消息缓存");
|
||||||
|
[self clearAllMessages];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
35
keyBoard/Class/AiTalk/M/KBChatSessionResetModel.h
Normal file
35
keyBoard/Class/AiTalk/M/KBChatSessionResetModel.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// KBChatSessionResetModel.h
|
||||||
|
// keyBoard
|
||||||
|
//
|
||||||
|
// Created by Mac on 2026/1/28.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/// 重置会话响应数据
|
||||||
|
@interface KBChatSessionResetData : NSObject
|
||||||
|
|
||||||
|
/// 会话 ID
|
||||||
|
@property (nonatomic, assign) NSInteger sessionId;
|
||||||
|
/// AI 角色 ID
|
||||||
|
@property (nonatomic, assign) NSInteger companionId;
|
||||||
|
/// 重置版本号
|
||||||
|
@property (nonatomic, assign) NSInteger resetVersion;
|
||||||
|
/// 创建时间
|
||||||
|
@property (nonatomic, copy) NSString *createdAt;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/// 重置会话响应
|
||||||
|
@interface KBChatSessionResetResponse : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, assign) NSInteger code;
|
||||||
|
@property (nonatomic, strong, nullable) KBChatSessionResetData *data;
|
||||||
|
@property (nonatomic, copy, nullable) NSString *message;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
16
keyBoard/Class/AiTalk/M/KBChatSessionResetModel.m
Normal file
16
keyBoard/Class/AiTalk/M/KBChatSessionResetModel.m
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// KBChatSessionResetModel.m
|
||||||
|
// keyBoard
|
||||||
|
//
|
||||||
|
// Created by Mac on 2026/1/28.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "KBChatSessionResetModel.h"
|
||||||
|
|
||||||
|
@implementation KBChatSessionResetData
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation KBChatSessionResetResponse
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
#import "AiVM.h"
|
#import "AiVM.h"
|
||||||
#import "KBImagePositionButton.h"
|
#import "KBImagePositionButton.h"
|
||||||
#import "KBAICommentView.h"
|
#import "KBAICommentView.h"
|
||||||
|
#import "KBAIChatMessageCacheManager.h"
|
||||||
#import <Masonry/Masonry.h>
|
#import <Masonry/Masonry.h>
|
||||||
#import <SDWebImage/SDWebImage.h>
|
#import <SDWebImage/SDWebImage.h>
|
||||||
#import <LSTPopView/LSTPopView.h>
|
#import <LSTPopView/LSTPopView.h>
|
||||||
@@ -71,16 +72,18 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 关键修复:Cell 复用时重置状态
|
/// 关键修复:Cell 复用时不清空数据,避免重复请求
|
||||||
- (void)prepareForReuse {
|
- (void)prepareForReuse {
|
||||||
[super prepareForReuse];
|
[super prepareForReuse];
|
||||||
|
|
||||||
// 停止音频播放
|
// 停止音频播放
|
||||||
[self.chatView stopPlayingAudio];
|
[self.chatView stopPlayingAudio];
|
||||||
|
|
||||||
// 重置加载状态
|
// 重置加载状态标志(但不清空 hasLoadedData)
|
||||||
self.isLoading = NO;
|
self.isLoading = NO;
|
||||||
self.hasLoadedData = NO;
|
|
||||||
|
// ✅ 移除了 self.hasLoadedData = NO;
|
||||||
|
// 这样 Cell 复用时不会重复请求数据
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - 1:控件初始化
|
#pragma mark - 1:控件初始化
|
||||||
@@ -157,11 +160,23 @@
|
|||||||
_persona = persona;
|
_persona = persona;
|
||||||
|
|
||||||
// 重置状态
|
// 重置状态
|
||||||
self.hasLoadedData = NO;
|
|
||||||
self.isLoading = NO;
|
self.isLoading = NO;
|
||||||
self.currentPage = 1;
|
self.currentPage = 1;
|
||||||
self.hasMoreHistory = YES;
|
self.hasMoreHistory = YES;
|
||||||
self.messages = [NSMutableArray array];
|
|
||||||
|
// ✅ 尝试从缓存加载 messages
|
||||||
|
NSArray *cachedMessages = [[KBAIChatMessageCacheManager shared] messagesForCompanionId:persona.personaId];
|
||||||
|
if (cachedMessages.count > 0) {
|
||||||
|
// 缓存命中,直接使用
|
||||||
|
self.messages = [cachedMessages mutableCopy];
|
||||||
|
self.hasLoadedData = YES;
|
||||||
|
NSLog(@"[Cell] ✅ 从缓存加载:personaId=%ld, 消息数=%ld", (long)persona.personaId, (long)cachedMessages.count);
|
||||||
|
} else {
|
||||||
|
// 缓存未命中,需要请求
|
||||||
|
self.messages = [NSMutableArray array];
|
||||||
|
self.hasLoadedData = NO;
|
||||||
|
NSLog(@"[Cell] ⚠️ 缓存未命中:personaId=%ld, 需要请求数据", (long)persona.personaId);
|
||||||
|
}
|
||||||
|
|
||||||
// 设置 UI
|
// 设置 UI
|
||||||
[self.backgroundImageView sd_setImageWithURL:[NSURL URLWithString:persona.coverImageUrl]
|
[self.backgroundImageView sd_setImageWithURL:[NSURL URLWithString:persona.coverImageUrl]
|
||||||
@@ -173,11 +188,19 @@
|
|||||||
|
|
||||||
// 关键修复:清空消息时停止音频播放,避免状态混乱
|
// 关键修复:清空消息时停止音频播放,避免状态混乱
|
||||||
[self.chatView stopPlayingAudio];
|
[self.chatView stopPlayingAudio];
|
||||||
[self.chatView clearMessages];
|
|
||||||
|
// 如果有缓存,直接显示
|
||||||
|
if (self.messages.count > 0) {
|
||||||
|
[self.chatView reloadWithMessages:self.messages
|
||||||
|
hasMoreHistory:self.hasMoreHistory
|
||||||
|
completion:nil];
|
||||||
|
} else {
|
||||||
|
[self.chatView clearMessages];
|
||||||
|
}
|
||||||
|
|
||||||
[self.commentButton setTitle:persona.commentCount forState:UIControlStateNormal];
|
[self.commentButton setTitle:persona.commentCount forState:UIControlStateNormal];
|
||||||
[self.likeButton setTitle:persona.likeCount forState:UIControlStateNormal];
|
[self.likeButton setTitle:persona.likeCount forState:UIControlStateNormal];
|
||||||
self.likeButton.selected = persona.liked;
|
self.likeButton.selected = persona.liked;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - 2:数据加载
|
#pragma mark - 2:数据加载
|
||||||
@@ -269,10 +292,16 @@
|
|||||||
keepOffset:keepOffset
|
keepOffset:keepOffset
|
||||||
scrollToBottom:scrollToBottom];
|
scrollToBottom:scrollToBottom];
|
||||||
[weakSelf.chatView endLoadMoreWithHasMoreData:weakSelf.hasMoreHistory];
|
[weakSelf.chatView endLoadMoreWithHasMoreData:weakSelf.hasMoreHistory];
|
||||||
|
|
||||||
|
// ✅ 保存到缓存
|
||||||
|
[[KBAIChatMessageCacheManager shared] saveMessages:weakSelf.messages
|
||||||
|
forCompanionId:companionId];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
weakSelf.currentPage++;
|
||||||
|
|
||||||
NSLog(@"[KBPersonaChatCell] 加载成功:第 %ld 页,%ld 条消息,还有更多:%@",
|
NSLog(@"[KBPersonaChatCell] 加载成功:第 %ld 页,%ld 条消息,还有更多:%@",
|
||||||
(long)weakSelf.currentPage,
|
(long)weakSelf.currentPage - 1,
|
||||||
(long)newMessages.count,
|
(long)newMessages.count,
|
||||||
pageModel.hasMore ? @"是" : @"否");
|
pageModel.hasMore ? @"是" : @"否");
|
||||||
}];
|
}];
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#import "KBCommentModel.h"
|
#import "KBCommentModel.h"
|
||||||
#import "KBLikedCompanionModel.h"
|
#import "KBLikedCompanionModel.h"
|
||||||
#import "KBChattedCompanionModel.h"
|
#import "KBChattedCompanionModel.h"
|
||||||
|
#import "KBChatSessionResetModel.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@@ -154,6 +155,14 @@ typedef void (^AiVMSpeechTranscribeCompletion)(KBAiSpeechTranscribeResponse *_Nu
|
|||||||
/// @param completion 完成回调(返回聊天角色数组)
|
/// @param completion 完成回调(返回聊天角色数组)
|
||||||
- (void)fetchChattedCompanionsWithCompletion:(void(^)(NSArray<KBChattedCompanionModel *> * _Nullable list, NSError * _Nullable error))completion;
|
- (void)fetchChattedCompanionsWithCompletion:(void(^)(NSArray<KBChattedCompanionModel *> * _Nullable list, NSError * _Nullable error))completion;
|
||||||
|
|
||||||
|
#pragma mark - 会话管理接口
|
||||||
|
|
||||||
|
/// 重置会话(将当前会话设为不活跃并创建新会话)
|
||||||
|
/// @param companionId AI 角色 ID
|
||||||
|
/// @param completion 完成回调(返回新会话信息)
|
||||||
|
- (void)resetChatSessionWithCompanionId:(NSInteger)companionId
|
||||||
|
completion:(void(^)(KBChatSessionResetResponse * _Nullable response, NSError * _Nullable error))completion;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#import "KBCommentModel.h"
|
#import "KBCommentModel.h"
|
||||||
#import "KBLikedCompanionModel.h"
|
#import "KBLikedCompanionModel.h"
|
||||||
#import "KBChattedCompanionModel.h"
|
#import "KBChattedCompanionModel.h"
|
||||||
|
#import "KBChatSessionResetModel.h"
|
||||||
#import <MJExtension/MJExtension.h>
|
#import <MJExtension/MJExtension.h>
|
||||||
|
|
||||||
@implementation KBAiSyncData
|
@implementation KBAiSyncData
|
||||||
@@ -691,4 +692,38 @@ autoShowBusinessError:NO
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - 会话管理接口
|
||||||
|
|
||||||
|
- (void)resetChatSessionWithCompanionId:(NSInteger)companionId
|
||||||
|
completion:(void (^)(KBChatSessionResetResponse * _Nullable, NSError * _Nullable))completion {
|
||||||
|
NSDictionary *params = @{
|
||||||
|
@"companionId": @(companionId)
|
||||||
|
};
|
||||||
|
|
||||||
|
NSLog(@"[AiVM] /chat/session/reset request: %@", params);
|
||||||
|
[[KBNetworkManager shared]
|
||||||
|
POST:@"/chat/session/reset"
|
||||||
|
jsonBody:params
|
||||||
|
headers:nil
|
||||||
|
autoShowBusinessError:NO
|
||||||
|
completion:^(NSDictionary *_Nullable json,
|
||||||
|
NSURLResponse *_Nullable response,
|
||||||
|
NSError *_Nullable error) {
|
||||||
|
if (error) {
|
||||||
|
NSLog(@"[AiVM] /chat/session/reset failed: %@", error.localizedDescription ?: @"");
|
||||||
|
if (completion) {
|
||||||
|
completion(nil, error);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog(@"[AiVM] /chat/session/reset response: %@", json);
|
||||||
|
|
||||||
|
KBChatSessionResetResponse *resetResponse = [KBChatSessionResetResponse mj_objectWithKeyValues:json];
|
||||||
|
if (completion) {
|
||||||
|
completion(resetResponse, nil);
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
Reference in New Issue
Block a user