Files
tp/main_dc/BB/api_bb/internal/service/review_service.go
T
valitovgaziz 15357fd3c0 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
2025-10-24 05:22:44 +05:00

197 lines
5.8 KiB
Go

// service/review_service.go
package service
import (
"api_bb/internal/models"
"api_bb/internal/repository"
"api_bb/pkg/logger"
"errors"
"go.uber.org/zap"
)
type ReviewService interface {
CreateReview(req *models.CreateReviewRequest, authorID uint) (*models.ReviewResponse, error)
GetReviewByID(id uint) (*models.ReviewResponse, error)
GetAllReviews(page, limit int, sortBy, filter string) ([]models.ReviewResponse, int, error)
GetUserReviews(userID uint) ([]models.ReviewResponse, error)
UpdateReview(id uint, req *models.UpdateReviewRequest, userID uint, isAdmin bool) (*models.ReviewResponse, error)
DeleteReview(id uint, userID uint, isAdmin bool) error
GetReviewsStats() (*models.ReviewsStatsResponse, error)
}
type reviewService struct {
reviewRepo repository.ReviewRepository
logger logger.LoggerInterface
}
func NewReviewService(reviewRepo repository.ReviewRepository, logger logger.LoggerInterface) ReviewService {
return &reviewService{
reviewRepo: reviewRepo,
logger: logger,
}
}
func (s *reviewService) CreateReview(req *models.CreateReviewRequest, authorID uint) (*models.ReviewResponse, error) {
review := &models.Review{
Rating: req.Rating,
Text: req.Text,
Achievement: req.Achievement,
Distance: req.Distance,
Improvement: req.Improvement,
Trainings: req.Trainings,
AuthorID: authorID,
Verified: false, // По умолчанию непроверенный
}
if err := s.reviewRepo.Create(review); err != nil {
s.logger.Error("Failed to create review", zap.Error(err))
return nil, err
}
// Получаем созданный отзыв с информацией об авторе
createdReview, err := s.reviewRepo.GetByID(review.ID)
if err != nil {
s.logger.Error("Failed to get created review", zap.Error(err))
return nil, err
}
return s.toReviewResponse(createdReview), nil
}
func (s *reviewService) GetReviewByID(id uint) (*models.ReviewResponse, error) {
review, err := s.reviewRepo.GetByID(id)
if err != nil {
s.logger.With(zap.Int("id", int(id))).Error("Failed to get review by ID", zap.Error(err))
return nil, err
}
return s.toReviewResponse(review), nil
}
func (s *reviewService) GetAllReviews(page, limit int, sortBy, filter string) ([]models.ReviewResponse, int, error) {
if page < 1 {
page = 1
}
if limit < 1 {
limit = 10
}
reviews, total, err := s.reviewRepo.GetAll(page, limit, sortBy, filter)
if err != nil {
s.logger.Error("Failed to get all reviews", zap.Error(err))
return nil, 0, err
}
responses := make([]models.ReviewResponse, len(reviews))
for i, review := range reviews {
responses[i] = *s.toReviewResponse(&review)
}
totalPages := (int(total) + limit - 1) / limit
return responses, totalPages, nil
}
func (s *reviewService) GetUserReviews(userID uint) ([]models.ReviewResponse, error) {
reviews, err := s.reviewRepo.GetByAuthorID(userID)
if err != nil {
s.logger.With(zap.Int("userID", int(userID))).Error("Failed to get user reviews", zap.Error(err))
return nil, err
}
responses := make([]models.ReviewResponse, len(reviews))
for i, review := range reviews {
responses[i] = *s.toReviewResponse(&review)
}
return responses, nil
}
func (s *reviewService) UpdateReview(id uint, req *models.UpdateReviewRequest, userID uint, isAdmin bool) (*models.ReviewResponse, error) {
review, err := s.reviewRepo.GetByID(id)
if err != nil {
s.logger.With(zap.Int("id", int(id))).Error("Failed to get review for update", zap.Error(err))
return nil, err
}
// Проверяем права доступа
if review.AuthorID != userID && !isAdmin {
s.logger.With(zap.Int("userID", int(userID))).With(zap.Int("reviewAuthorID", int(review.AuthorID))).Error("Unauthorized attempt to update review", zap.Error(err))
}
// Обновляем поля
if req.Rating != 0 {
review.Rating = req.Rating
}
if req.Text != "" {
review.Text = req.Text
}
if req.Achievement != "" {
review.Achievement = req.Achievement
}
if req.Distance != "" {
review.Distance = req.Distance
}
if req.Improvement != "" {
review.Improvement = req.Improvement
}
if req.Trainings != 0 {
review.Trainings = req.Trainings
}
if err := s.reviewRepo.Update(review); err != nil {
s.logger.With(zap.Int("id", int(id))).Error("Failed to update review", zap.Error(err))
return nil, err
}
// Получаем обновленный отзыв
updatedReview, err := s.reviewRepo.GetByID(id)
if err != nil {
s.logger.With(zap.Int("id", int(id))).Error("Failed to get updated review", zap.Error(err))
return nil, err
}
return s.toReviewResponse(updatedReview), nil
}
func (s *reviewService) DeleteReview(id uint, userID uint, isAdmin bool) error {
review, err := s.reviewRepo.GetByID(id)
if err != nil {
s.logger.With(zap.Int("id", int(id))).Error("Failed to get review for deletion", zap.Error(err))
return err
}
// Проверяем права доступа
if review.AuthorID != userID && !isAdmin {
s.logger.With(zap.Int("userID", int(userID))).With(zap.Int("reviewAuthorID", int(review.AuthorID))).Error("Unauthorized attempt to delete review", zap.Error(err))
return errors.New("unauthorized")
}
return s.reviewRepo.Delete(id)
}
func (s *reviewService) GetReviewsStats() (*models.ReviewsStatsResponse, error) {
return s.reviewRepo.GetStats()
}
func (s *reviewService) toReviewResponse(review *models.Review) *models.ReviewResponse {
return &models.ReviewResponse{
ID: review.ID,
CreatedAt: review.CreatedAt,
Rating: review.Rating,
Text: review.Text,
Achievement: review.Achievement,
Distance: review.Distance,
Improvement: review.Improvement,
Trainings: review.Trainings,
Verified: review.Verified,
Author: models.AuthorInfo{
ID: review.Author.ID,
FirstName: review.Author.FirstName,
LastName: review.Author.LastName,
Email: review.Author.Email,
},
}
}