diff --git a/src-tauri/src/proxy/forwarder.rs b/src-tauri/src/proxy/forwarder.rs index fa47ada0..a91dc593 100644 --- a/src-tauri/src/proxy/forwarder.rs +++ b/src-tauri/src/proxy/forwarder.rs @@ -29,6 +29,8 @@ pub struct RequestForwarder { failover_manager: Arc, /// AppHandle,用于发射事件和更新托盘 app_handle: Option, + /// 请求开始时的“当前供应商 ID”(用于判断是否需要同步 UI/托盘) + current_provider_id_at_start: String, } impl RequestForwarder { @@ -40,6 +42,7 @@ impl RequestForwarder { current_providers: Arc>>, failover_manager: Arc, app_handle: Option, + current_provider_id_at_start: String, ) -> Self { let mut client_builder = Client::builder(); if timeout_secs > 0 { @@ -58,6 +61,7 @@ impl RequestForwarder { current_providers, failover_manager, app_handle, + current_provider_id_at_start, } } @@ -145,7 +149,6 @@ impl RequestForwarder { ); let mut last_error = None; - let mut failover_happened = false; let mut attempted_providers = 0usize; // 依次尝试每个供应商 @@ -167,9 +170,6 @@ impl RequestForwarder { let used_half_open_permit = permit.used_half_open_permit; attempted_providers += 1; - if attempted_providers > 1 { - failover_happened = true; - } log::info!( "[{}] 尝试 {}/{} - 使用Provider: {} (sort_index: {})", @@ -228,16 +228,18 @@ impl RequestForwarder { let mut status = self.status.write().await; status.success_requests += 1; status.last_error = None; - if failover_happened { + let should_switch = + self.current_provider_id_at_start.as_str() != provider.id.as_str(); + if should_switch { status.failover_count += 1; log::info!( - "[{}] 故障转移成功!切换到 Provider: {} (耗时: {}ms)", + "[{}] 代理目标已切换到 Provider: {} (耗时: {}ms)", app_type_str, provider.name, latency ); - // 异步触发供应商切换,更新 UI 和托盘菜单 + // 异步触发供应商切换,更新 UI/托盘,并把“当前供应商”同步为实际使用的 provider let fm = self.failover_manager.clone(); let ah = self.app_handle.clone(); let pid = provider.id.clone(); diff --git a/src-tauri/src/proxy/handler_context.rs b/src-tauri/src/proxy/handler_context.rs index e8ba7c21..a8eae231 100644 --- a/src-tauri/src/proxy/handler_context.rs +++ b/src-tauri/src/proxy/handler_context.rs @@ -26,6 +26,11 @@ pub struct RequestContext { pub provider: Provider, /// 完整的 Provider 列表(用于故障转移) providers: Vec, + /// 请求开始时的“当前供应商”(用于判断是否需要同步 UI/托盘) + /// + /// 这里使用本地 settings 的设备级 current provider。 + /// 代理模式下如果实际使用的 provider 与此不一致,会触发切换以确保 UI 始终准确。 + pub current_provider_id: String, /// 请求中的模型名称 pub request_model: String, /// 日志标签(如 "Claude"、"Codex"、"Gemini") @@ -58,6 +63,8 @@ impl RequestContext { ) -> Result { let start_time = Instant::now(); let config = state.config.read().await.clone(); + let current_provider_id = + crate::settings::get_current_provider(&app_type).unwrap_or_default(); // 从请求体提取模型名称 let request_model = body @@ -92,6 +99,7 @@ impl RequestContext { config, provider, providers, + current_provider_id, request_model, tag, app_type_str, @@ -133,6 +141,7 @@ impl RequestContext { state.current_providers.clone(), state.failover_manager.clone(), state.app_handle.clone(), + self.current_provider_id.clone(), ) }