评论变为ajax加载 和提交
This commit is contained in:
+56
-57
@@ -2,6 +2,7 @@ package backend
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"goblog/database"
|
||||
"goblog/models"
|
||||
@@ -10,43 +11,72 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 创建评论请求
|
||||
type CreateCommentRequest struct {
|
||||
PostID uint `json:"post_id" binding:"required"`
|
||||
ParentID *uint `json:"parent_id"`
|
||||
Author string `json:"author" binding:"required"`
|
||||
Email string `json:"email" binding:"required,email"`
|
||||
Website string `json:"website"`
|
||||
Content string `json:"content" binding:"required"`
|
||||
}
|
||||
|
||||
// 获取评论列表
|
||||
func GetComments(c *gin.Context) {
|
||||
postID := c.Query("post_id")
|
||||
postSlug := c.Query("post_slug") // 前台使用 slug
|
||||
status := c.Query("status")
|
||||
pageStr := c.DefaultQuery("page", "1")
|
||||
pageSizeStr := c.DefaultQuery("page_size", "10")
|
||||
|
||||
// 解析分页参数
|
||||
page := 1
|
||||
pageSize := 10
|
||||
if p, err := strconv.Atoi(pageStr); err == nil && p > 0 {
|
||||
page = p
|
||||
}
|
||||
if ps, err := strconv.Atoi(pageSizeStr); err == nil && ps > 0 && ps <= 100 {
|
||||
pageSize = ps
|
||||
}
|
||||
|
||||
db := database.DB.Model(&models.Comment{}).Preload("User").
|
||||
Preload("Post", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "title", "slug")
|
||||
})
|
||||
|
||||
// 非管理员只能查看自己文章上的评论
|
||||
// 非管理员只能查看自己文章上的评论(后台)或已审核的评论(前台)
|
||||
if !isAdmin(c) {
|
||||
// 前台访问:只显示已审核的评论
|
||||
db = db.Where("status = ?", "approved")
|
||||
if userID, exists := c.Get("userID"); exists {
|
||||
db = db.Where("post_id IN (?)",
|
||||
database.DB.Model(&models.Post{}).Select("id").Where("author_id = ?", userID))
|
||||
// 如果是后台接口调用,限制为自己的文章
|
||||
if postID == "" && postSlug == "" {
|
||||
db = db.Where("post_id IN (?)",
|
||||
database.DB.Model(&models.Post{}).Select("id").Where("author_id = ?", userID))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 管理员可以查看所有状态的评论(通过 status 参数过滤)
|
||||
if status != "" {
|
||||
db = db.Where("status = ?", status)
|
||||
}
|
||||
}
|
||||
|
||||
// 按文章 ID 或 slug 过滤
|
||||
if postID != "" {
|
||||
db = db.Where("post_id = ?", postID)
|
||||
}
|
||||
if status != "" {
|
||||
db = db.Where("status = ?", status)
|
||||
} else if postSlug != "" {
|
||||
var post models.Post
|
||||
if err := database.DB.Where("slug = ?", postSlug).First(&post).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "文章不存在"})
|
||||
return
|
||||
}
|
||||
db = db.Where("post_id = ?", post.ID)
|
||||
}
|
||||
|
||||
// 统计总数
|
||||
var total int64
|
||||
db.Count(&total)
|
||||
|
||||
// 只查询顶级评论(parent_id IS NULL),子评论在 Preload 中加载
|
||||
var comments []models.Comment
|
||||
db.Order("created_at DESC").Find(&comments)
|
||||
offset := (page - 1) * pageSize
|
||||
db.Where("parent_id IS NULL").Order("created_at ASC").Offset(offset).Limit(pageSize).Find(&comments)
|
||||
|
||||
// 预加载子评论
|
||||
for i := range comments {
|
||||
database.DB.Model(&comments[i]).Association("Children").Find(&comments[i].Children)
|
||||
}
|
||||
|
||||
// Comment.Post 在 JSON 中被隐藏,额外附加文章标题和别名供前端展示
|
||||
type commentWithPost struct {
|
||||
@@ -59,48 +89,17 @@ func GetComments(c *gin.Context) {
|
||||
list = append(list, commentWithPost{cm, cm.Post.Title, cm.Post.Slug})
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"data": list})
|
||||
}
|
||||
|
||||
// 创建评论
|
||||
func CreateComment(c *gin.Context) {
|
||||
var req CreateCommentRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
totalPages := int((total + int64(pageSize) - 1) / int64(pageSize))
|
||||
if totalPages < 1 {
|
||||
totalPages = 1
|
||||
}
|
||||
|
||||
// 检查文章是否存在
|
||||
var post models.Post
|
||||
if err := database.DB.First(&post, req.PostID).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "文章不存在"})
|
||||
return
|
||||
}
|
||||
|
||||
comment := models.Comment{
|
||||
PostID: req.PostID,
|
||||
ParentID: req.ParentID,
|
||||
Author: req.Author,
|
||||
Email: req.Email,
|
||||
Website: req.Website,
|
||||
Content: req.Content,
|
||||
IP: c.ClientIP(),
|
||||
Status: "pending", // 默认待审核
|
||||
}
|
||||
|
||||
// 如果用户已登录
|
||||
if userID, exists := c.Get("userID"); exists {
|
||||
uid := userID.(uint)
|
||||
comment.UserID = &uid
|
||||
comment.Status = "approved" // 登录用户评论自动通过
|
||||
}
|
||||
|
||||
if err := database.DB.Create(&comment).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "发表评论失败"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, gin.H{"data": comment})
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"data": list,
|
||||
"page": page,
|
||||
"total_pages": totalPages,
|
||||
"total": total,
|
||||
})
|
||||
}
|
||||
|
||||
// loadAndVerifyComment 加载评论并校验权限,成功返回评论,失败直接写响应并返回 nil
|
||||
|
||||
Reference in New Issue
Block a user