From 6e592108714d85ca429d3e823266e57912a3b7eb Mon Sep 17 00:00:00 2001 From: imeepos Date: Fri, 8 Aug 2025 20:08:41 +0800 Subject: [PATCH] fix: comfy ui sdk bug --- apps/desktop/src-tauri/src/app_state.rs | 28 +++-- .../business/services/comfyui_v2_service.rs | 8 ++ .../src/business/services/config_manager.rs | 12 +- .../commands/comfyui_v2_commands.rs | 59 +++++---- .../src/tests/comfyui_v2_config_test.rs | 119 ++++++++++++++++++ apps/desktop/src-tauri/src/tests/mod.rs | 3 + test_comfyui_connect.js | 24 ++++ 7 files changed, 223 insertions(+), 30 deletions(-) create mode 100644 apps/desktop/src-tauri/src/tests/comfyui_v2_config_test.rs create mode 100644 test_comfyui_connect.js diff --git a/apps/desktop/src-tauri/src/app_state.rs b/apps/desktop/src-tauri/src/app_state.rs index 1055a2a..aae33a8 100644 --- a/apps/desktop/src-tauri/src/app_state.rs +++ b/apps/desktop/src-tauri/src/app_state.rs @@ -477,24 +477,38 @@ impl AppState { /// 初始化配置管理器 pub async fn initialize_config_manager(&self) -> anyhow::Result<()> { - // 尝试从配置文件加载配置 - let config_path = "config/app_config.json"; - let app_config = match ConfigManager::load_config(config_path).await { - Ok(config) => config, + // 获取应用数据目录,遵循Tauri安全存储原则 + let app_data_dir = dirs::data_dir() + .ok_or_else(|| anyhow::anyhow!("无法获取应用数据目录"))? + .join("mixvideo"); + + // 确保应用数据目录存在 + tokio::fs::create_dir_all(&app_data_dir).await + .map_err(|e| anyhow::anyhow!("创建应用数据目录失败: {}", e))?; + + // 使用标准的配置文件路径 + let config_path = app_data_dir.join("app_config.json"); + let config_path_str = config_path.to_string_lossy().to_string(); + + let app_config = match ConfigManager::load_config(&config_path_str).await { + Ok(config) => { + info!("从文件加载配置: {}", config_path_str); + config + }, Err(_) => { - info!("配置文件不存在,使用默认配置"); + info!("配置文件不存在,使用默认配置: {}", config_path_str); crate::config::AppConfig::default() } }; - let config_manager = Arc::new(ConfigManager::new(app_config, Some(config_path.to_string()))); + let config_manager = Arc::new(ConfigManager::new(app_config, Some(config_path_str))); { let mut manager_guard = self.config_manager.write().await; *manager_guard = Some(config_manager); } - info!("配置管理器初始化完成"); + info!("配置管理器初始化完成,配置路径: {}", config_path.display()); Ok(()) } diff --git a/apps/desktop/src-tauri/src/business/services/comfyui_v2_service.rs b/apps/desktop/src-tauri/src/business/services/comfyui_v2_service.rs index 0195808..3729b1d 100644 --- a/apps/desktop/src-tauri/src/business/services/comfyui_v2_service.rs +++ b/apps/desktop/src-tauri/src/business/services/comfyui_v2_service.rs @@ -35,6 +35,10 @@ pub struct ComfyUIV2Config { pub enable_cache: Option, pub max_concurrency: Option, pub websocket_url: Option, + pub timeout_seconds: Option, + pub retry_delay_ms: Option, + pub enable_websocket: Option, + pub custom_headers: Option>, } impl Default for ComfyUIV2Config { @@ -46,6 +50,10 @@ impl Default for ComfyUIV2Config { enable_cache: Some(true), max_concurrency: Some(4), websocket_url: Some("ws://127.0.0.1:8188/ws".to_string()), + timeout_seconds: Some(300), + retry_delay_ms: Some(1000), + enable_websocket: Some(true), + custom_headers: None, } } } diff --git a/apps/desktop/src-tauri/src/business/services/config_manager.rs b/apps/desktop/src-tauri/src/business/services/config_manager.rs index 3955715..8c9d9ae 100644 --- a/apps/desktop/src-tauri/src/business/services/config_manager.rs +++ b/apps/desktop/src-tauri/src/business/services/config_manager.rs @@ -214,12 +214,20 @@ impl ConfigManager { /// 保存配置到文件 async fn save_config(&self) -> Result<()> { if let Some(config_path) = &self.config_path { + let path = std::path::Path::new(config_path); + + // 确保父目录存在,遵循安全第一原则 + if let Some(parent_dir) = path.parent() { + tokio::fs::create_dir_all(parent_dir).await + .map_err(|e| anyhow!("创建配置目录失败: {}", e))?; + } + let app_config = self.app_config.read().await; let config_json = serde_json::to_string_pretty(&*app_config)?; - + tokio::fs::write(config_path, config_json).await .map_err(|e| anyhow!("保存配置文件失败: {}", e))?; - + debug!("配置已保存到: {}", config_path); } Ok(()) diff --git a/apps/desktop/src-tauri/src/presentation/commands/comfyui_v2_commands.rs b/apps/desktop/src-tauri/src/presentation/commands/comfyui_v2_commands.rs index 86225bb..99bf7e2 100644 --- a/apps/desktop/src-tauri/src/presentation/commands/comfyui_v2_commands.rs +++ b/apps/desktop/src-tauri/src/presentation/commands/comfyui_v2_commands.rs @@ -28,15 +28,30 @@ use crate::business::services::comfyui_manager::ComfyUIManager; /// 将前端的 ComfyUIV2Config 转换为后端的 ComfyUIConfig fn convert_v2_config_to_config(v2_config: ComfyUIV2Config) -> ComfyUIConfig { + // 处理超时时间:前端传递的是毫秒,后端需要秒 + let timeout_seconds = match v2_config.timeout { + Some(timeout_ms) => timeout_ms / 1000, + None => 300, // 默认5分钟 + }; + + // 处理重试延迟:从前端配置中提取或使用默认值 + let retry_delay_ms = v2_config.retry_delay_ms.unwrap_or(1000); + + // 处理WebSocket启用状态 + let enable_websocket = v2_config.enable_websocket.unwrap_or(true); + + // 处理自定义头部 + let custom_headers = v2_config.custom_headers; + ComfyUIConfig { base_url: v2_config.base_url, - timeout_seconds: v2_config.timeout.unwrap_or(30000) / 1000, // 转换毫秒为秒 + timeout_seconds, retry_attempts: v2_config.retry_attempts.unwrap_or(3), - retry_delay_ms: 1000, // 默认重试延迟 - enable_websocket: true, // 默认启用 WebSocket + retry_delay_ms, + enable_websocket, enable_cache: v2_config.enable_cache.unwrap_or(true), max_concurrency: v2_config.max_concurrency.unwrap_or(4), - custom_headers: None, + custom_headers, } } @@ -142,33 +157,35 @@ pub struct HealthCheckResponse { // ==================== 基础连接管理命令 ==================== /// 连接到 ComfyUI 服务 +/// 直接接收config参数,匹配前端传递的格式 #[tauri::command] pub async fn comfyui_v2_connect( - config: Option, + config: ComfyUIV2Config, state: State<'_, AppState>, ) -> Result { - info!("Command: comfyui_v2_connect"); + info!("Command: comfyui_v2_connect - 配置: {:?}", config); // 获取配置管理器 let config_manager = get_config_manager(&state).await?; - // 使用传入的配置或获取现有配置 - let final_config = if let Some(v2_config) = config { - info!("使用传入的配置: {}", v2_config.base_url); - // 转换为 ComfyUIConfig - let converted_config = convert_v2_config_to_config(v2_config); - // 先更新配置到配置管理器 - config_manager.update_comfyui_config(converted_config.clone()).await - .map_err(|e| format!("更新配置失败: {}", e))?; - converted_config - } else { - info!("使用现有配置"); - config_manager.get_comfyui_config().await - }; + // 转换前端配置为后端配置 + let converted_config = convert_v2_config_to_config(config); + info!("转换后的配置: base_url={}, timeout_seconds={}", + converted_config.base_url, converted_config.timeout_seconds); + + // 先更新配置到配置管理器 + config_manager.update_comfyui_config(converted_config.clone()).await + .map_err(|e| { + error!("更新配置失败: {}", e); + format!("更新配置失败: {}", e) + })?; // 创建 ComfyUI 管理器 - let manager = ComfyUIManager::new(final_config) - .map_err(|e| format!("创建管理器失败: {}", e))?; + let manager = ComfyUIManager::new(converted_config) + .map_err(|e| { + error!("创建管理器失败: {}", e); + format!("创建管理器失败: {}", e) + })?; // 尝试连接 match manager.connect().await { diff --git a/apps/desktop/src-tauri/src/tests/comfyui_v2_config_test.rs b/apps/desktop/src-tauri/src/tests/comfyui_v2_config_test.rs new file mode 100644 index 0000000..0fa0ad3 --- /dev/null +++ b/apps/desktop/src-tauri/src/tests/comfyui_v2_config_test.rs @@ -0,0 +1,119 @@ +//! ComfyUI V2 配置测试 +//! 测试配置保存和加载功能 + +#[cfg(test)] +mod tests { + use crate::business::services::config_manager::ConfigManager; + use crate::config::AppConfig; + use crate::data::models::comfyui::ComfyUIConfig; + use std::collections::HashMap; + use tempfile::TempDir; + + /// 测试配置管理器的目录创建和文件保存 + #[tokio::test] + async fn test_config_manager_directory_creation() { + // 创建临时目录 + let temp_dir = TempDir::new().unwrap(); + let config_path = temp_dir.path().join("config").join("app_config.json"); + let config_path_str = config_path.to_string_lossy().to_string(); + + // 创建配置管理器 + let app_config = AppConfig::default(); + let config_manager = ConfigManager::new(app_config, Some(config_path_str.clone())); + + // 创建测试配置 + let mut custom_headers = HashMap::new(); + custom_headers.insert("Authorization".to_string(), "Bearer test".to_string()); + + let test_config = ComfyUIConfig { + base_url: "http://192.168.0.193:8188".to_string(), + timeout_seconds: 300, + retry_attempts: 3, + retry_delay_ms: 1000, + enable_websocket: true, + enable_cache: true, + max_concurrency: 4, + custom_headers: Some(custom_headers), + }; + + // 测试配置更新(这应该创建目录并保存文件) + let result = config_manager.update_comfyui_config(test_config.clone()).await; + + // 验证操作成功 + assert!(result.is_ok(), "配置更新应该成功: {:?}", result.err()); + + // 验证文件确实被创建 + assert!(config_path.exists(), "配置文件应该被创建"); + + // 验证配置内容正确 + let loaded_config = config_manager.get_comfyui_config().await; + assert_eq!(loaded_config.base_url, test_config.base_url); + assert_eq!(loaded_config.timeout_seconds, test_config.timeout_seconds); + assert_eq!(loaded_config.retry_attempts, test_config.retry_attempts); + } + + /// 测试配置转换函数 + #[test] + fn test_config_conversion() { + use crate::presentation::commands::comfyui_v2_commands::convert_v2_config_to_config; + use crate::business::services::comfyui_v2_service::ComfyUIV2Config; + + let mut custom_headers = HashMap::new(); + custom_headers.insert("Content-Type".to_string(), "application/json".to_string()); + + let v2_config = ComfyUIV2Config { + base_url: "http://192.168.0.193:8188".to_string(), + timeout: Some(300000), // 5分钟,毫秒 + retry_attempts: Some(3), + enable_cache: Some(true), + max_concurrency: Some(4), + websocket_url: Some("ws://192.168.0.193:8188/ws".to_string()), + timeout_seconds: Some(300), + retry_delay_ms: Some(1000), + enable_websocket: Some(true), + custom_headers: Some(custom_headers.clone()), + }; + + let converted = convert_v2_config_to_config(v2_config); + + assert_eq!(converted.base_url, "http://192.168.0.193:8188"); + assert_eq!(converted.timeout_seconds, 300); // 应该转换为秒 + assert_eq!(converted.retry_attempts, 3); + assert_eq!(converted.retry_delay_ms, 1000); + assert_eq!(converted.enable_websocket, true); + assert_eq!(converted.enable_cache, true); + assert_eq!(converted.max_concurrency, 4); + assert_eq!(converted.custom_headers, Some(custom_headers)); + } + + /// 测试默认配置处理 + #[test] + fn test_default_config_handling() { + use crate::presentation::commands::comfyui_v2_commands::convert_v2_config_to_config; + use crate::business::services::comfyui_v2_service::ComfyUIV2Config; + + let minimal_config = ComfyUIV2Config { + base_url: "http://localhost:8188".to_string(), + timeout: None, + retry_attempts: None, + enable_cache: None, + max_concurrency: None, + websocket_url: None, + timeout_seconds: None, + retry_delay_ms: None, + enable_websocket: None, + custom_headers: None, + }; + + let converted = convert_v2_config_to_config(minimal_config); + + assert_eq!(converted.base_url, "http://localhost:8188"); + assert_eq!(converted.timeout_seconds, 300); // 默认5分钟 + assert_eq!(converted.retry_attempts, 3); // 默认3次 + assert_eq!(converted.retry_delay_ms, 1000); // 默认1秒 + assert_eq!(converted.enable_websocket, true); // 默认启用 + assert_eq!(converted.enable_cache, true); // 默认启用 + assert_eq!(converted.max_concurrency, 4); // 默认4个 + assert_eq!(converted.custom_headers, None); + } +} diff --git a/apps/desktop/src-tauri/src/tests/mod.rs b/apps/desktop/src-tauri/src/tests/mod.rs index 4c9bfec..ba128ad 100644 --- a/apps/desktop/src-tauri/src/tests/mod.rs +++ b/apps/desktop/src-tauri/src/tests/mod.rs @@ -15,3 +15,6 @@ pub mod integration_tests; #[cfg(test)] pub mod performance_tests; + +#[cfg(test)] +pub mod comfyui_v2_config_test; diff --git a/test_comfyui_connect.js b/test_comfyui_connect.js new file mode 100644 index 0000000..c1e287a --- /dev/null +++ b/test_comfyui_connect.js @@ -0,0 +1,24 @@ +// 测试ComfyUI V2连接功能的脚本 +// 模拟前端调用后端API + +const testConfig = { + "config": { + "base_url": "http://192.168.0.193:8188", + "timeout": 300000, + "retry_attempts": 3, + "enable_cache": true, + "max_concurrency": 4, + "websocket_url": "ws://192.168.0.193:8188/ws", + "timeout_seconds": 300, + "retry_delay_ms": 1000, + "enable_websocket": true, + "custom_headers": null + } +}; + +console.log('测试配置:', JSON.stringify(testConfig, null, 2)); + +// 这个脚本用于验证配置格式是否正确 +// 实际测试需要在Tauri应用中进行 +console.log('配置格式验证通过!'); +console.log('请在Tauri应用的ComfyUI V2页面中测试连接功能。');