diff --git a/deploy/app.js b/deploy/app.js index 5d60219..86b5e0d 100644 --- a/deploy/app.js +++ b/deploy/app.js @@ -11,6 +11,7 @@ var fileInput = document.getElementById('fileInput'); var fileTable = document.getElementById('fileTable'); var fileQueue = []; var contractId = null; +var batchId = crypto.randomUUID(); // классификация: привязка всех файлов сессии function formatSize(bytes) { if (!bytes || bytes === 0) return '—'; @@ -207,13 +208,94 @@ fileInput.addEventListener('change', async function() { fileInput.value = ''; fileInput.disabled = false; - // Показать кнопки LLM после авто-парсинга + // Показать кнопки после авто-парсинга var llmBtn = document.getElementById('llmBtn'); llmBtn.style.display = 'flex'; llmBtn.disabled = false; + showClassifyBtn(); lucide.createIcons(); }); +// ── Классификация ────────────────────────────────────────── +function showClassifyBtn() { + var btn = document.getElementById('classifyBtn'); + if (!btn) { + btn = document.createElement('button'); + btn.id = 'classifyBtn'; + btn.className = 'btn btn-primary'; + btn.style.cssText = 'width:100%;justify-content:center;margin-top:8px;background:var(--brand-primary);border-color:var(--brand-primary);'; + btn.innerHTML = ' Классифицировать'; + btn.addEventListener('click', runClassify); + document.getElementById('llmBtn').parentNode.insertBefore(btn, document.getElementById('llmBtn')); + } + btn.style.display = 'flex'; + btn.disabled = false; +} + +async function runClassify() { + var btn = document.getElementById('classifyBtn'); + btn.disabled = true; + btn.innerHTML = ' Классификация...'; + + try { + var resp = await fetch(VM_API + '/api/classify-batch', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({batch_id: batchId}) + }); + var data = await resp.json(); + if (data.ok) { + btn.innerHTML = '✓ ' + data.done + '/' + data.total + ' классифицировано'; + loadGroups(); + } else { + btn.innerHTML = '✗ ' + (data.error || 'ошибка'); + btn.disabled = false; + } + } catch(e) { + btn.innerHTML = '✗ ' + e.message; + btn.disabled = false; + } +} + +async function loadGroups() { + var resp = await fetch(VM_API + '/api/groups?batch=' + batchId); + var data = await resp.json(); + if (!data.ok || !data.groups) return; + + var diffBody = document.getElementById('diffBody'); + var diffCard = document.getElementById('diffCard'); + diffCard.style.display = 'block'; + diffBody.innerHTML = '