feat: render dossier timelines and exceptions

This commit is contained in:
Repinoid
2026-10-31 10:34:02 +03:00
parent 18730bf93e
commit 5d8d57797e
4 changed files with 212 additions and 2 deletions
+33 -2
View File
@@ -143,8 +143,32 @@ async function runClassify() {
// Poll progress каждые 2с — работает и для sync, и для async classify
var pollTimer = setInterval(async function() {
try {
var r = await fetch(VM_API + '/api/batch-progress?batch=' + state.batchId);
var progressUrl = state.v3Mode
? '/api/classify-progress?batch=' + encodeURIComponent(state.batchId)
: VM_API + '/api/batch-progress?batch=' + encodeURIComponent(state.batchId);
var r = await fetch(progressUrl);
var d = await r.json();
if (state.v3Mode && d.v3) {
var completed = d.done || 0;
var total = d.total || 0;
btn.innerHTML = '<span class="spinner"></span> Извлечение... ' + completed + '/' + total +
' (' + Math.round((Date.now() - start) / 1000) + 'с)';
if (d.finished) {
clearInterval(pollTimer);
clearInterval(timer);
classifyDone = true;
if (d.state === 'failed') {
btn.innerHTML = '✗ ' + escHtml(d.error || 'ошибка извлечения');
btn.disabled = false;
return;
}
btn.innerHTML = '✓ ' + completed + '/' + total + ' документов извлечено';
stepDone('stepClassify');
stepActive('stepGroups');
loadGroupsAction();
}
return;
}
if (d.ok && d.counts) {
var done = (d.counts.classified || 0)
+ (d.counts.failed || 0)
@@ -172,13 +196,20 @@ async function runClassify() {
body: JSON.stringify({batch_id: state.batchId})
});
var data = await resp.json();
state.v3Mode = Boolean(data.v3);
if (data.v3) state.v3Summary = data;
// sync classify: ответ уже содержит done
if (data.ok && data.done !== undefined) {
clearInterval(timer);
clearInterval(pollTimer);
classifyDone = true;
var summary = data.summary || (data.done + '/' + data.total + ' классифицировано');
var summary = data.v3
? data.done + '/' + data.total + ' извлечено; ' + (data.dossier_count || 0) + ' досье'
: data.summary || (data.done + '/' + data.total + ' классифицировано');
if (data.v3 && data.ignored_accounting) summary += ' | отсеяно: ' + data.ignored_accounting;
if (data.v3) summary += ' | арифметика: ' + data.math_checks_passed;
if (data.v3 && data.failed) summary += ' | ошибок: ' + data.failed;
if (data.garbage) summary += ' | 🗑️ ' + data.garbage + ' мусор';
if (data.types) summary += ' | ' + Object.entries(data.types).map(function(e){return e[1]+'×'+e[0];}).join(', ');
btn.innerHTML = '✓ ' + summary + ' (' + Math.round((Date.now() - start) / 1000) + 'с)';