v1.0.177: сравнение внутри карточки группы, только одно одновременно

This commit is contained in:
2026-06-24 19:34:00 +04:00
parent c223fc04c0
commit 498bee90d8
+55 -19
View File
@@ -414,19 +414,40 @@ async function loadGroups() {
escHtml(d.filename) +
(d.doc_date ? ' <span style="color:var(--muted);">' + escHtml(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>';
}).join('') + '</div>' +
'<button class="btn btn-primary cmp-btn" style="margin-top:6px;font-size:12px;height:28px;" data-gi="' + gi + '">▶ Сравнить эту группу</button>' +
'<div class="cmp-body" id="cmpBody_' + gi + '" style="display:none;margin-top:8px;"></div>';
}
diffBody.appendChild(card);
});
// Один обработчик на все кнопки сравнения
diffBody.querySelectorAll('.cmp-btn').forEach(function(btn) {
btn.addEventListener('click', function() {
var gi = parseInt(this.getAttribute('data-gi'));
runCompareForGroup(gi, this);
});
});
lucide.createIcons();
}
window.runCompareForGroup = async function(gi) {
// Текущий активный EventSource (только один одновременно)
var _activeCompareES = null;
var _activeCompareTimer = null;
window.runCompareForGroup = async function(gi, btn) {
var group = window._groupsData[gi];
if (!group || group.contract_number === '__unresolved__') return;
var btn = event.target;
// Остановить предыдущее сравнение
if (_activeCompareES) { _activeCompareES.close(); _activeCompareES = null; }
if (_activeCompareTimer) { clearInterval(_activeCompareTimer); _activeCompareTimer = null; }
// Свернуть все раскрытые сравнения
document.querySelectorAll('.cmp-body').forEach(function(el) { el.style.display = 'none'; });
document.querySelectorAll('.cmp-btn').forEach(function(b) {
b.disabled = false; b.innerHTML = '▶ Сравнить эту группу';
});
btn.disabled = true;
btn.innerHTML = '<span class="spinner"></span> Применяю...';
@@ -441,23 +462,26 @@ window.runCompareForGroup = async function(gi) {
}
var cid = ad.contract_ids[0];
var cmpBody = document.getElementById('cmpBody_' + gi);
cmpBody.style.display = 'block';
cmpBody.innerHTML = '';
btn.innerHTML = '<span class="spinner"></span> Сравнение...';
stepActive('stepCompare');
var compareCard = document.getElementById('compareCard');
var compareBody = document.getElementById('compareBody');
var compareStatus = document.getElementById('compareStatus');
compareCard.style.display = 'block';
compareBody.innerHTML = '';
compareStatus.textContent = '⏳ 0.0с';
var statusEl = document.createElement('div');
statusEl.style.cssText = 'font-size:11px;color:var(--muted);margin-bottom:4px;';
statusEl.textContent = '⏳ 0.0с';
cmpBody.appendChild(statusEl);
var start = Date.now();
var timer = setInterval(function() {
compareStatus.textContent = '⏳ ' + ((Date.now() - start) / 1000).toFixed(1) + 'с';
_activeCompareTimer = setInterval(function() {
statusEl.textContent = '⏳ ' + ((Date.now() - start) / 1000).toFixed(1) + 'с';
}, 200);
var es = new EventSource(VM_API + '/process-v2?contract_id=' + cid);
_activeCompareES = es;
var sections = {};
es.onmessage = function(e) {
var d = JSON.parse(e.data);
@@ -469,7 +493,7 @@ window.runCompareForGroup = async function(gi) {
var body = sec.querySelector('.diff-section-body');
body.style.display = body.style.display === 'none' ? 'block' : 'none';
});
compareBody.appendChild(sec);
cmpBody.appendChild(sec);
sections[d.supplement_id] = sec;
}
else if (d.type === 'llm_done') {
@@ -497,18 +521,30 @@ window.runCompareForGroup = async function(gi) {
}
}
else if (d.type === 'done') {
clearInterval(timer); es.close();
compareStatus.textContent = '✓ ' + d.total_time_s + 'с';
btn.innerHTML = '✓ Готово'; btn.disabled = false;
clearInterval(_activeCompareTimer); _activeCompareTimer = null;
es.close(); _activeCompareES = null;
statusEl.textContent = '✓ ' + d.total_time_s + 'с';
statusEl.style.color = 'var(--green)';
btn.innerHTML = '✓ Готово (' + d.total_time_s + 'с)';
btn.style.background = 'var(--green)';
btn.style.color = '#fff';
btn.style.borderColor = 'var(--green)';
btn.style.cursor = 'default';
btn.disabled = false;
stepDone('stepCompare');
}
else if (d.type === 'error') {
clearInterval(timer); es.close();
compareBody.innerHTML += '<div style="color:var(--destructive);">✗ ' + d.message + '</div>';
clearInterval(_activeCompareTimer); _activeCompareTimer = null;
es.close(); _activeCompareES = null;
cmpBody.innerHTML += '<div style="color:var(--destructive);">✗ ' + d.message + '</div>';
btn.innerHTML = '✗'; btn.disabled = false;
}
};
es.onerror = function() { clearInterval(timer); es.close(); btn.innerHTML = '✗ соединение'; btn.disabled = false; };
es.onerror = function() {
clearInterval(_activeCompareTimer); _activeCompareTimer = null;
es.close(); _activeCompareES = null;
btn.innerHTML = '✗ соединение'; btn.disabled = false;
};
};
function uploadFile(file, onProgress) {