/** * Template 命令封装 * 统一使用 execute_python_cli_command 模式 */ use serde::{Deserialize, Serialize}; use tauri::AppHandle; use crate::python_executor::{execute_python_command, execute_python_action_with_progress}; #[derive(Debug, Serialize, Deserialize)] pub struct TemplateResponse { pub success: bool, pub message: String, pub data: Option, pub output: Option, pub error: Option, } #[derive(Debug, Deserialize)] pub struct BatchImportRequest { pub source_folder: String, pub user_id: Option, pub verbose: Option, pub json_output: Option, } #[derive(Debug, Deserialize)] pub struct TemplateListRequest { pub user_id: Option, pub include_cloud: Option, pub limit: Option, pub verbose: Option, pub json_output: Option, } #[derive(Debug, Deserialize)] pub struct TemplateGetRequest { pub template_id: String, pub user_id: Option, pub verbose: Option, pub json_output: Option, } #[derive(Debug, Deserialize)] pub struct TemplateDeleteRequest { pub template_id: String, pub user_id: Option, pub verbose: Option, pub json_output: Option, } #[derive(Debug, Deserialize)] pub struct TemplateSearchRequest { pub query: String, pub user_id: Option, pub include_cloud: Option, pub limit: Option, pub verbose: Option, pub json_output: Option, } // Re-export PythonProgress as ImportProgress for backward compatibility // Note: This is used by frontend TypeScript definitions #[allow(unused_imports)] pub use crate::python_executor::PythonProgress as ImportProgress; #[derive(Debug, Serialize)] pub struct TemplateInfo { pub id: String, pub name: String, pub description: String, pub thumbnail_path: String, pub draft_content_path: String, pub resources_path: String, pub created_at: String, pub updated_at: String, pub canvas_config: serde_json::Value, pub duration: i64, pub material_count: i32, pub track_count: i32, pub tags: Vec, } /// 执行Python CLI命令的通用函数(统一模式) async fn execute_python_cli_command( app: AppHandle, command_args: Vec, ) -> Result { // 构建完整的命令参数 let mut args = vec!["-m".to_string(), "python_core.cli".to_string()]; args.extend(command_args); println!("Executing Template CLI: python {}", args.join(" ")); match execute_python_command(app, &args, None).await { Ok(output) => { // 尝试解析JSON响应 if let Ok(json_value) = serde_json::from_str::(&output) { Ok(TemplateResponse { success: true, message: "模板命令执行成功".to_string(), data: Some(json_value), output: Some(output), error: None, }) } else { // 如果不是JSON,直接返回文本输出 Ok(TemplateResponse { success: true, message: "模板命令执行成功".to_string(), data: None, output: Some(output), error: None, }) } } Err(error) => { Ok(TemplateResponse { success: false, message: "模板命令执行失败".to_string(), data: None, output: None, error: Some(error), }) } } } /// 批量导入模板(新版本,使用CLI模式) #[tauri::command] pub async fn batch_import_templates_cli( app: AppHandle, request: BatchImportRequest, ) -> Result { let mut args = vec!["template".to_string(), "batch-import".to_string(), request.source_folder]; if let Some(user_id) = request.user_id { args.push("--user-id".to_string()); args.push(user_id); } if request.verbose.unwrap_or(false) { args.push("--verbose".to_string()); } if request.json_output.unwrap_or(true) { args.push("--json".to_string()); } execute_python_cli_command(app, args).await } /// 批量导入模板(保持向后兼容) #[tauri::command] pub async fn batch_import_templates(app: tauri::AppHandle, request: BatchImportRequest) -> Result { let args = vec![ "-m".to_string(), "python_core.services.template_manager".to_string(), "--action".to_string(), "batch_import".to_string(), "--source_folder".to_string(), request.source_folder, ]; execute_python_command(app, &args, None).await } #[tauri::command] pub async fn batch_import_templates_with_progress( app: AppHandle, request: BatchImportRequest ) -> Result { let params = &[("--source_folder", request.source_folder.as_str())]; execute_python_action_with_progress( app, "python_core.services.template_manager", "batch_import", params, "template-import-progress", None, ).await } /// 获取模板列表(新版本,使用CLI模式) #[tauri::command] pub async fn get_templates_cli( app: AppHandle, request: TemplateListRequest, ) -> Result { let mut args = vec!["template".to_string(), "list".to_string()]; if let Some(user_id) = request.user_id { args.push("--user-id".to_string()); args.push(user_id); } if request.include_cloud.unwrap_or(true) { args.push("--include-cloud".to_string()); } if let Some(limit_val) = request.limit { args.push("--limit".to_string()); args.push(limit_val.to_string()); } if request.verbose.unwrap_or(false) { args.push("--verbose".to_string()); } if request.json_output.unwrap_or(true) { args.push("--json".to_string()); } execute_python_cli_command(app, args).await } /// 获取模板列表(保持向后兼容) #[tauri::command] pub async fn get_templates(app: tauri::AppHandle) -> Result { let args = vec![ "-m".to_string(), "python_core.services.template_manager".to_string(), "--action".to_string(), "get_templates".to_string(), ]; execute_python_command(app, &args, None).await } /// 获取单个模板(新版本,使用CLI模式) #[tauri::command] pub async fn get_template_cli( app: AppHandle, request: TemplateGetRequest, ) -> Result { let mut args = vec!["template".to_string(), "get".to_string(), request.template_id]; if let Some(user_id) = request.user_id { args.push("--user-id".to_string()); args.push(user_id); } if request.verbose.unwrap_or(false) { args.push("--verbose".to_string()); } if request.json_output.unwrap_or(true) { args.push("--json".to_string()); } execute_python_cli_command(app, args).await } /// 获取单个模板(保持向后兼容) #[tauri::command] pub async fn get_template(app: tauri::AppHandle, template_id: String) -> Result { let args = vec![ "-m".to_string(), "python_core.services.template_manager".to_string(), "--action".to_string(), "get_template".to_string(), "--template_id".to_string(), template_id, ]; execute_python_command(app, &args, None).await } /// 删除模板(新版本,使用CLI模式) #[tauri::command] pub async fn delete_template_cli( app: AppHandle, request: TemplateDeleteRequest, ) -> Result { let mut args = vec!["template".to_string(), "delete".to_string(), request.template_id]; if let Some(user_id) = request.user_id { args.push("--user-id".to_string()); args.push(user_id); } if request.verbose.unwrap_or(false) { args.push("--verbose".to_string()); } if request.json_output.unwrap_or(true) { args.push("--json".to_string()); } execute_python_cli_command(app, args).await } /// 删除模板(保持向后兼容) #[tauri::command] pub async fn delete_template(app: tauri::AppHandle, template_id: String) -> Result { let args = vec![ "-m".to_string(), "python_core.services.template_manager".to_string(), "--action".to_string(), "delete_template".to_string(), "--template_id".to_string(), template_id, ]; execute_python_command(app, &args, None).await } /// 搜索模板(新功能,使用CLI模式) #[tauri::command] pub async fn search_templates_cli( app: AppHandle, request: TemplateSearchRequest, ) -> Result { let mut args = vec!["template".to_string(), "search".to_string(), request.query]; if let Some(user_id) = request.user_id { args.push("--user-id".to_string()); args.push(user_id); } if request.include_cloud.unwrap_or(true) { args.push("--include-cloud".to_string()); } if let Some(limit_val) = request.limit { args.push("--limit".to_string()); args.push(limit_val.to_string()); } if request.verbose.unwrap_or(false) { args.push("--verbose".to_string()); } if request.json_output.unwrap_or(true) { args.push("--json".to_string()); } execute_python_cli_command(app, args).await } /// 获取模板详情(新版本,使用CLI模式) #[tauri::command] pub async fn get_template_detail_cli( app: AppHandle, request: TemplateGetRequest, ) -> Result { let mut args = vec!["template".to_string(), "detail".to_string(), request.template_id]; if let Some(user_id) = request.user_id { args.push("--user-id".to_string()); args.push(user_id); } if request.verbose.unwrap_or(false) { args.push("--verbose".to_string()); } if request.json_output.unwrap_or(true) { args.push("--json".to_string()); } execute_python_cli_command(app, args).await } /// 获取模板详情(保持向后兼容) #[tauri::command] pub async fn get_template_detail(app: tauri::AppHandle, template_id: String) -> Result { let args = vec![ "-m".to_string(), "python_core.services.template_manager".to_string(), "--action".to_string(), "get_template_detail".to_string(), "--template_id".to_string(), template_id, ]; execute_python_command(app, &args, None).await } // Example: AI Video generation with progress #[allow(dead_code)] #[tauri::command] pub async fn generate_video_with_progress( app: AppHandle, image_path: String, prompt: String, output_path: String, ) -> Result { let params = &[ ("--image_path", image_path.as_str()), ("--prompt", prompt.as_str()), ("--output_path", output_path.as_str()), ]; execute_python_action_with_progress( app, "python_core.ai_video.video_generator", "generate", params, "video-generation-progress", None, ).await } /// 获取模板统计信息(新功能) #[tauri::command] pub async fn get_template_stats_cli( app: AppHandle, user_id: Option, verbose: Option, ) -> Result { let mut args = vec!["template".to_string(), "stats".to_string()]; if let Some(user_id) = user_id { args.push("--user-id".to_string()); args.push(user_id); } if verbose.unwrap_or(false) { args.push("--verbose".to_string()); } args.push("--json".to_string()); execute_python_cli_command(app, args).await } /// 获取热门标签(新功能) #[tauri::command] pub async fn get_popular_tags_cli( app: AppHandle, user_id: Option, limit: Option, verbose: Option, ) -> Result { let mut args = vec!["template".to_string(), "tags".to_string()]; if let Some(user_id) = user_id { args.push("--user-id".to_string()); args.push(user_id); } if let Some(limit_val) = limit { args.push("--limit".to_string()); args.push(limit_val.to_string()); } if verbose.unwrap_or(false) { args.push("--verbose".to_string()); } args.push("--json".to_string()); execute_python_cli_command(app, args).await } /// 按标签获取模板(新功能) #[tauri::command] pub async fn get_templates_by_tag_cli( app: AppHandle, tag: String, user_id: Option, include_cloud: Option, limit: Option, verbose: Option, ) -> Result { let mut args = vec!["template".to_string(), "by-tag".to_string(), tag]; if let Some(user_id) = user_id { args.push("--user-id".to_string()); args.push(user_id); } if include_cloud.unwrap_or(true) { args.push("--include-cloud".to_string()); } if let Some(limit_val) = limit { args.push("--limit".to_string()); args.push(limit_val.to_string()); } if verbose.unwrap_or(false) { args.push("--verbose".to_string()); } args.push("--json".to_string()); execute_python_cli_command(app, args).await }