182 lines
6.1 KiB
Go
182 lines
6.1 KiB
Go
// 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")
|
|
)
|