// service/achievement_service.go (дополнение) package service import ( "api_bb/internal/models" "api_bb/internal/repository" "errors" ) type AchievementService struct { achievementRepo repository.AchievementRepository } func NewAchievementService(achievementRepo repository.AchievementRepository) *AchievementService { return &AchievementService{ achievementRepo: achievementRepo, } } // CreateAchievement создает новое достижение func (s *AchievementService) CreateAchievement(userID uint, req models.AchievementCreateRequest) (*models.Achievement, error) { // Проверяем, нет ли уже достижения с таким названием у пользователя exists, err := s.achievementRepo.ExistsByTitleAndUser(userID, req.Title) if err != nil { return nil, err } if exists { return nil, ErrAchievementAlreadyExists } achievement := &models.Achievement{ UserID: userID, Type: req.Type, Title: req.Title, Description: req.Description, Result: req.Result, Distance: req.Distance, Date: req.Date, BadgeImage: req.BadgeImage, Verified: false, // По умолчанию не подтверждено } if err := s.achievementRepo.Create(achievement); err != nil { return nil, err } return achievement, nil } // GetVerifiedAchievements возвращает только подтвержденные достижения пользователя func (s *AchievementService) GetVerifiedAchievements(userID uint) ([]models.Achievement, error) { return s.achievementRepo.GetVerifiedByUserID(userID) } // GetVerifiedRecentAchievements возвращает последние подтвержденные достижения func (s *AchievementService) GetVerifiedRecentAchievements(userID uint, limit int) ([]models.Achievement, error) { achievements, err := s.achievementRepo.GetRecentAchievements(userID, limit) if err != nil { return nil, err } // Фильтруем только подтвержденные var verified []models.Achievement for _, achievement := range achievements { if achievement.Verified { verified = append(verified, achievement) } } return verified, nil } // GetUserAchievements возвращает все достижения пользователя func (s *AchievementService) GetUserAchievements(userID uint) ([]models.Achievement, error) { return s.achievementRepo.GetByUserID(userID) } // GetUserAchievementsSummary возвращает сводку по достижениям пользователя func (s *AchievementService) GetUserAchievementsSummary(userID uint) (*models.UserAchievementsResponse, error) { return s.achievementRepo.GetUserAchievementsSummary(userID) } // VerifyAchievement подтверждает достижение func (s *AchievementService) VerifyAchievement(achievementID uint, userID uint) error { // Проверяем, что достижение принадлежит пользователю achievement, err := s.achievementRepo.GetByID(achievementID) if err != nil { return err } if achievement.UserID != userID { return ErrAchievementNotFound } return s.achievementRepo.VerifyAchievement(achievementID) } // GetRecentAchievements возвращает последние достижения func (s *AchievementService) GetRecentAchievements(userID uint, limit int) ([]models.Achievement, error) { return s.achievementRepo.GetRecentAchievements(userID, limit) } // GetAchievementsByType возвращает достижения по типу func (s *AchievementService) GetAchievementsByType(userID uint, achievementType models.AchievementType) ([]models.Achievement, error) { return s.achievementRepo.GetByUserAndType(userID, achievementType) } // DeleteAchievement удаляет достижение func (s *AchievementService) DeleteAchievement(achievementID uint, userID uint) error { // Проверяем, что достижение принадлежит пользователю achievement, err := s.achievementRepo.GetByID(achievementID) if err != nil { return err } if achievement.UserID != userID { return ErrAchievementNotFound } return s.achievementRepo.Delete(achievementID) } // GetAchievementByID возвращает достижение по ID func (s *AchievementService) GetAchievementByID(achievementID uint, userID uint) (*models.Achievement, error) { achievement, err := s.achievementRepo.GetByID(achievementID) if err != nil { return nil, err } // Проверяем, что достижение принадлежит пользователю if achievement.UserID != userID { return nil, ErrAchievementNotFound } return achievement, nil } // UpdateAchievement обновляет достижение func (s *AchievementService) UpdateAchievement(achievementID uint, userID uint, req models.AchievementCreateRequest) (*models.Achievement, error) { // Проверяем, что достижение принадлежит пользователю existingAchievement, err := s.achievementRepo.GetByID(achievementID) if err != nil { return nil, err } if existingAchievement.UserID != userID { return nil, ErrAchievementNotFound } // Проверяем, нет ли другого достижения с таким названием if existingAchievement.Title != req.Title { exists, err := s.achievementRepo.ExistsByTitleAndUser(userID, req.Title) if err != nil { return nil, err } if exists { return nil, ErrAchievementAlreadyExists } } // Обновляем данные existingAchievement.Type = req.Type existingAchievement.Title = req.Title existingAchievement.Description = req.Description existingAchievement.Result = req.Result existingAchievement.Distance = req.Distance existingAchievement.Date = req.Date existingAchievement.BadgeImage = req.BadgeImage if err := s.achievementRepo.Update(existingAchievement); err != nil { return nil, err } return existingAchievement, nil } // Ошибки var ( ErrAchievementAlreadyExists = errors.New("achievement with this title already exists") ErrAchievementNotFound = errors.New("achievement not found") )