Files
X-Agents/server/internal/handler/knowledge_handler.go
DESKTOP-72TV0V4\caoxiaozhu fdd6b2c17d fix: 优化后端各模块 handler
- database_handler, knowledge_handler, model_handler
- neo4j_handler, sub_table_handler
- system_handler, upload_handler
- knowledge_service, upload_service

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:26:04 +08:00

319 lines
9.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package handler
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"x-agents/server/internal/model"
"x-agents/server/internal/service"
)
type KnowledgeHandler struct {
service *service.KnowledgeService
}
func NewKnowledgeHandler(s *service.KnowledgeService) *KnowledgeHandler {
return &KnowledgeHandler{service: s}
}
// @Summary 创建知识库
// @Description 创建一个新的知识库
// @Tags 知识库
// @Accept json
// @Produce json
// @Param request body model.CreateKnowledgeRequest true "知识库信息"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]string
// @Router /api/knowledge/create [post]
func (h *KnowledgeHandler) Create(c *gin.Context) {
var req model.CreateKnowledgeRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": err.Error()})
return
}
kb, err := h.service.Create(req)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"id": kb.ID,
"message": "Knowledge base created successfully",
})
}
// @Summary 获取知识库列表
// @Description 获取所有知识库列表
// @Tags 知识库
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{}
// @Failure 500 {object} map[string]string
// @Router /api/knowledge/list [get]
func (h *KnowledgeHandler) List(c *gin.Context) {
list, err := h.service.List()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"success": true, "data": list})
}
// @Summary 获取知识库详情
// @Description 根据ID获取知识库详细信息
// @Tags 知识库
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]string
// @Failure 404 {object} map[string]string
// @Router /api/knowledge/{id} [get]
func (h *KnowledgeHandler) GetByID(c *gin.Context) {
id := c.Param("id")
if id == "" {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "id is required"})
return
}
kb, err := h.service.GetByID(id)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"success": false, "message": "Knowledge base not found"})
return
}
c.JSON(http.StatusOK, gin.H{"success": true, "data": kb})
}
// @Summary 更新知识库
// @Description 更新指定知识库的信息
// @Tags 知识库
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param request body model.UpdateKnowledgeRequest true "更新信息"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /api/knowledge/{id} [put]
func (h *KnowledgeHandler) Update(c *gin.Context) {
id := c.Param("id")
if id == "" {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "id is required"})
return
}
var req model.UpdateKnowledgeRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": err.Error()})
return
}
if err := h.service.Update(id, req); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"success": true, "message": "Knowledge base updated"})
}
// @Summary 删除知识库
// @Description 删除指定的知识库
// @Tags 知识库
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /api/knowledge/{id} [delete]
func (h *KnowledgeHandler) Delete(c *gin.Context) {
id := c.Param("id")
if id == "" {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "id is required"})
return
}
if err := h.service.Delete(id); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"success": true, "message": "Knowledge base deleted"})
}
// @Summary 获取知识库文档列表
// @Description 获取指定知识库下的所有文档
// @Tags 知识库
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param status query string false "文档状态筛选"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /api/knowledge/{id}/documents [get]
func (h *KnowledgeHandler) ListDocuments(c *gin.Context) {
id := c.Param("id")
if id == "" {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "id is required"})
return
}
status := c.Query("status")
list, err := h.service.ListDocuments(id, status)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"success": true, "data": list})
}
// @Summary 上传文档
// @Description 上传文档到指定知识库
// @Tags 知识库
// @Accept multipart/form-data
// @Produce json
// @Param id path string true "知识库ID"
// @Param file formData file true "文档文件"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /api/knowledge/{id}/documents [post]
func (h *KnowledgeHandler) UploadDocument(c *gin.Context) {
id := c.Param("id")
if id == "" {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "id is required"})
return
}
file, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "No file uploaded"})
return
}
// 检查文件大小(最大 100MB
if file.Size > 100*1024*1024 {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "File too large (max 100MB)"})
return
}
doc, fileURL, err := h.service.UploadDocument(id, file)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
return
}
if doc == nil {
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": "Upload failed"})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"id": doc.ID,
"url": fileURL,
"document": doc,
"message": "Document uploaded",
})
}
// @Summary 删除文档
// @Description 删除知识库中的指定文档
// @Tags 知识库
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param doc_id path string true "文档ID"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /api/knowledge/{id}/documents/{doc_id} [delete]
func (h *KnowledgeHandler) DeleteDocument(c *gin.Context) {
id := c.Param("id")
docID := c.Param("doc_id")
if id == "" || docID == "" {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "id and doc_id are required"})
return
}
if err := h.service.DeleteDocument(id, docID); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"success": true, "message": "Document deleted"})
}
// @Summary 重新解析文档
// @Description 重新解析指定文档(用于更新解析结果)
// @Tags 知识库
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param doc_id path string true "文档ID"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /api/knowledge/{id}/documents/{doc_id}/reparse [post]
func (h *KnowledgeHandler) ReparseDocument(c *gin.Context) {
id := c.Param("id")
docID := c.Param("doc_id")
if id == "" || docID == "" {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "id and doc_id are required"})
return
}
if err := h.service.ReparseDocument(id, docID); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"success": true, "message": "Document reparse started"})
}
// @Summary 获取文档预览
// @Description 获取文档的解析预览内容
// @Tags 知识库
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param doc_id path string true "文档ID"
// @Param page query int false "页码"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /api/knowledge/{id}/documents/{doc_id}/preview [get]
func (h *KnowledgeHandler) GetDocumentPreview(c *gin.Context) {
id := c.Param("id")
docID := c.Param("doc_id")
if id == "" || docID == "" {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "id and doc_id are required"})
return
}
page := 1
if p := c.Query("page"); p != "" {
if parsed, err := strconv.Atoi(p); err == nil {
page = parsed
}
}
preview, err := h.service.GetDocumentPreview(id, docID, page)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"success": true, "data": preview})
}