Browse Source

feat(translation): 改进翻译历史存储和显示逻辑

分离存储限制和显示限制,存储限制增加到1000条而显示限制为20条
新增getAllHistory方法获取完整历史记录
优化保存逻辑,仅保存完成态记录并减少频繁保存
newdev_shunjiawei
lxm 1 year ago
parent
commit
38f1bb3456
  1. 107
      lib/modules/translation/controllers/translation_controller.dart
  2. 16
      lib/modules/translation/controllers/translation_history_controller.dart

107
lib/modules/translation/controllers/translation_controller.dart

@ -45,11 +45,16 @@ class TranslationController extends GetxController {
Timer? _recordTimer;
//秒
int _seconds = 0;
// 存储相关
// 存储相关配置
static const String _historyKey = 'translation_history';
static const String _sourceLanguageKey = 'translation_source_language';
static const String _targetLanguageKey = 'translation_target_language';
static const int _maxHistoryItems = 10;
// 【重要改进】区分存储限制和显示限制
// 存储限制:大幅增加到1000条,充分利用本地存储能力,几乎无限制存储
static const int _maxStorageItems = 1000;
// 主页面显示限制:只显示最近20条,保证界面性能和用户体验
static const int _maxDisplayItems = 20;
RxInt activeSpeaker = 0.obs; // 0=无激活, 1=按钮1, 2=按钮2
RxInt lastActiveSpeaker = 0.obs; // 上一次状态
@ -559,8 +564,8 @@ class TranslationController extends GetxController {
String? translationResult;
try {
var detectedSourceLanguageCode;
var detectedTargetLanguageCode;
String detectedSourceLanguageCode;
String detectedTargetLanguageCode;
if ((currentMode.value == 'faceToFace' && activeSpeaker.value == 1) ||
(currentMode.value == 'faceToFace' &&
activeSpeaker.value == 0 &&
@ -608,7 +613,12 @@ class TranslationController extends GetxController {
translationHistory[index].targetLanguageCode =
detectedTargetLanguageCode;
translationHistory.refresh();
saveTranslationHistory();
// 【改进】只有在最终结果时才保存,避免中间态时的频繁保存
if (isFinal) {
saveTranslationHistory();
}
// 更新后滚动到底部
_scrollToBottom();
// 播放TTS - 只在最终结果时播放
@ -630,7 +640,7 @@ class TranslationController extends GetxController {
}
} else {
Logger.info(
'未找到匹配的历史项 ${sourceText} ${timestamp.toIso8601String() ?? "无时间戳"}');
'未找到匹配的历史项 $sourceText ${timestamp.toIso8601String()}');
}
}
} catch (e) {
@ -836,10 +846,13 @@ class TranslationController extends GetxController {
final List<TranslationItem> allHistory =
historyList.map((item) => TranslationItem.fromJson(item)).toList();
// 只保留最新的10条记录
if (allHistory.length > _maxHistoryItems) {
// 【注意】存储中的记录都是完成态记录(isIntermediate = false)
// 因为保存时已经过滤掉了中间态记录,确保数据质量
// 主页面只显示最近的20条完成态记录,保证界面性能
if (allHistory.length > _maxDisplayItems) {
translationHistory.value =
allHistory.sublist(allHistory.length - _maxHistoryItems);
allHistory.sublist(allHistory.length - _maxDisplayItems);
} else {
translationHistory.value = allHistory;
}
@ -855,22 +868,76 @@ class TranslationController extends GetxController {
}
}
// 保存翻译历史
// 保存翻译历史 - 回归原始简单实现
// 【修复】完全回归原始保存逻辑,只保存当前内存中的完成态记录
void saveTranslationHistory() {
if (translationHistory.length > _maxHistoryItems) {
translationHistory.removeRange(
0, translationHistory.length - _maxHistoryItems);
}
try {
// 只保存当前内存中的完成态记录,过滤掉中间态记录
final List<TranslationItem> finalRecords = translationHistory
.where((item) => !item.isIntermediate)
.toList();
// 应用存储限制,保留最新的1000条完成态记录
List<TranslationItem> historyToSave = finalRecords;
if (finalRecords.length > _maxStorageItems) {
historyToSave = finalRecords.sublist(finalRecords.length - _maxStorageItems);
}
// 保存到本地存储
final List<Map<String, dynamic>> historyJson =
translationHistory.map((item) => item.toJson()).toList();
historyToSave.map((item) => item.toJson()).toList();
_storage.write(_historyKey, jsonEncode(historyJson));
Logger.info('翻译历史保存成功: 存储${historyToSave.length}条记录');
} catch (e) {
Logger.error('保存翻译历史失败: ${e.toString()}');
}
}
// 获取所有完成态历史记录(供历史页面使用)
// 【修复】简化实现,合并存储和内存中的完成态记录
List<TranslationItem> getAllHistory() {
try {
final List<TranslationItem> result = <TranslationItem>[];
final Set<String> existingIds = <String>{};
// 添加存储的历史记录(存储中的记录都是完成态)
final historyJson = _storage.read(_historyKey);
if (historyJson != null) {
final List<dynamic> historyList = jsonDecode(historyJson);
final List<TranslationItem> storedHistory =
historyList.map((item) => TranslationItem.fromJson(item)).toList();
for (final item in storedHistory) {
final id = '${item.sessionId}_${item.timestamp.millisecondsSinceEpoch}';
if (!existingIds.contains(id)) {
existingIds.add(id);
result.add(item);
}
}
}
// 添加当前内存中的完成态记录(排除中间态记录)
for (final item in translationHistory) {
if (!item.isIntermediate) {
final id = '${item.sessionId}_${item.timestamp.millisecondsSinceEpoch}';
if (!existingIds.contains(id)) {
existingIds.add(id);
result.add(item);
}
}
}
// 按时间排序
result.sort((a, b) => a.timestamp.compareTo(b.timestamp));
return result;
} catch (e) {
Logger.error('获取完整历史记录失败: ${e.toString()}');
// 发生错误时,返回当前内存中的完成态记录
return translationHistory.where((item) => !item.isIntermediate).toList();
}
}
// 清除翻译历史
void clearTranslationHistory() {
translationHistory.clear();
@ -882,11 +949,9 @@ class TranslationController extends GetxController {
_scrollToBottom();
}
/// 处理原生语音交互开始事件
void _handleVoiceInteractionStarted() {
// 收到recognitionStarted事件时,停止当前的AI交互、录音和TTS
stopAll();
}
}
// 翻译项模型

16
lib/modules/translation/controllers/translation_history_controller.dart

@ -44,9 +44,12 @@ class TranslationHistoryController extends GetxController {
// 按日期对历史记录进行分组
void _groupHistoryByDate() {
final Map<String, List<TranslationItem>> newGroupedHistory = {};
// 获取完整的历史记录,而不仅仅是当前显示的记录
final List<TranslationItem> allHistory = translationController.getAllHistory();
// 筛选出每个会话的第一条记录
final List<TranslationItem> firstItemsOfSessions = translationController.translationHistory
final List<TranslationItem> firstItemsOfSessions = allHistory
.where((item) => item.isFirstInSession)
.toList();
@ -98,12 +101,15 @@ class TranslationHistoryController extends GetxController {
// 按会话ID对历史记录进行分组
void _groupHistoryBySession() {
final Map<String, List<TranslationItem>> newSessionMap = {};
for (var item in translationController.translationHistory) {
// 获取完整的历史记录进行会话分组
final List<TranslationItem> allHistory = translationController.getAllHistory();
for (var item in allHistory) {
if (!newSessionMap.containsKey(item.sessionId)) {
newSessionMap[item.sessionId] = [];
}
newSessionMap[item.sessionId]!.add(item);
}

Loading…
Cancel
Save