1
0

Добавлена загрузка rar, zip

1. Правка фронта
2. Правка бекенда
This commit is contained in:
2026-01-12 07:01:31 +07:00
parent 61c336b703
commit b4263bfe3f
5 changed files with 117 additions and 28 deletions

View File

@@ -144,7 +144,7 @@
<input
type="file"
ref="fileInput"
accept=".png,.jpg,.jpeg,image/png,image/jpeg"
accept=".png,.jpg,.jpeg,.zip,.rar,image/png,image/jpeg,application/zip,application/x-rar-compressed"
multiple
@change="handleFileSelect"
style="display: none"
@@ -189,8 +189,14 @@
<i data-lucide="x"></i>
</button>
</div>
<div class="file-thumbnail" @click="openImagePreview(file)">
<img :src="getFullUrl(file.preview)" :alt="file.name">
<div class="file-thumbnail" @click="!isArchive(file) && openImagePreview(file)">
<template v-if="isArchive(file)">
<div class="archive-icon">
<i data-lucide="archive"></i>
<span class="archive-ext">.{{ file.name.split('.').pop() }}</span>
</div>
</template>
<img v-else :src="getFullUrl(file.preview)" :alt="file.name">
</div>
</div>
@@ -274,7 +280,13 @@
<i data-lucide="x"></i>
</button>
</div>
<img :src="getFullUrl(previewImage.preview)" :alt="previewImage.name" class="image-preview-full">
<template v-if="isArchive(previewImage)">
<div class="archive-preview-icon">
<i data-lucide="archive"></i>
<span>{{ previewImage.name }}</span>
</div>
</template>
<img v-else :src="getFullUrl(previewImage.preview)" :alt="previewImage.name" class="image-preview-full">
<div class="image-preview-info">
<span class="preview-name">{{ previewImage.name }}</span>
<span class="preview-size">{{ formatFileSize(previewImage.size) }}</span>
@@ -335,9 +347,25 @@ const userSearch = ref('')
const attachedFiles = ref([])
const isDragging = ref(false)
const fileError = ref('')
const allowedTypes = ['image/png', 'image/jpeg', 'image/jpg']
const allowedExtensions = ['png', 'jpg', 'jpeg', 'zip', 'rar']
const archiveExtensions = ['zip', 'rar']
const maxFileSize = 10 * 1024 * 1024 // 10 MB
// Получить расширение файла
const getFileExt = (file) => {
return file.name?.split('.').pop()?.toLowerCase() || ''
}
// Проверка разрешён ли файл (по расширению)
const isAllowedFile = (file) => {
return allowedExtensions.includes(getFileExt(file))
}
// Проверка является ли файл архивом
const isArchive = (file) => {
return archiveExtensions.includes(getFileExt(file))
}
// Видимые файлы (без помеченных на удаление)
const visibleFiles = computed(() => attachedFiles.value.filter(f => !f.toDelete))
@@ -675,8 +703,8 @@ const processFiles = (files) => {
for (const file of files) {
// Проверка типа файла
if (!allowedTypes.includes(file.type)) {
fileError.value = `Файл "${file.name}" не поддерживается. Разрешены только PNG, JPEG, JPG.`
if (!isAllowedFile(file)) {
fileError.value = `Файл "${file.name}" не поддерживается. Разрешены: PNG, JPEG, JPG, ZIP, RAR.`
continue
}
@@ -1422,6 +1450,34 @@ onUpdated(refreshIcons)
object-fit: cover;
}
.archive-icon {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.05);
color: var(--text-secondary);
}
.archive-icon i {
width: 32px;
height: 32px;
opacity: 0.7;
}
.archive-ext {
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
margin-top: 4px;
opacity: 0.6;
}
.file-preview-item:hover .file-thumbnail {
opacity: 0.85;
}
@@ -1603,6 +1659,29 @@ onUpdated(refreshIcons)
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
.archive-preview-icon {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 16px;
padding: 60px;
background: var(--bg-card);
border-radius: 16px;
color: var(--text-secondary);
}
.archive-preview-icon i {
width: 64px;
height: 64px;
opacity: 0.6;
}
.archive-preview-icon span {
font-size: 14px;
font-weight: 500;
}
.image-preview-info {
display: flex;
align-items: center;