diff --git a/apps/desktop/src-tauri/src/presentation/commands/outfit_image_commands.rs b/apps/desktop/src-tauri/src/presentation/commands/outfit_image_commands.rs index 74c7fbe..c81f93d 100644 --- a/apps/desktop/src-tauri/src/presentation/commands/outfit_image_commands.rs +++ b/apps/desktop/src-tauri/src/presentation/commands/outfit_image_commands.rs @@ -243,6 +243,10 @@ pub async fn execute_outfit_image_generation( // 首先创建生成记录 let record_id = create_outfit_image_record(state.clone(), request.clone()).await?; + // 获取数据库和仓库 + let database = state.get_database(); + let outfit_repo = OutfitImageRepository::new(database.clone()); + // 初始化错误处理服务 let error_service = ErrorHandlingService::new(); @@ -263,6 +267,13 @@ pub async fn execute_outfit_image_generation( if !config.is_comfyui_enabled() { let simple_error = SimpleError("ComfyUI 功能未启用".to_string()); let user_error = error_service.handle_error(&simple_error, None); + + // 更新记录状态为失败 + if let Ok(Some(mut record)) = outfit_repo.get_record_by_id(&record_id) { + record.fail(user_error.message.clone()); + let _ = outfit_repo.update_record(&record); + } + return Ok(OutfitImageGenerationResponse { record_id, generated_images: Vec::new(), @@ -282,6 +293,13 @@ pub async fn execute_outfit_image_generation( if !comfyui_service.check_connection().await.unwrap_or(false) { let simple_error = SimpleError("ComfyUI 服务器连接失败".to_string()); let user_error = error_service.handle_error(&simple_error, None); + + // 更新记录状态为失败 + if let Ok(Some(mut record)) = outfit_repo.get_record_by_id(&record_id) { + record.fail(user_error.message.clone()); + let _ = outfit_repo.update_record(&record); + } + return Ok(OutfitImageGenerationResponse { record_id, generated_images: Vec::new(), @@ -292,7 +310,6 @@ pub async fn execute_outfit_image_generation( } // 获取模特图片URL(使用model_image_id) - let database = state.get_database(); let model_repo = ModelRepository::new(database.clone()); // 首先获取模特的所有照片,然后找到指定的照片 @@ -350,6 +367,13 @@ pub async fn execute_outfit_image_generation( } }; + // 更新记录状态为处理中 + if let Ok(Some(mut record)) = outfit_repo.get_record_by_id(&record_id) { + record.start_processing(); + let _ = outfit_repo.update_record(&record); + info!("📝 更新穿搭图片生成记录状态为处理中"); + } + // 处理多个商品图片,为每个商品图片创建生成任务 let mut all_generated_images = Vec::new(); let mut has_errors = false; @@ -455,7 +479,7 @@ pub async fn execute_outfit_image_generation( let end_time = Utc::now(); let total_duration = (end_time - start_time).num_milliseconds() as u64; - // 构建响应 + // 构建响应并更新数据库状态 let response = if all_generated_images.is_empty() { let error_message = if error_messages.is_empty() { "未生成任何图片".to_string() @@ -466,6 +490,13 @@ pub async fn execute_outfit_image_generation( let simple_error = SimpleError(error_message.clone()); let user_error = error_service.handle_error(&simple_error, None); + // 更新记录状态为失败 + if let Ok(Some(mut record)) = outfit_repo.get_record_by_id(&record_id) { + record.fail(user_error.message.clone()); + let _ = outfit_repo.update_record(&record); + info!("📝 更新穿搭图片生成记录状态为失败"); + } + OutfitImageGenerationResponse { record_id, generated_images: Vec::new(), @@ -482,9 +513,21 @@ pub async fn execute_outfit_image_generation( info!("{}", success_message); + // 转换S3 URL为CDN URL + let cdn_urls: Vec = all_generated_images.iter() + .map(|url| convert_s3_to_cdn_url(url)) + .collect(); + + // 更新记录状态为完成 + if let Ok(Some(mut record)) = outfit_repo.get_record_by_id(&record_id) { + record.complete(cdn_urls.clone()); + let _ = outfit_repo.update_record(&record); + info!("📝 更新穿搭图片生成记录状态为完成,保存 {} 张图片", cdn_urls.len()); + } + OutfitImageGenerationResponse { record_id, - generated_images: all_generated_images, + generated_images: cdn_urls, generation_time_ms: total_duration, success: true, error_message: if has_errors { Some(error_messages.join("; ")) } else { None }, @@ -539,17 +582,22 @@ async fn upload_image_to_cloud(file_path: &str, cloud_service: &CloudUploadServi /// 将S3 URL转换为CDN URL fn convert_s3_to_cdn_url(s3_url: &str) -> String { - // 如果已经是CDN URL,直接返回 - if s3_url.contains("bowongai-dev.modal.run") { - return s3_url.to_string(); - } - - // 提取S3 key部分 - if let Some(key_start) = s3_url.find(".com/") { - let key = &s3_url[key_start + 5..]; - format!("https://bowongai-dev.modal.run/cache/s3/{}", key) + if s3_url.starts_with("s3://ap-northeast-2/modal-media-cache/") { + // 将 s3://ap-northeast-2/modal-media-cache/ 替换为 https://cdn.roasmax.cn/ + s3_url.replace("s3://ap-northeast-2/modal-media-cache/", "https://cdn.roasmax.cn/") + } else if s3_url.starts_with("s3://") { + // 处理其他 s3:// 格式,转换为通用CDN格式 + s3_url.replace("s3://", "https://cdn.roasmax.cn/") + } else if s3_url.contains("amazonaws.com") { + // 如果是完整的S3 HTTPS URL,提取key部分 + if let Some(key_start) = s3_url.find(".com/") { + let key = &s3_url[key_start + 5..]; + format!("https://cdn.roasmax.cn/{}", key) + } else { + s3_url.to_string() + } } else { - // 如果无法解析,返回原URL + // 如果不是预期的S3格式,返回原URL s3_url.to_string() } }