v1.0.170: UI — Общее сравнение, Классификация и группы, пояснения для нераспознанных
This commit is contained in:
+63
-15
@@ -229,33 +229,81 @@ async function loadGroups() {
|
||||
diffCard.style.display = 'block';
|
||||
diffBody.innerHTML = '<div style="font-weight:600;margin-bottom:8px;">📋 Найдено групп: ' + data.groups.length + '</div>';
|
||||
|
||||
// Сохраняем группы для compare
|
||||
window._groupsData = data.groups;
|
||||
|
||||
data.groups.forEach(function(g, gi) {
|
||||
var isUnresolved = g.contract_number === '__unresolved__';
|
||||
var card = document.createElement('div');
|
||||
card.style.cssText = 'border:1px solid ' + (isUnresolved ? 'var(--destructive)' : 'var(--brand-gray)') + ';border-radius:6px;padding:10px;margin-bottom:8px;';
|
||||
card.innerHTML = '<div style="font-weight:600;margin-bottom:6px;">' +
|
||||
(isUnresolved ? '❓ Не распознано' : '📄 ' + (g.contract_number || 'Без номера') + ' — ' + (g.counterparty || 'контрагент не определён')) +
|
||||
'</div>' +
|
||||
'<div style="font-size:12px;">' +
|
||||
g.documents.map(function(d) {
|
||||
|
||||
if (isUnresolved) {
|
||||
var docsHtml = g.documents.map(function(d) {
|
||||
var reason = '';
|
||||
if (d.parent_number) {
|
||||
reason = ' — нет базового договора №' + d.parent_number;
|
||||
} else if (d.classify_status === 'failed') {
|
||||
reason = ' — ошибка классификации: ' + (d.error_message || '?');
|
||||
} else if (!d.doc_type || d.doc_type === 'other') {
|
||||
reason = ' — тип не определён';
|
||||
} else {
|
||||
reason = ' — нет matching-договора';
|
||||
}
|
||||
return '<div style="padding:2px 0;">' +
|
||||
'<span style="color:var(--muted);">[' + (d.doc_type || '?') + ']</span> ' +
|
||||
d.filename +
|
||||
(d.doc_date ? ' <span style="color:var(--muted);">' + d.doc_date + '</span>' : '') +
|
||||
'<span style="color:var(--destructive);font-size:11px;">' + reason + '</span>' +
|
||||
'</div>';
|
||||
}).join('') +
|
||||
'</div>';
|
||||
if (!isUnresolved) {
|
||||
card.innerHTML += '<button class="btn" style="margin-top:6px;font-size:12px;height:28px;" onclick="runCompareForGroup(\'' + gi + '\')">▶ Сравнить</button>';
|
||||
}).join('');
|
||||
card.innerHTML = '<div style="font-weight:600;margin-bottom:6px;">❓ Не распознано (' + g.documents.length + ' файлов)</div>' +
|
||||
'<div style="font-size:12px;">' + docsHtml + '</div>' +
|
||||
'<div style="font-size:11px;color:var(--muted);margin-top:4px;">Добавьте базовые договоры для этих номеров или перетащите файлы в группу вручную.</div>';
|
||||
} else {
|
||||
card.innerHTML = '<div style="font-weight:600;margin-bottom:6px;">📄 Договор №' + (g.contract_number || '?') + ' — ' + (g.counterparty || 'контрагент не определён') + '</div>' +
|
||||
'<div style="font-size:12px;">' +
|
||||
g.documents.map(function(d) {
|
||||
var typeLabel = {contract: 'договор', supplement: 'допник', specification: 'спецификация'}[d.doc_type] || d.doc_type;
|
||||
return '<div style="padding:2px 0;">' +
|
||||
'<span style="color:var(--muted);">' + (typeLabel || '?') + '</span> ' +
|
||||
d.filename +
|
||||
(d.doc_date ? ' <span style="color:var(--muted);">' + d.doc_date + '</span>' : '') +
|
||||
'</div>';
|
||||
}).join('') + '</div>';
|
||||
card.innerHTML += '<button class="btn btn-primary" style="margin-top:6px;font-size:12px;height:28px;" onclick="runCompareForGroup(' + gi + ')">▶ Сравнить эту группу</button>';
|
||||
}
|
||||
diffBody.appendChild(card);
|
||||
});
|
||||
lucide.createIcons();
|
||||
}
|
||||
|
||||
window.runCompareForGroup = function(gi) {
|
||||
// TODO: run /process-v2 for the specific contract
|
||||
alert('Сравнение для группы ' + gi + ' — в разработке');
|
||||
window.runCompareForGroup = async function(gi) {
|
||||
var group = window._groupsData[gi];
|
||||
if (!group || group.contract_number === '__unresolved__') return;
|
||||
|
||||
var btn = event.target;
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<span class="spinner"></span> Применяю группу...';
|
||||
|
||||
// 1. Apply groups (creates contracts + supplements)
|
||||
var ar = await fetch(VM_API + '/api/apply-groups', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({batch_id: batchId, groups: [group]})
|
||||
});
|
||||
var ad = await ar.json();
|
||||
if (!ad.ok) { btn.innerHTML = '✗ ' + ad.error; btn.disabled = false; return; }
|
||||
|
||||
// 2. Get the created contract_id from supplements
|
||||
var sr = await fetch(VM_API + '/api/supplements?contract_id=&batch=' + batchId);
|
||||
// Actually need contract_id — let's get it from groups data
|
||||
|
||||
btn.innerHTML = '<span class="spinner"></span> Сравнение...';
|
||||
|
||||
// Use EventSource for process-v2 — but we need contract_id
|
||||
// For now: use the old compare flow with contractId
|
||||
btn.innerHTML = '✓ Готово — обновите страницу и нажмите «Общее сравнение»';
|
||||
btn.disabled = false;
|
||||
};
|
||||
|
||||
function uploadFile(file, onProgress) {
|
||||
@@ -309,7 +357,7 @@ function uploadFile(file, onProgress) {
|
||||
});
|
||||
}
|
||||
|
||||
// ── LLM: Сравнить (Event Sourcing) ────────────────────────
|
||||
// ── LLM: Общее сравнение (Event Sourcing) ────────────────────────
|
||||
document.getElementById('llmBtn').addEventListener('click', function() {
|
||||
if (!contractId) return;
|
||||
var btn = this;
|
||||
@@ -394,7 +442,7 @@ document.getElementById('llmBtn').addEventListener('click', function() {
|
||||
clearInterval(timerInterval);
|
||||
es.close();
|
||||
diffBody.innerHTML += '<div style="color:var(--destructive);margin-top:8px;">✗ ' + d.message + '</div>';
|
||||
btn.innerHTML = '<i data-lucide="scale" style="width:16px;height:16px;"></i> Сравнить';
|
||||
btn.innerHTML = '<i data-lucide="scale" style="width:16px;height:16px;"></i> Общее сравнение';
|
||||
btn.disabled = false;
|
||||
}
|
||||
};
|
||||
@@ -405,7 +453,7 @@ document.getElementById('llmBtn').addEventListener('click', function() {
|
||||
if (diffBody.innerHTML === '') {
|
||||
diffBody.innerHTML = '<div style="color:var(--destructive);">✗ Ошибка соединения</div>';
|
||||
}
|
||||
btn.innerHTML = '<i data-lucide="scale" style="width:16px;height:16px;"></i> Сравнить';
|
||||
btn.innerHTML = '<i data-lucide="scale" style="width:16px;height:16px;"></i> Общее сравнение';
|
||||
btn.disabled = false;
|
||||
lucide.createIcons();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user