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.

415 lines
14 KiB

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/services/native_localization_sync.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<LanguageModel> languageList = appSupportedLanguages; // 应用支持的语言列表
Rx<LanguageModel> 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<void> 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<void> 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()}");
}
await NativeLocalizationSync.syncToNative(force: true);
// 保存用户选择
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<void> _updateAgentLanguageSettings(LanguageModel languageModel) async {
try {
final languageManager = Get.find<LanguageManager>();
List<String> 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<void> toggleTheme() async {
// 切换暗黑模式状态
isDarkMode.value = !isDarkMode.value;
// 更新全局主题
Get.changeThemeMode(isDarkMode.value ? ThemeMode.dark : ThemeMode.light);
// 保存用户选择的主题设置 - 确保立即写入存储
await _themeService.saveThemeMode(isDarkMode.value);
}
/// 清除BLE配对设备
// Future<void> clearBleDevices() async {
// // 显示确认对话框
// final confirmed = await Get.dialog<bool>(
// 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<BleManager>();
// final result = await bleManager.clearPairedDevices();
// if (result) {
// Get.snackbar('成功', 'BLE配对设备已清除');
// } else {
// Get.snackbar('失败', '清除BLE配对设备失败');
// }
// } catch (e) {
// Get.snackbar('错误', '清除BLE配对设备时发生错误');
// }
// }
// }
/// 手动检查版本更新
Future<void> 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<VersionUpdateService>();
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().dio.options.baseUrl}
''';
} catch (e) {
return '获取版本服务数据失败: $e';
}
}
}