MediaService.coffee 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. # app/services/MediaService.coffee
  2. { DomainEntity } = require 'app/types/data'
  3. class MediaFile extends DomainEntity
  4. constructor: ->
  5. super()
  6. @type = 'media_file'
  7. @name = ''
  8. @filename = ''
  9. @size = 0
  10. @mimeType = ''
  11. @url = ''
  12. @thumbnailUrl = ''
  13. @description = ''
  14. @tags = []
  15. @attachedTo = [] # Массив объектов, к которым прикреплен файл
  16. class MediaService
  17. constructor: ->
  18. @pouchService = require 'app/utils/pouch'
  19. @initialized = false
  20. init: ->
  21. return Promise.resolve() if @initialized
  22. try
  23. await @pouchService.init()
  24. @initialized = true
  25. log '✅ MediaService инициализирован'
  26. return Promise.resolve()
  27. catch error
  28. log '❌ Ошибка инициализации MediaService: '+error.message
  29. return Promise.reject(error)
  30. getAllFiles: (options = {}) ->
  31. await @ensureInit()
  32. try
  33. # Временная заглушка - возвращаем тестовые данные
  34. # В реальном приложении здесь будет запрос к PouchDB
  35. mockFiles = [
  36. {
  37. _id: 'media_file:1'
  38. name: 'product-image-1.jpg'
  39. filename: 'product-image-1.jpg'
  40. size: 1024000
  41. mimeType: 'image/jpeg'
  42. type: 'media_file'
  43. url: '/d/braer_color_shop/media_file:1/product-image-1.jpg'
  44. thumbnailUrl: '/d/braer_color_shop/media_file:1/thumb-product-image-1.jpg'
  45. createdAt: new Date().toISOString()
  46. updatedAt: new Date().toISOString()
  47. domains: [window.location.hostname]
  48. active: true
  49. }
  50. {
  51. _id: 'media_file:2'
  52. name: 'category-banner.png'
  53. filename: 'category-banner.png'
  54. size: 2048000
  55. mimeType: 'image/png'
  56. type: 'media_file'
  57. url: '/d/braer_color_shop/media_file:2/category-banner.png'
  58. thumbnailUrl: '/d/braer_color_shop/media_file:2/thumb-category-banner.png'
  59. createdAt: new Date(Date.now() - 86400000).toISOString()
  60. updatedAt: new Date(Date.now() - 86400000).toISOString()
  61. domains: [window.location.hostname]
  62. active: true
  63. }
  64. {
  65. _id: 'media_file:3'
  66. name: 'product-specification.pdf'
  67. filename: 'product-specification.pdf'
  68. size: 512000
  69. mimeType: 'application/pdf'
  70. type: 'media_file'
  71. url: '/d/braer_color_shop/media_file:3/product-specification.pdf'
  72. createdAt: new Date(Date.now() - 172800000).toISOString()
  73. updatedAt: new Date(Date.now() - 172800000).toISOString()
  74. domains: [window.location.hostname]
  75. active: true
  76. }
  77. ]
  78. # Фильтрация по опциям
  79. files = mockFiles
  80. if options.type
  81. files = files.filter (file) -> file.mimeType.startsWith(options.type)
  82. if options.search
  83. query = options.search.toLowerCase()
  84. files = files.filter (file) ->
  85. file.name.toLowerCase().includes(query) or
  86. file.filename.toLowerCase().includes(query)
  87. log '✅ Медиа-файлы загружены: '+files.length
  88. return files.map (file) -> new MediaFile(file)
  89. catch error
  90. log '❌ Ошибка загрузки медиа-файлов: '+error.message
  91. throw error
  92. uploadFiles: (files) ->
  93. await @ensureInit()
  94. try
  95. log '🚀 Начало загрузки файлов: '+files.length
  96. uploadedFiles = []
  97. for file in files
  98. # Создание документа медиа-файла
  99. mediaFile = new MediaFile()
  100. mediaFile._id = 'media_file:'+Date.now()+'_'+Math.random().toString(36).substr(2, 9)
  101. mediaFile.name = file.name
  102. mediaFile.filename = file.name
  103. mediaFile.size = file.size
  104. mediaFile.mimeType = file.type
  105. mediaFile.domains = [window.location.hostname]
  106. # Определение типа файла
  107. if file.type.startsWith('image/')
  108. mediaFile.type = 'image'
  109. else if file.type.startsWith('application/')
  110. mediaFile.type = 'document'
  111. else
  112. mediaFile.type = 'other'
  113. # В реальном приложении здесь будет загрузка файла как attachment в PouchDB
  114. # await @pouchService.putAttachment(mediaFile._id, file.name, file, file.type)
  115. # Сохранение документа
  116. # await @pouchService.saveDocument(mediaFile)
  117. uploadedFiles.push(mediaFile)
  118. log '✅ Файл загружен: '+file.name
  119. log '🎉 Все файлы успешно загружены: '+uploadedFiles.length
  120. return uploadedFiles
  121. catch error
  122. log '❌ Ошибка загрузки файлов: '+error.message
  123. throw error
  124. uploadFile: (file) ->
  125. await @ensureInit()
  126. try
  127. log '📤 Загрузка файла: '+file.name
  128. # Создание документа медиа-файла
  129. mediaFile = new MediaFile()
  130. mediaFile._id = 'media_file:'+Date.now()+'_'+Math.random().toString(36).substr(2, 9)
  131. mediaFile.name = file.name
  132. mediaFile.filename = file.name
  133. mediaFile.size = file.size
  134. mediaFile.mimeType = file.type
  135. mediaFile.domains = [window.location.hostname]
  136. # Определение типа файла
  137. if file.type.startsWith('image/')
  138. mediaFile.type = 'image'
  139. # Создание thumbnail для изображений (в реальном приложении)
  140. mediaFile.thumbnailUrl = '/d/braer_color_shop/'+mediaFile._id+'/thumb-'+file.name
  141. else if file.type.startsWith('application/')
  142. mediaFile.type = 'document'
  143. else
  144. mediaFile.type = 'other'
  145. # В реальном приложении здесь будет:
  146. # 1. Загрузка файла как attachment в PouchDB
  147. # 2. Создание thumbnail для изображений
  148. # 3. Сохранение документа медиа-файла
  149. # await @pouchService.putAttachment(mediaFile._id, file.name, file, file.type)
  150. # await @pouchService.saveDocument(mediaFile)
  151. log '✅ Файл успешно загружен: '+file.name
  152. return mediaFile
  153. catch error
  154. log '❌ Ошибка загрузки файла: '+error.message
  155. throw error
  156. deleteFile: (fileId) ->
  157. await @ensureInit()
  158. try
  159. log '🗑️ Удаление файла: '+fileId
  160. # В реальном приложении здесь будет:
  161. # 1. Получение документа
  162. # 2. Удаление attachments
  163. # 3. Удаление документа
  164. # const doc = await @pouchService.getDocument(fileId)
  165. # await @pouchService.removeDocument(doc)
  166. log '✅ Файл удален: '+fileId
  167. return true
  168. catch error
  169. log '❌ Ошибка удаления файла: '+error.message
  170. throw error
  171. deleteFiles: (fileIds) ->
  172. await @ensureInit()
  173. try
  174. log '🗑️ Пакетное удаление файлов: '+fileIds.length
  175. results = []
  176. for fileId in fileIds
  177. try
  178. # await @deleteFile(fileId)
  179. results.push({ fileId: fileId, success: true })
  180. catch error
  181. results.push({ fileId: fileId, success: false, error: error.message })
  182. successCount = results.filter((r) -> r.success).length
  183. log '✅ Удалено файлов: '+successCount+' из '+fileIds.length
  184. return results
  185. catch error
  186. log '❌ Ошибка пакетного удаления файлов: '+error.message
  187. throw error
  188. getFileUrl: (fileId, filename) ->
  189. # Генерация URL для доступа к файлу в CouchDB
  190. return '/d/braer_color_shop/'+fileId+'/'+filename
  191. getThumbnailUrl: (fileId, filename) ->
  192. # Генерация URL для thumbnail
  193. return '/d/braer_color_shop/'+fileId+'/thumb-'+filename
  194. attachFileToDocument: (fileId, targetDocId, targetType) ->
  195. await @ensureInit()
  196. try
  197. log '📎 Прикрепление файла '+fileId+' к документу '+targetDocId
  198. # Получение файла
  199. # const file = await @pouchService.getDocument(fileId)
  200. # Обновление списка прикрепленных документов
  201. # if not file.attachedTo
  202. # file.attachedTo = []
  203. #
  204. # file.attachedTo.push({
  205. # docId: targetDocId
  206. # type: targetType
  207. # attachedAt: new Date().toISOString()
  208. # })
  209. #
  210. # await @pouchService.saveDocument(file)
  211. log '✅ Файл прикреплен к документу'
  212. return true
  213. catch error
  214. log '❌ Ошибка прикрепления файла: '+error.message
  215. throw error
  216. detachFileFromDocument: (fileId, targetDocId) ->
  217. await @ensureInit()
  218. try
  219. log '📎 Открепление файла '+fileId+' от документа '+targetDocId
  220. # Получение файла
  221. # const file = await @pouchService.getDocument(fileId)
  222. #
  223. # if file.attachedTo
  224. # file.attachedTo = file.attachedTo.filter (attachment) ->
  225. # attachment.docId != targetDocId
  226. #
  227. # await @pouchService.saveDocument(file)
  228. log '✅ Файл откреплен от документа'
  229. return true
  230. catch error
  231. log '❌ Ошибка открепления файла: '+error.message
  232. throw error
  233. getFilesByDocument: (docId) ->
  234. await @ensureInit()
  235. try
  236. # В реальном приложении здесь будет запрос к PouchDB
  237. # для поиска файлов, прикрепленных к указанному документу
  238. # Временная заглушка
  239. allFiles = await @getAllFiles()
  240. # Фильтрация файлов, которые должны быть прикреплены к документу
  241. attachedFiles = allFiles.filter (file) ->
  242. file.attachedTo and file.attachedTo.some (attachment) ->
  243. attachment.docId == docId
  244. log '✅ Загружены файлы документа '+docId+': '+attachedFiles.length
  245. return attachedFiles
  246. catch error
  247. log '❌ Ошибка загрузки файлов документа: '+error.message
  248. throw error
  249. ensureInit: ->
  250. unless @initialized
  251. throw new Error('MediaService не инициализирован. Вызовите init() сначала.')
  252. module.exports = new MediaService()