fix: 修复一键匹配成功后素材片段未标记为已使用的问题

## 问题分析
- 单个匹配:前端会先调用save_matching_result保存匹配结果,然后额外调用create_usage_records_from_matching_result创建素材使用记录
- 一键匹配:只调用了save_matching_result保存匹配结果,但没有创建素材使用记录,导致片段管理显示已使用0

## 解决方案
在MaterialMatchingService的两个保存方法中添加创建素材使用记录的逻辑:

### 1. match_materials_and_save方法
- 在保存匹配结果成功后,自动创建素材使用记录
- 使用批量创建方法提高性能
- 失败时只记录警告,不阻断主流程

### 2. match_materials_with_used_segments方法
- 在一键匹配保存结果后,自动创建素材使用记录
- 确保一键匹配和单个匹配的行为一致

### 3. 使用记录内容
- 记录匹配分数、匹配原因、素材名称、模特名称等上下文信息
- 使用TemplateMatching类型标识使用场景
- 正确关联模板匹配结果ID

## 技术细节
- 使用create_usage_records_batch批量创建提高性能
- 在MaterialUsageRepository中自动更新素材片段的使用状态
- 保持事务一致性,确保数据完整性
- 添加详细日志便于调试和监控

## 测试验证
- 一键匹配成功后,片段管理应正确显示已使用数量
- 素材片段的is_used状态应正确更新
- 使用记录应正确保存到material_usage_records表
This commit is contained in:
imeepos 2025-07-18 13:24:50 +08:00
parent 483d63caaa
commit c5b944c4a3
2 changed files with 77 additions and 0 deletions

View File

@ -308,6 +308,44 @@ impl MaterialMatchingService {
matching_duration_ms, matching_duration_ms,
).await { ).await {
Ok(saved_result) => { Ok(saved_result) => {
// 创建素材使用记录
println!("📝 创建素材使用记录...");
let usage_requests: Vec<crate::data::models::material_usage::CreateMaterialUsageRecordRequest> = matching_result.matches
.iter()
.map(|segment_match| {
let usage_context = serde_json::json!({
"match_score": segment_match.match_score,
"match_reason": segment_match.match_reason,
"material_name": segment_match.material_name,
"model_name": segment_match.model_name
}).to_string();
crate::data::models::material_usage::CreateMaterialUsageRecordRequest {
material_segment_id: segment_match.material_segment_id.clone(),
material_id: segment_match.material_segment.material_id.clone(),
project_id: matching_result.project_id.clone(),
template_matching_result_id: saved_result.id.clone(),
template_id: matching_result.template_id.clone(),
binding_id: matching_result.binding_id.clone(),
track_segment_id: segment_match.track_segment_id.clone(),
usage_type: crate::data::models::material_usage::MaterialUsageType::TemplateMatching,
usage_context: Some(usage_context),
}
})
.collect();
if !usage_requests.is_empty() {
match self.material_usage_repo.create_usage_records_batch(usage_requests) {
Ok(usage_records) => {
println!("✅ 成功创建 {} 条素材使用记录", usage_records.len());
}
Err(e) => {
eprintln!("⚠️ 创建素材使用记录失败: {},但匹配结果已保存", e);
// 不阻断主流程,只记录警告
}
}
}
return Ok((matching_result, Some(saved_result))); return Ok((matching_result, Some(saved_result)));
} }
Err(e) => { Err(e) => {
@ -1067,6 +1105,44 @@ impl MaterialMatchingService {
0, // 匹配耗时这里简化为0 0, // 匹配耗时这里简化为0
).await?; ).await?;
// 创建素材使用记录
println!("📝 创建素材使用记录...");
let usage_requests: Vec<crate::data::models::material_usage::CreateMaterialUsageRecordRequest> = matching_result.matches
.iter()
.map(|segment_match| {
let usage_context = serde_json::json!({
"match_score": segment_match.match_score,
"match_reason": segment_match.match_reason,
"material_name": segment_match.material_name,
"model_name": segment_match.model_name
}).to_string();
crate::data::models::material_usage::CreateMaterialUsageRecordRequest {
material_segment_id: segment_match.material_segment_id.clone(),
material_id: segment_match.material_segment.material_id.clone(),
project_id: request.project_id.clone(),
template_matching_result_id: saved.id.clone(),
template_id: request.template_id.clone(),
binding_id: request.binding_id.clone(),
track_segment_id: segment_match.track_segment_id.clone(),
usage_type: crate::data::models::material_usage::MaterialUsageType::TemplateMatching,
usage_context: Some(usage_context),
}
})
.collect();
if !usage_requests.is_empty() {
match self.material_usage_repo.create_usage_records_batch(usage_requests) {
Ok(usage_records) => {
println!("✅ 成功创建 {} 条素材使用记录", usage_records.len());
}
Err(e) => {
eprintln!("⚠️ 创建素材使用记录失败: {},但匹配结果已保存", e);
// 不阻断主流程,只记录警告
}
}
}
Some(saved) Some(saved)
} else { } else {
None None

View File

@ -150,6 +150,7 @@ impl TemplateMatchingResultService {
self.repository.create_failed_segment_results(&failed_segment_results)?; self.repository.create_failed_segment_results(&failed_segment_results)?;
} }
println!("✅ TemplateMatchingResultService::save_matching_result 完成ID: {}", matching_result.id);
Ok(matching_result) Ok(matching_result)
} }