diff --git a/deploy/convert_server.py b/deploy/convert_server.py
index 9f092cb..04fabf4 100755
--- a/deploy/convert_server.py
+++ b/deploy/convert_server.py
@@ -208,7 +208,7 @@ class Handler(BaseHTTPRequestHandler):
ar = apply_resp.json()
# Lucee serializeJSON → UPPERCASE keys
summary = {k.lower(): v for k, v in ar.get("SUMMARY", {}).items()}
- self._sse({"type": "applied", "supplement_id": sid, "summary": summary})
+ self._sse({"type": "applied", "supplement_id": sid, "summary": summary, "ops": ops})
else:
self._sse({"type": "apply_error", "supplement_id": sid,
"error": f"apply HTTP {apply_resp.status_code}"})
diff --git a/index.cfm b/index.cfm
index 57426ab..45675c5 100644
--- a/index.cfm
+++ b/index.cfm
@@ -71,7 +71,7 @@
@@ -338,19 +338,51 @@ document.getElementById('llmBtn').addEventListener('click', function() {
}, 200);
var es = new EventSource('https://contracts.kube5s.ru/process-v2?contract_id=' + contractId);
+ var sections = {}; // supplement_id → DOM element
es.onmessage = function(e) {
var d = JSON.parse(e.data);
if (d.type === 'extract_start') {
- diffBody.innerHTML += '
⏳ ' + d.filename + ' → LLM...
';
+ var sec = document.createElement('div');
+ sec.style.cssText = 'margin-top:8px;border:1px solid var(--brand-gray);border-radius:6px;overflow:hidden;';
+ sec.innerHTML = '
';
+ sec.querySelector('.diff-section-header').addEventListener('click', function() {
+ var body = sec.querySelector('.diff-section-body');
+ body.style.display = body.style.display === 'none' ? 'block' : 'none';
+ });
+ diffBody.appendChild(sec);
+ sections[d.supplement_id] = sec;
}
else if (d.type === 'llm_done') {
- diffBody.innerHTML += '
✓ ' + d.filename + ': ' + d.ops_count + ' операций, ' + d.mode + ' (' + d.time_s + 'с)
';
+ var sec = sections[d.supplement_id];
+ if (sec) {
+ sec.querySelector('.diff-section-header').innerHTML = '✓ ' + d.filename + ' — ' + d.ops_count + ' оп., ' + d.mode + ' (' + d.time_s + 'с)';
+ sec.querySelector('.diff-section-header').style.color = 'var(--green)';
+ }
}
else if (d.type === 'applied') {
- var s = d.summary || {};
- diffBody.innerHTML += '
+' + (s.added||0) + ' ~' + (s.updated||0) + ' -' + (s.deleted||0) + ' ?' + (s.unresolved||0) + '
';
+ var sec = sections[d.supplement_id];
+ if (sec && d.ops && d.ops.length > 0) {
+ var s = d.summary || {};
+ var body = sec.querySelector('.diff-section-body');
+ var html = '
+' + (s.added||0) + ' ~' + (s.updated||0) + ' -' + (s.deleted||0) + ' ?' + (s.unresolved||0) + '
';
+ html += '
| Действие | Услуга | Цена | Кол-во | Сумма | Дата |
';
+ d.ops.forEach(function(op) {
+ var action = op.action;
+ var cls = action === 'ADD' ? 'diff-added' : action === 'DELETE' ? 'diff-deleted' : action === 'UPDATE' ? 'diff-changed' : '';
+ var nr = op.new_row || {};
+ var name = nr.name || '';
+ var price = nr.price != null ? nr.price : '';
+ var qty = nr.qty != null ? nr.qty : '';
+ var sum = nr.sum != null ? nr.sum : '';
+ var ds = nr.date_start || '';
+ html += '| ' + action + ' | ' + name + ' | ' + price + ' | ' + qty + ' | ' + sum + ' | ' + ds + ' |
';
+ });
+ html += '
';
+ body.innerHTML = html;
+ body.style.display = 'block';
+ }
}
else if (d.type === 'extract_error' || d.type === 'apply_error') {
diffBody.innerHTML += '
✗ ' + d.filename + ': ' + d.error + '
';
@@ -381,7 +413,7 @@ document.getElementById('llmBtn').addEventListener('click', function() {
if (diffBody.innerHTML === '') {
diffBody.innerHTML = '
✗ Ошибка соединения
';
}
- btn.innerHTML = '
Сравнить v2';
+ btn.innerHTML = '
Сравнить';
btn.disabled = false;
lucide.createIcons();
};