index.coffee 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. # Добавление стилей компонента
  2. if globalThis.stylFns and globalThis.stylFns['app/components/Admin/MediaUpload/index.styl']
  3. styleElement = document.createElement('style')
  4. styleElement.type = 'text/css'
  5. styleElement.textContent = globalThis.stylFns['app/components/Admin/MediaUpload/index.styl']
  6. document.head.appendChild(styleElement)
  7. else
  8. log '⚠️ Стили MediaUpload не найдены'
  9. module.exports =
  10. name: 'media-upload'
  11. props:
  12. currentImage:
  13. type: String
  14. default: ''
  15. previewAlt:
  16. type: String
  17. default: 'Превью изображения'
  18. maxSize:
  19. type: Number
  20. default: 10485760 # 10MB
  21. data: ->
  22. {
  23. isDragging: false
  24. selectedFile: null
  25. uploading: false
  26. uploadProgress: 0
  27. }
  28. methods:
  29. onDragOver: (event) ->
  30. event.preventDefault()
  31. @isDragging = true
  32. onDragLeave: (event) ->
  33. event.preventDefault()
  34. @isDragging = false
  35. onDrop: (event) ->
  36. event.preventDefault()
  37. @isDragging = false
  38. files = Array.from(event.dataTransfer.files)
  39. @handleFiles(files)
  40. openFileDialog: ->
  41. @$refs.fileInput?.click()
  42. onFileSelect: (event) ->
  43. files = Array.from(event.target.files)
  44. @handleFiles(files)
  45. # Сброс input для возможности выбора того же файла снова
  46. event.target.value = ''
  47. handleFiles: (files) ->
  48. if files.length == 0
  49. return
  50. file = files[0]
  51. # Валидация типа файла
  52. if not file.type.startsWith('image/')
  53. @$emit('error', 'Выберите файл изображения')
  54. return
  55. # Валидация размера
  56. if file.size > @maxSize
  57. @$emit('error', 'Файл слишком большой. Максимальный размер: ' + (@maxSize / 1048576) + 'MB')
  58. return
  59. @selectedFile = file
  60. # Создание preview
  61. if URL and URL.createObjectURL
  62. previewUrl = URL.createObjectURL(file)
  63. @$emit('image-selected', previewUrl)
  64. # Начало загрузки
  65. @startUpload(file)
  66. startUpload: (file) ->
  67. @uploading = true
  68. @uploadProgress = 0
  69. # Имитация загрузки файла
  70. # В реальном приложении здесь будет загрузка на сервер
  71. interval = setInterval (=>
  72. @uploadProgress += 10
  73. if @uploadProgress >= 100
  74. clearInterval(interval)
  75. @uploading = false
  76. @$emit('upload-complete', {
  77. file: file
  78. url: URL.createObjectURL(file)
  79. name: file.name
  80. size: file.size
  81. type: file.type
  82. })
  83. ), 100
  84. removeImage: ->
  85. @selectedFile = null
  86. @uploadProgress = 0
  87. @$emit('image-removed')
  88. if @currentImage and URL and URL.revokeObjectURL
  89. URL.revokeObjectURL(@currentImage)
  90. formatFileSize: (bytes) ->
  91. if bytes == 0
  92. return '0 Bytes'
  93. k = 1024
  94. sizes = ['Bytes', 'KB', 'MB', 'GB']
  95. i = Math.floor(Math.log(bytes) / Math.log(k))
  96. return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
  97. beforeUnmount: ->
  98. # Очистка URL объектов при уничтожении компонента
  99. if @currentImage and URL and URL.revokeObjectURL
  100. URL.revokeObjectURL(@currentImage)
  101. render: (new Function '_ctx', '_cache', globalThis.renderFns['app/components/Admin/MediaUpload/index.pug'])()