modified: begushiybashkir/bbvue/src/views/Reviews.vue
modified: serv_nginx/api_bb/internal/handlers/handlers.go new file: serv_nginx/api_bb/internal/handlers/review_handler.go new file: serv_nginx/api_bb/internal/models/review.go new file: serv_nginx/api_bb/internal/repository/review_repository.go modified: serv_nginx/api_bb/internal/routes/routes.go new file: serv_nginx/api_bb/internal/service/review_service.go set reviews router, handler, service, repository
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
// repository/review_repository.go
|
||||
package repository
|
||||
|
||||
import (
|
||||
"api_bb/internal/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ReviewRepository interface {
|
||||
Create(review *models.Review) error
|
||||
GetByID(id uint) (*models.Review, error)
|
||||
GetAll(page, limit int, sortBy, filter string) ([]models.Review, int64, error)
|
||||
GetByAuthorID(authorID uint) ([]models.Review, error)
|
||||
Update(review *models.Review) error
|
||||
Delete(id uint) error
|
||||
GetStats() (*models.ReviewsStatsResponse, error)
|
||||
GetRatingDistribution() (map[int]int, error)
|
||||
}
|
||||
|
||||
type reviewRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewReviewRepository(db *gorm.DB) ReviewRepository {
|
||||
return &reviewRepository{db: db}
|
||||
}
|
||||
|
||||
func (r *reviewRepository) Create(review *models.Review) error {
|
||||
return r.db.Create(review).Error
|
||||
}
|
||||
|
||||
func (r *reviewRepository) GetByID(id uint) (*models.Review, error) {
|
||||
var review models.Review
|
||||
err := r.db.Preload("Author").First(&review, id).Error
|
||||
return &review, err
|
||||
}
|
||||
|
||||
func (r *reviewRepository) GetAll(page, limit int, sortBy, filter string) ([]models.Review, int64, error) {
|
||||
var reviews []models.Review
|
||||
var total int64
|
||||
|
||||
query := r.db.Model(&models.Review{}).Preload("Author")
|
||||
|
||||
// Применяем фильтрацию по рейтингу
|
||||
if filter != "" && filter != "all" {
|
||||
query = query.Where("rating >= ?", filter)
|
||||
}
|
||||
|
||||
// Считаем общее количество
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// Применяем сортировку
|
||||
switch sortBy {
|
||||
case "newest":
|
||||
query = query.Order("created_at DESC")
|
||||
case "oldest":
|
||||
query = query.Order("created_at ASC")
|
||||
case "highest":
|
||||
query = query.Order("rating DESC, created_at DESC")
|
||||
case "lowest":
|
||||
query = query.Order("rating ASC, created_at DESC")
|
||||
default:
|
||||
query = query.Order("created_at DESC")
|
||||
}
|
||||
|
||||
// Применяем пагинацию
|
||||
offset := (page - 1) * limit
|
||||
err := query.Offset(offset).Limit(limit).Find(&reviews).Error
|
||||
|
||||
return reviews, total, err
|
||||
}
|
||||
|
||||
func (r *reviewRepository) GetByAuthorID(authorID uint) ([]models.Review, error) {
|
||||
var reviews []models.Review
|
||||
err := r.db.Where("author_id = ?", authorID).Preload("Author").Find(&reviews).Error
|
||||
return reviews, err
|
||||
}
|
||||
|
||||
func (r *reviewRepository) Update(review *models.Review) error {
|
||||
return r.db.Save(review).Error
|
||||
}
|
||||
|
||||
func (r *reviewRepository) Delete(id uint) error {
|
||||
return r.db.Delete(&models.Review{}, id).Error
|
||||
}
|
||||
|
||||
func (r *reviewRepository) GetStats() (*models.ReviewsStatsResponse, error) {
|
||||
var totalReviews int64
|
||||
var averageRating float64
|
||||
var successStories int64
|
||||
|
||||
// Общее количество отзывов
|
||||
if err := r.db.Model(&models.Review{}).Count(&totalReviews).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Средний рейтинг
|
||||
if err := r.db.Model(&models.Review{}).Select("AVG(rating)").Row().Scan(&averageRating); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Количество успешных историй (отзывы с рейтингом >= 4 и достижениями)
|
||||
if err := r.db.Model(&models.Review{}).
|
||||
Where("rating >= ? AND achievement != ?", 4, "").
|
||||
Count(&successStories).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Распределение по рейтингам
|
||||
ratingDistribution, err := r.GetRatingDistribution()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &models.ReviewsStatsResponse{
|
||||
TotalReviews: int(totalReviews),
|
||||
AverageRating: averageRating,
|
||||
SuccessStories: int(successStories),
|
||||
RatingDistribution: ratingDistribution,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *reviewRepository) GetRatingDistribution() (map[int]int, error) {
|
||||
var results []struct {
|
||||
Rating int
|
||||
Count int
|
||||
}
|
||||
|
||||
err := r.db.Model(&models.Review{}).
|
||||
Select("rating, COUNT(*) as count").
|
||||
Group("rating").
|
||||
Order("rating DESC").
|
||||
Scan(&results).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
distribution := make(map[int]int)
|
||||
for _, result := range results {
|
||||
distribution[result.Rating] = result.Count
|
||||
}
|
||||
|
||||
// Заполняем отсутствующие рейтинги нулями
|
||||
for i := 1; i <= 5; i++ {
|
||||
if _, exists := distribution[i]; !exists {
|
||||
distribution[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
return distribution, nil
|
||||
}
|
||||
Reference in New Issue
Block a user