From 5ae787479292438cb207990e4f9d00da875877c2 Mon Sep 17 00:00:00 2001 From: imeepos Date: Mon, 21 Jul 2025 19:24:58 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=E5=BA=8F=E5=8F=B7001=E5=85=A8=E5=B1=80=E9=99=90?= =?UTF-8?q?=E5=88=B6=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复问题: - 将序号001限制从仅针对FilenameSequence规则改为全局限制 - 现在所有匹配规则(AiClassification、RandomMatch、FilenameSequence)都会遵守序号001限制 - 在单个模板匹配过程中,最多只能使用一个文件名以001结尾的视频文件 实现细节: 1. 在match_single_segment方法开始时检查模板是否已使用序号001视频 2. 将此状态传递给所有匹配方法 3. 在每个匹配方法的过滤逻辑中应用序号001限制 4. 统一的过滤逻辑确保一致性 这确保了无论使用哪种匹配规则,都不会在同一个模板中使用多个序号001的视频文件。 --- .../services/material_matching_service.rs | 77 ++++++++++++++----- 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/apps/desktop/src-tauri/src/business/services/material_matching_service.rs b/apps/desktop/src-tauri/src/business/services/material_matching_service.rs index 963cdcb..7924b91 100644 --- a/apps/desktop/src-tauri/src/business/services/material_matching_service.rs +++ b/apps/desktop/src-tauri/src/business/services/material_matching_service.rs @@ -496,6 +496,18 @@ impl MaterialMatchingService { project_materials: &[Material], used_segment_ids: &mut HashSet, ) -> Result { + // 全局限制:检查当前模板匹配过程中是否已经使用了以001结尾的文件 + let mut template_already_used_sequence_001 = false; + for used_id in used_segment_ids.iter() { + if let Some((used_segment, _)) = available_segments.iter().find(|(seg, _)| seg.id == *used_id) { + if FilenameUtils::has_sequence_001(&used_segment.file_path) && FilenameUtils::is_video_file(&used_segment.file_path) { + template_already_used_sequence_001 = true; + println!("⚠️ 当前模板已使用序号001视频: {}", FilenameUtils::extract_filename(&used_segment.file_path)); + break; + } + } + } + // 检查匹配规则 match &track_segment.matching_rule { SegmentMatchingRule::FixedMaterial => { @@ -509,6 +521,7 @@ impl MaterialMatchingService { category_name, project_materials, used_segment_ids, + template_already_used_sequence_001, ).await } SegmentMatchingRule::RandomMatch => { @@ -517,6 +530,7 @@ impl MaterialMatchingService { available_segments, project_materials, used_segment_ids, + template_already_used_sequence_001, ).await } SegmentMatchingRule::FilenameSequence { target_sequence } => { @@ -526,6 +540,7 @@ impl MaterialMatchingService { target_sequence, project_materials, used_segment_ids, + template_already_used_sequence_001, ).await } } @@ -539,6 +554,7 @@ impl MaterialMatchingService { target_category: &str, project_materials: &[Material], used_segment_ids: &mut HashSet, + template_already_used_sequence_001: bool, ) -> Result { // 计算目标时长(微秒转秒)- 修复单位转换 let target_duration = track_segment.duration as f64 / 1_000_000.0; @@ -550,11 +566,25 @@ impl MaterialMatchingService { println!(" 转换后时长(秒): {:.3}", target_duration); println!(" 目标分类: {}", target_category); - // 过滤出匹配分类的片段 + // 过滤出匹配分类的片段,同时应用序号001限制 let category_segments: Vec<_> = available_segments .iter() .filter(|(segment, category)| { - category == target_category && !used_segment_ids.contains(&segment.id) + // 基本条件:分类匹配且未被使用 + if category != target_category || used_segment_ids.contains(&segment.id) { + return false; + } + + // 全局限制:如果模板已经使用了序号001的视频,则跳过所有序号001的视频 + if template_already_used_sequence_001 + && FilenameUtils::has_sequence_001(&segment.file_path) + && FilenameUtils::is_video_file(&segment.file_path) { + println!(" ⏭️ 跳过序号001片段(模板已使用序号001): {}", + FilenameUtils::extract_filename(&segment.file_path)); + return false; + } + + true }) .collect(); @@ -616,6 +646,7 @@ impl MaterialMatchingService { available_segments: &[(MaterialSegment, String)], project_materials: &[Material], used_segment_ids: &mut HashSet, + template_already_used_sequence_001: bool, ) -> Result { // 计算目标时长(微秒转秒)- 修复单位转换 let target_duration = track_segment.duration as f64 / 1_000_000.0; @@ -626,10 +657,26 @@ impl MaterialMatchingService { println!(" 原始时长(微秒): {}", track_segment.duration); println!(" 转换后时长(秒): {:.3}", target_duration); - // 过滤出未使用的片段 + // 过滤出未使用的片段,同时应用序号001限制 let unused_segments: Vec<_> = available_segments .iter() - .filter(|(segment, _)| !used_segment_ids.contains(&segment.id)) + .filter(|(segment, _)| { + // 基本条件:未被使用 + if used_segment_ids.contains(&segment.id) { + return false; + } + + // 全局限制:如果模板已经使用了序号001的视频,则跳过所有序号001的视频 + if template_already_used_sequence_001 + && FilenameUtils::has_sequence_001(&segment.file_path) + && FilenameUtils::is_video_file(&segment.file_path) { + println!(" ⏭️ 跳过序号001片段(模板已使用序号001): {}", + FilenameUtils::extract_filename(&segment.file_path)); + return false; + } + + true + }) .collect(); if unused_segments.is_empty() { @@ -728,6 +775,7 @@ impl MaterialMatchingService { target_sequence: &str, project_materials: &[Material], used_segment_ids: &mut HashSet, + template_already_used_sequence_001: bool, ) -> Result { println!("🔢 开始文件名序号匹配:"); println!(" 目标序号: {}", target_sequence); @@ -736,20 +784,7 @@ impl MaterialMatchingService { let target_duration = track_segment.duration as f64 / 1_000_000.0; // 转换为秒 println!(" 目标时长(秒): {:.3}", target_duration); - // 特殊处理:如果目标序号是001,检查当前模板匹配过程中是否已经使用了序号001的视频 - let mut template_already_used_sequence_001 = false; - if target_sequence == "001" { - // 检查当前模板匹配过程中已使用的片段中是否有序号001的视频 - for used_id in used_segment_ids.iter() { - if let Some((used_segment, _)) = available_segments.iter().find(|(seg, _)| seg.id == *used_id) { - if FilenameUtils::has_sequence_001(&used_segment.file_path) && FilenameUtils::is_video_file(&used_segment.file_path) { - template_already_used_sequence_001 = true; - println!("⚠️ 当前模板已使用序号001视频: {}", FilenameUtils::extract_filename(&used_segment.file_path)); - break; - } - } - } - } + // 序号001限制检查已在上层完成,这里直接使用传递的参数 // 筛选出包含目标序号的视频文件片段 let mut matching_segments = Vec::new(); @@ -762,8 +797,10 @@ impl MaterialMatchingService { // 检查文件名是否包含目标序号 if FilenameUtils::has_sequence_number(&segment.file_path, target_sequence) { - // 特殊处理:如果目标序号是001且当前模板已经使用了序号001的视频,则跳过这个片段 - if target_sequence == "001" && template_already_used_sequence_001 { + // 全局限制:如果模板已经使用了序号001的视频,则跳过所有序号001的视频 + if template_already_used_sequence_001 + && FilenameUtils::has_sequence_001(&segment.file_path) + && FilenameUtils::is_video_file(&segment.file_path) { println!(" ⏭️ 跳过序号001片段(模板已使用序号001): {}", FilenameUtils::extract_filename(&segment.file_path)); continue;