// use std::sync::Arc; // 未使用的导入 use tauri::State; use crate::app_state::AppState; use crate::data::models::material_usage::{ CreateMaterialUsageRecordRequest, MaterialUsageRecord, MaterialUsageStats, MaterialUsageType, ProjectMaterialUsageOverview, }; use crate::data::repositories::material_usage_repository::MaterialUsageRepository; /// 创建素材使用记录 #[tauri::command] pub async fn create_material_usage_record( state: State<'_, AppState>, request: CreateMaterialUsageRecordRequest, ) -> Result { let database = state.get_database(); let repo = MaterialUsageRepository::new(database); // 验证请求 request .validate() .map_err(|e| format!("请求验证失败: {}", e))?; repo.create_usage_record(request) .map_err(|e| format!("创建素材使用记录失败: {}", e)) } /// 批量创建素材使用记录 #[tauri::command] pub async fn create_material_usage_records_batch( state: State<'_, AppState>, requests: Vec, ) -> Result, String> { let database = state.get_database(); let repo = MaterialUsageRepository::new(database); // 验证所有请求 for request in &requests { request .validate() .map_err(|e| format!("请求验证失败: {}", e))?; } repo.create_usage_records_batch(requests) .map_err(|e| format!("批量创建素材使用记录失败: {}", e)) } /// 获取项目的素材使用记录 #[tauri::command] pub async fn get_project_material_usage_records( state: State<'_, AppState>, project_id: String, ) -> Result, String> { let database = state.get_database(); let repo = MaterialUsageRepository::new(database); repo.get_usage_records_by_project(&project_id) .map_err(|e| format!("获取项目素材使用记录失败: {}", e)) } /// 获取模板匹配结果的素材使用记录 #[tauri::command] pub async fn get_matching_result_usage_records( state: State<'_, AppState>, matching_result_id: String, ) -> Result, String> { let database = state.get_database(); let repo = MaterialUsageRepository::new(database); repo.get_usage_records_by_matching_result(&matching_result_id) .map_err(|e| format!("获取匹配结果使用记录失败: {}", e)) } /// 获取项目的素材使用统计信息 #[tauri::command] pub async fn get_project_material_usage_stats( state: State<'_, AppState>, project_id: String, ) -> Result, String> { let database = state.get_database(); let repo = MaterialUsageRepository::new(database); repo.get_material_usage_stats(&project_id) .map_err(|e| format!("获取素材使用统计失败: {}", e)) } /// 获取项目的素材使用概览 #[tauri::command] pub async fn get_project_material_usage_overview( state: State<'_, AppState>, project_id: String, ) -> Result { let database = state.get_database(); let repo = MaterialUsageRepository::new(database); repo.get_project_usage_overview(&project_id) .map_err(|e| format!("获取项目素材使用概览失败: {}", e)) } /// 从匹配结果创建素材使用记录 /// 这是一个便捷方法,用于在应用匹配结果时自动创建使用记录 #[tauri::command] pub async fn create_usage_records_from_matching_result( state: State<'_, AppState>, project_id: String, template_id: String, binding_id: String, template_matching_result_id: String, matches: Vec, // 匹配结果的JSON格式 ) -> Result, String> { println!("🔍 开始创建素材使用记录"); println!("📋 参数信息:"); println!(" - project_id: {}", project_id); println!(" - template_id: {}", template_id); println!(" - binding_id: {}", binding_id); println!(" - template_matching_result_id: {}", template_matching_result_id); println!(" - matches 数量: {}", matches.len()); let database = state.get_database(); let repo = MaterialUsageRepository::new(database); let mut requests = Vec::new(); // 解析匹配结果并创建使用记录请求 for (index, match_value) in matches.iter().enumerate() { println!("🔄 处理第 {} 个匹配结果", index + 1); // 直接从SegmentMatch结构中提取字段 let material_segment_id = match_value .get("material_segment_id") .and_then(|v| v.as_str()) .ok_or("缺少material_segment_id字段")?; // 从material_segment对象中获取material_id let material_id = match_value .get("material_segment") .and_then(|segment| segment.get("material_id")) .and_then(|v| v.as_str()) .ok_or("缺少material_id字段")?; let track_segment_id = match_value .get("track_segment_id") .and_then(|v| v.as_str()) .ok_or("缺少track_segment_id字段")?; let match_score = match_value .get("match_score") .and_then(|v| v.as_f64()) .unwrap_or(0.0); let match_reason = match_value .get("match_reason") .and_then(|v| v.as_str()) .unwrap_or("模板匹配"); // 创建使用上下文 let usage_context = serde_json::json!({ "match_score": match_score, "match_reason": match_reason, "usage_timestamp": chrono::Utc::now().to_rfc3339() }) .to_string(); // 创建使用记录请求 let request = CreateMaterialUsageRecordRequest { material_segment_id: material_segment_id.to_string(), material_id: material_id.to_string(), project_id: project_id.clone(), template_matching_result_id: template_matching_result_id.clone(), template_id: template_id.clone(), binding_id: binding_id.clone(), track_segment_id: track_segment_id.to_string(), usage_type: MaterialUsageType::TemplateMatching, usage_context: Some(usage_context), }; requests.push(request); } if requests.is_empty() { return Ok(Vec::new()); } // 批量创建使用记录 repo.create_usage_records_batch(requests) .map_err(|e| format!("从匹配结果创建使用记录失败: {}", e)) } /// 重置素材片段的使用状态 #[tauri::command] pub async fn reset_material_segment_usage( state: State<'_, AppState>, segment_ids: Vec, ) -> Result { let database = state.get_database(); let conn = database.get_connection(); let conn = conn.lock().unwrap(); // 开始事务 let tx = conn .unchecked_transaction() .map_err(|e| format!("开始事务失败: {}", e))?; // 删除使用记录 for segment_id in &segment_ids { tx.execute( "DELETE FROM material_usage_records WHERE material_segment_id = ?1", [segment_id], ) .map_err(|e| format!("删除使用记录失败: {}", e))?; // 重置素材片段状态 tx.execute( "UPDATE material_segments SET usage_count = 0, is_used = 0, last_used_at = NULL WHERE id = ?1", [segment_id], ).map_err(|e| format!("重置片段状态失败: {}", e))?; } // 提交事务 tx.commit().map_err(|e| format!("提交事务失败: {}", e))?; Ok(format!( "成功重置 {} 个素材片段的使用状态", segment_ids.len() )) } /// 重置项目所有素材的使用状态 #[tauri::command] pub async fn reset_project_material_usage( state: State<'_, AppState>, project_id: String, ) -> Result { let database = state.get_database(); let conn = database.get_connection(); let conn = conn.lock().unwrap(); // 开始事务 let tx = conn .unchecked_transaction() .map_err(|e| format!("开始事务失败: {}", e))?; // 删除项目的所有使用记录 let deleted_records = tx .execute( "DELETE FROM material_usage_records WHERE project_id = ?1", [&project_id], ) .map_err(|e| format!("删除使用记录失败: {}", e))?; // 重置项目所有素材片段状态 let updated_segments = tx .execute( "UPDATE material_segments SET usage_count = 0, is_used = 0, last_used_at = NULL WHERE material_id IN (SELECT id FROM materials WHERE project_id = ?1)", [&project_id], ) .map_err(|e| format!("重置片段状态失败: {}", e))?; // 提交事务 tx.commit().map_err(|e| format!("提交事务失败: {}", e))?; Ok(format!( "成功重置项目素材使用状态:删除 {} 条使用记录,重置 {} 个素材片段", deleted_records, updated_segments )) }