You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.9 KiB
135 lines
3.9 KiB
import 'dart:convert';
|
|
import 'package:get/get.dart';
|
|
import '../../modules/chat/models/message_model.dart';
|
|
import '../../core/utils/logger.dart';
|
|
import 'package:chat_storage/chat_storage.dart';
|
|
|
|
/// 聊天记录管理服务,负责保存和加载聊天记录
|
|
class ChatHistoryService extends GetxService {
|
|
// 最大历史记录数量
|
|
static const int _maxHistoryCount = 200; // 每个对话最多保存的消息数
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
Logger.info('ChatHistoryService 已初始化');
|
|
}
|
|
|
|
/// 保存聊天记录
|
|
///
|
|
/// [agentId] 代理ID
|
|
/// [messages] 消息列表
|
|
Future<void> saveHistory(String agentId, List<Message> messages) async {
|
|
try {
|
|
if (messages.isEmpty) return;
|
|
|
|
// 获取最新的消息
|
|
final latestMessage = messages.last;
|
|
|
|
// 如果是加载中的消息则跳过
|
|
if (latestMessage.isIntermediate) return;
|
|
|
|
// 直接插入最新的消息到数据库
|
|
await ChatStorage.saveMessage(
|
|
sessionId: agentId,
|
|
message: latestMessage.content,
|
|
sender: latestMessage.role,
|
|
);
|
|
|
|
// 检查并清理过多的历史记录
|
|
await _cleanupOldMessages(agentId);
|
|
} catch (e) {
|
|
Logger.error('保存聊天记录失败', e.toString());
|
|
}
|
|
}
|
|
|
|
/// 清理旧消息,保持每个会话的消息数量不超过最大限制
|
|
Future<void> _cleanupOldMessages(String agentId) async {
|
|
try {
|
|
final pagedResult = await ChatStorage.getMessages(
|
|
sessionId: agentId,
|
|
page: 1,
|
|
pageSize: 1, // 只获取总数信息
|
|
);
|
|
|
|
// 如果消息总数超过最大限制,删除最早的消息
|
|
if (pagedResult.totalCount > _maxHistoryCount) {
|
|
final messagesToDelete = pagedResult.totalCount - _maxHistoryCount;
|
|
// 获取最早的N条消息ID
|
|
final oldestMessages = await ChatStorage.getMessages(
|
|
sessionId: agentId,
|
|
page: 1,
|
|
pageSize: messagesToDelete,
|
|
);
|
|
|
|
// 构建要删除的消息ID列表
|
|
final List<int> messageIds = oldestMessages.messages
|
|
.where((m) => m.id != null)
|
|
.map((m) => m.id!)
|
|
.toList();
|
|
|
|
// 删除这些消息
|
|
if (messageIds.isNotEmpty) {
|
|
await ChatStorage.deleteMessages(messageIds: messageIds);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
Logger.error('清理旧消息失败', e);
|
|
}
|
|
}
|
|
|
|
/// 加载聊天记录
|
|
///
|
|
/// [agentId] 代理ID
|
|
/// 返回消息列表,如果没有找到或解析错误则返回空列表
|
|
Future<List<Message>> loadHistory(String agentId) async {
|
|
try {
|
|
final pagedResult = await ChatStorage.getMessages(
|
|
sessionId: agentId,
|
|
page: 1,
|
|
pageSize: _maxHistoryCount,
|
|
);
|
|
|
|
if (pagedResult.messages.isEmpty) {
|
|
return [];
|
|
}
|
|
|
|
// 将ChatStorage.ChatMessage转换为Message
|
|
final messages = pagedResult.messages.map((chatMessage) {
|
|
return Message(
|
|
role: chatMessage.sender,
|
|
content: chatMessage.message,
|
|
timestamp: DateTime.parse(
|
|
chatMessage.timestamp), // 直接使用chatMessage的timestamp
|
|
// isLoading 默认false
|
|
// isLoading: metadata['isLoading'] ?? false,
|
|
);
|
|
}).toList();
|
|
|
|
return messages;
|
|
} catch (e) {
|
|
Logger.error('加载聊天记录失败', e);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/// 清除特定代理的聊天记录
|
|
Future<void> clearHistory(String agentId) async {
|
|
try {
|
|
await ChatStorage.deleteMessages(sessionId: agentId);
|
|
Logger.info('已清除聊天记录,代理: $agentId');
|
|
} catch (e) {
|
|
Logger.error('清除聊天记录失败', e);
|
|
}
|
|
}
|
|
|
|
/// 清除所有聊天记录
|
|
Future<void> clearAllHistory() async {
|
|
try {
|
|
await ChatStorage.clearDatabase();
|
|
Logger.info('已清除所有聊天记录');
|
|
} catch (e) {
|
|
Logger.error('清除所有聊天记录失败', e);
|
|
}
|
|
}
|
|
}
|
|
|