fix: 修复模板匹配结果应用时素材使用记录创建失败的问题

- 修复 create_usage_records_from_matching_result 命令参数命名问题
- 将前端调用参数从 snake_case 改为 camelCase 以匹配 Tauri 自动转换规则
- 确保模板匹配结果应用后能正确创建素材使用记录
- 遵循 Tauri 开发规范的参数命名约定
This commit is contained in:
imeepos 2025-07-16 16:40:25 +08:00
parent 5d39ddea80
commit 31f94a51ff
4 changed files with 7 additions and 149 deletions

View File

@ -188,19 +188,6 @@ export const MaterialMatchingResultDialog: React.FC<MaterialMatchingResultDialog
<span> ({result.failed_segments.length})</span>
</div>
</button>
<button
onClick={() => setActiveTab('records')}
className={`py-4 px-1 border-b-2 font-medium text-sm transition-all duration-200 ${
activeTab === 'records'
? 'border-blue-500 text-blue-600'
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
}`}
>
<div className="flex items-center space-x-2">
<Users className="w-4 h-4" />
<span></span>
</div>
</button>
</nav>
</div>
@ -215,9 +202,6 @@ export const MaterialMatchingResultDialog: React.FC<MaterialMatchingResultDialog
{activeTab === 'failures' && (
<FailuresTab failures={result.failed_segments} />
)}
{activeTab === 'records' && (
<MatchingRecordsTab />
)}
</div>
</>
) : (
@ -547,131 +531,3 @@ const FailuresTab: React.FC<{ failures: FailedSegmentMatch[] }> = ({ failures })
</div>
);
};
// 匹配记录选项卡组件
const MatchingRecordsTab: React.FC = () => {
// 模拟匹配记录数据
const mockRecords = [
{
id: '1',
timestamp: '2024-01-15 14:30:25',
template_name: '时尚写真模板',
project_name: '春季新品拍摄',
success_rate: 0.85,
total_segments: 24,
matched_segments: 20,
used_materials: 15,
used_models: 3
},
{
id: '2',
timestamp: '2024-01-14 16:45:12',
template_name: '商务风格模板',
project_name: '企业形象拍摄',
success_rate: 0.92,
total_segments: 18,
matched_segments: 17,
used_materials: 12,
used_models: 2
},
{
id: '3',
timestamp: '2024-01-13 10:20:08',
template_name: '休闲生活模板',
project_name: '日常生活记录',
success_rate: 0.78,
total_segments: 32,
matched_segments: 25,
used_materials: 20,
used_models: 4
}
];
const getSuccessRateColor = (rate: number): string => {
if (rate >= 0.8) return 'text-green-600';
if (rate >= 0.6) return 'text-yellow-600';
return 'text-red-600';
};
const getSuccessRateBgColor = (rate: number): string => {
if (rate >= 0.8) return 'bg-green-100';
if (rate >= 0.6) return 'bg-yellow-100';
return 'bg-red-100';
};
return (
<div className="space-y-4">
<div className="flex items-center justify-between mb-6">
<div>
<h3 className="text-lg font-semibold text-gray-900"></h3>
<p className="text-sm text-gray-600 mt-1"></p>
</div>
<div className="text-sm text-gray-500">
{mockRecords.length}
</div>
</div>
{mockRecords.length === 0 ? (
<div className="text-center py-12">
<Users className="w-16 h-16 text-gray-400 mx-auto mb-4" />
<p className="text-gray-600 text-lg font-medium"></p>
<p className="text-gray-500 text-sm mt-2"></p>
</div>
) : (
<div className="space-y-4">
{mockRecords.map((record) => (
<div key={record.id} className="bg-white border border-gray-200 rounded-xl p-6 shadow-sm hover:shadow-md transition-all duration-200 hover:-translate-y-1">
<div className="flex items-start justify-between mb-4">
<div className="flex-1">
<div className="flex items-center space-x-3 mb-2">
<h4 className="font-semibold text-gray-900">{record.template_name}</h4>
<span className={`px-2 py-1 rounded-full text-xs font-medium ${getSuccessRateBgColor(record.success_rate)} ${getSuccessRateColor(record.success_rate)}`}>
{(record.success_rate * 100).toFixed(1)}%
</span>
</div>
<p className="text-sm text-gray-600 mb-1">: {record.project_name}</p>
<p className="text-xs text-gray-500">{record.timestamp}</p>
</div>
<div className="text-right">
<div className="text-sm text-gray-600 space-y-1">
<div>: {record.matched_segments}/{record.total_segments}</div>
<div>: {record.used_materials} </div>
<div>: {record.used_models} </div>
</div>
</div>
</div>
{/* 进度条 */}
<div className="mb-4">
<div className="flex items-center justify-between text-xs text-gray-600 mb-2">
<span></span>
<span>{record.matched_segments}/{record.total_segments}</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-2">
<div
className={`h-2 rounded-full transition-all duration-300 ${
record.success_rate >= 0.8 ? 'bg-gradient-to-r from-green-500 to-green-600' :
record.success_rate >= 0.6 ? 'bg-gradient-to-r from-yellow-500 to-yellow-600' :
'bg-gradient-to-r from-red-500 to-red-600'
}`}
style={{ width: `${record.success_rate * 100}%` }}
/>
</div>
</div>
{/* 操作按钮 */}
<div className="flex items-center justify-end space-x-2">
<button className="text-xs text-blue-600 hover:text-blue-700 font-medium px-3 py-1 rounded-md hover:bg-blue-50 transition-colors">
</button>
<button className="text-xs text-gray-600 hover:text-gray-700 font-medium px-3 py-1 rounded-md hover:bg-gray-50 transition-colors">
</button>
</div>
</div>
))}
</div>
)}
</div>
);
};

View File

@ -31,7 +31,7 @@ export const TabNavigation: React.FC<TabNavigationProps> = ({
className = '',
}) => {
const getTabClasses = (tab: TabItem, isActive: boolean) => {
const baseClasses = 'inline-flex items-center gap-2 font-medium transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2';
const baseClasses = 'inline-flex items-center gap-2 font-medium';
// 尺寸样式
const sizeClasses = {

View File

@ -304,6 +304,8 @@ export const TemplateMatchingResultDetailModal: React.FC<TemplateMatchingResultD
tabs={tabs}
activeTab={activeTab}
onTabChange={setActiveTab}
variant="underline"
className='px-4'
/>
{/* 标签页内容 */}

View File

@ -404,10 +404,10 @@ export const ProjectDetails: React.FC = () => {
if (savedResult && typeof savedResult === 'object' && 'id' in savedResult) {
try {
await invoke('create_usage_records_from_matching_result', {
project_id: project?.id,
template_id: currentMatchingBinding.binding.template_id,
binding_id: currentMatchingBinding.binding.id,
template_matching_result_id: (savedResult as any).id,
projectId: project?.id,
templateId: currentMatchingBinding.binding.template_id,
bindingId: currentMatchingBinding.binding.id,
templateMatchingResultId: (savedResult as any).id,
matches: result.matches
});
console.log('素材使用记录创建成功');