- копирую модуль upload/ из drhider (слои 1-2) - blueprint: параметр sink (drhider-сессия по умолчанию, сверка — DB+парсинг) - upload_bp: contracts_upload_sink = _store_and_parse - routes: регистрирую create_upload_refs_blueprint(cfg, sink=...) - app.py: корень репо в sys.path (для import upload) - History: план переиспользования + ревью Соннета
57 lines
2.6 KiB
JavaScript
57 lines
2.6 KiB
JavaScript
// Обработчик <input type="file" multiple> change: дедуп + раскрытие ZIP + фильтр.
|
|
// Экспортируется и чистая логика добавления массива файлов (addFiles),
|
|
// и фабрика обработчика для input (makeFilesChangeHandler).
|
|
|
|
import { listZipFiles } from '../zip/list_zip_files.js';
|
|
import { addFileWithDedup } from './add_file_with_dedup.js';
|
|
import { render } from './render.js';
|
|
|
|
// Добавить массив файлов в список (дедуп + раскрытие ZIP + лимиты).
|
|
// files: File[]. els.fileInput — для синхронизации input.files (DataTransfer),
|
|
// чтобы повторный выбор того же файла сработал. onStatus(cls, text) — колбэк сообщений.
|
|
export async function addFiles(state, cfg, files, els, onStatus) {
|
|
const incoming = Array.from(files);
|
|
const hasZip = incoming.some(f => f.name.toLowerCase().endsWith('.zip'));
|
|
if (hasZip) {
|
|
document.body.style.cursor = 'wait';
|
|
if (onStatus) onStatus('progress', 'Разбираю архивы…');
|
|
}
|
|
try {
|
|
for (const f of incoming) {
|
|
if (f.name.toLowerCase().endsWith('.zip')) {
|
|
try {
|
|
const nested = await listZipFiles(f, cfg.allowedExt);
|
|
if (nested.length) nested.forEach(x => addFileWithDedup(state, x, cfg));
|
|
else addFileWithDedup(state, f, cfg); // в архиве нет документов — архив как есть
|
|
} catch (err) {
|
|
addFileWithDedup(state, f, cfg); // не удалось распаковать — zip как есть
|
|
}
|
|
} else {
|
|
addFileWithDedup(state, f, cfg);
|
|
}
|
|
}
|
|
} finally {
|
|
if (hasZip) {
|
|
document.body.style.cursor = '';
|
|
if (onStatus) onStatus('', '');
|
|
}
|
|
}
|
|
// Синхронизировать input.files — чтобы повторный выбор того же файла сработал
|
|
if (els && els.fileInput && els.fileInput.files) {
|
|
const d = new DataTransfer();
|
|
state.files.forEach(f => d.items.add(f));
|
|
els.fileInput.files = d.files;
|
|
}
|
|
render(state, els, cfg);
|
|
}
|
|
|
|
// Фабрика обработчика change для <input type="file">.
|
|
// ctx = { state, cfg, els, onStatus }
|
|
export function makeFilesChangeHandler(ctx) {
|
|
const { state, cfg, els, onStatus } = ctx;
|
|
return () => {
|
|
if (state.busy) return; // во время загрузки/обработки менять список нельзя
|
|
addFiles(state, cfg, els.fileInput.files, els, onStatus);
|
|
};
|
|
}
|