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.

134 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);
}
}
/// 清理旧消息,保持每个会话的消息数量不超过最大限制
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);
}
}
}