v1.0.178: унификация ZIP. addZipFile → base64→File→addRegularFile (единый путь). confirm() при дубликате. unzip.py — только распаковка, без БД.
This commit is contained in:
+18
-39
@@ -294,25 +294,21 @@ function applyParseResult(entry, parsed, elapsed) {
|
||||
}
|
||||
|
||||
/**
|
||||
* addZipFile(file) — Async-action: обработка ZIP-файла (Фаза 1).
|
||||
* addZipFile(file) — Async-action: обработка ZIP-файла (Фаза 1, упрощена).
|
||||
*
|
||||
* 1. Показывает временную строку «⏳ распаковка...»
|
||||
* 2. Отправляет ZIP на бэкенд (UNZIP_URL)
|
||||
* 3. Убирает временную строку
|
||||
* 4. Добавляет файлы из архива в state.files, пропуская дубликаты
|
||||
* 5. Для каждого: applyParseResult (результат парсинга от бэкенда)
|
||||
* 1. Отправляет ZIP на бэкенд (только распаковка, без БД/парсинга)
|
||||
* 2. Для каждого файла из архива: base64 → Blob → File → addRegularFile()
|
||||
*
|
||||
* Мутирует state.files, вызывает render(state) после каждого изменения.
|
||||
* addRegularFile делает ВСЁ: upload, parse, дубликаты, статусы, render.
|
||||
* Никакого дублирования логики — единый путь для обычных и ZIP-файлов.
|
||||
*/
|
||||
async function addZipFile(file) {
|
||||
// Показать временную строку для ZIP
|
||||
var zipEntry = { name: file.name, lastModified: file.lastModified, size: file.size, status: { kind: 'unzipping' } };
|
||||
state.files.push(zipEntry);
|
||||
var zipIdx = state.files.length - 1;
|
||||
render(state);
|
||||
|
||||
try {
|
||||
// Отправить ZIP на бэкенд (multipart — бэкенд ищет boundary + PK magic)
|
||||
var zipResp = await new Promise(function(resolve, reject) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', UNZIP_URL);
|
||||
@@ -331,42 +327,21 @@ async function addZipFile(file) {
|
||||
state.files.splice(zipIdx, 1);
|
||||
render(state);
|
||||
|
||||
// Добавить файлы из архива (дубликаты перезаписываются)
|
||||
// Каждый файл из архива — через addRegularFile (единый путь)
|
||||
for (var zi = 0; zi < zipResp.files.length; zi++) {
|
||||
var zf = zipResp.files[zi];
|
||||
if (zf.error) continue; // файл с ошибкой — пропускаем
|
||||
if (zf.error) continue;
|
||||
|
||||
var zEntry = {
|
||||
name: zf.filename, size: zf.size,
|
||||
doc_id: zf.doc_id, uploaded: true,
|
||||
status: { kind: 'parsing' }
|
||||
};
|
||||
// base64 → Blob → File
|
||||
var byteStr = atob(zf.data_b64);
|
||||
var bytes = new Uint8Array(byteStr.length);
|
||||
for (var b = 0; b < byteStr.length; b++) bytes[b] = byteStr.charCodeAt(b);
|
||||
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() });
|
||||
|
||||
// Проверить дубликат по имени
|
||||
var dup = -1;
|
||||
for (var dj = 0; dj < state.files.length; dj++) {
|
||||
if (state.files[dj].name === zf.filename) { dup = dj; break; }
|
||||
}
|
||||
|
||||
if (dup >= 0) {
|
||||
// Заменить существующий (как addRegularFile — перезапись)
|
||||
state.files[dup] = zEntry;
|
||||
} else {
|
||||
state.files.push(zEntry);
|
||||
dup = state.files.length - 1;
|
||||
}
|
||||
|
||||
// Если это первый файл — запомнить contract_id
|
||||
if (!state.contractId && zf.contract_id) state.contractId = zf.contract_id;
|
||||
render(state);
|
||||
|
||||
// Применить результат парсинга от бэкенда (clean function)
|
||||
applyParseResult(state.files[dup], zf.parsed);
|
||||
render(state);
|
||||
await addRegularFile(extractedFile);
|
||||
}
|
||||
} catch(ze) {
|
||||
// Ошибка распаковки — показать в строке ZIP
|
||||
console.error('addZipFile error:', ze, 'UNZIP_URL=', UNZIP_URL);
|
||||
state.files[zipIdx].status = { kind: 'error', text: 'ZIP: ' + ze.message };
|
||||
render(state);
|
||||
}
|
||||
@@ -393,6 +368,10 @@ async function addRegularFile(file) {
|
||||
}
|
||||
var rowIdx;
|
||||
if (existingIdx >= 0) {
|
||||
// Файл с таким именем уже есть — спросить пользователя
|
||||
if (!confirm('Файл «' + file.name + '» уже есть в списке.\n\nOK — перезаписать\nОтмена — пропустить')) {
|
||||
return; // пользователь выбрал «пропустить»
|
||||
}
|
||||
state.files[existingIdx] = entry;
|
||||
rowIdx = existingIdx;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user