|
|
@@ -6,23 +6,21 @@ class MediaFile extends DomainEntity
|
|
|
super()
|
|
|
@type = 'media_file'
|
|
|
@name = ''
|
|
|
- @filename = ''
|
|
|
@size = 0
|
|
|
@mimeType = ''
|
|
|
@url = ''
|
|
|
- @thumbnailUrl = ''
|
|
|
- @description = ''
|
|
|
+ @thumbnail = ''
|
|
|
+ @dimensions = {}
|
|
|
@tags = []
|
|
|
- @attachedTo = [] # Массив объектов, к которым прикреплен файл
|
|
|
|
|
|
class MediaService
|
|
|
constructor: ->
|
|
|
@pouchService = require 'app/utils/pouch'
|
|
|
+ @cache = new Map()
|
|
|
@initialized = false
|
|
|
|
|
|
init: ->
|
|
|
return Promise.resolve() if @initialized
|
|
|
-
|
|
|
try
|
|
|
await @pouchService.init()
|
|
|
@initialized = true
|
|
|
@@ -36,171 +34,46 @@ class MediaService
|
|
|
await @ensureInit()
|
|
|
|
|
|
try
|
|
|
- # Временная заглушка - возвращаем тестовые данные
|
|
|
- # В реальном приложении здесь будет запрос к PouchDB
|
|
|
- mockFiles = [
|
|
|
+ # Здесь будет реальная логика получения файлов из PouchDB
|
|
|
+ # Временная заглушка
|
|
|
+ return [
|
|
|
{
|
|
|
- _id: 'media_file:1'
|
|
|
+ _id: 'media_1'
|
|
|
name: 'product-image-1.jpg'
|
|
|
- filename: 'product-image-1.jpg'
|
|
|
+ type: 'image'
|
|
|
size: 1024000
|
|
|
- mimeType: 'image/jpeg'
|
|
|
- type: 'media_file'
|
|
|
- url: '/d/braer_color_shop/media_file:1/product-image-1.jpg'
|
|
|
- thumbnailUrl: '/d/braer_color_shop/media_file:1/thumb-product-image-1.jpg'
|
|
|
createdAt: new Date().toISOString()
|
|
|
- updatedAt: new Date().toISOString()
|
|
|
- domains: [window.location.hostname]
|
|
|
- active: true
|
|
|
}
|
|
|
{
|
|
|
- _id: 'media_file:2'
|
|
|
+ _id: 'media_2'
|
|
|
name: 'category-banner.png'
|
|
|
- filename: 'category-banner.png'
|
|
|
+ type: 'image'
|
|
|
size: 2048000
|
|
|
- mimeType: 'image/png'
|
|
|
- type: 'media_file'
|
|
|
- url: '/d/braer_color_shop/media_file:2/category-banner.png'
|
|
|
- thumbnailUrl: '/d/braer_color_shop/media_file:2/thumb-category-banner.png'
|
|
|
- createdAt: new Date(Date.now() - 86400000).toISOString()
|
|
|
- updatedAt: new Date(Date.now() - 86400000).toISOString()
|
|
|
- domains: [window.location.hostname]
|
|
|
- active: true
|
|
|
- }
|
|
|
- {
|
|
|
- _id: 'media_file:3'
|
|
|
- name: 'product-specification.pdf'
|
|
|
- filename: 'product-specification.pdf'
|
|
|
- size: 512000
|
|
|
- mimeType: 'application/pdf'
|
|
|
- type: 'media_file'
|
|
|
- url: '/d/braer_color_shop/media_file:3/product-specification.pdf'
|
|
|
- createdAt: new Date(Date.now() - 172800000).toISOString()
|
|
|
- updatedAt: new Date(Date.now() - 172800000).toISOString()
|
|
|
- domains: [window.location.hostname]
|
|
|
- active: true
|
|
|
+ createdAt: new Date().toISOString()
|
|
|
}
|
|
|
]
|
|
|
-
|
|
|
- # Фильтрация по опциям
|
|
|
- files = mockFiles
|
|
|
- if options.type
|
|
|
- files = files.filter (file) -> file.mimeType.startsWith(options.type)
|
|
|
-
|
|
|
- if options.search
|
|
|
- query = options.search.toLowerCase()
|
|
|
- files = files.filter (file) ->
|
|
|
- file.name.toLowerCase().includes(query) or
|
|
|
- file.filename.toLowerCase().includes(query)
|
|
|
-
|
|
|
- log '✅ Медиа-файлы загружены: '+files.length
|
|
|
- return files.map (file) -> new MediaFile(file)
|
|
|
-
|
|
|
catch error
|
|
|
- log '❌ Ошибка загрузки медиа-файлов: '+error.message
|
|
|
+ log '❌ Ошибка получения файлов: '+error.message
|
|
|
throw error
|
|
|
|
|
|
uploadFiles: (files) ->
|
|
|
await @ensureInit()
|
|
|
|
|
|
try
|
|
|
- log '🚀 Начало загрузки файлов: '+files.length
|
|
|
-
|
|
|
- uploadedFiles = []
|
|
|
-
|
|
|
- for file in files
|
|
|
- # Создание документа медиа-файла
|
|
|
- mediaFile = new MediaFile()
|
|
|
- mediaFile._id = 'media_file:'+Date.now()+'_'+Math.random().toString(36).substr(2, 9)
|
|
|
- mediaFile.name = file.name
|
|
|
- mediaFile.filename = file.name
|
|
|
- mediaFile.size = file.size
|
|
|
- mediaFile.mimeType = file.type
|
|
|
- mediaFile.domains = [window.location.hostname]
|
|
|
-
|
|
|
- # Определение типа файла
|
|
|
- if file.type.startsWith('image/')
|
|
|
- mediaFile.type = 'image'
|
|
|
- else if file.type.startsWith('application/')
|
|
|
- mediaFile.type = 'document'
|
|
|
- else
|
|
|
- mediaFile.type = 'other'
|
|
|
-
|
|
|
- # В реальном приложении здесь будет загрузка файла как attachment в PouchDB
|
|
|
- # await @pouchService.putAttachment(mediaFile._id, file.name, file, file.type)
|
|
|
-
|
|
|
- # Сохранение документа
|
|
|
- # await @pouchService.saveDocument(mediaFile)
|
|
|
-
|
|
|
- uploadedFiles.push(mediaFile)
|
|
|
- log '✅ Файл загружен: '+file.name
|
|
|
-
|
|
|
- log '🎉 Все файлы успешно загружены: '+uploadedFiles.length
|
|
|
- return uploadedFiles
|
|
|
-
|
|
|
+ log 'Начало загрузки '+files.length+' файлов'
|
|
|
+ # Здесь будет реальная логика загрузки в PouchDB attachments
|
|
|
+ return { success: true, files: files }
|
|
|
catch error
|
|
|
log '❌ Ошибка загрузки файлов: '+error.message
|
|
|
throw error
|
|
|
|
|
|
- uploadFile: (file) ->
|
|
|
- await @ensureInit()
|
|
|
-
|
|
|
- try
|
|
|
- log '📤 Загрузка файла: '+file.name
|
|
|
-
|
|
|
- # Создание документа медиа-файла
|
|
|
- mediaFile = new MediaFile()
|
|
|
- mediaFile._id = 'media_file:'+Date.now()+'_'+Math.random().toString(36).substr(2, 9)
|
|
|
- mediaFile.name = file.name
|
|
|
- mediaFile.filename = file.name
|
|
|
- mediaFile.size = file.size
|
|
|
- mediaFile.mimeType = file.type
|
|
|
- mediaFile.domains = [window.location.hostname]
|
|
|
-
|
|
|
- # Определение типа файла
|
|
|
- if file.type.startsWith('image/')
|
|
|
- mediaFile.type = 'image'
|
|
|
-
|
|
|
- # Создание thumbnail для изображений (в реальном приложении)
|
|
|
- mediaFile.thumbnailUrl = '/d/braer_color_shop/'+mediaFile._id+'/thumb-'+file.name
|
|
|
-
|
|
|
- else if file.type.startsWith('application/')
|
|
|
- mediaFile.type = 'document'
|
|
|
- else
|
|
|
- mediaFile.type = 'other'
|
|
|
-
|
|
|
- # В реальном приложении здесь будет:
|
|
|
- # 1. Загрузка файла как attachment в PouchDB
|
|
|
- # 2. Создание thumbnail для изображений
|
|
|
- # 3. Сохранение документа медиа-файла
|
|
|
-
|
|
|
- # await @pouchService.putAttachment(mediaFile._id, file.name, file, file.type)
|
|
|
- # await @pouchService.saveDocument(mediaFile)
|
|
|
-
|
|
|
- log '✅ Файл успешно загружен: '+file.name
|
|
|
- return mediaFile
|
|
|
-
|
|
|
- catch error
|
|
|
- log '❌ Ошибка загрузки файла: '+error.message
|
|
|
- throw error
|
|
|
-
|
|
|
deleteFile: (fileId) ->
|
|
|
await @ensureInit()
|
|
|
|
|
|
try
|
|
|
- log '🗑️ Удаление файла: '+fileId
|
|
|
-
|
|
|
- # В реальном приложении здесь будет:
|
|
|
- # 1. Получение документа
|
|
|
- # 2. Удаление attachments
|
|
|
- # 3. Удаление документа
|
|
|
-
|
|
|
- # const doc = await @pouchService.getDocument(fileId)
|
|
|
- # await @pouchService.removeDocument(doc)
|
|
|
-
|
|
|
- log '✅ Файл удален: '+fileId
|
|
|
- return true
|
|
|
-
|
|
|
+ log 'Удаление файла: '+fileId
|
|
|
+ # Здесь будет реальная логика удаления из PouchDB
|
|
|
+ return { success: true }
|
|
|
catch error
|
|
|
log '❌ Ошибка удаления файла: '+error.message
|
|
|
throw error
|
|
|
@@ -209,102 +82,22 @@ class MediaService
|
|
|
await @ensureInit()
|
|
|
|
|
|
try
|
|
|
- log '🗑️ Пакетное удаление файлов: '+fileIds.length
|
|
|
-
|
|
|
- results = []
|
|
|
- for fileId in fileIds
|
|
|
- try
|
|
|
- # await @deleteFile(fileId)
|
|
|
- results.push({ fileId: fileId, success: true })
|
|
|
- catch error
|
|
|
- results.push({ fileId: fileId, success: false, error: error.message })
|
|
|
-
|
|
|
- successCount = results.filter((r) -> r.success).length
|
|
|
- log '✅ Удалено файлов: '+successCount+' из '+fileIds.length
|
|
|
- return results
|
|
|
-
|
|
|
+ log 'Пакетное удаление файлов: '+fileIds.length
|
|
|
+ # Здесь будет реальная логика пакетного удаления
|
|
|
+ return { success: true }
|
|
|
catch error
|
|
|
log '❌ Ошибка пакетного удаления файлов: '+error.message
|
|
|
throw error
|
|
|
|
|
|
- getFileUrl: (fileId, filename) ->
|
|
|
- # Генерация URL для доступа к файлу в CouchDB
|
|
|
- return '/d/braer_color_shop/'+fileId+'/'+filename
|
|
|
+ getCachedFile: (fileId) ->
|
|
|
+ return @cache.get(fileId)
|
|
|
|
|
|
- getThumbnailUrl: (fileId, filename) ->
|
|
|
- # Генерация URL для thumbnail
|
|
|
- return '/d/braer_color_shop/'+fileId+'/thumb-'+filename
|
|
|
-
|
|
|
- attachFileToDocument: (fileId, targetDocId, targetType) ->
|
|
|
- await @ensureInit()
|
|
|
-
|
|
|
- try
|
|
|
- log '📎 Прикрепление файла '+fileId+' к документу '+targetDocId
|
|
|
-
|
|
|
- # Получение файла
|
|
|
- # const file = await @pouchService.getDocument(fileId)
|
|
|
-
|
|
|
- # Обновление списка прикрепленных документов
|
|
|
- # if not file.attachedTo
|
|
|
- # file.attachedTo = []
|
|
|
- #
|
|
|
- # file.attachedTo.push({
|
|
|
- # docId: targetDocId
|
|
|
- # type: targetType
|
|
|
- # attachedAt: new Date().toISOString()
|
|
|
- # })
|
|
|
- #
|
|
|
- # await @pouchService.saveDocument(file)
|
|
|
-
|
|
|
- log '✅ Файл прикреплен к документу'
|
|
|
- return true
|
|
|
-
|
|
|
- catch error
|
|
|
- log '❌ Ошибка прикрепления файла: '+error.message
|
|
|
- throw error
|
|
|
-
|
|
|
- detachFileFromDocument: (fileId, targetDocId) ->
|
|
|
- await @ensureInit()
|
|
|
-
|
|
|
- try
|
|
|
- log '📎 Открепление файла '+fileId+' от документа '+targetDocId
|
|
|
-
|
|
|
- # Получение файла
|
|
|
- # const file = await @pouchService.getDocument(fileId)
|
|
|
- #
|
|
|
- # if file.attachedTo
|
|
|
- # file.attachedTo = file.attachedTo.filter (attachment) ->
|
|
|
- # attachment.docId != targetDocId
|
|
|
- #
|
|
|
- # await @pouchService.saveDocument(file)
|
|
|
-
|
|
|
- log '✅ Файл откреплен от документа'
|
|
|
- return true
|
|
|
-
|
|
|
- catch error
|
|
|
- log '❌ Ошибка открепления файла: '+error.message
|
|
|
- throw error
|
|
|
-
|
|
|
- getFilesByDocument: (docId) ->
|
|
|
- await @ensureInit()
|
|
|
-
|
|
|
- try
|
|
|
- # В реальном приложении здесь будет запрос к PouchDB
|
|
|
- # для поиска файлов, прикрепленных к указанному документу
|
|
|
-
|
|
|
- # Временная заглушка
|
|
|
- allFiles = await @getAllFiles()
|
|
|
- # Фильтрация файлов, которые должны быть прикреплены к документу
|
|
|
- attachedFiles = allFiles.filter (file) ->
|
|
|
- file.attachedTo and file.attachedTo.some (attachment) ->
|
|
|
- attachment.docId == docId
|
|
|
-
|
|
|
- log '✅ Загружены файлы документа '+docId+': '+attachedFiles.length
|
|
|
- return attachedFiles
|
|
|
-
|
|
|
- catch error
|
|
|
- log '❌ Ошибка загрузки файлов документа: '+error.message
|
|
|
- throw error
|
|
|
+ setCachedFile: (fileId, fileData) ->
|
|
|
+ @cache.set(fileId, fileData)
|
|
|
+ # Автоматическое удаление из кэша через 5 минут
|
|
|
+ setTimeout (=>
|
|
|
+ @cache.delete(fileId)
|
|
|
+ ), 300000
|
|
|
|
|
|
ensureInit: ->
|
|
|
unless @initialized
|