import 'dart:async'; import 'package:agent_service/agent_service.dart'; import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:get_storage/get_storage.dart'; import 'package:logger/logger.dart'; import 'package:package_info_plus/package_info_plus.dart'; import '../../../core/themes/theme_service.dart'; import '../../../core/translations/app_translations.dart'; import '../../../data/services/network/dio_manager.dart'; import '../../../routes/app_routes.dart'; import '../models/language_model.dart'; import '../models/app_supported_languages.dart'; import '../../../data/services/language_manager.dart'; import '../../../data/services/version_update_service.dart'; import '../../common/widgets/version_update_dialog.dart'; class SettingsController extends GetxController { // 语言设置 final List languageList = appSupportedLanguages; // 应用支持的语言列表 Rx currentLanguage = LanguageModel().obs; // 当前选择的语言 final GetStorage _storage = GetStorage(); // 主题服务 final ThemeService _themeService = ThemeService(); // 是否是暗黑模式 final RxBool isDarkMode = false.obs; // 添加版本信息变量 final appVersion = ''.obs; final buildNumber = ''.obs; bool isCheckingUpdate = false; //状态锁,防止重复检查 DateTime? lastCheckTime; // 添加上次检查时间记录 // 隐藏功能变量 int _clickCount = 0; // 点击计数 DateTime? _lastClickTime; // 上次点击时间 final RxBool showDebugInfo = false.obs; // 是否显示调试信息 @override void onInit() { super.onInit(); // 获取系统语言 _getLanguage(); // 从存储中加载上次保存的主题设置 final savedDarkMode = _themeService.isSavedDarkMode(); // 设置当前主题状态 isDarkMode.value = savedDarkMode; // 获取应用版本信息 getAppVersion(); } // 获取应用版本信息的方法 Future getAppVersion() async { try { final PackageInfo packageInfo = await PackageInfo.fromPlatform(); appVersion.value = packageInfo.version; buildNumber.value = packageInfo.buildNumber; } catch (e) { appVersion.value = '未知'; buildNumber.value = '0'; } } /// 获取系统语言 /// 从存储中读取用户上次选择的语言 /// 如果没有保存记录,则默认使用第一个语言 void _getLanguage() { String? storedLanguageCode = _storage.read('language'); //在语言列表中查找匹配的语言 LanguageModel languageToApply = languageList.firstWhere( //查找条件:元素的value属性与从存储中读取的值匹配 (element) => element.value == storedLanguageCode, //如果没有找到匹配的语言,返回第一个语言作为默认值 orElse: () => languageList[0], ); currentLanguage.value = languageToApply; } /// 设置应用语言 /// 1. 更新Flutter的Locale设置 /// 2. 保存用户选择到本地存储 /// 3. 更新agent服务的语音识别语言设置 /// 4. 显示语言切换成功提示 /// 5. 延迟一下确保语言更新完成,然后重新进入应用 Future setLanguage(LanguageModel selectedLanguage) async { try { // 如果用户选择的语言与当前语言一致,则直接返回,避免重复设置 // print('lxm--设置语言: ${selectedLanguage.value}'); // print('lxm--当前语言: ${currentLanguage.value.value}'); if (selectedLanguage.value == currentLanguage.value.value) { return; } Locale? targetLocale; // print('lxm--设置语言: ${selectedLanguage.value}'); if (selectedLanguage.value != 'system') { // 用户手动选择的语言 List languageList = selectedLanguage.value.split('_'); targetLocale = Locale(languageList[0], languageList[1]); } else { // 跟随系统语言,使用智能匹配 targetLocale = Get.deviceLocale; if (targetLocale != null) { // 智能匹配系统语言到支持的语言 targetLocale = AppTranslations.getMatchedLocale(targetLocale); } } if (targetLocale != null) { Get.updateLocale(targetLocale); Logger() .i("设置语言: ${selectedLanguage.value} -> ${targetLocale.toString()}"); } else { // 如果无法确定目标语言,使用智能fallback targetLocale = AppTranslations.getSmartFallbackLocale(); Get.updateLocale(targetLocale); Logger().i("使用fallback语言: ${targetLocale.toString()}"); } // 保存用户选择 currentLanguage.value = selectedLanguage; await _storage.write('language', selectedLanguage.value); // 更新agent服务的语音识别语言设置 await _updateAgentLanguageSettings(selectedLanguage); // 显示语言切换成功提示 Logger().i("lxm--语言切换成功: ${selectedLanguage.value}"); // 延迟一下确保语言更新完成,然后重新进入应用 await Future.delayed(const Duration(milliseconds: 500)); // 重新进入应用 - 回到启动页面重新初始化 Get.offAllNamed(Routes.splash); Get.back(); } catch (e) { Logger().e("设置语言时出错: $e"); } } /// 更新agent服务的语音识别语言设置 Future _updateAgentLanguageSettings(LanguageModel languageModel) async { try { final languageManager = Get.find(); List supportedLanguages = []; // 根据选择的语言设置对应的ASR语言代码 if (languageModel.value == 'system') { // 跟随系统语言 final deviceLocale = Get.deviceLocale; if (deviceLocale != null) { final matchedLocale = AppTranslations.getMatchedLocale(deviceLocale); final lang = matchedLocale.languageCode; final country = matchedLocale.countryCode; if (country != null && country.isNotEmpty) { final normalizedLang = lang.toLowerCase(); final normalizedCountry = country.toUpperCase(); if (normalizedLang == 'tl' && normalizedCountry == 'PH') { supportedLanguages.add('fil-PH'); } else { supportedLanguages.add('$normalizedLang-$normalizedCountry'); } } else { // 根据语言代码映射到对应的ASR代码 final asrCode = languageManager.getAsrCodeByShortCode(lang); if (asrCode != null) { supportedLanguages.add(asrCode); } else { supportedLanguages.add('en-US'); // 默认英语 } } } else { supportedLanguages.add('en-US'); // 默认英语 } } else { // 根据选择的语言值映射到ASR代码 final parts = languageModel.value.split('_'); if (parts.length == 2) { final lang = parts[0].toLowerCase(); final country = parts[1].toUpperCase(); if (lang == 'zh' && (country == 'HK' || country == 'TW' || country == 'CN')) { supportedLanguages.add('zh-$country'); } else if (lang == 'tl' && country == 'PH') { supportedLanguages.add('fil-PH'); } else { supportedLanguages.add('$lang-$country'); } } } // 确保至少有一个语言 if (supportedLanguages.isEmpty) { supportedLanguages.add('en-US'); } Logger().i('更新agent服务语音识别语言: ${supportedLanguages.join(', ')}'); // 调用agent服务更新语言设置 final success = await AgentService.setSupportedLanguages(supportedLanguages); if (success) { Logger().i('agent服务语言设置更新成功'); } else { Logger().w('agent服务语言设置更新失败'); } } catch (e) { Logger().e('更新agent服务语言设置时出错: $e'); } } // 切换主题 Future toggleTheme() async { // 切换暗黑模式状态 isDarkMode.value = !isDarkMode.value; // 更新全局主题 Get.changeThemeMode(isDarkMode.value ? ThemeMode.dark : ThemeMode.light); // 保存用户选择的主题设置 - 确保立即写入存储 await _themeService.saveThemeMode(isDarkMode.value); } /// 清除BLE配对设备 // Future clearBleDevices() async { // // 显示确认对话框 // final confirmed = await Get.dialog( // AlertDialog( // title: const Text('清除配对设备'), // content: const Text('确定要清除所有BLE配对设备吗?此操作不可撤销。'), // actions: [ // TextButton( // onPressed: () => Get.back(result: false), // child: Text('cancel'.tr), // ), // TextButton( // onPressed: () => Get.back(result: true), // style: TextButton.styleFrom( // foregroundColor: Colors.red, // ), // child: Text('confirm'.tr), //确认 // ), // ], // ), // ); // if (confirmed == true) { // try { // final bleManager = Get.find(); // final result = await bleManager.clearPairedDevices(); // if (result) { // Get.snackbar('成功', 'BLE配对设备已清除'); // } else { // Get.snackbar('失败', '清除BLE配对设备失败'); // } // } catch (e) { // Get.snackbar('错误', '清除BLE配对设备时发生错误'); // } // } // } /// 手动检查版本更新 Future checkForUpdate() async { // 检查是否在2秒内重复调用 final now = DateTime.now(); if (lastCheckTime != null && now.difference(lastCheckTime!).inSeconds < 2) { // 在2秒内重复调用,直接返回 // Get.snackbar( // 'checkUpdate'.tr, // 'checkUpdateTooFrequent'.tr, // 检查更新过于频繁,请稍后再试 // snackPosition: SnackPosition.TOP, // backgroundColor: Colors.orange.withValues(alpha: 0.8), // colorText: Colors.white, // ); return; } if (isCheckingUpdate) return; isCheckingUpdate = true; lastCheckTime = now; // 记录本次检查时间 // 用于跟踪我们的对话框 bool dialogShown = false; try { // 显示加载提示 dialogShown = true; Get.dialog( const Center( child: CircularProgressIndicator(), ), barrierDismissible: false, ); final versionService = VersionUpdateService.to; final updateInfo = await versionService.checkForUpdate(); // 关闭加载提示 - 使用精确的关闭方式 if (dialogShown) { dialogShown = false; // 直接关闭最顶层的对话框,不依赖状态判断 Navigator.of(Get.overlayContext!).pop(); } if (updateInfo.hasUpdate) { // 显示更新对话框 await VersionUpdateDialog.show(updateInfo); } else { // 显示已是最新版本的提示 Get.snackbar( 'checkUpdate'.tr, 'currentLatestVersion' .tr //当前已是最新版本 .replaceAll('{version}', updateInfo.currentVersion), snackPosition: SnackPosition.TOP, backgroundColor: Colors.green.withValues(alpha: 0.8), colorText: Colors.white, ); } } catch (e) { // 关闭加载提示 - 异常情况下的可靠关闭 if (dialogShown) { dialogShown = false; try { // 尝试直接关闭 Navigator.of(Get.overlayContext!).pop(); } catch (popError) { // 如果直接关闭失败,使用备用方案 if (Get.isDialogOpen == true) { Get.back(); } } } Get.snackbar( 'error'.tr, 'networkErrorRetry'.tr, // 网络错误,请稍后重试 snackPosition: SnackPosition.TOP, backgroundColor: Colors.red.withValues(alpha: 0.8), colorText: Colors.white, ); } finally { isCheckingUpdate = false; } } /// 处理隐藏功能点击 void handleSecretTap() { final now = DateTime.now(); // 如果距离上次点击超过2秒,重置计数 if (_lastClickTime != null && now.difference(_lastClickTime!).inSeconds > 2) { _clickCount = 0; } _lastClickTime = now; _clickCount++; // 点击5次后显示版本信息 if (_clickCount >= 5) { showDebugInfo.value = !showDebugInfo.value; _clickCount = 0; // Get.snackbar( // showDebugInfo.value ? '调试信息已显示' : '调试信息已隐藏', // '版本服务数据', // snackPosition: SnackPosition.TOP, // backgroundColor: Colors.blue.withOpacity(0.8), // colorText: Colors.white, // duration: const Duration(seconds: 1), // ); } } /// 获取当前应用信息 String getSomeAppInfo() { try { final versionService = Get.find(); return ''' 应用版本: ${versionService.cachedAppVersion} 构建号: ${versionService.cachedBuildNumber} 平台: ${versionService.cachedPlatform} 设备品牌: ${versionService.cachedDeviceBrand} 渠道: ${versionService.cachedChannel} 最新版本: ${versionService.cachedLatestVersion} 有更新: ${versionService.cachedHasUpdate} 强制更新: ${versionService.cachedIsForceUpdate} 更新链接: ${versionService.cachedUpdateUrl} 游客模式: ${versionService.cachedShowTourists} 最近版本检查时间: ${versionService.lastCheckTime ?? '未检查'} 国家地区编码: ${versionService.cachedCountryCode} 语言编码: ${versionService.cachedLanguageCode} 服务器地址: ${DioManager().baseUrl} '''; } catch (e) { return '获取版本服务数据失败: $e'; } } }