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:
2025-10-15 02:48:41 +05:00
parent 2327cd2f34
commit 6d8e179f90
7 changed files with 959 additions and 306 deletions
@@ -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
}