//! 故障转移队列命令 //! //! 管理代理模式下的故障转移队列(基于 providers 表的 in_failover_queue 字段) use crate::database::FailoverQueueItem; use crate::provider::Provider; use crate::store::AppState; /// 获取故障转移队列 #[tauri::command] pub async fn get_failover_queue( state: tauri::State<'_, AppState>, app_type: String, ) -> Result, String> { state .db .get_failover_queue(&app_type) .map_err(|e| e.to_string()) } /// 获取可添加到故障转移队列的供应商(不在队列中的) #[tauri::command] pub async fn get_available_providers_for_failover( state: tauri::State<'_, AppState>, app_type: String, ) -> Result, String> { state .db .get_available_providers_for_failover(&app_type) .map_err(|e| e.to_string()) } /// 添加供应商到故障转移队列 #[tauri::command] pub async fn add_to_failover_queue( state: tauri::State<'_, AppState>, app_type: String, provider_id: String, ) -> Result<(), String> { state .db .add_to_failover_queue(&app_type, &provider_id) .map_err(|e| e.to_string()) } /// 从故障转移队列移除供应商 #[tauri::command] pub async fn remove_from_failover_queue( state: tauri::State<'_, AppState>, app_type: String, provider_id: String, ) -> Result<(), String> { state .db .remove_from_failover_queue(&app_type, &provider_id) .map_err(|e| e.to_string()) } /// 获取指定应用的自动故障转移开关状态(从 proxy_config 表读取) #[tauri::command] pub async fn get_auto_failover_enabled( state: tauri::State<'_, AppState>, app_type: String, ) -> Result { state .db .get_proxy_config_for_app(&app_type) .await .map(|config| config.auto_failover_enabled) .map_err(|e| e.to_string()) } /// 设置指定应用的自动故障转移开关状态(写入 proxy_config 表) /// /// 注意:关闭故障转移时不会清除队列,队列内容会保留供下次开启时使用 #[tauri::command] pub async fn set_auto_failover_enabled( app: tauri::AppHandle, state: tauri::State<'_, AppState>, app_type: String, enabled: bool, ) -> Result<(), String> { log::info!( "[Failover] Setting auto_failover_enabled: app_type='{app_type}', enabled={enabled}" ); // 读取当前配置 let mut config = state .db .get_proxy_config_for_app(&app_type) .await .map_err(|e| e.to_string())?; // 更新 auto_failover_enabled 字段 config.auto_failover_enabled = enabled; // 写回数据库 state .db .update_proxy_config_for_app(config) .await .map_err(|e| e.to_string())?; // 刷新托盘菜单,确保状态同步 if let Ok(new_menu) = crate::tray::create_tray_menu(&app, &state) { if let Some(tray) = app.tray_by_id("main") { let _ = tray.set_menu(Some(new_menu)); } } Ok(()) }