202 lines
5.9 KiB
Go
202 lines
5.9 KiB
Go
|
|
package service
|
||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/json"
|
||
|
|
"fmt"
|
||
|
|
"dianshang/internal/model"
|
||
|
|
"dianshang/internal/repository"
|
||
|
|
)
|
||
|
|
|
||
|
|
type CommentService struct {
|
||
|
|
commentRepo *repository.CommentRepository
|
||
|
|
orderRepo *repository.OrderRepository
|
||
|
|
productRepo *repository.ProductRepository
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewCommentService(commentRepo *repository.CommentRepository, orderRepo *repository.OrderRepository, productRepo *repository.ProductRepository) *CommentService {
|
||
|
|
return &CommentService{
|
||
|
|
commentRepo: commentRepo,
|
||
|
|
orderRepo: orderRepo,
|
||
|
|
productRepo: productRepo,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// CreateCommentRequest 创建评论请求
|
||
|
|
type CreateCommentRequest struct {
|
||
|
|
OrderItemID uint `json:"order_item_id" binding:"required"`
|
||
|
|
Rating int `json:"rating" binding:"required,min=1,max=5"`
|
||
|
|
Content string `json:"content"`
|
||
|
|
Images []string `json:"images"`
|
||
|
|
IsAnonymous bool `json:"is_anonymous"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// CreateComment 创建评论
|
||
|
|
func (s *CommentService) CreateComment(userID uint, req *CreateCommentRequest) (*model.Comment, error) {
|
||
|
|
// 1. 验证订单项是否存在且属于该用户
|
||
|
|
orderItem, err := s.orderRepo.GetOrderItemByID(req.OrderItemID)
|
||
|
|
if err != nil {
|
||
|
|
return nil, fmt.Errorf("订单项不存在")
|
||
|
|
}
|
||
|
|
|
||
|
|
// 获取订单信息验证用户权限
|
||
|
|
order, err := s.orderRepo.GetByID(orderItem.OrderID)
|
||
|
|
if err != nil {
|
||
|
|
return nil, fmt.Errorf("订单不存在")
|
||
|
|
}
|
||
|
|
|
||
|
|
if order.UserID != userID {
|
||
|
|
return nil, fmt.Errorf("无权限评论此商品")
|
||
|
|
}
|
||
|
|
|
||
|
|
// 2. 验证订单状态(只有已完成的订单才能评论)
|
||
|
|
if order.Status != model.OrderStatusCompleted {
|
||
|
|
return nil, fmt.Errorf("订单未完成,无法评论")
|
||
|
|
}
|
||
|
|
|
||
|
|
// 3. 检查是否已经评论过
|
||
|
|
if orderItem.IsCommented {
|
||
|
|
return nil, fmt.Errorf("该商品已经评论过了")
|
||
|
|
}
|
||
|
|
|
||
|
|
// 4. 处理图片数据
|
||
|
|
var imagesJSON string
|
||
|
|
if len(req.Images) > 0 {
|
||
|
|
imagesBytes, _ := json.Marshal(req.Images)
|
||
|
|
imagesJSON = string(imagesBytes)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 5. 创建评论
|
||
|
|
comment := &model.Comment{
|
||
|
|
UserID: userID,
|
||
|
|
ProductID: orderItem.ProductID,
|
||
|
|
OrderID: orderItem.OrderID,
|
||
|
|
OrderItemID: req.OrderItemID,
|
||
|
|
Rating: req.Rating,
|
||
|
|
Content: req.Content,
|
||
|
|
Images: imagesJSON,
|
||
|
|
IsAnonymous: req.IsAnonymous,
|
||
|
|
Status: 1,
|
||
|
|
}
|
||
|
|
|
||
|
|
if err := s.commentRepo.Create(comment); err != nil {
|
||
|
|
return nil, fmt.Errorf("创建评论失败: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 6. 更新订单项评论状态
|
||
|
|
orderItem.IsCommented = true
|
||
|
|
if err := s.orderRepo.SaveOrderItem(orderItem); err != nil {
|
||
|
|
return nil, fmt.Errorf("更新订单项状态失败: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 7. 更新商品评论统计
|
||
|
|
if err := s.commentRepo.UpdateProductStats(orderItem.ProductID); err != nil {
|
||
|
|
return nil, fmt.Errorf("更新商品统计失败: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
return comment, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetProductComments 获取商品评论列表
|
||
|
|
func (s *CommentService) GetProductComments(productID uint, page, pageSize int, rating int) ([]model.Comment, int64, error) {
|
||
|
|
offset := (page - 1) * pageSize
|
||
|
|
return s.commentRepo.GetByProductID(productID, offset, pageSize, rating)
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetUserComments 获取用户评论列表
|
||
|
|
func (s *CommentService) GetUserComments(userID uint, page, pageSize int) ([]model.Comment, int64, error) {
|
||
|
|
offset := (page - 1) * pageSize
|
||
|
|
return s.commentRepo.GetByUserID(userID, offset, pageSize)
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetCommentStats 获取商品评论统计
|
||
|
|
func (s *CommentService) GetCommentStats(productID uint) (*model.CommentStats, error) {
|
||
|
|
return s.commentRepo.GetStats(productID)
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetCommentByID 获取评论详情
|
||
|
|
func (s *CommentService) GetCommentByID(id uint) (*model.Comment, error) {
|
||
|
|
return s.commentRepo.GetByID(id)
|
||
|
|
}
|
||
|
|
|
||
|
|
// CreateReplyRequest 创建回复请求
|
||
|
|
type CreateReplyRequest struct {
|
||
|
|
CommentID uint `json:"comment_id" binding:"required"`
|
||
|
|
Content string `json:"content" binding:"required"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// CreateReply 创建评论回复
|
||
|
|
func (s *CommentService) CreateReply(userID uint, req *CreateReplyRequest, isAdmin bool) (*model.CommentReply, error) {
|
||
|
|
// 验证评论是否存在
|
||
|
|
comment, err := s.commentRepo.GetByID(req.CommentID)
|
||
|
|
if err != nil {
|
||
|
|
return nil, fmt.Errorf("评论不存在")
|
||
|
|
}
|
||
|
|
|
||
|
|
if comment.Status != 1 {
|
||
|
|
return nil, fmt.Errorf("评论状态异常,无法回复")
|
||
|
|
}
|
||
|
|
|
||
|
|
// 创建回复
|
||
|
|
reply := &model.CommentReply{
|
||
|
|
CommentID: req.CommentID,
|
||
|
|
UserID: userID,
|
||
|
|
Content: req.Content,
|
||
|
|
IsAdmin: isAdmin,
|
||
|
|
Status: 1,
|
||
|
|
}
|
||
|
|
|
||
|
|
if err := s.commentRepo.CreateReply(reply); err != nil {
|
||
|
|
return nil, fmt.Errorf("创建回复失败: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
return reply, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// LikeComment 点赞评论
|
||
|
|
func (s *CommentService) LikeComment(commentID, userID uint) error {
|
||
|
|
return s.commentRepo.LikeComment(commentID, userID)
|
||
|
|
}
|
||
|
|
|
||
|
|
// UnlikeComment 取消点赞评论
|
||
|
|
func (s *CommentService) UnlikeComment(commentID, userID uint) error {
|
||
|
|
return s.commentRepo.UnlikeComment(commentID, userID)
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetCommentList 获取评论列表(管理端)
|
||
|
|
func (s *CommentService) GetCommentList(page, pageSize int, conditions map[string]interface{}) ([]model.Comment, int64, error) {
|
||
|
|
offset := (page - 1) * pageSize
|
||
|
|
return s.commentRepo.GetList(offset, pageSize, conditions)
|
||
|
|
}
|
||
|
|
|
||
|
|
// UpdateCommentStatus 更新评论状态(管理端)
|
||
|
|
func (s *CommentService) UpdateCommentStatus(id uint, status int) error {
|
||
|
|
comment, err := s.commentRepo.GetByID(id)
|
||
|
|
if err != nil {
|
||
|
|
return fmt.Errorf("评论不存在")
|
||
|
|
}
|
||
|
|
|
||
|
|
comment.Status = status
|
||
|
|
if err := s.commentRepo.Update(comment); err != nil {
|
||
|
|
return fmt.Errorf("更新评论状态失败: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 如果是隐藏或删除评论,需要更新商品统计
|
||
|
|
if status != 1 {
|
||
|
|
if err := s.commentRepo.UpdateProductStats(comment.ProductID); err != nil {
|
||
|
|
return fmt.Errorf("更新商品统计失败: %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// DeleteComment 删除评论(管理端)
|
||
|
|
func (s *CommentService) DeleteComment(id uint) error {
|
||
|
|
return s.UpdateCommentStatus(id, 3)
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetUncommentedOrderItems 获取用户未评论的订单项
|
||
|
|
func (s *CommentService) GetUncommentedOrderItems(userID uint) ([]model.OrderItem, error) {
|
||
|
|
// 获取用户已完成但未评论的订单项
|
||
|
|
return s.orderRepo.GetUncommentedOrderItems(userID)
|
||
|
|
}
|