Files
memory/server/internal/handler/comment.go
2025-12-14 20:33:33 +08:00

120 lines
3.0 KiB
Go

package handler
import (
"database/sql"
"net/http"
"strconv"
"memory/internal/config"
"memory/internal/middleware"
"memory/internal/model"
"github.com/gin-gonic/gin"
)
type CommentHandler struct {
db *sql.DB
cfg *config.Config
}
func NewCommentHandler(db *sql.DB, cfg *config.Config) *CommentHandler {
return &CommentHandler{db: db, cfg: cfg}
}
func (h *CommentHandler) Create(c *gin.Context) {
postID, _ := strconv.ParseInt(c.Param("id"), 10, 64)
userID := middleware.GetUserID(c)
var req model.CreateCommentRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 检查帖子是否存在
var exists int
err := h.db.QueryRow("SELECT COUNT(*) FROM posts WHERE id = ?", postID).Scan(&exists)
if err != nil || exists == 0 {
c.JSON(http.StatusNotFound, gin.H{"error": "post not found"})
return
}
result, err := h.db.Exec(
"INSERT INTO comments (post_id, user_id, content) VALUES (?, ?, ?)",
postID, userID, req.Content,
)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create comment"})
return
}
commentID, _ := result.LastInsertId()
c.JSON(http.StatusCreated, gin.H{"id": commentID})
}
func (h *CommentHandler) List(c *gin.Context) {
postID, _ := strconv.ParseInt(c.Param("id"), 10, 64)
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
offset := (page - 1) * pageSize
rows, err := h.db.Query(`
SELECT c.id, c.post_id, c.user_id, c.content, c.created_at,
u.id, u.username, u.nickname, u.avatar_url
FROM comments c
JOIN users u ON c.user_id = u.id
WHERE c.post_id = ?
ORDER BY c.created_at ASC
LIMIT ? OFFSET ?
`, postID, pageSize, offset)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "database error"})
return
}
defer rows.Close()
comments := []model.Comment{}
for rows.Next() {
var comment model.Comment
var user model.User
err := rows.Scan(
&comment.ID, &comment.PostID, &comment.UserID, &comment.Content, &comment.CreatedAt,
&user.ID, &user.Username, &user.Nickname, &user.AvatarURL,
)
if err != nil {
continue
}
comment.User = &user
comments = append(comments, comment)
}
c.JSON(http.StatusOK, comments)
}
func (h *CommentHandler) Delete(c *gin.Context) {
commentID, _ := strconv.ParseInt(c.Param("comment_id"), 10, 64)
userID := middleware.GetUserID(c)
isAdmin, _ := c.Get("is_admin")
// 检查权限
var commentUserID int64
err := h.db.QueryRow("SELECT user_id FROM comments WHERE id = ?", commentID).Scan(&commentUserID)
if err == sql.ErrNoRows {
c.JSON(http.StatusNotFound, gin.H{"error": "comment not found"})
return
}
if commentUserID != userID && !isAdmin.(bool) {
c.JSON(http.StatusForbidden, gin.H{"error": "permission denied"})
return
}
_, err = h.db.Exec("DELETE FROM comments WHERE id = ?", commentID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to delete comment"})
return
}
c.JSON(http.StatusOK, gin.H{"message": "deleted"})
}