Files
tp/main_dc/BB/api_bb/internal/handlers/user.go
T
valitovgaziz 15357fd3c0 create and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarba
2025-10-24 05:22:44 +05:00

204 lines
6.1 KiB
Go

// handlers/user.go
package handlers
import (
"bytes"
"encoding/json"
"io"
"net/http"
"time"
"api_bb/internal/models"
"api_bb/internal/service"
"api_bb/pkg/logger"
"api_bb/pkg/middleware"
"api_bb/pkg/utils"
"go.uber.org/zap"
)
type UserHandler struct {
logger logger.LoggerInterface
userService service.UserService
}
func NewUserHandler(userService service.UserService) *UserHandler {
return &UserHandler{
logger: logger.NewWrapper(logger.Get().With(zap.String("handler", "user"))),
userService: userService,
}
}
type UserResponse struct {
ID uint `json:"id"`
Email string `json:"email"`
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Avatar string `json:"avatar"`
Phone string `json:"phone"`
Experience string `json:"experience"`
Goals string `json:"goals"`
Newsletter bool `json:"newsletter"`
Role string `json:"role"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// GetUsers возвращает список всех пользователей
func (h *UserHandler) GetUsers(w http.ResponseWriter, r *http.Request) {
h.logger.Info("handling get users request",
zap.String("method", r.Method),
zap.String("path", r.URL.Path),
zap.String("remote_addr", r.RemoteAddr),
)
// Получаем пользователя из контекста для проверки аутентификации
_, ok := middleware.GetUserFromContext(r.Context())
if !ok {
h.logger.Warn("get users failed - authentication required")
utils.RespondWithError(w, http.StatusUnauthorized, "Authentication required")
return
}
// Получаем список пользователей из сервиса
users, err := h.userService.GetAllUsers()
if err != nil {
h.logger.Error("failed to get users from service", zap.Error(err))
utils.RespondWithError(w, http.StatusInternalServerError, "Failed to get users: "+err.Error())
return
}
// Преобразуем в response формат
var userResponses []UserResponse
for _, user := range users {
userResponses = append(userResponses, toUserResponse(&user))
}
h.logger.Info("users list retrieved successfully",
zap.Int("users_count", len(userResponses)),
)
utils.RespondWithJSON(w, http.StatusOK, userResponses)
}
func (h *UserHandler) GetProfile(w http.ResponseWriter, r *http.Request) {
h.logger.Info("handling get profile request",
zap.String("method", r.Method),
zap.String("path", r.URL.Path),
zap.String("remote_addr", r.RemoteAddr),
)
user, ok := middleware.GetUserFromContext(r.Context())
if !ok {
h.logger.Warn("get profile failed - authentication required")
utils.RespondWithError(w, http.StatusUnauthorized, "Authentication required")
return
}
h.logger.Info("profile retrieved successfully",
zap.Uint("user_id", user.ID),
zap.String("email", user.Email),
zap.String("avatar", user.Avatar),
)
utils.RespondWithJSON(w, http.StatusOK, toUserResponse(user))
}
type UpdateProfileRequest struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Phone string `json:"phone"`
Experience string `json:"experience"`
Goals string `json:"goals"`
Newsletter bool `json:"newsletter"`
}
func (h *UserHandler) UpdateProfile(w http.ResponseWriter, r *http.Request) {
h.logger.Info("handling update profile request",
zap.String("method", r.Method),
zap.String("path", r.URL.Path),
zap.String("remote_addr", r.RemoteAddr),
)
// Логируем тело запроса для отладки
bodyBytes, err := io.ReadAll(r.Body)
if err != nil {
h.logger.Error("failed to read request body", zap.Error(err))
utils.RespondWithError(w, http.StatusBadRequest, "Failed to read request body: "+err.Error())
return
}
// Восстанавливаем тело для дальнейшего использования
r.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
h.logger.Debug("raw request body", zap.String("body", string(bodyBytes)))
// Получаем пользователя из контекста
currentUser, ok := middleware.GetUserFromContext(r.Context())
if !ok {
h.logger.Warn("update profile failed - authentication required")
utils.RespondWithError(w, http.StatusUnauthorized, "Authentication required")
return
}
var req UpdateProfileRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
h.logger.Error("failed to decode JSON payload", zap.Error(err))
utils.RespondWithError(w, http.StatusBadRequest, "Invalid request payload: "+err.Error())
return
}
// Валидация обязательных полей
if req.FirstName == "" {
h.logger.Warn("update profile failed - first name required")
utils.RespondWithError(w, http.StatusBadRequest, "First name is required")
return
}
if req.LastName == "" {
h.logger.Warn("update profile failed - last name required")
utils.RespondWithError(w, http.StatusBadRequest, "Last name is required")
return
}
h.logger.Info("updating user profile",
zap.Uint("user_id", currentUser.ID),
zap.String("first_name", req.FirstName),
zap.String("last_name", req.LastName),
zap.String("experience", req.Experience),
zap.String("goals", req.Goals),
zap.Bool("newsletter", req.Newsletter),
)
// Обновляем данные пользователя
updatedUser := &models.User{
ID: currentUser.ID,
FirstName: req.FirstName,
LastName: req.LastName,
Phone: req.Phone,
Experience: req.Experience,
Goals: req.Goals,
Newsletter: req.Newsletter,
UpdatedAt: time.Now(),
}
// Сохраняем обновленные данные
if err := h.userService.UpdateProfile(updatedUser); err != nil {
h.logger.Error("failed to update profile in service",
zap.Uint("user_id", currentUser.ID),
zap.Error(err),
)
utils.RespondWithError(w, http.StatusInternalServerError, "Failed to update profile: "+err.Error())
return
}
h.logger.Info("profile updated successfully",
zap.Uint("user_id", currentUser.ID),
)
utils.RespondWithJSON(w, http.StatusOK, map[string]interface{}{
"message": "Profile updated successfully",
"user": toUserResponse(updatedUser),
})
}