From 2934a2b7f262e792d06fd74384f68a90d25b2ed1 Mon Sep 17 00:00:00 2001 From: Kasserrr Date: Thu, 28 Aug 2025 02:58:45 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0win=E4=B8=8B=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E6=89=98=E7=9B=98=20=E8=8A=82=E7=82=B9=20=E4=BB=A3?= =?UTF-8?q?=E7=90=86->=E4=BB=A3=E7=90=86=E7=BB=84->nodes=20=E5=90=8C?= =?UTF-8?q?=E6=97=B6=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=AF=B9=E5=BA=94gui?= =?UTF-8?q?=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/cmd/proxy.rs | 36 +++++++++++- src-tauri/src/core/tray/mod.rs | 46 +++++++-------- src-tauri/src/lib.rs | 1 + src/components/proxy/proxy-groups.tsx | 83 +++++++++++++++------------ src/services/cmds.ts | 4 ++ 5 files changed, 109 insertions(+), 61 deletions(-) diff --git a/src-tauri/src/cmd/proxy.rs b/src-tauri/src/cmd/proxy.rs index c5da4132..82c7a5a7 100644 --- a/src-tauri/src/cmd/proxy.rs +++ b/src-tauri/src/cmd/proxy.rs @@ -1,5 +1,7 @@ +use tauri::Emitter; + use super::CmdResult; -use crate::{ipc::IpcManager, logging, state::proxy::ProxyRequestCache, utils::logging::Type}; +use crate::{core::{handle::Handle, tray::Tray}, ipc::IpcManager, logging, state::proxy::ProxyRequestCache, utils::logging::Type}; use std::time::Duration; const PROXIES_REFRESH_INTERVAL: Duration = Duration::from_secs(60); @@ -62,3 +64,35 @@ pub async fn sync_tray_proxy_selection() -> CmdResult<()> { } } } + +/// 更新代理选择并同步托盘和GUI状态 +#[tauri::command] +pub async fn update_proxy_and_sync(group: String, proxy: String) -> CmdResult<()> { + + + match IpcManager::global().update_proxy(&group, &proxy).await { + Ok(_) => { + logging!(info, Type::Cmd, "Proxy updated successfully: {} -> {}", group, proxy); + + let cache = crate::state::proxy::ProxyRequestCache::global(); + let key = crate::state::proxy::ProxyRequestCache::make_key("proxies", "default"); + cache.map.remove(&key); + + if let Err(e) = Tray::global().update_menu().await { + logging!(error, Type::Cmd, "Failed to sync tray menu: {}", e); + } + + if let Some(app_handle) = Handle::global().app_handle() { + let _ = app_handle.emit("verge://force-refresh-proxies", ()); + let _ = app_handle.emit("verge://refresh-proxy-config", ()); + } + + logging!(info, Type::Cmd, "Proxy and sync completed successfully: {} -> {}", group, proxy); + Ok(()) + } + Err(e) => { + logging!(error, Type::Cmd, "Failed to update proxy: {} -> {}, error: {}", group, proxy, e); + Err(e.to_string()) + } + } +} diff --git a/src-tauri/src/core/tray/mod.rs b/src-tauri/src/core/tray/mod.rs index 0ccf0b72..f4de6042 100644 --- a/src-tauri/src/core/tray/mod.rs +++ b/src-tauri/src/core/tray/mod.rs @@ -1039,14 +1039,13 @@ fn on_menu_event(_: &AppHandle, event: MenuEvent) { feat::toggle_proxy_profile(profile_index.into()).await; // Await async function } id if id.starts_with("proxy_") => { - // 处理代理节点切换: proxy_{group_name}_{proxy_name} + // proxy_{group_name}_{proxy_name} let parts: Vec<&str> = id.splitn(3, '_').collect(); if parts.len() == 3 && parts[0] == "proxy" { let group_name = parts[1]; let proxy_name = parts[2]; - // 获取当前clash配置模式 let current_mode = { Config::clash() .await @@ -1058,31 +1057,30 @@ fn on_menu_event(_: &AppHandle, event: MenuEvent) { .to_owned() }; - // 使用 IPC 管理器切换代理节点 - match IpcManager::global().update_proxy(group_name, proxy_name).await { + match cmd::proxy::update_proxy_and_sync(group_name.to_string(), proxy_name.to_string()).await { Ok(_) => { - log::info!(target: "app", "代理节点切换成功: {} -> {} (模式: {}, 目标组: {})", group_name, proxy_name, current_mode, group_name); - - println!("代理节点切换成功: {} -> {} (模式: {}, 目标组: {})", group_name, proxy_name, current_mode, group_name); - // 立即刷新托盘菜单 - if let Err(e) = Tray::global().update_menu().await { - log::warn!(target: "app", "立即更新托盘菜单失败: {e}"); - } - - // 发出前端刷新事件,确保GUI及时更新 - if let Some(app_handle) = handle::Handle::global().app_handle() { - - // 先强制刷新代理缓存,然后发送GUI刷新事件 - let _ = app_handle.emit("verge://force-refresh-proxies", ()); - // 发送GUI刷新事件 - let _ = app_handle.emit("verge://refresh-proxy-config", ()); - let _ = app_handle.emit("verge://refresh-clash-config", ()); - - log::debug!(target: "app", "托盘代理切换事件已发送到前端"); - } + log::info!(target: "app", " {} -> {} (模式: {})", group_name, proxy_name, current_mode); } Err(e) => { - log::error!(target: "app", "代理节点切换失败: {} -> {}, 错误: {}", group_name, proxy_name, e); + log::error!(target: "app", " {} -> {}, 错误: {:?}", group_name, proxy_name, e); + + match IpcManager::global().update_proxy(group_name, proxy_name).await { + Ok(_) => { + log::info!(target: "app", " {} -> {}", group_name, proxy_name); + + if let Err(e) = Tray::global().update_menu().await { + log::warn!(target: "app", "托盘菜单更新失败: {e}"); + } + + if let Some(app_handle) = handle::Handle::global().app_handle() { + let _ = app_handle.emit("verge://force-refresh-proxies", ()); + let _ = app_handle.emit("verge://refresh-proxy-config", ()); + } + } + Err(e2) => { + log::error!(target: "app", "托盘代理切换回退也失败: {} -> {}, 错误: {}", group_name, proxy_name, e2); + } + } } } } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 83c2e0a2..f921ece5 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -338,6 +338,7 @@ mod app_init { cmd::force_refresh_proxies, cmd::get_providers_proxies, cmd::sync_tray_proxy_selection, + cmd::update_proxy_and_sync, cmd::save_dns_config, cmd::apply_dns_config, cmd::check_dns_config_exists, diff --git a/src/components/proxy/proxy-groups.tsx b/src/components/proxy/proxy-groups.tsx index a951d98f..ca93677b 100644 --- a/src/components/proxy/proxy-groups.tsx +++ b/src/components/proxy/proxy-groups.tsx @@ -8,6 +8,7 @@ import { deleteConnection, getGroupProxyDelays, syncTrayProxySelection, + updateProxyAndSync, } from "@/services/cmds"; import { forceRefreshProxies } from "@/services/cmds"; import { useProfiles } from "@/hooks/use-profiles"; @@ -344,44 +345,54 @@ export const ProxyGroups = (props: Props) => { const { name, now } = group; console.log(`[ProxyGroups] GUI代理切换: ${name} -> ${proxy.name}`); - await updateProxy(name, proxy.name); - - await forceRefreshProxies(); - - onProxies(); - - // 断开连接 - if (verge?.auto_close_connection) { - getConnections().then(({ connections }) => { - connections.forEach((conn) => { - if (conn.chains.includes(now!)) { - deleteConnection(conn.id); - } - }); - }); - } - - // 保存到selected中 - if (!current) return; - if (!current.selected) current.selected = []; - - const index = current.selected.findIndex( - (item) => item.name === group.name, - ); - - if (index < 0) { - current.selected.push({ name, now: proxy.name }); - } else { - current.selected[index] = { name, now: proxy.name }; - } - await patchCurrent({ selected: current.selected }); - - // 同步托盘菜单状态 try { - await syncTrayProxySelection(); - console.log(`[ProxyGroups] 托盘状态同步成功: ${name} -> ${proxy.name}`); + // 1. 保存到selected中 (先保存本地状态) + if (current) { + if (!current.selected) current.selected = []; + + const index = current.selected.findIndex( + (item) => item.name === group.name, + ); + + if (index < 0) { + current.selected.push({ name, now: proxy.name }); + } else { + current.selected[index] = { name, now: proxy.name }; + } + await patchCurrent({ selected: current.selected }); + } + + // 2. 使用统一的同步命令更新代理并同步状态 + await updateProxyAndSync(name, proxy.name); + console.log(`[ProxyGroups] 代理和状态同步完成: ${name} -> ${proxy.name}`); + + // 3. 刷新前端显示 + onProxies(); + + // 4. 断开连接 (异步处理,不影响UI更新) + if (verge?.auto_close_connection) { + getConnections().then(({ connections }) => { + connections.forEach((conn) => { + if (conn.chains.includes(now!)) { + deleteConnection(conn.id); + } + }); + }); + } + } catch (error) { - console.warn("Failed to sync tray proxy selection:", error); + console.error(`[ProxyGroups] 代理切换失败: ${name} -> ${proxy.name}`, error); + // 如果统一命令失败,回退到原来的方式 + try { + await updateProxy(name, proxy.name); + await forceRefreshProxies(); + await syncTrayProxySelection(); + onProxies(); + console.log(`[ProxyGroups] 代理切换回退成功: ${name} -> ${proxy.name}`); + } catch (fallbackError) { + console.error(`[ProxyGroups] 代理切换回退也失败: ${name} -> ${proxy.name}`, fallbackError); + onProxies(); // 至少刷新显示 + } } }, ); diff --git a/src/services/cmds.ts b/src/services/cmds.ts index ef4e5257..18e0c552 100644 --- a/src/services/cmds.ts +++ b/src/services/cmds.ts @@ -147,6 +147,10 @@ export async function syncTrayProxySelection() { return invoke("sync_tray_proxy_selection"); } +export async function updateProxyAndSync(group: string, proxy: string) { + return invoke("update_proxy_and_sync", { group, proxy }); +} + export async function getProxies(): Promise<{ global: IProxyGroupItem; direct: IProxyItem;