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 } // GetHighRatingComments 获取高分评论(用于首页展示) func (r *CommentRepository) GetHighRatingComments(limit int, minRating int) ([]model.Comment, error) { var comments []model.Comment // 获取评分>=minRating的评论,按评分降序、创建时间降序排列 err := r.db.Model(&model.Comment{}). Where("status = ? AND rating >= ?", 1, minRating). Preload("User"). Preload("Product"). Order("rating DESC, created_at DESC"). Limit(limit). Find(&comments).Error return comments, err } // 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 }