diff --git a/index.cfm b/index.cfm index 88bd85c..de9d17d 100644 --- a/index.cfm +++ b/index.cfm @@ -64,7 +64,7 @@
Nubes - Сверка договоров v1.0.27 — Lucee + Сверка договоров v1.0.28 — Lucee
@@ -221,68 +221,98 @@ fileInput.addEventListener('change', function() { renderTable(); }); -// ── Загрузка (FileReader → base64 → JSON POST) ───────── +// ── Загрузка (FileReader → base64 → JSON POST все сразу) ─ uploadBtn.addEventListener('click', function() { if (fileQueue.length === 0) return; uploadBtn.disabled = true; uploadStartTime = Date.now(); uploadTimer.style.display = 'block'; - function uploadNext(i) { - if (i >= fileQueue.length) { - uploadTimer.style.display = 'none'; - uploadBtn.disabled = false; - if (contractId) { - document.getElementById('actionsCard').style.display = 'block'; - document.getElementById('chatCard').style.display = 'block'; - } - return; - } - var f = fileQueue[i]; - if (f.status === 'uploaded') { uploadNext(i + 1); return; } + // Читаем все файлы в base64 + var pending = fileQueue.filter(function(f) { return !f.doc_id; }); + var done = 0; + var payloads = []; + function readNext(i) { + if (i >= pending.length) { sendAll(); return; } + var f = pending[i]; f.status = 'читаю...'; renderTable(); - uploadTimer.textContent = 'Загрузка ' + (i+1) + '/' + fileQueue.length + '...'; - var reader = new FileReader(); reader.onload = function(e) { - var b64 = e.target.result.split(',')[1]; - var payload = {filename: f.name, data: b64}; - if (contractId) payload.contract_id = contractId; - - fetch('/upload.cfm', { - method: 'POST', - headers: {'Content-Type': 'application/json'}, - body: JSON.stringify(payload) - }).then(function(r) { return r.json(); }) - .then(function(r) { - if (r.OK) { - contractId = r.CONTRACT_ID; - f.doc_id = r.DOC_ID; - f.status = 'uploaded'; - var elapsed = ((Date.now() - uploadStartTime) / 1000).toFixed(1); - log('✅ ' + f.name + ' (' + formatSize(f.size) + ') — ' + elapsed + 'с'); - } else { - f.status = 'error: ' + (r.ERROR || 'неизв.'); - log('❌ ' + f.name + ': ' + (r.ERROR || '')); - } - renderTable(); - setTimeout(function() { uploadNext(i + 1); }, 300); - }).catch(function(e) { - f.status = 'error: ' + e.message; - renderTable(); - setTimeout(function() { uploadNext(i + 1); }, 300); - }); + payloads.push({filename: f.name, data: e.target.result.split(',')[1]}); + done++; + uploadTimer.textContent = 'Чтение ' + done + '/' + pending.length + '...'; + readNext(i + 1); }; reader.onerror = function() { f.status = 'error: чтение'; renderTable(); - uploadNext(i + 1); + readNext(i + 1); }; reader.readAsDataURL(f.file); } - uploadNext(0); + + function sendAll() { + if (payloads.length === 0) { + uploadTimer.style.display = 'none'; + uploadBtn.disabled = false; + return; + } + uploadTimer.textContent = 'Отправка ' + payloads.length + ' файлов...'; + var body = {files: payloads}; + if (contractId) body.contract_id = contractId; + + fetch('/upload.cfm', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify(body) + }).then(function(r) { return r.json(); }) + .then(function(data) { + uploadTimer.style.display = 'none'; + uploadBtn.disabled = false; + if (data.OK && data.RESULTS) { + for (var i = 0; i < data.RESULTS.length; i++) { + var r = data.RESULTS[i]; + // Найти файл в очереди по имени + for (var j = 0; j < fileQueue.length; j++) { + if (fileQueue[j].name === r.filename) { + if (r.OK) { + fileQueue[j].status = 'uploaded'; + fileQueue[j].doc_id = r.DOC_ID; + contractId = r.CONTRACT_ID || contractId; + log('✅ ' + r.filename + ' (' + formatSize(fileQueue[j].size) + ')'); + } else { + fileQueue[j].status = 'error: ' + (r.ERROR || ''); + log('❌ ' + r.filename + ': ' + (r.ERROR || '')); + } + } + } + } + } else { + log('❌ ' + (data.ERROR || 'неизв. ошибка')); + for (var i = 0; i < pending.length; i++) { + pending[i].status = 'error'; + } + } + renderTable(); + var hasErrors = fileQueue.some(function(f) { return f.status && f.status.indexOf('error') === 0; }); + if (contractId && !hasErrors) { + document.getElementById('actionsCard').style.display = 'block'; + document.getElementById('chatCard').style.display = 'block'; + } + }).catch(function(e) { + uploadTimer.style.display = 'none'; + uploadBtn.disabled = false; + log('❌ Сеть: ' + e.message); + for (var i = 0; i < pending.length; i++) { + pending[i].status = 'error: ' + e.message; + } + renderTable(); + }); + } + + readNext(0); }); // ── Инфо ────────────────────────────────────────────────── diff --git a/upload.cfm b/upload.cfm index 2cbaaad..866b2bc 100644 --- a/upload.cfm +++ b/upload.cfm @@ -13,21 +13,84 @@ - + - - - - - + + + + + - + #serializeJSON(result)# + + + + + + + + + + + + + + + + + + INSERT INTO documents (filename, mime_type, original_bytes, status) + VALUES ( + , + , + , + 'uploaded' + ) + + + SELECT id FROM documents + WHERE filename = + AND status = 'uploaded' ORDER BY created_at DESC LIMIT 1 + + + + + + + INSERT INTO contracts (number, client) VALUES ( + , '' + ) + + + SELECT id FROM contracts ORDER BY created_at DESC LIMIT 1 + + + + + + INSERT INTO supplements (contract_id, document_id, type) VALUES ( + , + , + + ) + + + + + + + + + + + #serializeJSON(result)# +