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
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
// models/user.go
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// models/user.go - добавить поле Avatar
|
||||
type User struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
Email string `json:"email" gorm:"uniqueIndex;not null"`
|
||||
Password string `json:"-" gorm:"not null"`
|
||||
FirstName string `json:"first_name" gorm:"not null"`
|
||||
LastName string `json:"last_name" gorm:"not null"`
|
||||
Avatar string `json:"avatar"` // Путь к файлу аватара
|
||||
Phone string `json:"phone"`
|
||||
Experience string `json:"experience"`
|
||||
Goals string `json:"goals"`
|
||||
Newsletter bool `json:"newsletter"`
|
||||
Role string `json:"role" gorm:"default:user"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
|
||||
EmailVerified bool `json:"email_verified" gorm:"default:false"`
|
||||
VerifiedAt time.Time `json:"verified_at"`
|
||||
|
||||
// Связи
|
||||
Workouts []Workout `json:"workouts,omitempty" gorm:"foreignKey:UserID"`
|
||||
PersonalBests []PersonalBest `json:"personal_bests,omitempty" gorm:"foreignKey:UserID"`
|
||||
Achievements []Achievement `json:"achievements,omitempty" gorm:"foreignKey:UserID"`
|
||||
TrainingPlans []TrainingPlan `json:"training_plans,omitempty" gorm:"foreignKey:UserID"`
|
||||
News []News `json:"news,omitempty" gorm:"foreignKey:AuthorID"`
|
||||
Comments []Comment `json:"comments,omitempty" gorm:"foreignKey:AuthorID"`
|
||||
Reviews []Review `json:"reviews,omitempty" gorm:"foreignKey:AuthorID"`
|
||||
Gallery []Gallery `json:"gallery,omitempty" gorm:"foreignKey:AuthorID"`
|
||||
EventRegistrations []EventRegistration `json:"event_registrations,omitempty" gorm:"foreignKey:UserID"`
|
||||
}
|
||||
|
||||
type UserUpdate struct {
|
||||
ID uint `json:"id"`
|
||||
FirstName string `json:"first_name"`
|
||||
LastName string `json:"last_name"`
|
||||
Avatar string `json:"avatar"`
|
||||
Phone string `json:"phone"`
|
||||
Experience string `json:"experience"`
|
||||
Goals string `json:"goals"`
|
||||
Newsletter bool `json:"newsletter"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// HashPassword хеширует пароль перед сохранением
|
||||
func (u *User) HashPassword() error {
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.Password = string(hashedPassword)
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckPassword проверяет пароль
|
||||
func (u *User) CheckPassword(password string) bool {
|
||||
err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// BeforeCreate hook для GORM
|
||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
||||
if u.CreatedAt.IsZero() {
|
||||
u.CreatedAt = time.Now()
|
||||
}
|
||||
if u.UpdatedAt.IsZero() {
|
||||
u.UpdatedAt = time.Now()
|
||||
}
|
||||
return u.HashPassword()
|
||||
}
|
||||
|
||||
// BeforeUpdate hook для GORM
|
||||
func (u *User) BeforeUpdate(tx *gorm.DB) error {
|
||||
u.UpdatedAt = time.Now()
|
||||
return nil
|
||||
}
|
||||
|
||||
// DTO для обновления профиля
|
||||
type UserUpdateRequest struct {
|
||||
FirstName string `json:"first_name" validate:"required,min=2,max=100"`
|
||||
LastName string `json:"last_name" validate:"required,min=2,max=100"`
|
||||
Phone string `json:"phone" validate:"max=20"`
|
||||
Experience string `json:"experience" validate:"max=50"`
|
||||
Goals string `json:"goals" validate:"max=100"`
|
||||
Newsletter bool `json:"newsletter"`
|
||||
}
|
||||
|
||||
// DTO для ответа с пользователем (без sensitive данных)
|
||||
type UserResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Email string `json:"email"`
|
||||
FirstName string `json:"first_name"`
|
||||
LastName string `json:"last_name"`
|
||||
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"`
|
||||
}
|
||||
|
||||
// DTO для ответа с пользователем и статистикой
|
||||
type UserWithStatsResponse struct {
|
||||
UserResponse
|
||||
Stats *UserStatsResponse `json:"stats,omitempty"`
|
||||
}
|
||||
Reference in New Issue
Block a user