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.
661 lines
22 KiB
661 lines
22 KiB
import 'dart:async';
|
|
|
|
import 'package:agent_service/agent_service.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:dio/dio.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 '../../../data/services/speech_factory.dart';
|
|
import '../../../routes/app_routes.dart';
|
|
import '../models/language_model.dart';
|
|
import '../../../data/services/ble_manager.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 = [
|
|
LanguageModel(
|
|
name: 'followingSystem', alias: '', value: 'system'), // 跟随系统.tr
|
|
LanguageModel(name: 'english', alias: 'English', value: 'en_US'), // 英语.tr
|
|
LanguageModel(name: 'chinese', alias: '中文', value: 'zh_CN'), // 中文.tr
|
|
LanguageModel(
|
|
name: 'traditionalChinese', alias: '繁體中文', value: 'zh_HK'), // 添加繁体中文
|
|
LanguageModel(
|
|
name: 'spanish', alias: 'Español', value: 'es_ES'), // 添加西班牙语选项
|
|
LanguageModel(
|
|
name: 'portuguese', alias: 'Português', value: 'pt_PT'), // 添加葡萄牙语
|
|
LanguageModel(name: 'japanese', alias: '日本語', value: 'ja_JP'), // 添加日语选项
|
|
LanguageModel(name: 'korean', alias: '한국어', value: 'ko_KR'), // 添加韩语选项
|
|
LanguageModel(name: 'french', alias: 'Français', value: 'fr_FR'), // 添加法语选项
|
|
LanguageModel(name: 'german', alias: 'Deutsch', value: 'de_DE'), // 添加德语选项
|
|
LanguageModel(name: 'russian', alias: 'Русский', value: 'ru_RU'), // 添加俄语选项
|
|
LanguageModel(name: 'arabic', alias: 'العربية', value: 'ar_SA'), // 阿拉伯语
|
|
LanguageModel(name: 'persian', alias: 'فارسی', value: 'fa_IR'), // 波斯语
|
|
|
|
LanguageModel(
|
|
name: 'vietnamese', alias: 'Tiếng Việt', value: 'vi_VN'), // 添加越南语选项
|
|
LanguageModel(
|
|
name: 'italian', alias: 'Italiano', value: 'it_IT'), // 添加意大利语选项
|
|
LanguageModel(
|
|
name: 'hindi', alias: 'हिन्दी', value: 'hi_IN'), // 添加印度语(印地语)选项
|
|
LanguageModel(
|
|
name: 'indonesian',
|
|
alias: 'Bahasa Indonesia',
|
|
value: 'id_ID'), // 添加印尼语选项
|
|
LanguageModel(name: 'thai', alias: 'ไทย', value: 'th_TH'), // 添加泰语选项
|
|
LanguageModel(
|
|
name: 'malay', alias: 'Bahasa Melayu', value: 'ms_MY'), // 添加马来语选项
|
|
LanguageModel(name: 'turkish', alias: 'Türkçe', value: 'tr_TR'), // 添加土耳其语选项
|
|
LanguageModel(name: 'polish', alias: 'Polski', value: 'pl_PL'), // 添加波兰语选项
|
|
LanguageModel(name: 'filipino', alias: 'Filipino', value: 'tl_PH'), // 菲律宾语
|
|
LanguageModel(name: 'dutch', alias: 'Nederlands', value: 'nl_NL'), // 荷兰语
|
|
LanguageModel(name: 'swedish', alias: 'Svenska', value: 'sv_SE'), // 瑞典语
|
|
LanguageModel(name: 'danish', alias: 'Dansk', value: 'da_DK'), // 丹麦语
|
|
LanguageModel(name: 'finnish', alias: 'Suomi', value: 'fi_FI'), // 芬兰语
|
|
LanguageModel(name: 'czech', alias: 'Čeština', value: 'cs_CZ'), // 捷克语
|
|
LanguageModel(name: 'hungarian', alias: 'Magyar', value: 'hu_HU'), // 匈牙利语
|
|
LanguageModel(name: 'norwegian', alias: 'Norsk', value: 'nb_NO'), // 挪威语
|
|
LanguageModel(name: 'romanian', alias: 'Română', value: 'ro_RO'), // 罗马尼亚语
|
|
LanguageModel(
|
|
name: 'ukrainian', alias: 'Українська', value: 'uk_UA'), // 乌克兰语
|
|
LanguageModel(name: 'greek', alias: 'Ελληνικά', value: 'el_GR'), // 希腊语
|
|
LanguageModel(
|
|
name: 'bulgarian', alias: 'Български', value: 'bg_BG'), // 保加利亚语
|
|
LanguageModel(name: 'croatian', alias: 'Hrvatski', value: 'hr_HR'), // 克罗地亚语
|
|
LanguageModel(name: 'slovak', alias: 'Slovenský', value: 'sk_SK'), // 斯洛伐克语
|
|
LanguageModel(
|
|
name: 'slovenian', alias: 'Slovenščina', value: 'sl_SI'), // 斯洛文尼亚语
|
|
LanguageModel(
|
|
name: 'lithuanian', alias: 'Lietuvių', value: 'lt_LT'), // 立陶宛语
|
|
LanguageModel(name: 'latvian', alias: 'Latviešu', value: 'lv_LV'), // 拉脱维亚语
|
|
LanguageModel(name: 'estonian', alias: 'Eesti', value: 'et_EE'), // 爱沙尼亚语
|
|
LanguageModel(
|
|
name: 'serbian', alias: 'Srpski', value: 'sr_RS'), // 塞尔维亚语(拉丁)
|
|
LanguageModel(name: 'icelandic', alias: 'Íslenska', value: 'is_IS'), // 冰岛语
|
|
];
|
|
|
|
Rx<LanguageModel> language = LanguageModel().obs;
|
|
|
|
final GetStorage _storage = GetStorage();
|
|
|
|
// 主题服务
|
|
final ThemeService _themeService = ThemeService();
|
|
|
|
// 是否是暗黑模式
|
|
final RxBool isDarkMode = false.obs;
|
|
|
|
// 翻译语言对
|
|
final RxString sourceLanguage = '中文'.obs;
|
|
final RxString targetLanguage = '英文'.obs;
|
|
final List<String> availableLanguages = [
|
|
'中文',
|
|
'英文',
|
|
'日文',
|
|
'韩文',
|
|
'法文',
|
|
'德文',
|
|
'西班牙文',
|
|
'俄文'
|
|
];
|
|
|
|
// 语音服务类型
|
|
final Rx<SpeechServiceType> speechServiceType = SpeechServiceType.azure.obs;
|
|
final List<Map<String, dynamic>> availableSpeechServices = [
|
|
{
|
|
'type': SpeechServiceType.azure,
|
|
'name': 'azureVoiceService', // Azure 语音服务.tr
|
|
'description': 'azureVoiceServiceInfo' // 微软云端语音服务,支持高质量语音合成和识别.tr
|
|
},
|
|
{
|
|
'type': SpeechServiceType.flutter,
|
|
'name': 'flutterVoiceService', // Flutter 本地语音服务.tr
|
|
'description': 'flutterVoiceServiceInfo' // 设备本地语音服务,无需联网即可使用.tr
|
|
},
|
|
];
|
|
|
|
RxString timbreName = 'defaultTimbre'.obs;
|
|
|
|
//用户信息
|
|
// static const String userKey = 'user_info';
|
|
// final Rx<User> userInfo = User.instance.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();
|
|
|
|
_getTimbre();
|
|
|
|
// 从存储中加载上次保存的主题设置
|
|
final savedDarkMode = _themeService.isSavedDarkMode();
|
|
|
|
// 设置当前主题状态
|
|
isDarkMode.value = savedDarkMode;
|
|
|
|
// 获取当前语音服务类型
|
|
_loadCurrentSpeechServiceType();
|
|
|
|
//获取用户信息
|
|
// loadUserInfo();
|
|
|
|
// 获取应用版本信息
|
|
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 loadUserInfo() {
|
|
// final userJson = _storage.read(userKey);
|
|
// Logger().d('加载用户信息: $userJson');
|
|
|
|
// if (userJson != null) {
|
|
// userInfo.value = User.instance;
|
|
// Logger().d('用户信息已加载: ${userInfo.value.toJson()}');
|
|
|
|
// if (userInfo.value.avatar.isNotEmpty) {
|
|
// Logger().d('开始下载头像');
|
|
// _downloadAndSaveAvatar(userInfo.value.avatar);
|
|
// } else {
|
|
// Logger().d('用户没有头像');
|
|
// }
|
|
// } else {
|
|
// Logger().d('没有找到用户信息');
|
|
// }
|
|
// }
|
|
|
|
// Future<void> saveUserInfo() async {
|
|
// await _storage.write(userKey, userInfo.value.toJson());
|
|
// }
|
|
|
|
// 下载并保存远程头像
|
|
// Future<void> _downloadAndSaveAvatar(String url) async {
|
|
// try {
|
|
// Logger().d('开始下载头像: $url');
|
|
|
|
// final dio = Dio(BaseOptions(
|
|
// headers: {
|
|
// 'accept': '*/*',
|
|
// 'Authorization': _storage.read<String>("logintoken"),
|
|
// },
|
|
// ));
|
|
|
|
// final response = await dio.get(
|
|
// url,
|
|
// options: Options(responseType: ResponseType.bytes),
|
|
// );
|
|
|
|
// Logger().d('下载状态: ${response.statusCode}');
|
|
|
|
// if (response.statusCode == 200) {
|
|
// // 保存到应用文档目录
|
|
// final appDir = await getApplicationSupportDirectory();
|
|
// final fileName =
|
|
// '/UserAvatar/avatar_${DateTime.now().millisecondsSinceEpoch}.jpg';
|
|
// final localPath = '${appDir.path}/$fileName';
|
|
|
|
// // 确保目录存在
|
|
// final file = File(localPath);
|
|
// await file.parent.create(recursive: true);
|
|
|
|
// await file.writeAsBytes(response.data);
|
|
|
|
// // 更新本地头像路径
|
|
// //localAvatar.value = localPath;
|
|
// await _storage.write('local_avatar', localPath);
|
|
// Logger().d('头像已下载到本地: $localPath');
|
|
// //Get.snackbar('头像', '头像已下载到本地');
|
|
// }
|
|
// } catch (e) {
|
|
// Logger().e('下载头像失败: $e');
|
|
// }
|
|
// }
|
|
|
|
// Future<void> updateUserAvatar() async {
|
|
// final XFile? image = await _picker.pickImage(
|
|
// source: ImageSource.gallery,
|
|
// maxWidth: 800,
|
|
// maxHeight: 800,
|
|
// imageQuality: 85,
|
|
// );
|
|
|
|
// if (image != null) {
|
|
// userInfo.update((user) {
|
|
// if (user != null) {
|
|
// user.avatar = image.path;
|
|
// }
|
|
// });
|
|
// await saveUserInfo();
|
|
// }
|
|
// }
|
|
|
|
// Future<void> updateUserName(String name) async {
|
|
// if (name.trim().isNotEmpty) {
|
|
// userInfo.update((user) {
|
|
// if (user != null) {
|
|
// user.name = name.trim();
|
|
// }
|
|
// });
|
|
// await saveUserInfo();
|
|
// }
|
|
// }
|
|
|
|
// Future<void> updateDeviceName(String deviceName) async {
|
|
// userInfo.update((user) {
|
|
// if (user != null) {
|
|
// user.deviceName = deviceName;
|
|
// }
|
|
// });
|
|
// await saveUserInfo();
|
|
// }
|
|
// }
|
|
|
|
void _getLanguage() {
|
|
String? languageValue = _storage.read('language');
|
|
LanguageModel data = languageList.firstWhere(
|
|
(element) => element.value == languageValue,
|
|
orElse: () => languageList[0],
|
|
);
|
|
language.value = data;
|
|
}
|
|
|
|
// 获取音色
|
|
void _getTimbre() {
|
|
List? timbreList = _storage.read('timbreList');
|
|
String? timbre = _storage.read('timbre');
|
|
if (timbreList != null && timbre != null) {
|
|
Map data = timbreList.firstWhere(
|
|
(element) => element['type'] == timbre,
|
|
orElse: () => {},
|
|
);
|
|
if (data.isNotEmpty) {
|
|
timbreName.value = data['name'];
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 设置语言
|
|
Future<void> setLanguage(LanguageModel data) async {
|
|
try {
|
|
// 如果用户选择的语言与当前语言一致,则直接返回,避免重复设置
|
|
// print('lxm--设置语言: ${data.value}');
|
|
// print('lxm--当前语言: ${language.value.value}');
|
|
if (data.value == language.value.value) {
|
|
return;
|
|
}
|
|
|
|
Locale? targetLocale;
|
|
// print('lxm--设置语言: ${data.value}');
|
|
|
|
if (data.value != 'system') {
|
|
// 用户手动选择的语言
|
|
List languageList = data.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);
|
|
print("设置语言: ${data.value} -> ${targetLocale.toString()}");
|
|
} else {
|
|
// 如果无法确定目标语言,使用智能fallback
|
|
targetLocale = AppTranslations.getSmartFallbackLocale();
|
|
Get.updateLocale(targetLocale);
|
|
print("使用fallback语言: ${targetLocale.toString()}");
|
|
}
|
|
|
|
// 保存用户选择
|
|
language.value = data;
|
|
await _storage.write('language', data.value);
|
|
|
|
// 更新agent服务的语音识别语言设置
|
|
await _updateAgentLanguageSettings(data);
|
|
|
|
// 显示语言切换成功提示
|
|
// Get.snackbar(
|
|
// 'success'.tr,
|
|
// 'languageChanged'.tr, // 需要在语言文件中添加这个key
|
|
// snackPosition: SnackPosition.TOP,
|
|
// duration: const Duration(seconds: 2),
|
|
// );
|
|
|
|
// 延迟一下确保语言更新完成,然后重新进入应用
|
|
await Future.delayed(const Duration(milliseconds: 500));
|
|
|
|
// 重新进入应用 - 回到启动页面重新初始化
|
|
Get.offAllNamed(Routes.splash);
|
|
Get.back();
|
|
} catch (e) {
|
|
print("设置语言时出错: $e");
|
|
// Get.snackbar(
|
|
// 'error'.tr,
|
|
// 'languageChangeFailed'.tr, // 需要在语言文件中添加这个key
|
|
// snackPosition: SnackPosition.TOP,
|
|
// backgroundColor: Colors.red.withValues(alpha: 0.8),
|
|
// colorText: Colors.white,
|
|
// );
|
|
}
|
|
}
|
|
|
|
/// 更新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 lang = deviceLocale.languageCode;
|
|
final country = deviceLocale.countryCode;
|
|
if (country != null && country.isNotEmpty) {
|
|
supportedLanguages.add('$lang-$country');
|
|
} 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 asrCode = languageManager.getAsrCodeByShortCode(parts[0]);
|
|
if (asrCode != null) {
|
|
supportedLanguages.add(asrCode);
|
|
} else {
|
|
// 直接使用语言-国家格式
|
|
supportedLanguages.add('${parts[0]}-${parts[1]}');
|
|
}
|
|
}
|
|
}
|
|
|
|
// 确保至少有一个语言
|
|
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');
|
|
}
|
|
}
|
|
|
|
// 加载当前语音服务类型
|
|
void _loadCurrentSpeechServiceType() {
|
|
try {
|
|
final factory = Get.find<SpeechFactory>();
|
|
speechServiceType.value = factory.currentServiceType;
|
|
} catch (e) {
|
|
// 如果找不到SpeechFactory实例,使用默认值
|
|
}
|
|
}
|
|
|
|
// 切换主题
|
|
Future<void> toggleTheme() async {
|
|
// 切换暗黑模式状态
|
|
isDarkMode.value = !isDarkMode.value;
|
|
|
|
// 更新全局主题
|
|
Get.changeThemeMode(isDarkMode.value ? ThemeMode.dark : ThemeMode.light);
|
|
|
|
// 保存用户选择的主题设置 - 确保立即写入存储
|
|
await _themeService.saveThemeMode(isDarkMode.value);
|
|
}
|
|
|
|
// 设置语音服务类型
|
|
void setSpeechServiceType(SpeechServiceType type) {
|
|
try {
|
|
final factory = Get.find<SpeechFactory>();
|
|
factory.setServiceType(type);
|
|
speechServiceType.value = type;
|
|
} catch (e) {
|
|
// 处理错误
|
|
}
|
|
}
|
|
|
|
void setSourceLanguage(String language) {
|
|
sourceLanguage.value = language;
|
|
}
|
|
|
|
void setTargetLanguage(String language) {
|
|
targetLanguage.value = language;
|
|
}
|
|
|
|
void swapLanguages() {
|
|
final temp = sourceLanguage.value;
|
|
sourceLanguage.value = targetLanguage.value;
|
|
targetLanguage.value = temp;
|
|
}
|
|
|
|
/// 清除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 getSomeAppData() {
|
|
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().baseUrl}
|
|
''';
|
|
} catch (e) {
|
|
return '获取版本服务数据失败: $e';
|
|
}
|
|
}
|
|
}
|
|
|