Initial commit
This commit is contained in:
464
server/internal/handler/comment.go
Normal file
464
server/internal/handler/comment.go
Normal file
@@ -0,0 +1,464 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"dianshang/internal/model"
|
||||
"dianshang/internal/service"
|
||||
"dianshang/pkg/response"
|
||||
"dianshang/pkg/utils"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type CommentHandler struct {
|
||||
commentService *service.CommentService
|
||||
}
|
||||
|
||||
// CommentResponse 评论响应结构
|
||||
type CommentResponse struct {
|
||||
ID uint `json:"id"`
|
||||
UserID uint `json:"user_id"`
|
||||
ProductID uint `json:"product_id"`
|
||||
OrderID uint `json:"order_id"`
|
||||
OrderItemID uint `json:"order_item_id"`
|
||||
Rating int `json:"rating"`
|
||||
Content string `json:"content"`
|
||||
Images []string `json:"images"`
|
||||
IsAnonymous bool `json:"is_anonymous"`
|
||||
Status int `json:"status"`
|
||||
ReplyCount int `json:"reply_count"`
|
||||
LikeCount int `json:"like_count"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
UserName string `json:"user_name"` // 映射字段
|
||||
OrderNo string `json:"order_no"` // 映射字段
|
||||
User *model.User `json:"user,omitempty"`
|
||||
Product *model.Product `json:"product,omitempty"`
|
||||
Order *model.Order `json:"order,omitempty"`
|
||||
OrderItem *model.OrderItem `json:"order_item,omitempty"`
|
||||
Replies []model.CommentReply `json:"replies,omitempty"`
|
||||
AdminReply *AdminReplyResponse `json:"admin_reply,omitempty"`
|
||||
}
|
||||
|
||||
// AdminReplyResponse 管理员回复响应结构
|
||||
type AdminReplyResponse struct {
|
||||
Content string `json:"content"`
|
||||
AdminName string `json:"admin_name"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
func NewCommentHandler(commentService *service.CommentService) *CommentHandler {
|
||||
return &CommentHandler{
|
||||
commentService: commentService,
|
||||
}
|
||||
}
|
||||
|
||||
// CreateComment 创建评论
|
||||
func (h *CommentHandler) CreateComment(c *gin.Context) {
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
response.Unauthorized(c)
|
||||
return
|
||||
}
|
||||
|
||||
var req service.CreateCommentRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
comment, err := h.commentService.CreateComment(userID.(uint), &req)
|
||||
if err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, comment)
|
||||
}
|
||||
|
||||
// GetProductComments 获取商品评论列表
|
||||
func (h *CommentHandler) GetProductComments(c *gin.Context) {
|
||||
productIDStr := c.Param("product_id")
|
||||
productID := utils.StringToUint(productIDStr)
|
||||
if productID == 0 {
|
||||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "商品ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
|
||||
rating, _ := strconv.Atoi(c.DefaultQuery("rating", "0"))
|
||||
|
||||
comments, total, err := h.commentService.GetProductComments(productID, page, pageSize, rating)
|
||||
if err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Page(c, comments, total, page, pageSize)
|
||||
}
|
||||
|
||||
// GetUserComments 获取用户评论列表
|
||||
func (h *CommentHandler) GetUserComments(c *gin.Context) {
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
response.Unauthorized(c)
|
||||
return
|
||||
}
|
||||
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
|
||||
|
||||
comments, total, err := h.commentService.GetUserComments(userID.(uint), page, pageSize)
|
||||
if err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Page(c, comments, total, page, pageSize)
|
||||
}
|
||||
|
||||
// GetCommentStats 获取商品评论统计
|
||||
func (h *CommentHandler) GetCommentStats(c *gin.Context) {
|
||||
productIDStr := c.Param("product_id")
|
||||
productID := utils.StringToUint(productIDStr)
|
||||
if productID == 0 {
|
||||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "商品ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
stats, err := h.commentService.GetCommentStats(productID)
|
||||
if err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, stats)
|
||||
}
|
||||
|
||||
// GetCommentDetail 获取评论详情
|
||||
func (h *CommentHandler) GetCommentDetail(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id := utils.StringToUint(idStr)
|
||||
if id == 0 {
|
||||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "评论ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
comment, err := h.commentService.GetCommentByID(id)
|
||||
if err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 转换为响应格式
|
||||
commentResponse := h.convertToResponse(*comment)
|
||||
response.Success(c, commentResponse)
|
||||
}
|
||||
|
||||
// CreateReply 创建评论回复
|
||||
func (h *CommentHandler) CreateReply(c *gin.Context) {
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
response.Unauthorized(c)
|
||||
return
|
||||
}
|
||||
|
||||
var req service.CreateReplyRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
reply, err := h.commentService.CreateReply(userID.(uint), &req, false)
|
||||
if err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, reply)
|
||||
}
|
||||
|
||||
// convertToResponse 转换评论为响应格式
|
||||
func (h *CommentHandler) convertToResponse(comment model.Comment) CommentResponse {
|
||||
// 解析图片数组
|
||||
var images []string
|
||||
if comment.Images != "" {
|
||||
if err := json.Unmarshal([]byte(comment.Images), &images); err != nil {
|
||||
// 如果解析失败,返回空数组
|
||||
images = []string{}
|
||||
}
|
||||
} else {
|
||||
images = []string{}
|
||||
}
|
||||
|
||||
result := CommentResponse{
|
||||
ID: comment.ID,
|
||||
UserID: comment.UserID,
|
||||
ProductID: comment.ProductID,
|
||||
OrderID: comment.OrderID,
|
||||
OrderItemID: comment.OrderItemID,
|
||||
Rating: comment.Rating,
|
||||
Content: comment.Content,
|
||||
Images: images,
|
||||
IsAnonymous: comment.IsAnonymous,
|
||||
Status: comment.Status,
|
||||
ReplyCount: comment.ReplyCount,
|
||||
LikeCount: comment.LikeCount,
|
||||
CreatedAt: comment.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: comment.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
User: &comment.User,
|
||||
Product: &comment.Product,
|
||||
Order: &comment.Order,
|
||||
OrderItem: &comment.OrderItem,
|
||||
Replies: comment.Replies,
|
||||
}
|
||||
|
||||
// 映射用户名字段
|
||||
if comment.User.ID > 0 {
|
||||
result.UserName = comment.User.Nickname
|
||||
}
|
||||
|
||||
// 映射订单号字段
|
||||
if comment.Order.ID > 0 {
|
||||
result.OrderNo = comment.Order.OrderNo
|
||||
}
|
||||
|
||||
// 提取管理员回复
|
||||
for _, reply := range comment.Replies {
|
||||
if reply.IsAdmin && reply.Status == 1 { // 只取正常状态的管理员回复
|
||||
adminName := "管理员"
|
||||
if reply.User.ID > 0 && reply.User.Nickname != "" {
|
||||
adminName = reply.User.Nickname
|
||||
}
|
||||
|
||||
result.AdminReply = &AdminReplyResponse{
|
||||
Content: reply.Content,
|
||||
AdminName: adminName,
|
||||
CreatedAt: reply.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
break // 只取第一个管理员回复
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// convertToResponseList 转换评论列表为响应格式
|
||||
func (h *CommentHandler) convertToResponseList(comments []model.Comment) []CommentResponse {
|
||||
result := make([]CommentResponse, len(comments))
|
||||
for i, comment := range comments {
|
||||
result[i] = h.convertToResponse(comment)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// LikeComment 点赞评论
|
||||
func (h *CommentHandler) LikeComment(c *gin.Context) {
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
response.Unauthorized(c)
|
||||
return
|
||||
}
|
||||
|
||||
idStr := c.Param("id")
|
||||
commentID := utils.StringToUint(idStr)
|
||||
if commentID == 0 {
|
||||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "评论ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
err := h.commentService.LikeComment(commentID, userID.(uint))
|
||||
if err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, nil)
|
||||
}
|
||||
|
||||
// UnlikeComment 取消点赞评论
|
||||
func (h *CommentHandler) UnlikeComment(c *gin.Context) {
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
response.Unauthorized(c)
|
||||
return
|
||||
}
|
||||
|
||||
idStr := c.Param("id")
|
||||
commentID := utils.StringToUint(idStr)
|
||||
if commentID == 0 {
|
||||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "评论ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
err := h.commentService.UnlikeComment(commentID, userID.(uint))
|
||||
if err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, nil)
|
||||
}
|
||||
|
||||
// GetUncommentedOrderItems 获取用户未评论的订单项
|
||||
func (h *CommentHandler) GetUncommentedOrderItems(c *gin.Context) {
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
response.Unauthorized(c)
|
||||
return
|
||||
}
|
||||
|
||||
orderItems, err := h.commentService.GetUncommentedOrderItems(userID.(uint))
|
||||
if err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, orderItems)
|
||||
}
|
||||
|
||||
// ===== 管理端接口 =====
|
||||
|
||||
// GetCommentListForAdmin 获取评论列表(管理端)
|
||||
func (h *CommentHandler) GetCommentListForAdmin(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||||
|
||||
conditions := make(map[string]interface{})
|
||||
|
||||
if productID := c.Query("product_id"); productID != "" {
|
||||
conditions["product_id"] = utils.StringToUint(productID)
|
||||
}
|
||||
if userID := c.Query("user_id"); userID != "" {
|
||||
conditions["user_id"] = utils.StringToUint(userID)
|
||||
}
|
||||
if rating := c.Query("rating"); rating != "" {
|
||||
conditions["rating"] = utils.StringToUint(rating)
|
||||
}
|
||||
if status := c.Query("status"); status != "" {
|
||||
conditions["status"] = utils.StringToUint(status)
|
||||
}
|
||||
if keyword := c.Query("keyword"); keyword != "" {
|
||||
conditions["keyword"] = keyword
|
||||
}
|
||||
|
||||
comments, total, err := h.commentService.GetCommentList(page, pageSize, conditions)
|
||||
if err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 转换为响应格式
|
||||
commentsResponse := h.convertToResponseList(comments)
|
||||
response.Page(c, commentsResponse, total, page, pageSize)
|
||||
}
|
||||
|
||||
// UpdateCommentStatus 更新评论状态(管理端)
|
||||
func (h *CommentHandler) UpdateCommentStatus(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id := utils.StringToUint(idStr)
|
||||
if id == 0 {
|
||||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "评论ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
Status int `json:"status" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
err := h.commentService.UpdateCommentStatus(id, req.Status)
|
||||
if err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, nil)
|
||||
}
|
||||
|
||||
// DeleteComment 删除评论(管理端)
|
||||
func (h *CommentHandler) DeleteComment(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id := utils.StringToUint(idStr)
|
||||
if id == 0 {
|
||||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "评论ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
err := h.commentService.DeleteComment(id)
|
||||
if err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, nil)
|
||||
}
|
||||
|
||||
// CreateAdminReply 管理员回复评论
|
||||
func (h *CommentHandler) CreateAdminReply(c *gin.Context) {
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
response.Unauthorized(c)
|
||||
return
|
||||
}
|
||||
|
||||
var req service.CreateReplyRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
reply, err := h.commentService.CreateReply(userID.(uint), &req, true)
|
||||
if err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, reply)
|
||||
}
|
||||
|
||||
// CreateAdminReplyForComment 管理员回复指定评论
|
||||
func (h *CommentHandler) CreateAdminReplyForComment(c *gin.Context) {
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
response.Unauthorized(c)
|
||||
return
|
||||
}
|
||||
|
||||
// 从URL参数获取评论ID
|
||||
commentIDStr := c.Param("id")
|
||||
commentID := utils.StringToUint(commentIDStr)
|
||||
if commentID == 0 {
|
||||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "无效的评论ID")
|
||||
return
|
||||
}
|
||||
|
||||
// 定义请求结构,只需要content字段
|
||||
var reqBody struct {
|
||||
Content string `json:"content" binding:"required"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&reqBody); err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 构造CreateReplyRequest
|
||||
req := service.CreateReplyRequest{
|
||||
CommentID: commentID,
|
||||
Content: reqBody.Content,
|
||||
}
|
||||
|
||||
reply, err := h.commentService.CreateReply(userID.(uint), &req, true)
|
||||
if err != nil {
|
||||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, reply)
|
||||
}
|
||||
Reference in New Issue
Block a user