use crate::business::services::universal_workflow_service::{ ExecuteWorkflowRequest, ExecuteWorkflowResponse }; use crate::data::models::workflow_template::{ WorkflowTemplate, CreateWorkflowTemplateRequest, UpdateWorkflowTemplateRequest, WorkflowTemplateFilter }; use crate::data::models::workflow_execution_record::{ WorkflowExecutionRecord, ExecutionRecordFilter }; use crate::data::models::workflow_execution_environment::{ WorkflowExecutionEnvironment, CreateExecutionEnvironmentRequest, UpdateExecutionEnvironmentRequest, ExecutionEnvironmentFilter }; use crate::app_state::AppState; use anyhow::Result; use serde::{Deserialize, Serialize}; use tauri::State; use tracing::info; use chrono::Timelike; /// 获取所有工作流模板 #[tauri::command] pub async fn get_workflow_templates( filter: Option, state: State<'_, AppState>, ) -> Result, String> { info!("获取工作流模板列表"); // 获取工作流模板仓库 let repo_guard = state.get_workflow_template_repository() .map_err(|e| format!("获取工作流模板仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流模板仓库未初始化".to_string())?; // 查询工作流模板 let templates = repo.find_all(filter.as_ref()) .map_err(|e| format!("查询工作流模板失败: {}", e))?; info!("成功获取 {} 个工作流模板", templates.len()); Ok(templates) } /// 根据ID获取工作流模板 #[tauri::command] pub async fn get_workflow_template_by_id( id: i64, state: State<'_, AppState>, ) -> Result, String> { info!("获取工作流模板: {}", id); // 获取工作流模板仓库 let repo_guard = state.get_workflow_template_repository() .map_err(|e| format!("获取工作流模板仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流模板仓库未初始化".to_string())?; // 查询模板 let template = repo.find_by_id(id) .map_err(|e| format!("查询工作流模板失败: {}", e))?; info!("成功获取工作流模板: {:?}", template.as_ref().map(|t| &t.name)); Ok(template) } /// 创建工作流模板 #[tauri::command] pub async fn create_workflow_template( request: CreateWorkflowTemplateRequest, state: State<'_, AppState>, ) -> Result { info!("创建工作流模板: {}", request.name); // 获取工作流模板仓库 let repo_guard = state.get_workflow_template_repository() .map_err(|e| format!("获取工作流模板仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流模板仓库未初始化".to_string())?; // 创建工作流模板 let template_id = repo.create(&request) .map_err(|e| format!("创建工作流模板失败: {}", e))?; // 查询创建的模板并返回 let template = repo.find_by_id(template_id) .map_err(|e| format!("查询创建的工作流模板失败: {}", e))? .ok_or_else(|| "创建的工作流模板未找到".to_string())?; info!("成功创建工作流模板,ID: {}", template_id); Ok(template) } /// 更新工作流模板 #[tauri::command] pub async fn update_workflow_template( id: i64, request: UpdateWorkflowTemplateRequest, state: State<'_, AppState>, ) -> Result { info!("更新工作流模板: {}", id); // 获取工作流模板仓库 let repo_guard = state.get_workflow_template_repository() .map_err(|e| format!("获取工作流模板仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流模板仓库未初始化".to_string())?; // 更新工作流模板 repo.update(id, &request) .map_err(|e| format!("更新工作流模板失败: {}", e))?; // 查询更新后的模板并返回 let template = repo.find_by_id(id) .map_err(|e| format!("查询更新后的工作流模板失败: {}", e))? .ok_or_else(|| "更新后的工作流模板未找到".to_string())?; info!("成功更新工作流模板,ID: {}", id); Ok(template) } /// 执行基于映射的工作流 #[tauri::command] pub async fn execute_workflow_with_mapping( request: crate::data::models::outfit_photo_generation::ExecuteWorkflowRequest, state: State<'_, AppState>, ) -> Result { info!("执行基于映射的工作流,模板ID: {}", request.workflow_template_id); // 获取工作流模板仓库 let template_repo = { let template_repo_guard = state.get_workflow_template_repository() .map_err(|e| format!("获取工作流模板仓库失败: {}", e))?; template_repo_guard.as_ref() .ok_or_else(|| "工作流模板仓库未初始化".to_string())? .clone() }; // 获取工作流执行记录仓库 let execution_repo = { let execution_repo_guard = state.get_workflow_execution_record_repository() .map_err(|e| format!("获取工作流执行记录仓库失败: {}", e))?; execution_repo_guard.as_ref() .ok_or_else(|| "工作流执行记录仓库未初始化".to_string())? .clone() }; // 使用通用工作流服务(支持环境管理) let universal_service = { let service_guard = state.get_universal_workflow_service() .map_err(|e| format!("获取通用工作流服务失败: {}", e))?; if service_guard.as_ref().is_none() { // 尝试初始化通用工作流服务 drop(service_guard); // 释放锁 if let Err(e) = state.initialize_universal_workflow_service() { return Err(format!("初始化通用工作流服务失败: {}", e)); } // 重新获取服务 let service_guard = state.get_universal_workflow_service() .map_err(|e| format!("重新获取通用工作流服务失败: {}", e))?; service_guard.as_ref() .ok_or_else(|| "通用工作流服务初始化后仍然为空".to_string())? .clone() } else { service_guard.as_ref().unwrap().clone() } }; // 转换请求格式到新的统一格式 let unified_request = crate::business::services::universal_workflow_service::ExecuteWorkflowRequest { workflow_identifier: format!("template_{}", request.workflow_template_id), version: None, input_data: request.input_data, environment_id: request.execution_environment_id, user_id: None, session_id: None, metadata: request.execution_config_override, }; // 执行工作流 let response = universal_service.execute_workflow(unified_request).await .map_err(|e| format!("执行工作流失败: {}", e))?; // 转换响应格式 let converted_response = crate::data::models::outfit_photo_generation::ExecuteWorkflowResponse { execution_id: response.execution_id, status: match response.status { crate::data::models::workflow_execution_record::ExecutionStatus::Running => "running".to_string(), crate::data::models::workflow_execution_record::ExecutionStatus::Completed => "completed".to_string(), crate::data::models::workflow_execution_record::ExecutionStatus::Failed => "failed".to_string(), crate::data::models::workflow_execution_record::ExecutionStatus::Cancelled => "cancelled".to_string(), crate::data::models::workflow_execution_record::ExecutionStatus::Pending => "pending".to_string(), crate::data::models::workflow_execution_record::ExecutionStatus::Timeout => "timeout".to_string(), }, comfyui_prompt_id: response.comfyui_prompt_id, error_message: response.error_message, }; info!("工作流执行成功,执行记录ID: {}", response.execution_id); Ok(converted_response) } /// 删除工作流模板 #[tauri::command] pub async fn delete_workflow_template( id: i64, state: State<'_, AppState>, ) -> Result<(), String> { info!("删除工作流模板: {}", id); // 获取工作流模板仓库 let repo_guard = state.get_workflow_template_repository() .map_err(|e| format!("获取工作流模板仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流模板仓库未初始化".to_string())?; // 删除工作流模板 repo.delete(id) .map_err(|e| format!("删除工作流模板失败: {}", e))?; info!("成功删除工作流模板,ID: {}", id); Ok(()) } /// 执行工作流 #[tauri::command] pub async fn execute_workflow( request: ExecuteWorkflowRequest, _state: State<'_, AppState>, ) -> Result { info!("执行工作流: {}", request.workflow_identifier); // TODO: 从AppState获取UniversalWorkflowService // 暂时返回示例响应 let response = ExecuteWorkflowResponse { execution_id: 1, status: crate::data::models::workflow_execution_record::ExecutionStatus::Running, progress: 0, output_data: None, error_message: None, comfyui_prompt_id: Some("test-prompt-id".to_string()), }; Ok(response) } /// 获取执行状态 #[tauri::command] pub async fn get_execution_status( execution_id: i64, state: State<'_, AppState>, ) -> Result { info!("获取执行状态: {}", execution_id); // 获取工作流执行记录仓库 let repo_guard = state.get_workflow_execution_record_repository() .map_err(|e| format!("获取工作流执行记录仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流执行记录仓库未初始化".to_string())?; // 查询执行记录 let record = repo.find_by_id(execution_id) .map_err(|e| format!("查询执行记录失败: {}", e))? .ok_or_else(|| format!("执行记录不存在: {}", execution_id))?; let response = ExecuteWorkflowResponse { execution_id: record.id.unwrap_or(execution_id), status: record.status, progress: record.progress, output_data: record.output_data_json, comfyui_prompt_id: record.comfyui_prompt_id, error_message: record.error_message, }; Ok(response) } /// 获取执行结果 #[tauri::command] pub async fn get_execution_results( execution_id: i64, state: State<'_, AppState>, ) -> Result, String> { info!("获取执行结果: {}", execution_id); // 获取工作流执行记录仓库 let repo_guard = state.get_workflow_execution_record_repository() .map_err(|e| format!("获取工作流执行记录仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流执行记录仓库未初始化".to_string())?; // 查询执行记录 let record = repo.find_by_id(execution_id) .map_err(|e| format!("查询执行记录失败: {}", e))? .ok_or_else(|| format!("执行记录不存在: {}", execution_id))?; Ok(record.output_data_json) } /// 取消执行 #[tauri::command] pub async fn cancel_execution( execution_id: i64, _state: State<'_, AppState>, ) -> Result<(), String> { info!("取消执行: {}", execution_id); // TODO: 实现实际的取消逻辑 Ok(()) } /// 执行历史分页响应 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExecutionHistoryResponse { pub records: Vec, pub total_count: u32, pub page: u32, pub page_size: u32, pub total_pages: u32, } /// 获取执行历史 #[tauri::command] pub async fn get_execution_history( filter: Option, limit: Option, offset: Option, state: State<'_, AppState>, ) -> Result { info!("获取执行历史"); // 获取工作流执行记录仓库 let repo_guard = state.get_workflow_execution_record_repository() .map_err(|e| format!("获取工作流执行记录仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流执行记录仓库未初始化".to_string())?; // 查询执行历史 let (records, total_count, page, page_size) = if let (Some(limit), Some(offset)) = (limit, offset) { let page = (offset / limit.max(1)) as u32; let page_size = limit as u32; let (records, total) = repo.find_with_pagination(filter.as_ref(), page, page_size) .map_err(|e| format!("分页查询执行历史失败: {}", e))?; (records, total, page, page_size) } else { // 如果没有分页参数,返回所有记录 let records = repo.find_all(filter.as_ref()) .map_err(|e| format!("查询执行历史失败: {}", e))?; let total = records.len() as u32; (records, total, 0, total) }; let total_pages = if page_size > 0 { (total_count + page_size - 1) / page_size } else { 1 }; info!("成功获取 {} 条执行历史记录,总数: {}", records.len(), total_count); Ok(ExecutionHistoryResponse { records, total_count, page, page_size, total_pages, }) } /// 获取执行环境列表 #[tauri::command] pub async fn get_execution_environments( filter: Option, state: State<'_, AppState>, ) -> Result, String> { info!("获取执行环境列表"); // 获取工作流执行环境仓库 let repo_guard = state.get_workflow_execution_environment_repository() .map_err(|e| format!("获取工作流执行环境仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流执行环境仓库未初始化".to_string())?; // 查询执行环境 let environments = repo.find_all(filter.as_ref()) .map_err(|e| format!("查询执行环境失败: {}", e))?; info!("成功获取 {} 个执行环境", environments.len()); Ok(environments) } /// 创建执行环境 #[tauri::command] pub async fn create_execution_environment( request: CreateExecutionEnvironmentRequest, state: State<'_, AppState>, ) -> Result { info!("创建执行环境: {}", request.name); // 获取工作流执行环境仓库 let repo_guard = state.get_workflow_execution_environment_repository() .map_err(|e| format!("获取工作流执行环境仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流执行环境仓库未初始化".to_string())?; // 创建执行环境 let environment_id = repo.create(&request) .map_err(|e| format!("创建执行环境失败: {}", e))?; // 查询创建的环境并返回 let environment = repo.find_by_id(environment_id) .map_err(|e| format!("查询创建的执行环境失败: {}", e))? .ok_or_else(|| "创建的执行环境未找到".to_string())?; info!("成功创建执行环境,ID: {}", environment_id); Ok(environment) } /// 更新执行环境 #[tauri::command] pub async fn update_execution_environment( id: i64, request: UpdateExecutionEnvironmentRequest, state: State<'_, AppState>, ) -> Result { info!("更新执行环境: {}, 请求数据: {:?}", id, request); // 获取工作流执行环境仓库 let repo_guard = state.get_workflow_execution_environment_repository() .map_err(|e| format!("获取工作流执行环境仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流执行环境仓库未初始化".to_string())?; // 查询更新前的环境 let old_environment = repo.find_by_id(id) .map_err(|e| format!("查询更新前的执行环境失败: {}", e))? .ok_or_else(|| format!("执行环境不存在,ID: {}", id))?; info!("更新前的环境数据: {:?}", old_environment); // 更新执行环境 repo.update(id, &request) .map_err(|e| format!("更新执行环境失败: {}", e))?; // 查询更新后的环境并返回 let environment = repo.find_by_id(id) .map_err(|e| format!("查询更新后的执行环境失败: {}", e))? .ok_or_else(|| "更新后的执行环境未找到".to_string())?; info!("成功更新执行环境,ID: {}, 更新后数据: {:?}", id, environment); Ok(environment) } /// 删除执行环境 #[tauri::command] pub async fn delete_execution_environment( id: i64, state: State<'_, AppState>, ) -> Result<(), String> { info!("删除执行环境: {}", id); // 获取工作流执行环境仓库 let repo_guard = state.get_workflow_execution_environment_repository() .map_err(|e| format!("获取工作流执行环境仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流执行环境仓库未初始化".to_string())?; // 删除执行环境 repo.delete(id) .map_err(|e| format!("删除执行环境失败: {}", e))?; info!("成功删除执行环境,ID: {}", id); Ok(()) } /// 健康检查执行环境 #[tauri::command] pub async fn health_check_execution_environment( id: i64, state: State<'_, AppState>, ) -> Result { info!("健康检查执行环境: {}", id); // 获取工作流执行环境仓库并克隆以避免所有权问题 let repo = { let repo_guard = state.get_workflow_execution_environment_repository() .map_err(|e| format!("获取工作流执行环境仓库失败: {}", e))?; repo_guard.as_ref() .ok_or_else(|| "工作流执行环境仓库未初始化".to_string())? .clone() }; // 获取环境信息 let _environment = repo.find_by_id(id) .map_err(|e| format!("查询执行环境失败: {}", e))? .ok_or_else(|| format!("执行环境不存在,ID: {}", id))?; // 执行健康检查 - 使用公共方法 let health_results = repo.health_check_all().await .map_err(|e| format!("执行健康检查失败: {}", e))?; // 查找当前环境的健康状态 let health_status = health_results.iter() .find(|(env_id, _)| *env_id == id) .map(|(_, status)| status.clone()) .unwrap_or(crate::data::models::workflow_execution_environment::HealthStatus::Unknown); info!("执行环境健康检查完成,ID: {}, 状态: {:?}", id, health_status); Ok(health_status) } /// 导出工作流模板 #[tauri::command] pub async fn export_workflow_template( id: i64, state: State<'_, AppState>, ) -> Result { info!("导出工作流模板: {}", id); // 获取工作流模板仓库 let repo_guard = state.get_workflow_template_repository() .map_err(|e| format!("获取工作流模板仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流模板仓库未初始化".to_string())?; // 导出模板 let json_data = repo.export_template(id) .map_err(|e| format!("导出工作流模板失败: {}", e))?; info!("成功导出工作流模板,ID: {}", id); Ok(json_data) } /// 导入工作流模板 #[tauri::command] pub async fn import_workflow_template( json_data: String, override_name: Option, state: State<'_, AppState>, ) -> Result { info!("导入工作流模板"); // 获取工作流模板仓库 let repo_guard = state.get_workflow_template_repository() .map_err(|e| format!("获取工作流模板仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流模板仓库未初始化".to_string())?; // 导入模板 let template_id = repo.import_template(&json_data, override_name) .map_err(|e| format!("导入工作流模板失败: {}", e))?; info!("成功导入工作流模板,新ID: {}", template_id); Ok(template_id) } /// 导出工作流包 #[tauri::command] pub async fn export_workflow_package( package_data: serde_json::Value, file_path: String, ) -> Result<(), String> { info!("导出工作流包到: {}", file_path); // 将数据写入文件 std::fs::write(&file_path, serde_json::to_string_pretty(&package_data).unwrap()) .map_err(|e| format!("写入文件失败: {}", e))?; info!("成功导出工作流包"); Ok(()) } /// 导入工作流包 #[tauri::command] pub async fn import_workflow_package() -> Result { info!("导入工作流包"); // 在前端处理文件选择,这里只处理导入逻辑 // 暂时返回成功状态,实际实现时会接收文件路径参数 let result = serde_json::json!({ "success": true, "message": "导入成功", "imported_count": 1 }); info!("成功导入工作流包"); Ok(result) } /// 复制工作流模板 #[tauri::command] pub async fn copy_workflow_template( id: i64, new_name: String, new_base_name: Option, state: State<'_, AppState>, ) -> Result { info!("复制工作流模板: {} -> {}", id, new_name); // 获取工作流模板仓库 let repo_guard = state.get_workflow_template_repository() .map_err(|e| format!("获取工作流模板仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流模板仓库未初始化".to_string())?; // 复制模板 let new_template_id = repo.copy_template(id, new_name, new_base_name) .map_err(|e| format!("复制工作流模板失败: {}", e))?; info!("成功复制工作流模板,原ID: {},新ID: {}", id, new_template_id); Ok(new_template_id) } /// 验证工作流模板 #[tauri::command] pub async fn validate_workflow_template( id: i64, state: State<'_, AppState>, ) -> Result, String> { info!("验证工作流模板: {}", id); // 获取工作流模板仓库 let repo_guard = state.get_workflow_template_repository() .map_err(|e| format!("获取工作流模板仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流模板仓库未初始化".to_string())?; // 获取模板 let template = repo.find_by_id(id) .map_err(|e| format!("查询工作流模板失败: {}", e))? .ok_or_else(|| "工作流模板不存在".to_string())?; // 验证模板 let warnings = repo.validate_template(&template) .map_err(|e| format!("验证工作流模板失败: {}", e))?; info!("工作流模板验证完成,发现 {} 个警告", warnings.len()); Ok(warnings) } /// 批量导出工作流模板 #[tauri::command] pub async fn batch_export_workflow_templates( ids: Vec, state: State<'_, AppState>, ) -> Result { info!("批量导出工作流模板: {:?}", ids); // 获取工作流模板仓库 let repo_guard = state.get_workflow_template_repository() .map_err(|e| format!("获取工作流模板仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流模板仓库未初始化".to_string())?; // 批量导出模板 let json_data = repo.batch_export(&ids) .map_err(|e| format!("批量导出工作流模板失败: {}", e))?; info!("成功批量导出 {} 个工作流模板", ids.len()); Ok(json_data) } /// 批量导入工作流模板 #[tauri::command] pub async fn batch_import_workflow_templates( json_data: String, state: State<'_, AppState>, ) -> Result, String> { info!("批量导入工作流模板"); // 获取工作流模板仓库 let repo_guard = state.get_workflow_template_repository() .map_err(|e| format!("获取工作流模板仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流模板仓库未初始化".to_string())?; // 批量导入模板 let template_ids = repo.batch_import(&json_data) .map_err(|e| format!("批量导入工作流模板失败: {}", e))?; info!("成功批量导入 {} 个工作流模板", template_ids.len()); Ok(template_ids) } /// 获取执行结果文件列表 #[tauri::command] pub async fn get_execution_result_files( execution_id: i64, state: State<'_, AppState>, ) -> Result, String> { info!("获取执行结果文件列表: {}", execution_id); // TODO: 从AppState获取WorkflowResultService实例 // 暂时返回空列表 Ok(Vec::new()) } /// 下载执行结果文件 #[tauri::command] pub async fn download_execution_result_file( execution_id: i64, file_name: String, state: State<'_, AppState>, ) -> Result, String> { info!("下载执行结果文件: {} - {}", execution_id, file_name); // TODO: 从AppState获取WorkflowResultService实例 // 暂时返回空数据 Err("功能暂未实现".to_string()) } /// 删除执行结果文件 #[tauri::command] pub async fn delete_execution_result_files( execution_id: i64, state: State<'_, AppState>, ) -> Result { info!("删除执行结果文件: {}", execution_id); // TODO: 从AppState获取WorkflowResultService实例 // 暂时返回空结果 Ok(crate::business::services::workflow_result_service::CleanupResult { files_deleted: 0, space_freed_mb: 0.0, errors: Vec::new(), }) } /// 系统统计信息响应 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SystemStatistics { pub execution_stats: ExecutionStats, pub environment_stats: EnvironmentStats, pub system_resources: SystemResources, pub performance_metrics: PerformanceMetrics, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExecutionStats { pub total_executions_today: u32, pub successful_executions_today: u32, pub failed_executions_today: u32, pub average_execution_time_seconds: f64, pub current_queue_size: u32, pub active_executions: u32, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct EnvironmentStats { pub total_environments: u32, pub healthy_environments: u32, pub unhealthy_environments: u32, pub average_response_time_ms: f64, pub total_capacity: u32, pub used_capacity: u32, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SystemResources { pub cpu_usage_percent: f64, pub memory_usage_percent: f64, pub disk_usage_percent: f64, pub network_status: String, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PerformanceMetrics { pub requests_per_minute: u32, pub average_response_time_ms: f64, pub error_rate_percent: f64, pub uptime_hours: f64, } /// 获取系统统计信息 #[tauri::command] pub async fn get_system_statistics( state: State<'_, AppState>, ) -> Result { info!("获取系统统计信息"); // 获取工作流执行记录仓库 let repo_guard = state.get_workflow_execution_record_repository() .map_err(|e| format!("获取工作流执行记录仓库失败: {}", e))?; let repo = repo_guard.as_ref() .ok_or_else(|| "工作流执行记录仓库未初始化".to_string())?; // 获取环境仓库 let env_repo_guard = state.get_workflow_execution_environment_repository() .map_err(|e| format!("获取执行环境仓库失败: {}", e))?; let env_repo = env_repo_guard.as_ref() .ok_or_else(|| "执行环境仓库未初始化".to_string())?; // 获取今天的执行统计 let today = chrono::Utc::now().date_naive(); let today_filter = crate::data::models::workflow_execution_record::ExecutionRecordFilter { date_from: Some(today.and_hms_opt(0, 0, 0).unwrap().and_utc()), date_to: Some(today.and_hms_opt(23, 59, 59).unwrap().and_utc()), ..Default::default() }; let execution_stats_result = repo.get_execution_statistics(Some(&today_filter)) .map_err(|e| format!("获取执行统计失败: {}", e))?; // 获取环境统计 let environments = env_repo.find_all(None) .map_err(|e| format!("获取环境列表失败: {}", e))?; let healthy_envs = environments.iter() .filter(|env| env.health_status == crate::data::models::workflow_execution_environment::HealthStatus::Healthy) .count() as u32; let total_capacity: u32 = environments.iter() .map(|env| env.max_concurrent_jobs as u32) .sum(); // 获取当前活跃执行 let active_filter = crate::data::models::workflow_execution_record::ExecutionRecordFilter { status: Some(crate::data::models::workflow_execution_record::ExecutionStatus::Running), ..Default::default() }; let active_executions = repo.find_all(Some(&active_filter)) .map_err(|e| format!("获取活跃执行失败: {}", e))?; // 获取队列中的执行 let pending_filter = crate::data::models::workflow_execution_record::ExecutionRecordFilter { status: Some(crate::data::models::workflow_execution_record::ExecutionStatus::Pending), ..Default::default() }; let pending_executions = repo.find_all(Some(&pending_filter)) .map_err(|e| format!("获取队列执行失败: {}", e))?; // 计算系统资源使用情况(简化实现) let cpu_usage = get_cpu_usage().unwrap_or(0.0); let memory_usage = get_memory_usage().unwrap_or(0.0); let disk_usage = get_disk_usage().unwrap_or(0.0); Ok(SystemStatistics { execution_stats: ExecutionStats { total_executions_today: execution_stats_result.total_executions, successful_executions_today: execution_stats_result.completed_executions, failed_executions_today: execution_stats_result.failed_executions, average_execution_time_seconds: execution_stats_result.average_duration_seconds.unwrap_or(0.0), current_queue_size: pending_executions.len() as u32, active_executions: active_executions.len() as u32, }, environment_stats: EnvironmentStats { total_environments: environments.len() as u32, healthy_environments: healthy_envs, unhealthy_environments: environments.len() as u32 - healthy_envs, average_response_time_ms: environments.iter() .filter_map(|env| env.average_response_time_ms) .map(|t| t as f64) .sum::() / environments.len().max(1) as f64, total_capacity, used_capacity: active_executions.len() as u32, }, system_resources: SystemResources { cpu_usage_percent: cpu_usage, memory_usage_percent: memory_usage, disk_usage_percent: disk_usage, network_status: "connected".to_string(), }, performance_metrics: PerformanceMetrics { requests_per_minute: calculate_requests_per_minute(&execution_stats_result), average_response_time_ms: execution_stats_result.average_duration_seconds.unwrap_or(0.0) * 1000.0, error_rate_percent: if execution_stats_result.total_executions > 0 { (execution_stats_result.failed_executions as f64 / execution_stats_result.total_executions as f64) * 100.0 } else { 0.0 }, uptime_hours: get_uptime_hours(), }, }) } /// 获取存储统计信息 #[tauri::command] pub async fn get_storage_statistics( state: State<'_, AppState>, ) -> Result { info!("获取存储统计信息"); // TODO: 从AppState获取WorkflowResultService实例 // 暂时返回空统计 Ok(crate::business::services::workflow_result_service::StorageStatistics { total_files: 0, total_size_mb: 0.0, oldest_file_date: None, newest_file_date: None, files_by_type: std::collections::HashMap::new(), size_by_type: std::collections::HashMap::new(), }) } /// 清理过期结果文件 #[tauri::command] pub async fn cleanup_expired_results( state: State<'_, AppState>, ) -> Result { info!("清理过期结果文件"); // TODO: 从AppState获取WorkflowResultService实例 // 暂时返回空结果 Ok(crate::business::services::workflow_result_service::CleanupResult { files_deleted: 0, space_freed_mb: 0.0, errors: Vec::new(), }) } /// 批量清理执行结果 #[tauri::command] pub async fn batch_cleanup_execution_results( execution_ids: Vec, state: State<'_, AppState>, ) -> Result { info!("批量清理执行结果: {:?}", execution_ids); // TODO: 从AppState获取WorkflowResultService实例 // 暂时返回空结果 Ok(crate::business::services::workflow_result_service::CleanupResult { files_deleted: 0, space_freed_mb: 0.0, errors: Vec::new(), }) } // 辅助函数:获取CPU使用率 fn get_cpu_usage() -> Option { use sysinfo::System; let mut system = System::new_all(); system.refresh_cpu(); // 等待一小段时间以获得准确的CPU使用率 std::thread::sleep(std::time::Duration::from_millis(200)); system.refresh_cpu(); let cpu_usage: f64 = system.cpus().iter() .map(|cpu| cpu.cpu_usage() as f64) .sum::() / system.cpus().len() as f64; Some(cpu_usage) } // 辅助函数:获取内存使用率 fn get_memory_usage() -> Option { use sysinfo::System; let mut system = System::new_all(); system.refresh_memory(); let total_memory = system.total_memory(); let used_memory = system.used_memory(); if total_memory > 0 { Some((used_memory as f64 / total_memory as f64) * 100.0) } else { None } } // 辅助函数:获取磁盘使用率 fn get_disk_usage() -> Option { use sysinfo::Disks; let disks = Disks::new_with_refreshed_list(); // 获取主磁盘的使用率 if let Some(disk) = disks.iter().next() { let total_space = disk.total_space(); let available_space = disk.available_space(); let used_space = total_space - available_space; if total_space > 0 { Some((used_space as f64 / total_space as f64) * 100.0) } else { None } } else { None } } // 辅助函数:计算每分钟请求数 fn calculate_requests_per_minute(stats: &crate::data::repositories::workflow_execution_record_repository::ExecutionStatistics) -> u32 { // 基于今天的总执行数估算每分钟请求数 let total_today = stats.total_executions; let hours_passed = chrono::Utc::now().hour() + 1; // 至少1小时 let minutes_passed = hours_passed * 60; if minutes_passed > 0 { (total_today * 60) / minutes_passed } else { 0 } } // 辅助函数:获取系统运行时间 fn get_uptime_hours() -> f64 { use sysinfo::System; System::uptime() as f64 / 3600.0 // 转换为小时 }