From fbcf49a3a642ab6877da8590ce203be493a5c564 Mon Sep 17 00:00:00 2001 From: 107 <107@DESKTOP-UP8U7M2> Date: Fri, 23 May 2025 13:01:57 +0700 Subject: [PATCH] =?UTF-8?q?=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B8=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D0=B8=20=D1=84=D0=BE=D1=82?= =?UTF-8?q?=D0=BE=20=D0=BF=D1=80=D0=BE=D1=84=D0=B8=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/EditProfileForm.vue | 245 +++++++++-------------------- src/views/ProfileView.vue | 26 ++- 2 files changed, 96 insertions(+), 175 deletions(-) diff --git a/src/components/EditProfileForm.vue b/src/components/EditProfileForm.vue index f878c78..1209e63 100644 --- a/src/components/EditProfileForm.vue +++ b/src/components/EditProfileForm.vue @@ -2,12 +2,10 @@
-
-

- ✏️ +

✏️ Редактирование профиля

-

Обновите информацию о себе и добавьте новые фотографии

+

Обновите основную информацию о себе

@@ -163,107 +161,7 @@ Сохранить изменения
- -
- - -
-
-

- 📸 - Загрузка фотографий -

-

Добавьте новые фотографии в свой профиль

-
- -
- -
- -
- - -
-

- 📋 - Выбранные файлы ({{ selectedFiles.length }}) -

-
-
-
- 🖼️ - {{ file.name }} - {{ formatFileSize(file.size) }} -
-
-
-
- - -
-
- - - - ⏸️ - {{ message.message }} -
-
- - -
- - {{ photoUploadSuccessMessage }} -
-
- - {{ photoUploadErrorMessage }} -
- - - -
-
+ @@ -275,6 +173,7 @@ import api from '@/services/api'; import imageCompression from 'browser-image-compression'; import russianCities from '@/assets/russian-cities.json'; // Импортируем список городов +const emit = defineEmits(['profile-updated', 'photo-upload-complete']); const { user, fetchUser } = useAuth(); const formData = ref({ @@ -503,80 +402,82 @@ const onFilesSelected = (event) => { } }; -// Обновляем handlePhotoUpload для загрузки нескольких файлов последовательно -const handleMultiplePhotoUpload = async () => { - if (selectedFiles.value.length === 0) { - photoUploadErrorMessage.value = 'Пожалуйста, выберите файлы для загрузки.'; - // Очистим индивидуальные сообщения, если они были - photoUploadMessages.value.forEach(msg => { - if (msg.status === 'pending') msg.status = 'cancelled'; - }); +// Метод для загрузки фото, вызываемый из родительского компонента ProfileView +const handlePhotoUpload = async (files) => { + if (!files || files.length === 0) { + console.log('[EditProfileForm] handlePhotoUpload: нет файлов для загрузки'); return; } - photoLoading.value = true; // Общий индикатор загрузки - photoUploadErrorMessage.value = ''; // Сбрасываем общую ошибку - - for (let i = 0; i < selectedFiles.value.length; i++) { - const originalFile = selectedFiles.value[i]; - const fileMessageIndex = photoUploadMessages.value.findIndex(m => m.name === originalFile.name && m.status !== 'success'); - - if (fileMessageIndex === -1) continue; - - photoUploadMessages.value[fileMessageIndex].status = 'uploading'; - photoUploadMessages.value[fileMessageIndex].message = 'Сжатие и загрузка...'; - - try { - // Опции сжатия - const options = { - maxSizeMB: 1, // Максимальный размер файла в MB - maxWidthOrHeight: 1920, // Максимальная ширина или высота - useWebWorker: true, // Использовать Web Worker для лучшей производительности - // Дополнительные опции можно найти в документации библиотеки - // Например, initialQuality для JPEG - } + console.log(`[EditProfileForm] handlePhotoUpload: получено файлов: ${files.length}`); + + // Индикатор для отслеживания успешных загрузок + let successCount = 0; + let errorCount = 0; + photoLoading.value = true; + photoUploadErrorMessage.value = ''; + photoUploadSuccessMessage.value = ''; + + // Настройки для сжатия изображений + const options = { + maxSizeMB: 1, + maxWidthOrHeight: 1920, + useWebWorker: true, + }; + + try { + for (let i = 0; i < files.length; i++) { + const originalFile = files[i]; - console.log(`[EditProfileForm] Сжатие файла ${originalFile.name}...`); - const compressedFile = await imageCompression(originalFile, options); - console.log(`[EditProfileForm] Файл ${originalFile.name} сжат. Оригинальный размер: ${(originalFile.size / 1024 / 1024).toFixed(2)} MB, Новый размер: ${(compressedFile.size / 1024 / 1024).toFixed(2)} MB`); - - const fd = new FormData(); - // Важно: сервер ожидает имя файла, поэтому передаем его как третий аргумент - fd.append('profilePhoto', compressedFile, originalFile.name); - - console.log(`[EditProfileForm] Отправка файла ${originalFile.name} (сжатого) на сервер...`); - const response = await api.uploadUserProfilePhoto(fd); - console.log(`[EditProfileForm] Ответ от сервера (фото ${originalFile.name}):`, response.data); - - photoUploadMessages.value[fileMessageIndex].status = 'success'; - photoUploadMessages.value[fileMessageIndex].message = response.data.message || 'Фото успешно загружено!'; - - await fetchUser(); - console.log(`[EditProfileForm] Данные пользователя обновлены (фото ${originalFile.name})`); - - } catch (err) { - console.error(`[EditProfileForm] Ошибка при сжатии или загрузке фото ${originalFile.name}:`, err); - photoUploadMessages.value[fileMessageIndex].status = 'error'; - // Проверяем, является ли ошибка ошибкой сжатия - if (err instanceof Error && err.message.includes('compression')) { - photoUploadMessages.value[fileMessageIndex].message = `Ошибка при сжатии фото ${originalFile.name}.`; - } else { - photoUploadMessages.value[fileMessageIndex].message = (err.response && err.response.data && err.response.data.message) - ? err.response.data.message - : `Ошибка при загрузке фото ${originalFile.name}.`; + try { + // Сжимаем файл + console.log(`[EditProfileForm] Сжатие файла ${originalFile.name}...`); + const compressedFile = await imageCompression(originalFile, options); + console.log(`[EditProfileForm] Файл ${originalFile.name} сжат. Оригинальный размер: ${(originalFile.size / 1024 / 1024).toFixed(2)} MB, Новый размер: ${(compressedFile.size / 1024 / 1024).toFixed(2)} MB`); + + // Создаем FormData для отправки на сервер + const fd = new FormData(); + fd.append('profilePhoto', compressedFile, originalFile.name); + + // Отправляем файл + console.log(`[EditProfileForm] Отправка файла ${originalFile.name} (сжатого) на сервер...`); + const response = await api.uploadUserProfilePhoto(fd); + console.log(`[EditProfileForm] Ответ сервера (фото ${originalFile.name}):`, response.data); + + // Увеличиваем счетчик успешных загрузок + successCount++; + + // Обновляем данные пользователя после каждой успешной загрузки + await fetchUser(); + console.log(`[EditProfileForm] Данные пользователя обновлены после загрузки фото ${originalFile.name}`); + + } catch (err) { + console.error(`[EditProfileForm] Ошибка при сжатии или загрузке фото ${originalFile.name}:`, err); + errorCount++; } } + + // Формируем сообщение для пользователя + if (successCount > 0) { + photoUploadSuccessMessage.value = `Успешно загружено фотографий: ${successCount}`; + console.log(`[EditProfileForm] Успешно загружено фотографий: ${successCount}`); + + // Автоматически скрываем сообщение через 3 секунды + setTimeout(() => { + photoUploadSuccessMessage.value = ''; + }, 3000); + } + + if (errorCount > 0) { + photoUploadErrorMessage.value = `Не удалось загрузить некоторые фото (${errorCount})`; + console.log(`[EditProfileForm] Ошибок при загрузке: ${errorCount}`); + } + + // Отправляем событие родителю + emit('photo-upload-complete', { success: successCount, errors: errorCount }); + } finally { + photoLoading.value = false; } - - // После завершения всех загрузок - selectedFiles.value = []; // Очищаем выбранные файлы - // Не очищаем photoInput.value здесь, т.к. input type="file" multiple сам управляет списком - // Можно сбросить значение инпута, чтобы пользователь мог выбрать те же файлы снова, если захочет - const photoInput = document.getElementById('profilePhotos'); // Убедимся, что ID правильный - if (photoInput) { - photoInput.value = ''; - } - photoLoading.value = false; // Выключаем общий индикатор }; diff --git a/src/views/ProfileView.vue b/src/views/ProfileView.vue index 1c25ea3..8666fae 100644 --- a/src/views/ProfileView.vue +++ b/src/views/ProfileView.vue @@ -195,12 +195,11 @@ - - - + @@ -367,6 +366,27 @@ const handleProfileUpdate = () => { clearMessages(); }; +const handlePhotoUploadComplete = (result) => { + console.log('[ProfileView] Получено событие photo-upload-complete:', result); + if (result.success > 0) { + photoActionSuccess.value = `Успешно загружено фотографий: ${result.success}`; + + // Автоматически скрываем сообщение через 3 секунды + setTimeout(() => { + photoActionSuccess.value = ''; + }, 3000); + + // Прокручиваем к разделу с фотографиями + setTimeout(() => { + scrollToPhotos(); + }, 100); + } + + if (result.errors > 0) { + photoActionError.value = `Не удалось загрузить некоторые фото (${result.errors})`; + } +}; + const clearMessages = () => { photoActionError.value = ''; photoActionSuccess.value = '';