use tauri::{command, State}; use crate::app_state::AppState; use crate::business::services::video_generation_service::{VideoGenerationService, VideoGenerationStatistics}; use crate::data::models::video_generation::{ VideoGenerationTask, VideoGenerationQueryParams, CreateVideoGenerationRequest }; /// 创建视频生成任务命令 /// 遵循 Tauri 开发规范的命令设计模式 #[command] pub async fn create_video_generation_task( state: State<'_, AppState>, request: CreateVideoGenerationRequest, ) -> Result { // 克隆仓库引用以避免跨await边界的Send问题 let (video_gen_repo, model_repo) = { let video_gen_repository_guard = state.get_video_generation_repository() .map_err(|e| format!("获取视频生成仓库失败: {}", e))?; let video_gen_repository = video_gen_repository_guard.as_ref() .ok_or("视频生成仓库未初始化")?; let model_repository_guard = state.get_model_repository() .map_err(|e| format!("获取模特仓库失败: {}", e))?; let model_repository = model_repository_guard.as_ref() .ok_or("模特仓库未初始化")?; // 这里我们需要克隆仓库,但由于仓库包含Arc,这应该是轻量级的 (video_gen_repository.clone(), model_repository.clone()) }; VideoGenerationService::create_task(&video_gen_repo, &model_repo, request) .await .map_err(|e| e.to_string()) } /// 执行视频生成任务命令 #[command] pub async fn execute_video_generation_task( state: State<'_, AppState>, task_id: String, ) -> Result { let (video_gen_repo, model_repo) = { let video_gen_repository_guard = state.get_video_generation_repository() .map_err(|e| format!("获取视频生成仓库失败: {}", e))?; let video_gen_repository = video_gen_repository_guard.as_ref() .ok_or("视频生成仓库未初始化")?; let model_repository_guard = state.get_model_repository() .map_err(|e| format!("获取模特仓库失败: {}", e))?; let model_repository = model_repository_guard.as_ref() .ok_or("模特仓库未初始化")?; (video_gen_repository.clone(), model_repository.clone()) }; VideoGenerationService::execute_task(&video_gen_repo, &model_repo, &task_id) .await .map_err(|e| e.to_string()) } /// 获取视频生成任务命令 #[command] pub async fn get_video_generation_task( state: State<'_, AppState>, task_id: String, ) -> Result, String> { let repository_guard = state.get_video_generation_repository() .map_err(|e| format!("获取视频生成仓库失败: {}", e))?; let repository = repository_guard.as_ref() .ok_or("视频生成仓库未初始化")?; VideoGenerationService::get_task(repository, &task_id) .map_err(|e| e.to_string()) } /// 获取视频生成任务列表命令 #[command] pub async fn get_video_generation_tasks( state: State<'_, AppState>, params: VideoGenerationQueryParams, ) -> Result, String> { let repository_guard = state.get_video_generation_repository() .map_err(|e| format!("获取视频生成仓库失败: {}", e))?; let repository = repository_guard.as_ref() .ok_or("视频生成仓库未初始化")?; VideoGenerationService::get_tasks(repository, ¶ms) .map_err(|e| e.to_string()) } /// 取消视频生成任务命令 #[command] pub async fn cancel_video_generation_task( state: State<'_, AppState>, task_id: String, ) -> Result { let repository_guard = state.get_video_generation_repository() .map_err(|e| format!("获取视频生成仓库失败: {}", e))?; let repository = repository_guard.as_ref() .ok_or("视频生成仓库未初始化")?; VideoGenerationService::cancel_task(repository, &task_id) .map_err(|e| e.to_string()) } /// 删除视频生成任务命令 #[command] pub async fn delete_video_generation_task( state: State<'_, AppState>, task_id: String, ) -> Result<(), String> { let repository_guard = state.get_video_generation_repository() .map_err(|e| format!("获取视频生成仓库失败: {}", e))?; let repository = repository_guard.as_ref() .ok_or("视频生成仓库未初始化")?; VideoGenerationService::delete_task(repository, &task_id) .map_err(|e| e.to_string()) } /// 重试视频生成任务命令 #[command] pub async fn retry_video_generation_task( state: State<'_, AppState>, task_id: String, ) -> Result { let (video_gen_repo, model_repo) = { let video_gen_repository_guard = state.get_video_generation_repository() .map_err(|e| format!("获取视频生成仓库失败: {}", e))?; let video_gen_repository = video_gen_repository_guard.as_ref() .ok_or("视频生成仓库未初始化")?; let model_repository_guard = state.get_model_repository() .map_err(|e| format!("获取模特仓库失败: {}", e))?; let model_repository = model_repository_guard.as_ref() .ok_or("模特仓库未初始化")?; (video_gen_repository.clone(), model_repository.clone()) }; VideoGenerationService::retry_task(&video_gen_repo, &model_repo, &task_id) .await .map_err(|e| e.to_string()) } /// 获取模特视频生成统计命令 #[command] pub async fn get_model_video_generation_statistics( state: State<'_, AppState>, model_id: String, ) -> Result { let repository_guard = state.get_video_generation_repository() .map_err(|e| format!("获取视频生成仓库失败: {}", e))?; let repository = repository_guard.as_ref() .ok_or("视频生成仓库未初始化")?; VideoGenerationService::get_model_statistics(repository, &model_id) .map_err(|e| e.to_string()) } /// 获取模特详情(包含照片)命令 #[command] pub async fn get_model_detail_with_photos( state: State<'_, AppState>, model_id: String, ) -> Result, String> { let repository_guard = state.get_model_repository() .map_err(|e| format!("获取模特仓库失败: {}", e))?; let repository = repository_guard.as_ref() .ok_or("模特仓库未初始化")?; // 使用完整的get_by_id方法获取包含照片的模特信息 repository.get_by_id(&model_id) .map_err(|e| e.to_string()) } /// 批量上传模特照片命令(上传到云端) #[command] pub async fn batch_upload_model_photos( state: State<'_, AppState>, model_id: String, file_paths: Vec, photo_type: crate::data::models::model::PhotoType, description: Option, tags: Option>, ) -> Result, String> { // 克隆仓库引用以避免跨await边界的Send问题 let repository = { let repository_guard = state.get_model_repository() .map_err(|e| format!("获取模特仓库失败: {}", e))?; let repository = repository_guard.as_ref() .ok_or("模特仓库未初始化")?; repository.clone() }; let mut uploaded_photos = Vec::new(); for file_path in file_paths { match crate::business::services::model_service::ModelService::add_model_photo_with_cloud_upload( &repository, &model_id, file_path, photo_type.clone(), description.clone(), tags.clone(), ).await { Ok(photo) => uploaded_photos.push(photo), Err(e) => { println!("⚠️ 上传照片失败: {}", e); // 继续上传其他照片,不中断整个过程 } } } if uploaded_photos.is_empty() { return Err("没有成功上传任何照片".to_string()); } Ok(uploaded_photos) }