new file: serv_nginx/api_bb/internal/repository/achievement_repository.go
modified: serv_nginx/api_bb/internal/repository/personal_best_repository.go new file: serv_nginx/api_bb/internal/service/achievement_service.go new file: serv_nginx/api_bb/internal/service/personal_best_service.go new file: serv_nginx/api_bb/internal/service/user_stats_service.go add some services
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
// repositories/achievement_repository.go
|
||||
package repository
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"api_bb/internal/models"
|
||||
)
|
||||
|
||||
type AchievementRepository interface {
|
||||
Create(achievement *models.Achievement) error
|
||||
GetByID(id uint) (*models.Achievement, error)
|
||||
GetByUserID(userID uint) ([]models.Achievement, error)
|
||||
GetByUserAndType(userID uint, achievementType models.AchievementType) ([]models.Achievement, error)
|
||||
GetVerifiedByUserID(userID uint) ([]models.Achievement, error)
|
||||
GetByDateRange(userID uint, startDate, endDate time.Time) ([]models.Achievement, error)
|
||||
Update(achievement *models.Achievement) error
|
||||
Delete(id uint) error
|
||||
VerifyAchievement(id uint) error
|
||||
GetUserAchievementsSummary(userID uint) (*models.UserAchievementsResponse, error)
|
||||
GetRecentAchievements(userID uint, limit int) ([]models.Achievement, error)
|
||||
CountByType(userID uint) (map[models.AchievementType]int64, error)
|
||||
ExistsByTitleAndUser(userID uint, title string) (bool, error)
|
||||
}
|
||||
|
||||
type achievementRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewAchievementRepository(db *gorm.DB) AchievementRepository {
|
||||
return &achievementRepository{db: db}
|
||||
}
|
||||
|
||||
// Create создает новое достижение
|
||||
func (r *achievementRepository) Create(achievement *models.Achievement) error {
|
||||
return r.db.Create(achievement).Error
|
||||
}
|
||||
|
||||
// GetByID возвращает достижение по ID
|
||||
func (r *achievementRepository) GetByID(id uint) (*models.Achievement, error) {
|
||||
var achievement models.Achievement
|
||||
err := r.db.Preload("User").First(&achievement, id).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &achievement, nil
|
||||
}
|
||||
|
||||
// GetByUserID возвращает все достижения пользователя
|
||||
func (r *achievementRepository) GetByUserID(userID uint) ([]models.Achievement, error) {
|
||||
var achievements []models.Achievement
|
||||
err := r.db.Where("user_id = ?", userID).
|
||||
Order("date DESC, created_at DESC").
|
||||
Find(&achievements).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return achievements, nil
|
||||
}
|
||||
|
||||
// GetByUserAndType возвращает достижения пользователя по типу
|
||||
func (r *achievementRepository) GetByUserAndType(userID uint, achievementType models.AchievementType) ([]models.Achievement, error) {
|
||||
var achievements []models.Achievement
|
||||
err := r.db.Where("user_id = ? AND type = ?", userID, achievementType).
|
||||
Order("date DESC").
|
||||
Find(&achievements).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return achievements, nil
|
||||
}
|
||||
|
||||
// GetVerifiedByUserID возвращает подтвержденные достижения пользователя
|
||||
func (r *achievementRepository) GetVerifiedByUserID(userID uint) ([]models.Achievement, error) {
|
||||
var achievements []models.Achievement
|
||||
err := r.db.Where("user_id = ? AND verified = ?", userID, true).
|
||||
Order("date DESC").
|
||||
Find(&achievements).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return achievements, nil
|
||||
}
|
||||
|
||||
// GetByDateRange возвращает достижения за период времени
|
||||
func (r *achievementRepository) GetByDateRange(userID uint, startDate, endDate time.Time) ([]models.Achievement, error) {
|
||||
var achievements []models.Achievement
|
||||
err := r.db.Where("user_id = ? AND date BETWEEN ? AND ?", userID, startDate, endDate).
|
||||
Order("date DESC").
|
||||
Find(&achievements).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return achievements, nil
|
||||
}
|
||||
|
||||
// Update обновляет достижение
|
||||
func (r *achievementRepository) Update(achievement *models.Achievement) error {
|
||||
return r.db.Save(achievement).Error
|
||||
}
|
||||
|
||||
// Delete удаляет достижение
|
||||
func (r *achievementRepository) Delete(id uint) error {
|
||||
return r.db.Delete(&models.Achievement{}, id).Error
|
||||
}
|
||||
|
||||
// VerifyAchievement подтверждает достижение
|
||||
func (r *achievementRepository) VerifyAchievement(id uint) error {
|
||||
return r.db.Model(&models.Achievement{}).
|
||||
Where("id = ?", id).
|
||||
Update("verified", true).
|
||||
Error
|
||||
}
|
||||
|
||||
// GetUserAchievementsSummary возвращает сводку по достижениям пользователя
|
||||
func (r *achievementRepository) GetUserAchievementsSummary(userID uint) (*models.UserAchievementsResponse, error) {
|
||||
var totalCount int64
|
||||
var verifiedCount int64
|
||||
|
||||
// Считаем общее количество достижений
|
||||
err := r.db.Model(&models.Achievement{}).
|
||||
Where("user_id = ?", userID).
|
||||
Count(&totalCount).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Считаем количество подтвержденных достижений
|
||||
err = r.db.Model(&models.Achievement{}).
|
||||
Where("user_id = ? AND verified = ?", userID, true).
|
||||
Count(&verifiedCount).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Получаем все достижения пользователя
|
||||
achievements, err := r.GetByUserID(userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Вычисляем процент прогресса
|
||||
progressPercent := 0.0
|
||||
if totalCount > 0 {
|
||||
progressPercent = (float64(verifiedCount) / float64(totalCount)) * 100
|
||||
}
|
||||
|
||||
return &models.UserAchievementsResponse{
|
||||
TotalAchievements: int(totalCount),
|
||||
Completed: int(verifiedCount),
|
||||
ProgressPercent: progressPercent,
|
||||
Achievements: achievements,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetRecentAchievements возвращает последние достижения пользователя
|
||||
func (r *achievementRepository) GetRecentAchievements(userID uint, limit int) ([]models.Achievement, error) {
|
||||
var achievements []models.Achievement
|
||||
err := r.db.Where("user_id = ?", userID).
|
||||
Order("created_at DESC").
|
||||
Limit(limit).
|
||||
Find(&achievements).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return achievements, nil
|
||||
}
|
||||
|
||||
// CountByType возвращает количество достижений по типам
|
||||
func (r *achievementRepository) CountByType(userID uint) (map[models.AchievementType]int64, error) {
|
||||
type CountResult struct {
|
||||
Type models.AchievementType
|
||||
Count int64
|
||||
}
|
||||
|
||||
var results []CountResult
|
||||
err := r.db.Model(&models.Achievement{}).
|
||||
Select("type, COUNT(*) as count").
|
||||
Where("user_id = ?", userID).
|
||||
Group("type").
|
||||
Scan(&results).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
counts := make(map[models.AchievementType]int64)
|
||||
for _, result := range results {
|
||||
counts[result.Type] = result.Count
|
||||
}
|
||||
|
||||
return counts, nil
|
||||
}
|
||||
|
||||
// ExistsByTitleAndUser проверяет, существует ли достижение с таким названием у пользователя
|
||||
func (r *achievementRepository) ExistsByTitleAndUser(userID uint, title string) (bool, error) {
|
||||
var count int64
|
||||
err := r.db.Model(&models.Achievement{}).
|
||||
Where("user_id = ? AND title = ?", userID, title).
|
||||
Count(&count).Error
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
// GetUnverifiedAchievements возвращает неподтвержденные достижения
|
||||
func (r *achievementRepository) GetUnverifiedAchievements(userID uint) ([]models.Achievement, error) {
|
||||
var achievements []models.Achievement
|
||||
err := r.db.Where("user_id = ? AND verified = ?", userID, false).
|
||||
Order("created_at DESC").
|
||||
Find(&achievements).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return achievements, nil
|
||||
}
|
||||
|
||||
// GetAchievementsWithPagination возвращает достижения с пагинацией
|
||||
func (r *achievementRepository) GetAchievementsWithPagination(userID uint, page, pageSize int) ([]models.Achievement, int64, error) {
|
||||
var achievements []models.Achievement
|
||||
var totalCount int64
|
||||
|
||||
// Считаем общее количество
|
||||
err := r.db.Model(&models.Achievement{}).
|
||||
Where("user_id = ?", userID).
|
||||
Count(&totalCount).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// Получаем данные с пагинацией
|
||||
offset := (page - 1) * pageSize
|
||||
err = r.db.Where("user_id = ?", userID).
|
||||
Order("date DESC, created_at DESC").
|
||||
Offset(offset).
|
||||
Limit(pageSize).
|
||||
Find(&achievements).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return achievements, totalCount, nil
|
||||
}
|
||||
@@ -21,6 +21,7 @@ type PersonalBestRepository interface {
|
||||
GetByDateRange(userID uint, startDate, endDate time.Time) ([]models.PersonalBest, error)
|
||||
GetPersonalBestsSummary(userID uint) (*models.PersonalBestsSummary, error)
|
||||
ExistsBetterTime(userID uint, distanceType models.DistanceType, time string) (bool, error)
|
||||
CalculatePace(timeStr string, distanceType models.DistanceType) (string, error)
|
||||
}
|
||||
|
||||
type personalBestRepository struct {
|
||||
|
||||
Reference in New Issue
Block a user