diff --git a/src-tauri/src/commands/proxy.rs b/src-tauri/src/commands/proxy.rs index 3366003e..9c9a3421 100644 --- a/src-tauri/src/commands/proxy.rs +++ b/src-tauri/src/commands/proxy.rs @@ -7,14 +7,6 @@ use crate::proxy::types::*; use crate::proxy::{CircuitBreakerConfig, CircuitBreakerStats}; use crate::store::AppState; -/// 启动代理服务器 -#[tauri::command] -pub async fn start_proxy_server( - state: tauri::State<'_, AppState>, -) -> Result { - state.proxy_service.start().await -} - /// 启动代理服务器(带 Live 配置接管) #[tauri::command] pub async fn start_proxy_with_takeover( @@ -23,12 +15,6 @@ pub async fn start_proxy_with_takeover( state.proxy_service.start_with_takeover().await } -/// 停止代理服务器 -#[tauri::command] -pub async fn stop_proxy_server(state: tauri::State<'_, AppState>) -> Result<(), String> { - state.proxy_service.stop().await -} - /// 停止代理服务器(恢复 Live 配置) #[tauri::command] pub async fn stop_proxy_with_restore(state: tauri::State<'_, AppState>) -> Result<(), String> { diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 7d6e773b..41c96fa0 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -647,9 +647,7 @@ pub fn run() { commands::set_auto_launch, commands::get_auto_launch_status, // Proxy server management - commands::start_proxy_server, commands::start_proxy_with_takeover, - commands::stop_proxy_server, commands::stop_proxy_with_restore, commands::get_proxy_status, commands::get_proxy_config, @@ -691,6 +689,22 @@ pub fn run() { .expect("error while running tauri application"); app.run(|app_handle, event| { + // 处理退出请求(所有平台) + if let RunEvent::ExitRequested { api, .. } = &event { + log::info!("收到退出请求,开始清理..."); + // 阻止立即退出,执行清理 + api.prevent_exit(); + + let app_handle = app_handle.clone(); + tauri::async_runtime::spawn(async move { + cleanup_before_exit(&app_handle).await; + log::info!("清理完成,退出应用"); + // 使用 std::process::exit 避免再次触发 ExitRequested + std::process::exit(0); + }); + return; + } + #[cfg(target_os = "macos")] { match event { @@ -770,6 +784,44 @@ pub fn run() { }); } +// ============================================================ +// 应用退出清理 +// ============================================================ + +/// 应用退出前的清理工作 +/// +/// 在应用退出前检查代理服务器状态,如果正在运行则停止代理并恢复 Live 配置。 +/// 确保 Claude Code/Codex/Gemini 的配置不会处于损坏状态。 +pub async fn cleanup_before_exit(app_handle: &tauri::AppHandle) { + if let Some(state) = app_handle.try_state::() { + let proxy_service = &state.proxy_service; + + // 检查代理是否在运行 + if proxy_service.is_running().await { + log::info!("检测到代理服务器正在运行,开始清理..."); + + // 检查是否处于 Live 接管模式 + if let Ok(is_takeover) = state.db.is_live_takeover_active().await { + if is_takeover { + // 接管模式:停止并恢复配置 + if let Err(e) = proxy_service.stop_with_restore().await { + log::error!("退出时恢复 Live 配置失败: {e}"); + } else { + log::info!("已恢复 Live 配置"); + } + } else { + // 非接管模式:仅停止代理 + if let Err(e) = proxy_service.stop().await { + log::error!("退出时停止代理失败: {e}"); + } + } + } + + log::info!("代理服务器清理完成"); + } + } +} + // ============================================================ // 迁移错误对话框辅助函数 // ============================================================ diff --git a/src/hooks/useProxyStatus.ts b/src/hooks/useProxyStatus.ts index f5e0d311..12d7ac6a 100644 --- a/src/hooks/useProxyStatus.ts +++ b/src/hooks/useProxyStatus.ts @@ -32,19 +32,6 @@ export function useProxyStatus() { queryFn: () => invoke("is_live_takeover_active"), }); - // 启动服务器(普通模式) - const startMutation = useMutation({ - mutationFn: () => invoke("start_proxy_server"), - onSuccess: (info) => { - toast.success(`代理服务已启动 - ${info.address}:${info.port}`); - queryClient.invalidateQueries({ queryKey: ["proxyStatus"] }); - }, - onError: (error: Error) => { - const detail = extractErrorMessage(error) || "未知错误"; - toast.error(`启动失败: ${detail}`); - }, - }); - // 启动服务器(带 Live 配置接管) const startWithTakeoverMutation = useMutation({ mutationFn: () => invoke("start_proxy_with_takeover"), @@ -67,19 +54,6 @@ export function useProxyStatus() { }, }); - // 停止服务器(普通模式) - const stopMutation = useMutation({ - mutationFn: () => invoke("stop_proxy_server"), - onSuccess: () => { - toast.success("代理服务已停止"); - queryClient.invalidateQueries({ queryKey: ["proxyStatus"] }); - }, - onError: (error: Error) => { - const detail = extractErrorMessage(error) || "未知错误"; - toast.error(`停止失败: ${detail}`); - }, - }); - // 停止服务器(恢复 Live 配置) const stopWithRestoreMutation = useMutation({ mutationFn: () => invoke("stop_proxy_with_restore"), @@ -144,11 +118,7 @@ export function useProxyStatus() { isRunning: status?.running || false, isTakeoverActive: isTakeoverActive || false, - // 普通模式 - start: startMutation.mutateAsync, - stop: stopMutation.mutateAsync, - - // 接管模式(推荐使用) + // 启动/停止(接管模式) startWithTakeover: startWithTakeoverMutation.mutateAsync, stopWithRestore: stopWithRestoreMutation.mutateAsync, @@ -160,12 +130,9 @@ export function useProxyStatus() { checkTakeoverActive, // 加载状态 - isStarting: startMutation.isPending || startWithTakeoverMutation.isPending, - isStopping: stopMutation.isPending || stopWithRestoreMutation.isPending, + isStarting: startWithTakeoverMutation.isPending, + isStopping: stopWithRestoreMutation.isPending, isPending: - startMutation.isPending || - stopMutation.isPending || - startWithTakeoverMutation.isPending || - stopWithRestoreMutation.isPending, + startWithTakeoverMutation.isPending || stopWithRestoreMutation.isPending, }; }