Files
ai_dianshang/server/internal/repository/comment.go
2025-11-17 13:32:54 +08:00

289 lines
7.6 KiB
Go

package repository
import (
"fmt"
"gorm.io/gorm"
"dianshang/internal/model"
)
type CommentRepository struct {
db *gorm.DB
}
func NewCommentRepository(db *gorm.DB) *CommentRepository {
return &CommentRepository{db: db}
}
// Create 创建评论
func (r *CommentRepository) Create(comment *model.Comment) error {
return r.db.Create(comment).Error
}
// GetByID 根据ID获取评论
func (r *CommentRepository) GetByID(id uint) (*model.Comment, error) {
var comment model.Comment
err := r.db.Preload("User").Preload("Product").Preload("Order").Preload("Replies.User").First(&comment, id).Error
return &comment, err
}
// GetByProductID 根据商品ID获取评论列表
func (r *CommentRepository) GetByProductID(productID uint, offset, limit int, rating int) ([]model.Comment, int64, error) {
var comments []model.Comment
var total int64
query := r.db.Model(&model.Comment{}).Where("product_id = ? AND status = ?", productID, 1)
// 按评分筛选
if rating > 0 && rating <= 5 {
query = query.Where("rating = ?", rating)
}
// 获取总数
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
// 获取评论列表
err := query.Preload("User").Preload("Replies", "status = ?", 1).Preload("Replies.User").
Order("created_at DESC").Offset(offset).Limit(limit).Find(&comments).Error
return comments, total, err
}
// GetByUserID 根据用户ID获取评论列表
func (r *CommentRepository) GetByUserID(userID uint, offset, limit int) ([]model.Comment, int64, error) {
var comments []model.Comment
var total int64
query := r.db.Model(&model.Comment{}).Where("user_id = ? AND status = ?", userID, 1)
// 获取总数
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
// 获取评论列表
err := query.Preload("Product").Preload("Replies", "status = ?", 1).Preload("Replies.User").
Order("created_at DESC").Offset(offset).Limit(limit).Find(&comments).Error
return comments, total, err
}
// GetByOrderItemID 根据订单项ID获取评论
func (r *CommentRepository) GetByOrderItemID(orderItemID uint) (*model.Comment, error) {
var comment model.Comment
err := r.db.Where("order_item_id = ? AND status = ?", orderItemID, 1).First(&comment).Error
if err != nil {
return nil, err
}
return &comment, nil
}
// Update 更新评论
func (r *CommentRepository) Update(comment *model.Comment) error {
return r.db.Save(comment).Error
}
// Delete 删除评论(软删除)
func (r *CommentRepository) Delete(id uint) error {
return r.db.Model(&model.Comment{}).Where("id = ?", id).Update("status", 3).Error
}
// GetStats 获取商品评论统计
func (r *CommentRepository) GetStats(productID uint) (*model.CommentStats, error) {
var stats model.CommentStats
stats.ProductID = productID
// 获取总评论数和平均评分
err := r.db.Model(&model.Comment{}).
Select("COUNT(*) as total_count, AVG(rating) as average_rating").
Where("product_id = ? AND status = ?", productID, 1).
Scan(&stats).Error
if err != nil {
return nil, err
}
// 获取各星级评论数
var ratingCounts []struct {
Rating int `json:"rating"`
Count int `json:"count"`
}
err = r.db.Model(&model.Comment{}).
Select("rating, COUNT(*) as count").
Where("product_id = ? AND status = ?", productID, 1).
Group("rating").
Scan(&ratingCounts).Error
if err != nil {
return nil, err
}
// 填充各星级评论数
for _, rc := range ratingCounts {
switch rc.Rating {
case 1:
stats.Rating1Count = rc.Count
case 2:
stats.Rating2Count = rc.Count
case 3:
stats.Rating3Count = rc.Count
case 4:
stats.Rating4Count = rc.Count
case 5:
stats.Rating5Count = rc.Count
}
}
// 获取带图评论数
var hasImagesCount int64
err = r.db.Model(&model.Comment{}).
Where("product_id = ? AND status = ? AND images != '' AND images != '[]'", productID, 1).
Count(&hasImagesCount).Error
if err != nil {
return nil, err
}
stats.HasImagesCount = int(hasImagesCount)
return &stats, nil
}
// GetList 获取评论列表(管理端使用)
func (r *CommentRepository) GetList(offset, limit int, conditions map[string]interface{}) ([]model.Comment, int64, error) {
var comments []model.Comment
var total int64
query := r.db.Model(&model.Comment{})
// 添加查询条件
for key, value := range conditions {
switch key {
case "product_id":
query = query.Where("product_id = ?", value)
case "user_id":
query = query.Where("user_id = ?", value)
case "rating":
query = query.Where("rating = ?", value)
case "status":
query = query.Where("status = ?", value)
case "keyword":
query = query.Where("content LIKE ?", "%"+value.(string)+"%")
}
}
// 获取总数
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
// 获取评论列表
err := query.Preload("User").Preload("Product").Preload("Order").
Order("created_at DESC").Offset(offset).Limit(limit).Find(&comments).Error
return comments, total, err
}
// CreateReply 创建评论回复
func (r *CommentRepository) CreateReply(reply *model.CommentReply) error {
tx := r.db.Begin()
// 创建回复
if err := tx.Create(reply).Error; err != nil {
tx.Rollback()
return err
}
// 更新评论回复数量
if err := tx.Model(&model.Comment{}).Where("id = ?", reply.CommentID).
UpdateColumn("reply_count", gorm.Expr("reply_count + ?", 1)).Error; err != nil {
tx.Rollback()
return err
}
return tx.Commit().Error
}
// GetReplies 获取评论回复列表
func (r *CommentRepository) GetReplies(commentID uint) ([]model.CommentReply, error) {
var replies []model.CommentReply
err := r.db.Where("comment_id = ? AND status = ?", commentID, 1).
Preload("User").Order("created_at ASC").Find(&replies).Error
return replies, err
}
// LikeComment 点赞评论
func (r *CommentRepository) LikeComment(commentID, userID uint) error {
tx := r.db.Begin()
// 检查是否已点赞
var count int64
if err := tx.Model(&model.CommentLike{}).Where("comment_id = ? AND user_id = ?", commentID, userID).Count(&count).Error; err != nil {
tx.Rollback()
return err
}
if count > 0 {
tx.Rollback()
return fmt.Errorf("已经点赞过了")
}
// 创建点赞记录
like := &model.CommentLike{
CommentID: commentID,
UserID: userID,
}
if err := tx.Create(like).Error; err != nil {
tx.Rollback()
return err
}
// 更新评论点赞数量
if err := tx.Model(&model.Comment{}).Where("id = ?", commentID).
UpdateColumn("like_count", gorm.Expr("like_count + ?", 1)).Error; err != nil {
tx.Rollback()
return err
}
return tx.Commit().Error
}
// UnlikeComment 取消点赞评论
func (r *CommentRepository) UnlikeComment(commentID, userID uint) error {
tx := r.db.Begin()
// 删除点赞记录
if err := tx.Where("comment_id = ? AND user_id = ?", commentID, userID).Delete(&model.CommentLike{}).Error; err != nil {
tx.Rollback()
return err
}
// 更新评论点赞数量
if err := tx.Model(&model.Comment{}).Where("id = ?", commentID).
UpdateColumn("like_count", gorm.Expr("like_count - ?", 1)).Error; err != nil {
tx.Rollback()
return err
}
return tx.Commit().Error
}
// UpdateProductStats 更新商品评论统计
func (r *CommentRepository) UpdateProductStats(productID uint) error {
var stats struct {
Count int `json:"count"`
Rating float64 `json:"rating"`
}
err := r.db.Model(&model.Comment{}).
Select("COUNT(*) as count, AVG(rating) as rating").
Where("product_id = ? AND status = ?", productID, 1).
Scan(&stats).Error
if err != nil {
return err
}
return r.db.Model(&model.Product{}).Where("id = ?", productID).
Updates(map[string]interface{}{
"comment_count": stats.Count,
"average_rating": stats.Rating,
}).Error
}