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 @@
-
-
-
-
-
+
@@ -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 = '';