feat(plagiarism): показывать тематически близкие источники, а не только нарушения
Кандидаты уровня 3 (FAISS), которые прошли порог семантической схожести, но LLM не подтвердила заимствование, раньше молча отбрасывались. Теперь это отдельный блок "recommendations" в отчёте — не плагиат, но источники, полезные для раскрытия темы.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { AlertTriangle, CheckCircle, Info } from 'lucide-react';
|
||||
import { AlertTriangle, CheckCircle, Info, Lightbulb } from 'lucide-react';
|
||||
import { clsx } from 'clsx';
|
||||
import type { PlagiarismResultData } from '../types';
|
||||
|
||||
@@ -173,6 +173,49 @@ export function PlagiarismReport({ data }: PlagiarismReportProps) {
|
||||
<p className="text-base font-medium">Совпадений не обнаружено</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Рекомендации по теме — тематически близкие работы, не заимствование */}
|
||||
{!!data.recommendations?.length && (
|
||||
<div>
|
||||
<h3 className="flex items-center gap-1.5 text-base font-semibold text-gray-900 mb-1">
|
||||
<Lightbulb className="w-4 h-4 text-blue-500" />
|
||||
Похожие по теме работы ({data.recommendations.length})
|
||||
</h3>
|
||||
<p className="text-sm text-gray-500 mb-3">
|
||||
Не заимствование — семантический поиск нашёл близкие по смыслу источники.
|
||||
Могут пригодиться для раскрытия темы и списка литературы.
|
||||
</p>
|
||||
<div className="space-y-3">
|
||||
{data.recommendations.map((rec, i) => (
|
||||
<div key={i} className="border border-blue-100 bg-blue-50/40 rounded-xl overflow-hidden">
|
||||
<div className="flex items-center gap-3 px-4 py-2.5 border-b border-blue-100">
|
||||
<span className="text-sm font-medium text-gray-700 flex-1 truncate">
|
||||
{rec.source_title}
|
||||
</span>
|
||||
<span className="text-xs font-medium px-2 py-0.5 rounded-full bg-blue-100 text-blue-700">
|
||||
{rec.similarity.toFixed(0)}% по смыслу
|
||||
</span>
|
||||
</div>
|
||||
<div className="px-4 py-3">
|
||||
<p className="text-sm text-gray-700 italic leading-relaxed line-clamp-2">
|
||||
«{rec.fragment}»
|
||||
</p>
|
||||
{rec.source_url && (
|
||||
<a
|
||||
href={rec.source_url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-xs text-brand-600 hover:underline mt-1.5 inline-block"
|
||||
>
|
||||
Открыть источник →
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -62,6 +62,16 @@ export interface PlagiarismMatch {
|
||||
cited?: boolean;
|
||||
}
|
||||
|
||||
export interface PlagiarismRecommendation {
|
||||
fragment: string;
|
||||
position_start: number;
|
||||
position_end: number;
|
||||
similarity: number;
|
||||
source_title: string;
|
||||
source_url: string | null;
|
||||
source_db: string;
|
||||
}
|
||||
|
||||
export interface PlagiarismResultData {
|
||||
overall_similarity: number;
|
||||
// Доля БЕЗ похожих на корректную цитату фрагментов — «настоящий» плагиат.
|
||||
@@ -77,6 +87,10 @@ export interface PlagiarismResultData {
|
||||
fuzzy: number;
|
||||
semantic_llm: number;
|
||||
};
|
||||
// Тематически близкие работы, которые LLM не подтвердила как заимствование —
|
||||
// не плагиат, но кандидаты для раскрытия/развития темы. Опционально: старые
|
||||
// задачи в БД посчитаны без этого поля.
|
||||
recommendations?: PlagiarismRecommendation[];
|
||||
}
|
||||
|
||||
// ─── Библиография ─────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user