feat: 提交国家选择
Build Windows / build (push) Successful in 7h7m43s
Build Windows / 编译 libcore (Windows) (20.15.1) (push) Successful in 20m1s

This commit is contained in:
2025-11-11 01:29:16 -08:00
parent a884e6c838
commit 748ec6bee9
3 changed files with 172 additions and 103 deletions
@@ -1275,11 +1275,108 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
}
}
Future<void> onCountrySelected(String countryTag) async {
await KRSingBoxImp.instance.kr_selectCountry(countryTag);
KRCommonUtil.kr_showToast('已切换到 $countryTag 节点组');
/// 🌍 执行国家切换(包含UI同步与VPN热重载)
/// 返回 true 表示切换成功,false 表示失败
Future<bool> kr_performCountrySwitch(String countryTag) async {
try {
KRLogUtil.kr_i('🔄 开始切换国家: $countryTag', tag: 'HomeController');
// 1. 保存原国家,以备失败恢复
final originalCountry = kr_coutryText.value;
// 2. 设置切换中状态
kr_coutryText.value = countryTag;
kr_currentNodeName.value = countryTag; // UI显示当前国家
// 3. 获取该国家的节点列表
final countryData = kr_subscribeService.countryOutboundList
.firstWhereOrNull((c) => c.country.toUpperCase() == countryTag.toUpperCase());
if (countryData == null || countryData.outboundList.isEmpty) {
KRLogUtil.kr_w('⚠️ 未找到国家 [$countryTag] 的节点列表', tag: 'HomeController');
KRCommonUtil.kr_showToast('该国家暂无可用节点');
return false;
}
// 取第一个节点作为默认节点(后续由 sing-box 自动在该组内切换)
final defaultNode = countryData.outboundList.first.tag;
KRLogUtil.kr_i(
'📊 国家 [$countryTag] 包含 ${countryData.outboundList.length} 个节点,默认节点: $defaultNode',
tag: 'HomeController',
);
// 4. 如果VPN未连接,只更新UI变量即可
if (!kr_isConnected.value) {
KRLogUtil.kr_i('📴 VPN未连接,只更新UI变量: $countryTag', tag: 'HomeController');
kr_cutSeletedTag.value = defaultNode;
kr_cutTag.value = defaultNode;
kr_currentNodeLatency.value = -2;
// 保存国家选择与默认节点
await KRSecureStorage().kr_saveData(key: 'SELECTED_COUNTRY_TAG', value: countryTag);
await KRSecureStorage().kr_saveData(key: 'SELECTED_NODE_TAG', value: defaultNode);
KRLogUtil.kr_i('✅ 已保存国家选择 [$countryTag] (未连接状态)', tag: 'HomeController');
return true;
}
// 5. VPN已连接状态,执行完整重载逻辑
try {
KRLogUtil.kr_i('🔌 VPN已连接,准备切换国家 [$countryTag]', tag: 'HomeController');
// 显示连接中
kr_currentNodeLatency.value = -1;
kr_isLatency.value = true;
// 保存选择
await KRSecureStorage().kr_saveData(key: 'SELECTED_COUNTRY_TAG', value: countryTag);
await KRSecureStorage().kr_saveData(key: 'SELECTED_NODE_TAG', value: defaultNode);
// 🔧 调用 SingBox 层逻辑切换国家分组(稍后在 kr_sing_box_imp.dart 实现)
KRLogUtil.kr_i('🧩 调用 sing-box 切换国家分组逻辑: $countryTag', tag: 'HomeController');
await KRSingBoxImp.instance.kr_selectCountry(countryTag);
// 🔁 停止并重启 VPN
await KRSingBoxImp.instance.kr_stop();
KRLogUtil.kr_i('⏳ 等待VPN停止(1500ms', tag: 'HomeController');
await Future.delayed(const Duration(milliseconds: 1500));
await KRSingBoxImp.instance.kr_start();
KRLogUtil.kr_i('⏳ 等待VPN启动(2500ms', tag: 'HomeController');
await Future.delayed(const Duration(milliseconds: 2500));
// ✅ 切换成功,更新UI
kr_cutSeletedTag.value = defaultNode;
kr_cutTag.value = defaultNode;
kr_updateConnectionInfo();
// 更新延迟信息
_kr_updateLatencyOnConnected();
KRLogUtil.kr_i('✅ 国家切换成功: $countryTag', tag: 'HomeController');
return true;
} catch (switchError) {
KRLogUtil.kr_e('❌ 国家切换失败: $switchError', tag: 'HomeController');
// 恢复原国家状态
kr_coutryText.value = originalCountry;
await KRSecureStorage().kr_saveData(key: 'SELECTED_COUNTRY_TAG', value: originalCountry ?? '');
KRCommonUtil.kr_showToast('切换国家失败,已恢复为: ${originalCountry ?? ""}');
return false;
}
} catch (e) {
KRLogUtil.kr_e('❌ 国家切换异常: $e', tag: 'HomeController');
KRCommonUtil.kr_showToast('国家切换异常,请重试');
return false;
} finally {
kr_isLatency.value = false;
KRLogUtil.kr_i('🔄 国家切换流程完成', tag: 'HomeController');
}
}
/// 🔧 修复:简化的 kr_selectNode 方法
/// 现在只是委托给新的 kr_performNodeSwitch 方法
/// 为了保持向后兼容,保留此方法但改为调用新方法