diff --git a/deploy/convert_server.py b/deploy/convert_server.py index 0744c92..bdc852f 100755 --- a/deploy/convert_server.py +++ b/deploy/convert_server.py @@ -119,6 +119,12 @@ class Handler(BaseHTTPRequestHandler): f"JOIN documents d ON s.document_id=d.id " f"WHERE s.contract_id='{cid}' AND d.elements_json IS NOT NULL ORDER BY s.created_at" ) + # Reorder if client specified &order=... + order_ids = (params.get("order", [None])[0] or "").strip() + if order_ids: + order_list = [x.strip() for x in order_ids.split(",") if x.strip()] + order_map = {oid: i for i, oid in enumerate(order_list)} + supps.sort(key=lambda s: order_map.get(s["id"], 999999)) if not supps: self._sse({"type": "error", "message": "Нет распарсенных файлов"}) return diff --git a/index.cfm b/index.cfm index 98b9190..252efd5 100644 --- a/index.cfm +++ b/index.cfm @@ -39,6 +39,10 @@ .info-btn { cursor: pointer; color: var(--muted); background: none; border: none; padding: 2px 4px; font-size: 14px; display: none; } .info-btn:hover { color: var(--brand-primary); } .info-btn.visible { display: inline; } + .first-row td { background: rgba(37,99,235,.06); font-weight: 600; } + .arrow-btn { cursor: pointer; color: var(--muted); background: none; border: none; padding: 2px; font-size: 12px; line-height: 1; } + .arrow-btn:hover { color: var(--brand-primary); } + .arrow-btn:disabled { opacity: .3; cursor: default; color: var(--muted); } .modal-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,.4); z-index: 100; justify-content: center; align-items: center; } .modal-overlay.open { display: flex; } .modal { background: var(--background); border-radius: 12px; border: 1px solid var(--brand-gray); box-shadow: 0 4px 24px rgba(0,0,0,.15); max-width: 520px; width: 90%; max-height: 80vh; display: flex; flex-direction: column; } @@ -71,7 +75,7 @@
Nubes - Сверка договоров — LLM AI-driven Event Sourcing v1.0.108 — Lucee + Сверка договоров — LLM AI-driven Event Sourcing v1.0.109 — Lucee
@@ -86,7 +90,7 @@
- +
ИмяИзменёнРазмерПарсингБазовыйТекст
ИмяИзменёнРазмерПарсингТекст
@@ -172,16 +176,16 @@ function renderTable() { fileTable.innerHTML = 'Нет файлов — выберите .docx / .pdf / .zip'; } else { fileTable.innerHTML = fileQueue.map(function(f, i) { - var radio = ''; - if (f.supp_id) { - radio = ''; - } - return '' + + var isFirst = (i === 0); + var isLast = (i === fileQueue.length - 1); + var arrows = '' + + ''; + return '' + '' + f.name + '' + '' + formatDate(f.lastModified) + '' + '' + formatSize(f.size) + '' + '' + (f.status || '') + '' + - '' + radio + '' + + '' + arrows + '' + '' + '' + ''; @@ -197,6 +201,19 @@ function removeFile(i) { } window.removeFile = removeFile; +function moveUp(i) { + if (i <= 0) return; + var tmp = fileQueue[i]; fileQueue[i] = fileQueue[i-1]; fileQueue[i-1] = tmp; + renderTable(); +} +function moveDown(i) { + if (i >= fileQueue.length - 1) return; + var tmp = fileQueue[i]; fileQueue[i] = fileQueue[i+1]; fileQueue[i+1] = tmp; + renderTable(); +} +window.moveUp = moveUp; +window.moveDown = moveDown; + // ── Автозагрузка при выборе файлов ────────────────────────── fileInput.addEventListener('change', async function() { var newFiles = Array.from(fileInput.files); @@ -337,7 +354,8 @@ document.getElementById('llmBtn').addEventListener('click', function() { diffStatus.textContent = '⏳ ' + ((Date.now() - llmStart) / 1000).toFixed(1) + 'с'; }, 200); - var es = new EventSource('https://contracts.kube5s.ru/process-v2?contract_id=' + contractId); + var order = fileQueue.map(function(f) { return f.supp_id; }).filter(Boolean).join(','); + var es = new EventSource('https://contracts.kube5s.ru/process-v2?contract_id=' + contractId + (order ? '&order=' + encodeURIComponent(order) : '')); var sections = {}; // supplement_id → DOM element es.onmessage = function(e) { @@ -444,12 +462,6 @@ async function refreshSupps() { } catch(e) { console.log('refreshSupps error:', e); } } -function setInitial(suppId) { - fetch('/api.cfm?action=set_initial&supplement_id=' + suppId) - .then(function() { refreshSupps(); }); -} -window.setInitial = setInitial; - // ── Чат ────────────────────────────────────────────────────── document.getElementById('chatSend').addEventListener('click', function() { var input = document.getElementById('chatInput');