From f46dd25f77649b58e0f52d6e2a5b54cccb5e35f8 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Fri, 12 Sep 2025 16:51:50 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat(ota=5Fupgrade):=20=E5=9C=A8=E5=BC=80?= =?UTF-8?q?=E5=A7=8B=E6=9B=B4=E6=96=B0=E6=97=B6=E6=98=BE=E7=A4=BA=E8=AF=A6?= =?UTF-8?q?=E7=BB=86=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat(translation): 添加语音播放防重复机制 在OTA升级控制器中添加状态反馈,立即显示检查设备状态 在翻译控制器中实现防重复点击机制,避免短时间内重复播放同一内容 --- .../controllers/ota_upgrade_controller.dart | 4 ++ .../controllers/translation_controller.dart | 50 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart b/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart index 9e56c02d8..f306bde15 100644 --- a/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart +++ b/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart @@ -123,6 +123,10 @@ class OtaUpgradeController extends GetxController { /// 开始更新流程的公共方法 /// 供视图调用的更新入口点 Future startUpdate() async { + //立即给用户状态反馈 + showDetailedStatus.value = true; + detailedStatus.value = '正在检查设备状态...'; + await _startUpdateProcess(); } diff --git a/lib/modules/translation/controllers/translation_controller.dart b/lib/modules/translation/controllers/translation_controller.dart index 9b54119e4..f1bfff331 100644 --- a/lib/modules/translation/controllers/translation_controller.dart +++ b/lib/modules/translation/controllers/translation_controller.dart @@ -116,6 +116,11 @@ class TranslationController extends GetxController with WidgetsBindingObserver { StreamSubscription? _voiceInteractionSubscription; Timer? _translationDebounceTimer; + // 播放防重复机制 + String? _lastPlayedItemKey; // 最后播放的项目标识 + int _lastPlayTime = 0; // 最后播放时间 + static const int _playDebounceInterval = 500; // 防抖间隔:500毫秒 + // 底部控制栏高度 double _bottomBarHeight = 0.0; @@ -1083,7 +1088,30 @@ class TranslationController extends GetxController with WidgetsBindingObserver { Future playTranslationItem(TranslationItem item) async { if (item.translatedText.isEmpty) return; + // 防重复点击:如果短时间内重复点击同一项,忽略后续点击 + final currentTime = DateTime.now().millisecondsSinceEpoch; + final itemKey = + '${item.sessionId}_${item.timestamp.millisecondsSinceEpoch}'; + + // 检查是否是重复点击同一项 + if (_lastPlayedItemKey == itemKey && + currentTime - _lastPlayTime < _playDebounceInterval) { + Logger.info('防重复播放:忽略短时间内的重复点击'); + return; + } + + // 如果正在播放,先停止当前播放 + if (_ttsService.isSpeaking) { + await _ttsService.stop(); + // 短暂延迟确保停止完成 + await Future.delayed(const Duration(milliseconds: 100)); + } + try { + // 更新播放记录 + _lastPlayedItemKey = itemKey; + _lastPlayTime = currentTime; + final voiceName = _languageManager.getTtsVoiceNameByAsrCode(item.targetLanguageCode) ?? 'en-US-AriaNeural'; @@ -1100,7 +1128,29 @@ class TranslationController extends GetxController with WidgetsBindingObserver { Future playText(String text, {String? languageCode}) async { if (text.isEmpty) return; + // 防重复点击:基于文本内容和语言代码生成唯一标识 + final currentTime = DateTime.now().millisecondsSinceEpoch; + final textKey = '${text}_${languageCode ?? targetLanguageCode.value}'; + + // 检查是否是重复点击同一文本 + if (_lastPlayedItemKey == textKey && + currentTime - _lastPlayTime < _playDebounceInterval) { + Logger.info('防重复播放:忽略短时间内的重复文本播放请求'); + return; + } + + // 如果正在播放,先停止当前播放 + if (_ttsService.isSpeaking) { + await _ttsService.stop(); + // 短暂延迟确保停止完成 + await Future.delayed(const Duration(milliseconds: 100)); + } + try { + // 更新播放记录 + _lastPlayedItemKey = textKey; + _lastPlayTime = currentTime; + final voiceName = languageCode != null ? _languageManager.getTtsVoiceNameByAsrCode(languageCode) ?? 'en-US-AriaNeural' From 713b43379c21e705a9ccc865dfbcb8da3e2656b6 Mon Sep 17 00:00:00 2001 From: fdp <1286779656@qq.com> Date: Fri, 12 Sep 2025 17:30:46 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E4=BC=9A=E8=BF=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/data/services/bluetooth_manager.dart | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/data/services/bluetooth_manager.dart b/lib/data/services/bluetooth_manager.dart index 654cfa603..4c4f58ffd 100644 --- a/lib/data/services/bluetooth_manager.dart +++ b/lib/data/services/bluetooth_manager.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:get/get.dart'; import 'package:classic_bluetooth/classic_bluetooth.dart'; import '../../core/utils/logger.dart'; +import '../../routes/app_routes.dart'; // 重新导出蓝牙设备类型,让外部可以通过BluetoothManager访问 export 'package:classic_bluetooth/classic_bluetooth.dart' show BluetoothDevice; @@ -58,6 +59,7 @@ class BluetoothManager extends GetxService { try { _bluetoothSubscription = ClassicBluetooth.events.listen( (event) { + print("_setupBluetoothListener$event"); if (event.type == 'stateChanged' && event.state != null) { _bluetoothState.value = event.state!; Logger.info('蓝牙状态变更: ${event.state}'); @@ -70,9 +72,15 @@ class BluetoothManager extends GetxService { // 直接从事件中获取设备信息 final newDevice = event.device!; - // 更新当前设备 currentDeviceRx.value = newDevice; + // 检查当前是否在OTA升级界面,如果是则不跳转 + if (!_isInOtaUpgradePage()) { + Get.toNamed(Routes.pairing, arguments: newDevice); + } else { + Logger.info('当前在OTA升级界面,跳过配对页面跳转'); + } + // 正常模式:更新当前设备并触发监听器 Logger.info('经典蓝牙设备已连接: ${newDevice.name} (${newDevice.address})'); } else if (event.type == 'deviceDisconnected' && event.device != null) { @@ -138,4 +146,16 @@ class BluetoothManager extends GetxService { return false; } } + + /// 检查当前是否在OTA升级界面 + /// 返回true表示当前在OTA界面,不应该跳转到配对页面 + bool _isInOtaUpgradePage() { + try { + final currentRoute = Get.currentRoute; + return currentRoute == Routes.OTA_UPGRADE; + } catch (e) { + Logger.error('检查当前路由失败: ${e.toString()}'); + return false; + } + } }