243 lines
5.9 KiB
Go
243 lines
5.9 KiB
Go
package handlers
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/niangaodev/art-code/models"
|
|
"github.com/niangaodev/art-code/repositories"
|
|
"github.com/niangaodev/art-code/utils"
|
|
)
|
|
|
|
// 获取博客文章列表
|
|
func GetPosts(c *gin.Context) {
|
|
// 获取查询参数
|
|
keyword := c.Query("q")
|
|
|
|
// 从数据库获取所有博客文章
|
|
posts, err := repositories.GetPosts(keyword)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch posts"})
|
|
return
|
|
}
|
|
|
|
// 构建响应
|
|
responses := repositories.BuildPostsResponse(posts)
|
|
|
|
c.JSON(http.StatusOK, responses)
|
|
}
|
|
|
|
func GetPost(c *gin.Context) {
|
|
idStr := c.Param("id")
|
|
// 转换ID
|
|
var id uint
|
|
if _, err := fmt.Sscanf(idStr, "%d", &id); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid post ID"})
|
|
return
|
|
}
|
|
|
|
// 从数据库获取博客文章
|
|
post, err := repositories.GetPostByID(id)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch post"})
|
|
return
|
|
}
|
|
|
|
if post == nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Post not found"})
|
|
return
|
|
}
|
|
|
|
// 构建响应,包含内容
|
|
response := repositories.BuildPostResponse(post, true)
|
|
|
|
// 记录用户访问日志 (异步执行,不阻塞响应)
|
|
go func() {
|
|
// 获取客户端IP
|
|
ip := c.ClientIP()
|
|
|
|
// 获取归属地
|
|
location := utils.GetRegion(ip)
|
|
|
|
// 获取用户ID (如果已登录)
|
|
var userID uint = 0
|
|
if uid, exists := c.Get("userID"); exists {
|
|
userID = uid.(uint)
|
|
}
|
|
|
|
logEntry := &models.UserAccessLog{
|
|
UserID: userID,
|
|
UserIP: ip,
|
|
UserLocation: location,
|
|
ArticleID: post.ID,
|
|
}
|
|
|
|
if err := repositories.CreateUserAccessLog(logEntry); err != nil {
|
|
log.Printf("Failed to create access log: %v", err)
|
|
}
|
|
}()
|
|
|
|
c.JSON(http.StatusOK, response)
|
|
}
|
|
|
|
func GetPostsByTagID(c *gin.Context) {
|
|
// 解析标签ID
|
|
idStr := c.Param("id")
|
|
var id uint
|
|
_, err := fmt.Sscanf(idStr, "%d", &id)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid tag ID"})
|
|
return
|
|
}
|
|
|
|
// 从数据库获取标签相关的文章
|
|
posts, err := repositories.GetPostsByTagID(id)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch posts by tag"})
|
|
return
|
|
}
|
|
|
|
// 构建响应
|
|
responses := repositories.BuildPostsResponse(posts)
|
|
|
|
c.JSON(http.StatusOK, responses)
|
|
}
|
|
|
|
// 获取所有文章(包括未发布的)
|
|
func AdminGetPosts(c *gin.Context) {
|
|
posts, err := repositories.GetAllPosts()
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get posts"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, repositories.BuildPostsResponse(posts))
|
|
}
|
|
|
|
// 创建文章
|
|
func AdminCreatePost(c *gin.Context) {
|
|
var post models.Post
|
|
if err := c.ShouldBindJSON(&post); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
|
|
return
|
|
}
|
|
|
|
// 创建文章
|
|
if err := repositories.CreatePost(&post); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create post"})
|
|
return
|
|
}
|
|
|
|
// 保存历史记录
|
|
userID, _ := c.Get("userID")
|
|
if err := repositories.SavePostHistory(&post, userID.(uint)); err != nil {
|
|
log.Printf("Error saving post history: %v", err)
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "Post created successfully"})
|
|
}
|
|
|
|
// 更新文章
|
|
func AdminUpdatePost(c *gin.Context) {
|
|
postIDStr := c.Param("id")
|
|
var postID uint
|
|
if _, err := fmt.Sscanf(postIDStr, "%d", &postID); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid post ID"})
|
|
return
|
|
}
|
|
|
|
var post models.Post
|
|
if err := c.ShouldBindJSON(&post); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
|
|
return
|
|
}
|
|
|
|
// 设置文章ID
|
|
post.ID = postID
|
|
|
|
// 更新文章
|
|
if err := repositories.UpdatePost(&post); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update post"})
|
|
return
|
|
}
|
|
|
|
// 保存历史记录
|
|
userID, _ := c.Get("userID")
|
|
if err := repositories.SavePostHistory(&post, userID.(uint)); err != nil {
|
|
log.Printf("Error saving post history: %v", err)
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "Post updated successfully"})
|
|
}
|
|
|
|
// 删除文章
|
|
func AdminDeletePost(c *gin.Context) {
|
|
postIDStr := c.Param("id")
|
|
var postID uint
|
|
if _, err := fmt.Sscanf(postIDStr, "%d", &postID); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid post ID"})
|
|
return
|
|
}
|
|
|
|
// 删除文章
|
|
if err := repositories.DeletePost(postID); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete post"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "Post deleted successfully"})
|
|
}
|
|
|
|
// 获取文章历史记录
|
|
func AdminGetPostHistory(c *gin.Context) {
|
|
postIDStr := c.Param("id")
|
|
var postID uint
|
|
if _, err := fmt.Sscanf(postIDStr, "%d", &postID); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid post ID"})
|
|
return
|
|
}
|
|
|
|
history, err := repositories.GetPostHistory(postID)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get post history"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, repositories.BuildPostHistoryResponses(history))
|
|
}
|
|
|
|
// 获取指定版本的文章历史记录
|
|
func AdminGetPostHistoryByVersion(c *gin.Context) {
|
|
postIDStr := c.Param("id")
|
|
var postID uint
|
|
if _, err := fmt.Sscanf(postIDStr, "%d", &postID); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid post ID"})
|
|
return
|
|
}
|
|
|
|
version := c.Param("version")
|
|
|
|
// 转换版本号为uint
|
|
var versionUint uint
|
|
_, err := fmt.Sscanf(version, "%d", &versionUint)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid version"})
|
|
return
|
|
}
|
|
|
|
history, err := repositories.GetPostHistoryByVersion(postID, versionUint)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get post history"})
|
|
return
|
|
}
|
|
|
|
if history == nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "History not found"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, repositories.BuildPostHistoryResponse(history))
|
|
}
|