Browse Source

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

分离存储限制和显示限制,存储限制增加到1000条而显示限制为20条
新增getAllHistory方法获取完整历史记录
优化保存逻辑,仅保存完成态记录并减少频繁保存
weicu
lxm 1 year ago
parent
commit
42d44fd5f9
  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; Timer? _recordTimer;
//秒 //秒
int _seconds = 0; int _seconds = 0;
// 存储相关 // 存储相关配置
static const String _historyKey = 'translation_history'; static const String _historyKey = 'translation_history';
static const String _sourceLanguageKey = 'translation_source_language'; static const String _sourceLanguageKey = 'translation_source_language';
static const String _targetLanguageKey = 'translation_target_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 activeSpeaker = 0.obs; // 0=无激活, 1=按钮1, 2=按钮2
RxInt lastActiveSpeaker = 0.obs; // 上一次状态 RxInt lastActiveSpeaker = 0.obs; // 上一次状态
@ -559,8 +564,8 @@ class TranslationController extends GetxController {
String? translationResult; String? translationResult;
try { try {
var detectedSourceLanguageCode; String detectedSourceLanguageCode;
var detectedTargetLanguageCode; String detectedTargetLanguageCode;
if ((currentMode.value == 'faceToFace' && activeSpeaker.value == 1) || if ((currentMode.value == 'faceToFace' && activeSpeaker.value == 1) ||
(currentMode.value == 'faceToFace' && (currentMode.value == 'faceToFace' &&
activeSpeaker.value == 0 && activeSpeaker.value == 0 &&
@ -608,7 +613,12 @@ class TranslationController extends GetxController {
translationHistory[index].targetLanguageCode = translationHistory[index].targetLanguageCode =
detectedTargetLanguageCode; detectedTargetLanguageCode;
translationHistory.refresh(); translationHistory.refresh();
saveTranslationHistory();
// 【改进】只有在最终结果时才保存,避免中间态时的频繁保存
if (isFinal) {
saveTranslationHistory();
}
// 更新后滚动到底部 // 更新后滚动到底部
_scrollToBottom(); _scrollToBottom();
// 播放TTS - 只在最终结果时播放 // 播放TTS - 只在最终结果时播放
@ -630,7 +640,7 @@ class TranslationController extends GetxController {
} }
} else { } else {
Logger.info( Logger.info(
'未找到匹配的历史项 ${sourceText} ${timestamp.toIso8601String() ?? "无时间戳"}'); '未找到匹配的历史项 $sourceText ${timestamp.toIso8601String()}');
} }
} }
} catch (e) { } catch (e) {
@ -836,10 +846,13 @@ class TranslationController extends GetxController {
final List<TranslationItem> allHistory = final List<TranslationItem> allHistory =
historyList.map((item) => TranslationItem.fromJson(item)).toList(); historyList.map((item) => TranslationItem.fromJson(item)).toList();
// 只保留最新的10条记录 // 【注意】存储中的记录都是完成态记录(isIntermediate = false)
if (allHistory.length > _maxHistoryItems) { // 因为保存时已经过滤掉了中间态记录,确保数据质量
// 主页面只显示最近的20条完成态记录,保证界面性能
if (allHistory.length > _maxDisplayItems) {
translationHistory.value = translationHistory.value =
allHistory.sublist(allHistory.length - _maxHistoryItems); allHistory.sublist(allHistory.length - _maxDisplayItems);
} else { } else {
translationHistory.value = allHistory; translationHistory.value = allHistory;
} }
@ -855,22 +868,76 @@ class TranslationController extends GetxController {
} }
} }
// 保存翻译历史 // 保存翻译历史 - 回归原始简单实现
// 【修复】完全回归原始保存逻辑,只保存当前内存中的完成态记录
void saveTranslationHistory() { void saveTranslationHistory() {
if (translationHistory.length > _maxHistoryItems) {
translationHistory.removeRange(
0, translationHistory.length - _maxHistoryItems);
}
try { 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 = final List<Map<String, dynamic>> historyJson =
translationHistory.map((item) => item.toJson()).toList(); historyToSave.map((item) => item.toJson()).toList();
_storage.write(_historyKey, jsonEncode(historyJson)); _storage.write(_historyKey, jsonEncode(historyJson));
Logger.info('翻译历史保存成功: 存储${historyToSave.length}条记录');
} catch (e) { } catch (e) {
Logger.error('保存翻译历史失败: ${e.toString()}'); 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() { void clearTranslationHistory() {
translationHistory.clear(); translationHistory.clear();
@ -882,11 +949,9 @@ class TranslationController extends GetxController {
_scrollToBottom(); _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() { void _groupHistoryByDate() {
final Map<String, List<TranslationItem>> newGroupedHistory = {}; 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) .where((item) => item.isFirstInSession)
.toList(); .toList();
@ -98,12 +101,15 @@ class TranslationHistoryController extends GetxController {
// 按会话ID对历史记录进行分组 // 按会话ID对历史记录进行分组
void _groupHistoryBySession() { void _groupHistoryBySession() {
final Map<String, List<TranslationItem>> newSessionMap = {}; 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)) { if (!newSessionMap.containsKey(item.sessionId)) {
newSessionMap[item.sessionId] = []; newSessionMap[item.sessionId] = [];
} }
newSessionMap[item.sessionId]!.add(item); newSessionMap[item.sessionId]!.add(item);
} }

Loading…
Cancel
Save