v1.0.91: раскрывающиеся секции с дифф-таблицами в результатах сравнения
This commit is contained in:
@@ -208,7 +208,7 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
ar = apply_resp.json()
|
ar = apply_resp.json()
|
||||||
# Lucee serializeJSON → UPPERCASE keys
|
# Lucee serializeJSON → UPPERCASE keys
|
||||||
summary = {k.lower(): v for k, v in ar.get("SUMMARY", {}).items()}
|
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:
|
else:
|
||||||
self._sse({"type": "apply_error", "supplement_id": sid,
|
self._sse({"type": "apply_error", "supplement_id": sid,
|
||||||
"error": f"apply HTTP {apply_resp.status_code}"})
|
"error": f"apply HTTP {apply_resp.status_code}"})
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="topbar">
|
<div class="topbar">
|
||||||
<img src="/nubes-logo.svg" alt="Nubes">
|
<img src="/nubes-logo.svg" alt="Nubes">
|
||||||
<span class="title">Сверка договоров — LLM <span style="font-weight:400;color:var(--muted);font-size:12px;">v1.0.90 — Lucee</span></span>
|
<span class="title">Сверка договоров — LLM <span style="font-weight:400;color:var(--muted);font-size:12px;">v1.0.91 — Lucee</span></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@@ -338,19 +338,51 @@ document.getElementById('llmBtn').addEventListener('click', function() {
|
|||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
var es = new EventSource('https://contracts.kube5s.ru/process-v2?contract_id=' + contractId);
|
var es = new EventSource('https://contracts.kube5s.ru/process-v2?contract_id=' + contractId);
|
||||||
|
var sections = {}; // supplement_id → DOM element
|
||||||
|
|
||||||
es.onmessage = function(e) {
|
es.onmessage = function(e) {
|
||||||
var d = JSON.parse(e.data);
|
var d = JSON.parse(e.data);
|
||||||
|
|
||||||
if (d.type === 'extract_start') {
|
if (d.type === 'extract_start') {
|
||||||
diffBody.innerHTML += '<div style="font-size:12px;color:var(--muted);margin-top:2px;">⏳ ' + d.filename + ' → LLM...</div>';
|
var sec = document.createElement('div');
|
||||||
|
sec.style.cssText = 'margin-top:8px;border:1px solid var(--brand-gray);border-radius:6px;overflow:hidden;';
|
||||||
|
sec.innerHTML = '<div class="diff-section-header" style="padding:8px 12px;background:var(--brand-grey-light);cursor:pointer;font-size:13px;font-weight:600;">⏳ ' + d.filename + '</div><div class="diff-section-body" style="display:none;padding:8px 12px;"></div>';
|
||||||
|
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') {
|
else if (d.type === 'llm_done') {
|
||||||
diffBody.innerHTML += '<div style="font-size:12px;color:var(--green);">✓ ' + d.filename + ': ' + d.ops_count + ' операций, ' + d.mode + ' (' + d.time_s + 'с)</div>';
|
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') {
|
else if (d.type === 'applied') {
|
||||||
var s = d.summary || {};
|
var sec = sections[d.supplement_id];
|
||||||
diffBody.innerHTML += '<div style="font-size:12px;margin-left:8px;"> +' + (s.added||0) + ' ~' + (s.updated||0) + ' -' + (s.deleted||0) + ' ?' + (s.unresolved||0) + '</div>';
|
if (sec && d.ops && d.ops.length > 0) {
|
||||||
|
var s = d.summary || {};
|
||||||
|
var body = sec.querySelector('.diff-section-body');
|
||||||
|
var html = '<div style="font-size:12px;margin-bottom:6px;">+' + (s.added||0) + ' ~' + (s.updated||0) + ' -' + (s.deleted||0) + ' ?' + (s.unresolved||0) + '</div>';
|
||||||
|
html += '<div class="table-wrap"><table style="font-size:11px;"><thead><tr><th>Действие</th><th>Услуга</th><th>Цена</th><th>Кол-во</th><th>Сумма</th><th>Дата</th></tr></thead><tbody>';
|
||||||
|
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 += '<tr class="' + cls + '"><td>' + action + '</td><td>' + name + '</td><td class="num-cell">' + price + '</td><td class="num-cell">' + qty + '</td><td class="num-cell">' + sum + '</td><td>' + ds + '</td></tr>';
|
||||||
|
});
|
||||||
|
html += '</tbody></table></div>';
|
||||||
|
body.innerHTML = html;
|
||||||
|
body.style.display = 'block';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (d.type === 'extract_error' || d.type === 'apply_error') {
|
else if (d.type === 'extract_error' || d.type === 'apply_error') {
|
||||||
diffBody.innerHTML += '<div style="font-size:12px;color:var(--destructive);">✗ ' + d.filename + ': ' + d.error + '</div>';
|
diffBody.innerHTML += '<div style="font-size:12px;color:var(--destructive);">✗ ' + d.filename + ': ' + d.error + '</div>';
|
||||||
@@ -381,7 +413,7 @@ document.getElementById('llmBtn').addEventListener('click', function() {
|
|||||||
if (diffBody.innerHTML === '') {
|
if (diffBody.innerHTML === '') {
|
||||||
diffBody.innerHTML = '<div style="color:var(--destructive);">✗ Ошибка соединения</div>';
|
diffBody.innerHTML = '<div style="color:var(--destructive);">✗ Ошибка соединения</div>';
|
||||||
}
|
}
|
||||||
btn.innerHTML = '<i data-lucide="scale" style="width:16px;height:16px;"></i> Сравнить v2';
|
btn.innerHTML = '<i data-lucide="scale" style="width:16px;height:16px;"></i> Сравнить';
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
lucide.createIcons();
|
lucide.createIcons();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user