89 lines
3.2 KiB
Go
89 lines
3.2 KiB
Go
// models/workout.go
|
|
package models
|
|
|
|
import (
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type WorkoutType string
|
|
|
|
const (
|
|
WorkoutTypeEasy WorkoutType = "easy"
|
|
WorkoutTypeTempo WorkoutType = "tempo"
|
|
WorkoutTypeInterval WorkoutType = "interval"
|
|
WorkoutTypeLong WorkoutType = "long"
|
|
WorkoutTypeRecovery WorkoutType = "recovery"
|
|
)
|
|
|
|
type Workout struct {
|
|
ID uint `json:"id" gorm:"primaryKey"`
|
|
UserID uint `json:"user_id" gorm:"not null;index"`
|
|
Type WorkoutType `json:"type" gorm:"type:varchar(20);not null"`
|
|
Distance float64 `json:"distance_km" gorm:"type:decimal(5,2);not null"` // Дистанция в км
|
|
Duration int `json:"duration_min" gorm:"not null"` // Продолжительность в минутах
|
|
Pace string `json:"pace" gorm:"size:20"` // Темп (например, "5:30")
|
|
Calories int `json:"calories" gorm:"default:0"` // Сожженные калории
|
|
Notes string `json:"notes" gorm:"type:text"` // Заметки к тренировке
|
|
Date time.Time `json:"date" gorm:"not null;index"` // Дата тренировки
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
|
|
// Связи
|
|
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
|
}
|
|
|
|
// BeforeCreate hook
|
|
func (w *Workout) BeforeCreate(tx *gorm.DB) error {
|
|
if w.CreatedAt.IsZero() {
|
|
w.CreatedAt = time.Now()
|
|
}
|
|
if w.UpdatedAt.IsZero() {
|
|
w.UpdatedAt = time.Now()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// BeforeUpdate hook
|
|
func (w *Workout) BeforeUpdate(tx *gorm.DB) error {
|
|
w.UpdatedAt = time.Now()
|
|
return nil
|
|
}
|
|
|
|
// DTO для создания тренировки
|
|
type WorkoutCreateRequest struct {
|
|
Type WorkoutType `json:"type" validate:"required,oneof=easy tempo interval long recovery"`
|
|
Distance float64 `json:"distance_km" validate:"required,min=0.1,max=1000"`
|
|
Duration int `json:"duration_min" validate:"required,min=1,max=1440"`
|
|
Pace string `json:"pace" validate:"maxlen=20"`
|
|
Calories int `json:"calories" validate:"minint=0,maxint=5000"`
|
|
Notes string `json:"notes" validate:"maxlen=1000"`
|
|
Date time.Time `json:"date" validate:"required"`
|
|
}
|
|
|
|
// DTO для обновления тренировки
|
|
type WorkoutUpdateRequest struct {
|
|
Type WorkoutType `json:"type" validate:"oneof=easy tempo interval long recovery"`
|
|
Distance float64 `json:"distance_km" validate:"min=0.1,max=1000"`
|
|
Duration int `json:"duration_min" validate:"min=1,max=1440"`
|
|
Pace string `json:"pace" validate:"maxlen=20"`
|
|
Calories int `json:"calories" validate:"minint=0,maxint=5000"`
|
|
Notes string `json:"notes" validate:"maxlen=1000"`
|
|
Date time.Time `json:"date"`
|
|
}
|
|
|
|
// DTO для статистики тренировок
|
|
type WorkoutStatsResponse struct {
|
|
TotalWorkouts int `json:"total_workouts"`
|
|
TotalDistance float64 `json:"total_distance_km"`
|
|
TotalTime int `json:"total_time_min"`
|
|
AveragePace string `json:"average_pace"`
|
|
MonthlyStats []MonthlyStat `json:"monthly_stats"`
|
|
}
|
|
|
|
type MonthlyStat struct {
|
|
Month string `json:"month"`
|
|
Distance float64 `json:"distance_km"`
|
|
Workouts int `json:"workouts"`
|
|
} |