v1.0.178: zip_source — БД, Python, JS. Дедупликация по паре (zip_source, name). addZipFile передаёт имя архива.

This commit is contained in:
2026-06-26 09:48:18 +04:00
parent 08779c3938
commit 4e59c83699
5 changed files with 26 additions and 14 deletions
+10 -7
View File
@@ -170,7 +170,7 @@ window.toggleClassifyDetail = async function(i) {
* - Возвращает Promise<ответ API> с полями doc_id, contract_id, parsed
* - Таймаут 180с (большие PDF)
*/
function uploadFile(file, onProgress) {
function uploadFile(file, onProgress, zipSource) {
return new Promise(function(resolve, reject) {
// .doc → конвертация в docx (старый формат Word)
var isDoc = file.name.toLowerCase().endsWith('.doc') && !file.name.toLowerCase().endsWith('.docx');
@@ -183,6 +183,7 @@ function uploadFile(file, onProgress) {
fd.append('files', uploadFile, uploadName);
if (state.contractId) fd.append('contract_id', state.contractId);
fd.append('batch_id', state.batchId);
if (zipSource) fd.append('zip_source', zipSource);
xhr.open('POST', UPLOAD_URL);
xhr.upload.onprogress = function(e) {
if (e.lengthComputable && onProgress) onProgress(Math.round(e.loaded / e.total * 100));
@@ -340,7 +341,7 @@ async function addZipFile(file) {
var mime = {docx:'application/vnd.openxmlformats-officedocument.wordprocessingml.document',doc:'application/msword',pdf:'application/pdf'}[zf.ext] || 'application/octet-stream';
var extractedFile = new File([bytes], zf.filename, { type: mime, lastModified: Date.now() });
await addRegularFile(extractedFile);
await addRegularFile(extractedFile, file.name);
}
// Шаг 3: убрать временную строку ZIP (только после успешной обработки всех файлов)
@@ -365,14 +366,16 @@ async function addZipFile(file) {
*
* Мутирует state.files, вызывает render(state) после каждого изменения.
*/
async function addRegularFile(file) {
async function addRegularFile(file, zipSource) {
// Создать запись с начальным статусом
var entry = { name: file.name, lastModified: file.lastModified, size: file.size, file: file, status: { kind: 'uploading', pct: 0 } };
var entry = { name: file.name, lastModified: file.lastModified, size: file.size, file: file, status: { kind: 'uploading', pct: 0 }, zip_source: zipSource || null };
// Заменить существующий файл с тем же именем или добавить новый
// ДЕДУПЛИКАЦИЯ: ключ = (zip_source, name), чтобы одноимённые файлы из разных ZIP не затирались
var dupKey = (zipSource || '') + '/' + file.name;
var existingIdx = -1;
for (var j = 0; j < state.files.length; j++) {
if (state.files[j].name === file.name) { existingIdx = j; break; }
var ejKey = (state.files[j].zip_source || '') + '/' + state.files[j].name;
if (ejKey === dupKey) { existingIdx = j; break; }
}
var rowIdx;
if (existingIdx >= 0) {
@@ -393,7 +396,7 @@ async function addRegularFile(file) {
var resp = await uploadFile(file, function(pct) {
state.files[rowIdx].status = { kind: 'uploading', pct: pct };
render(state);
});
}, zipSource);
// Бэкенд возвращает doc_id и contract_id (нижний регистр — Python keys)
if (resp && resp.contract_id) state.contractId = resp.contract_id;
state.files[rowIdx].doc_id = resp.doc_id;