Files
new-api/controller/document.go
T
2026-06-14 21:20:47 +08:00

257 lines
6.0 KiB
Go

package controller
import (
"net/http"
"strconv"
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/model"
"github.com/gin-gonic/gin"
)
// GetCategories 获取文档分类列表(公开)
func GetCategories(c *gin.Context) {
categories, err := model.GetDocumentCategories()
if err != nil {
common.ApiError(c, err)
return
}
common.ApiSuccess(c, categories)
}
// CreateCategory 创建文档分类(管理员)
func CreateCategory(c *gin.Context) {
var category model.DocumentCategory
if err := c.ShouldBindJSON(&category); err != nil {
common.ApiError(c, err)
return
}
if category.Name == "" {
common.ApiErrorMsg(c, "分类名称不能为空")
return
}
if category.Slug == "" {
common.ApiErrorMsg(c, "分类标识不能为空")
return
}
if err := model.CreateDocumentCategory(&category); err != nil {
common.ApiError(c, err)
return
}
common.ApiSuccess(c, &category)
}
// UpdateCategory 更新文档分类(管理员)
func UpdateCategory(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
common.ApiError(c, err)
return
}
var category model.DocumentCategory
if err := c.ShouldBindJSON(&category); err != nil {
common.ApiError(c, err)
return
}
category.Id = id
if err := model.UpdateDocumentCategory(&category); err != nil {
common.ApiError(c, err)
return
}
common.ApiSuccess(c, &category)
}
// DeleteCategory 删除文档分类(管理员)
func DeleteCategory(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
common.ApiError(c, err)
return
}
if err := model.DeleteDocumentCategory(id); err != nil {
common.ApiError(c, err)
return
}
common.ApiSuccess(c, nil)
}
// GetDocuments 获取文档列表(公开,根据认证状态过滤可见性)
func GetDocuments(c *gin.Context) {
keyword := c.Query("keyword")
categoryIdStr := c.Query("category_id")
var categoryId *int
if categoryIdStr != "" {
id, err := strconv.Atoi(categoryIdStr)
if err == nil {
categoryId = &id
}
}
pageInfo := common.GetPageQuery(c)
// 根据用户认证状态决定可见性过滤
visibility := c.Query("visibility")
role := c.GetInt("role")
var documents []*model.Document
var total int64
var err error
if role >= common.RoleAdminUser {
// 管理员可看所有
documents, total, err = model.GetDocuments(keyword, visibility, categoryId, pageInfo.GetStartIdx(), pageInfo.GetPageSize())
} else if role >= common.RoleCommonUser {
// 普通用户只能看 public 和 auth
if visibility == "public" || visibility == "auth" {
documents, total, err = model.GetDocuments(keyword, visibility, categoryId, pageInfo.GetStartIdx(), pageInfo.GetPageSize())
} else {
documents, total, err = model.GetDocumentsByVisibility(keyword, []string{"public", "auth"}, categoryId, pageInfo.GetStartIdx(), pageInfo.GetPageSize())
}
} else {
// 未登录用户只能看 public
documents, total, err = model.GetDocuments(keyword, "public", categoryId, pageInfo.GetStartIdx(), pageInfo.GetPageSize())
}
if err != nil {
common.ApiError(c, err)
return
}
pageInfo.SetTotal(int(total))
pageInfo.SetItems(documents)
common.ApiSuccess(c, pageInfo)
}
// GetDocument 获取单个文档(根据可见性检查权限)
func GetDocument(c *gin.Context) {
slug := c.Param("slug")
doc, err := model.GetDocumentBySlug(slug)
if err != nil {
common.ApiError(c, err)
return
}
// 检查可见性权限
role := c.GetInt("role")
switch doc.Visibility {
case "admin":
if role < common.RoleAdminUser {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "无权访问该文档",
})
return
}
case "auth":
if role < common.RoleCommonUser {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "请先登录后查看该文档",
})
return
}
}
common.ApiSuccess(c, doc)
}
// CreateDocument 创建文档(管理员)
func CreateDocument(c *gin.Context) {
var doc model.Document
if err := c.ShouldBindJSON(&doc); err != nil {
common.ApiError(c, err)
return
}
if doc.Title == "" {
common.ApiErrorMsg(c, "文档标题不能为空")
return
}
if doc.Slug == "" {
common.ApiErrorMsg(c, "文档标识不能为空")
return
}
if doc.Content == "" {
common.ApiErrorMsg(c, "文档内容不能为空")
return
}
if doc.Visibility == "" {
doc.Visibility = "public"
}
doc.AuthorId = c.GetInt("id")
if err := model.CreateDocument(&doc); err != nil {
common.ApiError(c, err)
return
}
common.ApiSuccess(c, &doc)
}
// UpdateDocument 更新文档(管理员,自动创建版本记录)
func UpdateDocument(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
common.ApiError(c, err)
return
}
var doc model.Document
if err := c.ShouldBindJSON(&doc); err != nil {
common.ApiError(c, err)
return
}
doc.Id = id
// 获取旧文档内容,自动创建版本记录
oldDoc, err := model.GetDocumentById(id)
if err != nil {
common.ApiError(c, err)
return
}
version := &model.DocumentVersion{
DocumentId: oldDoc.Id,
Content: oldDoc.Content,
AuthorId: oldDoc.AuthorId,
}
if err := model.CreateDocumentVersion(version); err != nil {
common.ApiError(c, err)
return
}
if err := model.UpdateDocument(&doc); err != nil {
common.ApiError(c, err)
return
}
common.ApiSuccess(c, &doc)
}
// DeleteDocument 删除文档(管理员)
func DeleteDocument(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
common.ApiError(c, err)
return
}
if err := model.DeleteDocument(id); err != nil {
common.ApiError(c, err)
return
}
common.ApiSuccess(c, nil)
}
// GetDocumentVersions 获取文档版本历史(管理员)
func GetDocumentVersions(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
common.ApiError(c, err)
return
}
pageInfo := common.GetPageQuery(c)
versions, total, err := model.GetDocumentVersions(id, pageInfo.GetStartIdx(), pageInfo.GetPageSize())
if err != nil {
common.ApiError(c, err)
return
}
pageInfo.SetTotal(int(total))
pageInfo.SetItems(versions)
common.ApiSuccess(c, pageInfo)
}