modified: internal/handlers/user.go

modified:   internal/models/user.go
	modified:   internal/repository/user_repository.go
	modified:   internal/service/auth_service.go
	new file:   internal/service/user_service.go

	modified:   ../../begushiybashkir/bbvue/src/views/ProfileEdit.vue
fix bag not editable profile
This commit is contained in:
2025-10-12 10:16:52 +05:00
parent 8447dbe882
commit 38bee8e077
5 changed files with 122 additions and 76 deletions
@@ -33,10 +33,6 @@ func NewUserHandler(authService service.AuthService) *UserHandler {
func (h *UserHandler) Routes() chi.Router { func (h *UserHandler) Routes() chi.Router {
r := chi.NewRouter() r := chi.NewRouter()
// Обработка OPTIONS запросов для CORS
r.Options("/profile", h.handleOptions)
r.Options("/editProfile", h.handleOptions)
r.Get("/profile", h.GetProfile) r.Get("/profile", h.GetProfile)
r.Post("/editProfile", h.UpdateProfile) r.Post("/editProfile", h.UpdateProfile)
+11
View File
@@ -24,6 +24,17 @@ type User struct {
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"` DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
} }
type UserUpdate struct {
ID uint `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Phone string `json:"phone"`
Experience string `json:"experience"`
Goals string `json:"goals"`
Newsletter bool `json:"newsletter"`
UpdatedAt time.Time `json:"updated_at"`
}
// HashPassword хеширует пароль перед сохранением // HashPassword хеширует пароль перед сохранением
func (u *User) HashPassword() error { func (u *User) HashPassword() error {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost) hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
@@ -2,6 +2,8 @@ package repository
import ( import (
"api_bb/internal/models" "api_bb/internal/models"
"fmt"
"gorm.io/gorm" "gorm.io/gorm"
) )
@@ -11,6 +13,7 @@ type UserRepository interface {
FindByEmail(email string) (*models.User, error) FindByEmail(email string) (*models.User, error)
Update(user *models.User) error Update(user *models.User) error
Delete(id uint) error Delete(id uint) error
UpdateExcludeEmail(userUpdate *models.User) error
} }
type userRepository struct { type userRepository struct {
@@ -44,3 +47,27 @@ func (r *userRepository) Update(user *models.User) error {
func (r *userRepository) Delete(id uint) error { func (r *userRepository) Delete(id uint) error {
return r.db.Delete(&models.User{}, id).Error return r.db.Delete(&models.User{}, id).Error
} }
// repository/user_repository.go
func (r *userRepository) UpdateExcludeEmail(userUpdate *models.User) error {
// Обновляем только разрешенные поля
result := r.db.Model(userUpdate).Where("id = ?", userUpdate.ID).Updates(map[string]interface{}{
"first_name": userUpdate.FirstName,
"last_name": userUpdate.LastName,
"phone": userUpdate.Phone,
"experience": userUpdate.Experience,
"goals": userUpdate.Goals,
"newsletter": userUpdate.Newsletter,
"updated_at": userUpdate.UpdatedAt,
})
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("user not found")
}
return nil
}
@@ -3,8 +3,6 @@ package service
import ( import (
"errors" "errors"
"fmt"
"time"
"api_bb/internal/models" "api_bb/internal/models"
"api_bb/internal/repository" "api_bb/internal/repository"
@@ -38,57 +36,6 @@ func NewAuthService(userRepo repository.UserRepository, jwtService JWTService, l
} }
} }
func (s *authService) UpdateProfile(user *models.User) error {
s.logger.Info("Updating user profile",
zap.Uint("user_id", user.ID),
)
existingUser, err := s.userRepo.FindByID(user.ID)
if err != nil {
s.logger.Warn("User not found for profile update",
zap.Uint("user_id", user.ID),
zap.Error(err),
)
return fmt.Errorf("user not found")
}
updateData := &models.User{
ID: existingUser.ID,
FirstName: user.FirstName,
LastName: user.LastName,
Phone: user.Phone,
Experience: user.Experience,
Goals: user.Goals,
Newsletter: user.Newsletter,
UpdatedAt: time.Now(),
}
s.logger.Debug("Profile update data prepared",
zap.Uint("user_id", user.ID),
zap.String("first_name", updateData.FirstName),
zap.String("last_name", updateData.LastName),
)
if err := s.userRepo.Update(updateData); err != nil {
s.logger.Error("Failed to update user profile",
zap.Uint("user_id", user.ID),
zap.Error(err),
)
return err
}
user.Email = existingUser.Email
user.Password = existingUser.Password
user.Role = existingUser.Role
user.CreatedAt = existingUser.CreatedAt
user.UpdatedAt = updateData.UpdatedAt
s.logger.Info("User profile updated successfully",
zap.Uint("user_id", user.ID),
)
return nil
}
func (s *authService) Register(user *models.User) error { func (s *authService) Register(user *models.User) error {
s.logger.Info("Registering new user", s.logger.Info("Registering new user",
@@ -174,20 +121,3 @@ func min(a, b int) int {
} }
return b return b
} }
func (s *authService) GetUserProfile(userID uint) (*models.User, error) {
s.logger.Debug("Getting user profile",
zap.Uint("user_id", userID),
)
user, err := s.userRepo.FindByID(userID)
if err != nil {
s.logger.Warn("Failed to get user profile",
zap.Uint("user_id", userID),
zap.Error(err),
)
return nil, err
}
return user, nil
}
@@ -0,0 +1,82 @@
package service
import (
"api_bb/internal/models"
"api_bb/internal/repository"
"api_bb/pkg/logger"
"fmt"
"time"
"go.uber.org/zap"
)
type UserService interface {
GetUserProfile(userID uint) (*models.User, error)
UpdateProfile(user *models.User) error
}
type userService struct {
userRepo repository.UserRepository
jwtService JWTService
logger logger.Interface
}
func NewUserService(userRepo repository.UserRepository, jwtService JWTService, log logger.Interface) AuthService {
// Создаем логгер с контекстом для сервиса
serviceLogger := log.With(zap.String("service", "auth"))
return &authService{
userRepo: userRepo,
jwtService: jwtService,
logger: serviceLogger,
}
}
func (s *authService) UpdateProfile(user *models.User) error {
s.logger.Info("Updating user profile",
zap.Uint("user_id", user.ID),
)
// Проверяем, что пользователь существует
existingUser, err := s.userRepo.FindByID(user.ID)
if err != nil {
s.logger.Error("User not found for profile update",
zap.Uint("user_id", user.ID),
zap.Error(err),
)
return fmt.Errorf("user not found")
}
// Убеждаемся, что email не меняется
user.Email = existingUser.Email
updateData := &models.User{
ID: user.ID,
FirstName: user.FirstName,
LastName: user.LastName,
Phone: user.Phone,
Experience: user.Experience,
Goals: user.Goals,
Newsletter: user.Newsletter,
UpdatedAt: time.Now(),
}
return s.userRepo.UpdateExcludeEmail(updateData)
}
func (s *authService) GetUserProfile(userID uint) (*models.User, error) {
s.logger.Debug("Getting user profile",
zap.Uint("user_id", userID),
)
user, err := s.userRepo.FindByID(userID)
if err != nil {
s.logger.Warn("Failed to get user profile",
zap.Uint("user_id", userID),
zap.Error(err),
)
return nil, err
}
return user, nil
}