// handlers/avatar.go package handlers import ( "net/http" "api_bb/internal/service" "api_bb/pkg/logger" "api_bb/pkg/middleware" "api_bb/pkg/utils" "github.com/go-chi/chi/v5" "go.uber.org/zap" ) type AvatarHandler struct { logger logger.LoggerInterface avatarService service.AvatarService } func NewAvatarHandler(avatarService service.AvatarService) *AvatarHandler { return &AvatarHandler{ logger: logger.NewWrapper(logger.Get().With(zap.String("handler", "avatar"))), avatarService: avatarService, } } func (h *AvatarHandler) Routes() chi.Router { r := chi.NewRouter() r.Post("/upload", h.UploadAvatar) r.Delete("/delete", h.DeleteAvatar) return r } func (h *AvatarHandler) UploadAvatar(w http.ResponseWriter, r *http.Request) { user, ok := middleware.GetUserFromContext(r.Context()) if !ok { utils.RespondWithError(w, http.StatusUnauthorized, "Authentication required") return } // Парсим multipart форму if err := r.ParseMultipartForm(10 << 20); err != nil { // 10MB limit utils.RespondWithError(w, http.StatusBadRequest, "Failed to parse form: "+err.Error()) return } file, header, err := r.FormFile("avatar") if err != nil { utils.RespondWithError(w, http.StatusBadRequest, "Failed to get file: "+err.Error()) return } defer file.Close() // Проверяем тип файла allowedTypes := map[string]bool{ "image/jpeg": true, "image/jpg": true, "image/png": true, "image/gif": true, } if !allowedTypes[header.Header.Get("Content-Type")] { utils.RespondWithError(w, http.StatusBadRequest, "Only JPEG, PNG and GIF images are allowed") return } // Загружаем аватар avatarPath, err := h.avatarService.UploadAvatar(user.ID, file, header) if err != nil { h.logger.Error("Failed to upload avatar", zap.Error(err)) utils.RespondWithError(w, http.StatusInternalServerError, "Failed to upload avatar: "+err.Error()) return } utils.RespondWithJSON(w, http.StatusOK, map[string]interface{}{ "message": "Avatar uploaded successfully", "avatar": avatarPath, }) } func (h *AvatarHandler) DeleteAvatar(w http.ResponseWriter, r *http.Request) { user, ok := middleware.GetUserFromContext(r.Context()) if !ok { utils.RespondWithError(w, http.StatusUnauthorized, "Authentication required") return } if err := h.avatarService.DeleteAvatar(user.ID); err != nil { h.logger.Error("Failed to delete avatar", zap.Error(err)) utils.RespondWithError(w, http.StatusInternalServerError, "Failed to delete avatar: "+err.Error()) return } utils.RespondWithJSON(w, http.StatusOK, map[string]interface{}{ "message": "Avatar deleted successfully", }) }