Сервис отвечает за хранение и раздачу файлов/медиа, валидацию категорий и параметров, а также за сценарии «отложенной загрузки» через резервирование токенов (для загрузки файлов от 1С). Предоставляет низкоуровневые операции (пути/метаданные/удаление) и высокоуровневые (загрузка, резервирование, превью по конфигу).
GetFilePath(fileId): string - получить физический путь хранения.DeleteFile(fileId): void - удалить файл.ValidExistFile(fileId): bool - проверить существование файла.GetFileInfo(fileId): FileDescriptor - базовая информация по файлу.GetFileInfoByHashAndCategory(hash, category): FileDescriptor - получить файл по хэшу и категории (для дедупликации).GetFileConfig(category): FileImageConfig - конфигурация обработки/хранения для категории.UploadFile(category, stream): FileDescriptor - загрузить файл в указанную категорию, вернуть дескриптор.ValidExistFileAndCategoryAsync(filesIds, category): bool - проверить, что все файлы существуют и принадлежат категории.ReserveUploadFilesAsync(reserves[]): FileUploadReserve[] - зарезервировать параметры будущих файлов и выдать токены/идентификаторы резерва.QueryReservedFileAsync(reserveIds[]): FileDescriptor?[] - узнать, загружен ли файл по резервации.UploadReservedFileAsync(reserveTokenId, stream): FileDescriptor - загрузить файл по ранее выданному токену.FilesServiceConfig - корневые параметры: каталог хранилища и массив конфигов по категориям.FileImageConfig - правила обработки по категории: JPEG-качество, лимиты размеров/веса, ресайзы, набор превью, MIME, доступы. Также может содержать вложенные Previews - каскад настроек для генерации производных изображений.Ключевые поля FileImageConfig:
Quality - качество изображения при сохранении;ResizeToWidth / ResizeToHeight / MaxSideSize / ResizeToWH - правила изменения размеров (с приоритетами);MaxFileSize - ограничение размера исходного файла;Directory - подкаталог хранения для категории;Mime - ожидаемый MIME тип;Previews[] - список правил для генерации превью;Accesses[] - список доступов, которым разрешена работа с категорией (если используется контроль доступа на уровне медиа).В config.json (приложен к коду, как пример) заданы категории Product, UserIcon, Brand, Article, ArticleTile, Review - каждая со своими лимитами, директориями и превью:
Product: MaxSideSize: 2048, превью 256/512, Mime: image/jpeg.UserIcon: обрезка/ресайз до ResizeToWH: [512, 512].Article и ArticleTile: с Accesses: [100] (пример ограничения по доступам).Review: MaxSideSize: 1920 и превью 128x128.
Корневой каталог хранилища - FilesStorageDirectory: "filesstorage".FileDescriptorstring Id - идентификатор файла, он же название файла
string Hash - SHA256
string Category - категория файла
FileTypeEnum Type - тип файла (пока используется только Image = 1)
string Mime
DateTime Created
string Attributes - дополнительная информация о файле
FileUploadReserveМодель резервации: ReserveId, TokenId (для последующей загрузки), Category, FileId (заполняется, если файл уже загружен).
Используется для отложенной загрузки файла от мастер-системы.
[DirectoryService] --v
[Connector1CService] -> [FilesDirectoryService] -> [Static Files] <- [nginx] <-> PWA
^
[1C] --^
Для получения файла нужно знать его категорию и его Id. Балансировочный сервер настраивается на доступ к физическим файлам по ссылке (корневой каталог, который указан в конфиге)/(Название категории)/(ID файла). Таким образом можно обращаться напрямую к статике минуя сервисы.
UploadFile(category, stream) → 3) сервис валидирует MIME/размер/правила категории, применяет ресайз/качество, создаёт превью → 4) возвращает FileDescriptor (ID, MIME, Category и т. д.).ReserveUploadFilesAsyncUploadReservedFileAsync(token, stream);QueryReservedFileAsync(reserveIds);FileId становится доступным в модели резерва и можно его обновить у инициатора.Так Directory синхронизируя данные с мастер системой, может зарезервировать файлы на загрузку. В качестве TokenId указывается Id файла из мастер системы. Данные о товарах загружаются большим скопом и быстро, а файлы загружаются долго. Поэтому приходится резервировать место для файлов, чтобы мастер система могла потом сама загрузить нужные файлы в FilesDirectory, когда будет возможность. Directory по заданию опрашивает FilesDirectory на предмет загрузки зарезервированных файлов, и обновляет информацию у себя.
ValidExistFileAndCategoryAsync и GetFileInfoByHashAndCategory защищают от подмены категории/хэша и ошибок склейки.FileImageConfig с приоритетами правил ресайза (ширина → высота → max side → точный WH).Accesses[] доступ ограничивается доступами/ролями (пример - статьи/тайлы). Это позволяет хранить служебные медиа, недоступные обычным пользователям.Hash + Category позволяет повторно использовать уже загруженный файл.Если нужно, оформлю это как отдельный раздел в документе и добавлю таблицу категорий из config.json (категория → директория → лимиты → превью → доступы).
Содержит таблицы и индексы
-- Migration 1
files (
Id TEXT PRIMARY KEY NOT NULL,
Category TEXT NOT NULL DEFAULT '',
Path TEXT NOT NULL DEFAULT '', -- физический путь к файлу
Hash TEXT NOT NULL DEFAULT '',
Type INTEGER,
Mime TEXT NOT NULL DEFAULT '',
Created NUMBER,
CreatorId NUMBER,
Attributes TEXT);
reserves (
ReserveId INTEGER PRIMARY KEY AUTOINCREMENT,
TokenId TEXT NOT NULL DEFAULT '',
Category TEXT NOT NULL DEFAULT '',
FileId TEXT NOT NULL DEFAULT '');
INDEX files_hash on files (hash);