mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-08-03 19:12:04 +08:00
feat(commands): add global and per-app proxy config commands
Add new Tauri commands for the refactored proxy configuration: - get_global_proxy_config / update_global_proxy_config - get_proxy_config_for_app / update_proxy_config_for_app Update startup restore logic to read from proxy_config table.
This commit is contained in:
@@ -56,21 +56,21 @@ pub async fn remove_from_failover_queue(
|
|||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 获取指定应用的自动故障转移开关状态
|
/// 获取指定应用的自动故障转移开关状态(从 proxy_config 表读取)
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn get_auto_failover_enabled(
|
pub async fn get_auto_failover_enabled(
|
||||||
state: tauri::State<'_, AppState>,
|
state: tauri::State<'_, AppState>,
|
||||||
app_type: String,
|
app_type: String,
|
||||||
) -> Result<bool, String> {
|
) -> Result<bool, String> {
|
||||||
let key = format!("auto_failover_enabled_{app_type}");
|
|
||||||
state
|
state
|
||||||
.db
|
.db
|
||||||
.get_setting(&key)
|
.get_proxy_config_for_app(&app_type)
|
||||||
.map(|v| v.map(|s| s == "true").unwrap_or(false)) // 默认关闭
|
.await
|
||||||
|
.map(|config| config.auto_failover_enabled)
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 设置指定应用的自动故障转移开关状态
|
/// 设置指定应用的自动故障转移开关状态(写入 proxy_config 表)
|
||||||
///
|
///
|
||||||
/// 注意:关闭故障转移时不会清除队列,队列内容会保留供下次开启时使用
|
/// 注意:关闭故障转移时不会清除队列,队列内容会保留供下次开启时使用
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -79,12 +79,24 @@ pub async fn set_auto_failover_enabled(
|
|||||||
app_type: String,
|
app_type: String,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let key = format!("auto_failover_enabled_{app_type}");
|
|
||||||
let value = if enabled { "true" } else { "false" };
|
|
||||||
|
|
||||||
log::info!(
|
log::info!(
|
||||||
"[Failover] Setting auto_failover_enabled: key='{key}', value='{value}', app_type='{app_type}'"
|
"[Failover] Setting auto_failover_enabled: app_type='{app_type}', enabled={enabled}"
|
||||||
);
|
);
|
||||||
|
|
||||||
state.db.set_setting(&key, value).map_err(|e| e.to_string())
|
// 读取当前配置
|
||||||
|
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())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,63 @@ pub async fn update_proxy_config(
|
|||||||
state.proxy_service.update_config(&config).await
|
state.proxy_service.update_config(&config).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== Global & Per-App Config ====================
|
||||||
|
|
||||||
|
/// 获取全局代理配置
|
||||||
|
///
|
||||||
|
/// 返回统一的全局配置字段(代理开关、监听地址、端口、日志开关)
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn get_global_proxy_config(
|
||||||
|
state: tauri::State<'_, AppState>,
|
||||||
|
) -> Result<GlobalProxyConfig, String> {
|
||||||
|
let db = &state.db;
|
||||||
|
db.get_global_proxy_config()
|
||||||
|
.await
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 更新全局代理配置
|
||||||
|
///
|
||||||
|
/// 更新统一的全局配置字段,会同时更新三行(claude/codex/gemini)
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn update_global_proxy_config(
|
||||||
|
state: tauri::State<'_, AppState>,
|
||||||
|
config: GlobalProxyConfig,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
let db = &state.db;
|
||||||
|
db.update_global_proxy_config(config)
|
||||||
|
.await
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取指定应用的代理配置
|
||||||
|
///
|
||||||
|
/// 返回应用级配置(enabled、auto_failover、超时、熔断器等)
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn get_proxy_config_for_app(
|
||||||
|
state: tauri::State<'_, AppState>,
|
||||||
|
app_type: String,
|
||||||
|
) -> Result<AppProxyConfig, String> {
|
||||||
|
let db = &state.db;
|
||||||
|
db.get_proxy_config_for_app(&app_type)
|
||||||
|
.await
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 更新指定应用的代理配置
|
||||||
|
///
|
||||||
|
/// 更新应用级配置(enabled、auto_failover、超时、熔断器等)
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn update_proxy_config_for_app(
|
||||||
|
state: tauri::State<'_, AppState>,
|
||||||
|
config: AppProxyConfig,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
let db = &state.db;
|
||||||
|
db.update_proxy_config_for_app(config)
|
||||||
|
.await
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
/// 检查代理服务器是否正在运行
|
/// 检查代理服务器是否正在运行
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn is_proxy_running(state: tauri::State<'_, AppState>) -> Result<bool, String> {
|
pub async fn is_proxy_running(state: tauri::State<'_, AppState>) -> Result<bool, String> {
|
||||||
@@ -126,19 +183,12 @@ pub async fn reset_circuit_breaker(
|
|||||||
.reset_provider_circuit_breaker(&provider_id, &app_type)
|
.reset_provider_circuit_breaker(&provider_id, &app_type)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// 3. 检查是否应该切回优先级更高的供应商
|
// 3. 检查是否应该切回优先级更高的供应商(从 proxy_config 表读取)
|
||||||
let failover_key = format!("auto_failover_enabled_{app_type}");
|
let auto_failover_enabled = match db.get_proxy_config_for_app(&app_type).await {
|
||||||
let auto_failover_enabled = match db.get_setting(&failover_key) {
|
Ok(config) => config.auto_failover_enabled,
|
||||||
Ok(Some(value)) => value == "true",
|
|
||||||
Ok(None) => {
|
|
||||||
log::debug!(
|
|
||||||
"[{app_type}] Failover setting '{failover_key}' not found, defaulting to disabled"
|
|
||||||
);
|
|
||||||
false
|
|
||||||
}
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!(
|
log::error!(
|
||||||
"[{app_type}] Failed to read failover setting '{failover_key}': {e}, defaulting to disabled"
|
"[{app_type}] Failed to read proxy_config for auto_failover_enabled: {e}, defaulting to disabled"
|
||||||
);
|
);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-16
@@ -596,7 +596,7 @@ pub fn run() {
|
|||||||
commands::upsert_mcp_server_in_config,
|
commands::upsert_mcp_server_in_config,
|
||||||
commands::delete_mcp_server_in_config,
|
commands::delete_mcp_server_in_config,
|
||||||
commands::set_mcp_enabled,
|
commands::set_mcp_enabled,
|
||||||
// v3.7.0: Unified MCP management
|
// Unified MCP management
|
||||||
commands::get_mcp_servers,
|
commands::get_mcp_servers,
|
||||||
commands::upsert_mcp_server,
|
commands::upsert_mcp_server,
|
||||||
commands::delete_mcp_server,
|
commands::delete_mcp_server,
|
||||||
@@ -656,6 +656,11 @@ pub fn run() {
|
|||||||
commands::get_proxy_status,
|
commands::get_proxy_status,
|
||||||
commands::get_proxy_config,
|
commands::get_proxy_config,
|
||||||
commands::update_proxy_config,
|
commands::update_proxy_config,
|
||||||
|
// Global & Per-App Config
|
||||||
|
commands::get_global_proxy_config,
|
||||||
|
commands::update_global_proxy_config,
|
||||||
|
commands::get_proxy_config_for_app,
|
||||||
|
commands::update_proxy_config_for_app,
|
||||||
commands::is_proxy_running,
|
commands::is_proxy_running,
|
||||||
commands::is_live_takeover_active,
|
commands::is_live_takeover_active,
|
||||||
commands::switch_proxy_provider,
|
commands::switch_proxy_provider,
|
||||||
@@ -845,22 +850,20 @@ pub async fn cleanup_before_exit(app_handle: &tauri::AppHandle) {
|
|||||||
// 启动时恢复代理状态
|
// 启动时恢复代理状态
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
/// 启动时根据 settings 表中的代理状态自动恢复代理服务
|
/// 启动时根据 proxy_config 表中的代理状态自动恢复代理服务
|
||||||
///
|
///
|
||||||
/// 检查 `proxy_takeover_claude`、`proxy_takeover_codex`、`proxy_takeover_gemini` 的值,
|
/// 检查 `proxy_config.enabled` 字段,如果有任一应用的状态为 `true`,
|
||||||
/// 如果有任一应用的状态为 `true`,则自动启动代理服务并接管对应应用的 Live 配置。
|
/// 则自动启动代理服务并接管对应应用的 Live 配置。
|
||||||
async fn restore_proxy_state_on_startup(state: &store::AppState) {
|
async fn restore_proxy_state_on_startup(state: &store::AppState) {
|
||||||
// 收集需要恢复接管的应用列表
|
// 收集需要恢复接管的应用列表(从 proxy_config.enabled 读取)
|
||||||
let apps_to_restore: Vec<&str> = ["claude", "codex", "gemini"]
|
let mut apps_to_restore = Vec::new();
|
||||||
.iter()
|
for app_type in ["claude", "codex", "gemini"] {
|
||||||
.filter(|app_type| {
|
if let Ok(config) = state.db.get_proxy_config_for_app(app_type).await {
|
||||||
state
|
if config.enabled {
|
||||||
.db
|
apps_to_restore.push(app_type);
|
||||||
.get_proxy_takeover_enabled(app_type)
|
}
|
||||||
.unwrap_or(false)
|
}
|
||||||
})
|
}
|
||||||
.copied()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if apps_to_restore.is_empty() {
|
if apps_to_restore.is_empty() {
|
||||||
log::debug!("启动时无需恢复代理状态");
|
log::debug!("启动时无需恢复代理状态");
|
||||||
@@ -882,7 +885,11 @@ async fn restore_proxy_state_on_startup(state: &store::AppState) {
|
|||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("✗ 恢复 {app_type} 的代理接管状态失败: {e}");
|
log::error!("✗ 恢复 {app_type} 的代理接管状态失败: {e}");
|
||||||
// 失败时清除该应用的状态,避免下次启动再次尝试
|
// 失败时清除该应用的状态,避免下次启动再次尝试
|
||||||
if let Err(clear_err) = state.db.set_proxy_takeover_enabled(app_type, false) {
|
if let Err(clear_err) = state
|
||||||
|
.proxy_service
|
||||||
|
.set_takeover_for_app(app_type, false)
|
||||||
|
.await
|
||||||
|
{
|
||||||
log::error!("清除 {app_type} 代理状态失败: {clear_err}");
|
log::error!("清除 {app_type} 代理状态失败: {clear_err}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user