fix: 修复模板匹配结果相关的数据类型错误
1. 修复list_matching_results接口'Invalid column type Integer at index: 18, name: is_active'错误 - 修正template_matching_result_repository.rs中row_to_matching_result函数的is_active字段处理 - 使用rusqlite::types::Value枚举正确处理多种数据类型 2. 修复数据插入和读取的类型不一致问题 - 修正数据插入时将INTEGER字段转换为字符串的错误 - 统一数据类型:数字字段直接使用原始类型而非字符串 3. 实现应用匹配结果功能 - 修复ProjectDetails.tsx中handleApplyMatchingResult函数 - 调用save_matching_result API保存匹配结果到数据库 - 添加成功/失败通知提示 修复的具体问题: - template_matching_results表的is_active字段类型处理 - 数字字段(total_segments, matched_segments等)的类型转换 - quality_score字段的NULL值处理 - 前端应用匹配结果后保存到数据库的逻辑
This commit is contained in:
parent
a4cacf42da
commit
3e6c05c4ac
|
|
@ -53,19 +53,19 @@ impl TemplateMatchingResultRepository {
|
|||
&final_result.binding_id,
|
||||
&final_result.result_name,
|
||||
&final_result.description,
|
||||
&final_result.total_segments.to_string(),
|
||||
&final_result.matched_segments.to_string(),
|
||||
&final_result.failed_segments.to_string(),
|
||||
&final_result.success_rate.to_string(),
|
||||
&final_result.used_materials.to_string(),
|
||||
&final_result.used_models.to_string(),
|
||||
&final_result.matching_duration_ms.to_string(),
|
||||
&final_result.quality_score.map(|s| s.to_string()),
|
||||
&final_result.total_segments,
|
||||
&final_result.matched_segments,
|
||||
&final_result.failed_segments,
|
||||
&final_result.success_rate,
|
||||
&final_result.used_materials,
|
||||
&final_result.used_models,
|
||||
&final_result.matching_duration_ms,
|
||||
&final_result.quality_score,
|
||||
&serde_json::to_string(&final_result.status).unwrap(),
|
||||
&final_result.metadata,
|
||||
&final_result.created_at.to_rfc3339(),
|
||||
&final_result.updated_at.to_rfc3339(),
|
||||
&(final_result.is_active as i32).to_string(),
|
||||
&(final_result.is_active as i32),
|
||||
],
|
||||
)?;
|
||||
|
||||
|
|
@ -458,8 +458,7 @@ impl TemplateMatchingResultRepository {
|
|||
let status: MatchingResultStatus = serde_json::from_str(&status_str)
|
||||
.unwrap_or(MatchingResultStatus::Success);
|
||||
|
||||
let quality_score_str: Option<String> = row.get("quality_score")?;
|
||||
let quality_score = quality_score_str.and_then(|s| s.parse::<f64>().ok());
|
||||
let quality_score: Option<f64> = row.get("quality_score")?;
|
||||
|
||||
let created_at_str: String = row.get("created_at")?;
|
||||
let updated_at_str: String = row.get("updated_at")?;
|
||||
|
|
@ -470,8 +469,13 @@ impl TemplateMatchingResultRepository {
|
|||
.unwrap_or_else(|_| Utc::now().into())
|
||||
.with_timezone(&Utc);
|
||||
|
||||
let is_active_str: String = row.get("is_active")?;
|
||||
let is_active = is_active_str.parse::<i32>().unwrap_or(1) != 0;
|
||||
// 正确处理 is_active 字段,支持多种数据类型
|
||||
let is_active = match row.get::<_, rusqlite::types::Value>("is_active")? {
|
||||
rusqlite::types::Value::Integer(i) => i != 0,
|
||||
rusqlite::types::Value::Text(s) => s == "1" || s.to_lowercase() == "true",
|
||||
rusqlite::types::Value::Real(f) => f != 0.0,
|
||||
_ => true, // 默认为 true
|
||||
};
|
||||
|
||||
Ok(TemplateMatchingResult {
|
||||
id: row.get("id")?,
|
||||
|
|
@ -480,13 +484,13 @@ impl TemplateMatchingResultRepository {
|
|||
binding_id: row.get("binding_id")?,
|
||||
result_name: row.get("result_name")?,
|
||||
description: row.get("description")?,
|
||||
total_segments: row.get::<_, String>("total_segments")?.parse().unwrap_or(0),
|
||||
matched_segments: row.get::<_, String>("matched_segments")?.parse().unwrap_or(0),
|
||||
failed_segments: row.get::<_, String>("failed_segments")?.parse().unwrap_or(0),
|
||||
success_rate: row.get::<_, String>("success_rate")?.parse().unwrap_or(0.0),
|
||||
used_materials: row.get::<_, String>("used_materials")?.parse().unwrap_or(0),
|
||||
used_models: row.get::<_, String>("used_models")?.parse().unwrap_or(0),
|
||||
matching_duration_ms: row.get::<_, String>("matching_duration_ms")?.parse().unwrap_or(0),
|
||||
total_segments: row.get("total_segments")?,
|
||||
matched_segments: row.get("matched_segments")?,
|
||||
failed_segments: row.get("failed_segments")?,
|
||||
success_rate: row.get("success_rate")?,
|
||||
used_materials: row.get("used_materials")?,
|
||||
used_models: row.get("used_models")?,
|
||||
matching_duration_ms: row.get("matching_duration_ms")?,
|
||||
quality_score,
|
||||
status,
|
||||
metadata: row.get("metadata")?,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import { zhCN } from 'date-fns/locale';
|
|||
import { MaterialSegmentStats } from '../components/MaterialSegmentStats';
|
||||
import { MaterialSegmentViewMode } from '../types/materialSegmentView';
|
||||
import { TemplateMatchingResultManager } from '../components/TemplateMatchingResultManager';
|
||||
import { useNotifications } from '../components/NotificationSystem';
|
||||
|
||||
// 格式化时间
|
||||
const formatTime = (dateString: string) => {
|
||||
|
|
@ -78,6 +79,7 @@ export const ProjectDetails: React.FC = () => {
|
|||
queueStats,
|
||||
getProjectQueueStatus
|
||||
} = useVideoClassificationStore();
|
||||
const { success: addNotification } = useNotifications();
|
||||
|
||||
// 模板绑定状态管理
|
||||
const {
|
||||
|
|
@ -362,20 +364,46 @@ export const ProjectDetails: React.FC = () => {
|
|||
|
||||
const handleApplyMatchingResult = async (result: MaterialMatchingResult) => {
|
||||
try {
|
||||
// 这里可以添加应用匹配结果的逻辑
|
||||
// 例如更新模板绑定的匹配状态等
|
||||
console.log('应用匹配结果:', result);
|
||||
if (!currentMatchingBinding) {
|
||||
throw new Error('没有找到当前匹配绑定信息');
|
||||
}
|
||||
|
||||
// 生成结果名称
|
||||
const resultName = `匹配结果_${new Date().toLocaleString('zh-CN')}`;
|
||||
const description = `模板 ${currentMatchingBinding.template_name} 的匹配结果,成功匹配 ${result.statistics.matched_segments} 个片段`;
|
||||
|
||||
// 调用后端API保存匹配结果
|
||||
await invoke('save_matching_result', {
|
||||
serviceResult: {
|
||||
project_id: project?.id,
|
||||
template_id: currentMatchingBinding.binding.template_id,
|
||||
binding_id: currentMatchingBinding.binding.id,
|
||||
matches: result.matches,
|
||||
failed_segments: result.failed_segments,
|
||||
statistics: result.statistics,
|
||||
matching_duration_ms: 0 // MaterialMatchingResult 没有这个字段,使用默认值
|
||||
},
|
||||
resultName,
|
||||
description,
|
||||
matchingDurationMs: 0 // 使用默认值
|
||||
});
|
||||
|
||||
// 关闭对话框
|
||||
setShowMatchingResultDialog(false);
|
||||
setMatchingResult(null);
|
||||
setCurrentMatchingBinding(null);
|
||||
|
||||
// 可以显示成功提示
|
||||
alert('匹配结果已应用');
|
||||
// 显示成功提示
|
||||
addNotification('匹配结果已保存', `已成功保存匹配结果"${resultName}",可在匹配记录页面查看。`);
|
||||
|
||||
// 如果当前在匹配记录选项卡,刷新数据
|
||||
if (activeTab === 'matching-results') {
|
||||
// 触发匹配记录列表刷新
|
||||
window.location.reload();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('应用匹配结果失败:', error);
|
||||
alert(`应用匹配结果失败: ${error}`);
|
||||
addNotification('保存匹配结果失败', `保存匹配结果时发生错误: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue