mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-06-29 23:41:12 +08:00
feat[Go] implement api/v1/thumbnails API (#15416)
### What problem does this PR solve? As title ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) - [x] New Feature (non-breaking change which adds functionality
This commit is contained in:
@@ -18,8 +18,11 @@ package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"mime"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/entity"
|
||||
"strconv"
|
||||
@@ -31,6 +34,8 @@ import (
|
||||
"ragflow/internal/service"
|
||||
)
|
||||
|
||||
var IMG_BASE64_PREFIX = "data:image/png;base64,"
|
||||
|
||||
// DocumentHandler document handler
|
||||
type DocumentHandler struct {
|
||||
documentService *service.DocumentService
|
||||
@@ -120,6 +125,58 @@ func (h *DocumentHandler) GetDocumentByID(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// GetThumbnail Get thumbnails for documents.
|
||||
func (h *DocumentHandler) GetThumbnail(c *gin.Context) {
|
||||
_, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
jsonError(c, errorCode, errorMessage)
|
||||
return
|
||||
}
|
||||
|
||||
id := c.Query("doc_ids")
|
||||
if id == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errors.New("invalid document id"),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.documentService.GetThumbnail(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{
|
||||
"error": fmt.Errorf("thumbnail not found"),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if result.Thumbnail != nil && *result.Thumbnail != "" {
|
||||
newThumbURL := fmt.Sprintf("/api/v1/documents/images/%s-%s", result.KbID, *result.Thumbnail)
|
||||
result.Thumbnail = &newThumbURL
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": common.CodeSuccess,
|
||||
"data": map[string]interface{}{result.ID: result.Thumbnail},
|
||||
"message": "success",
|
||||
})
|
||||
}
|
||||
|
||||
// GetDocumentImage returns a document image from object storage.
|
||||
func (h *DocumentHandler) GetDocumentImage(c *gin.Context) {
|
||||
imageID := c.Param("image_id")
|
||||
data, err := h.documentService.GetDocumentImage(imageID)
|
||||
if err != nil {
|
||||
jsonError(c, common.CodeDataError, "Image not found.")
|
||||
return
|
||||
}
|
||||
|
||||
contentType := mime.TypeByExtension(strings.ToLower(filepath.Ext(imageID)))
|
||||
if contentType == "" {
|
||||
contentType = "image/JPEG"
|
||||
}
|
||||
c.Data(http.StatusOK, contentType, data)
|
||||
}
|
||||
|
||||
// UpdateDocument update document
|
||||
// @Summary Update Document
|
||||
// @Description Update document info
|
||||
|
||||
@@ -116,6 +116,9 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
|
||||
// Register
|
||||
apiNoAuth.POST("/users", r.userHandler.Register)
|
||||
|
||||
// Document images are embedded directly in pages and match Python's public route.
|
||||
apiNoAuth.GET("/documents/images/:image_id", r.documentHandler.GetDocumentImage)
|
||||
}
|
||||
|
||||
// Protected routes
|
||||
@@ -411,6 +414,8 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
doc.POST("/delete_meta", r.documentHandler.DeleteMeta) // Internal API only for GO
|
||||
}
|
||||
|
||||
v1.GET("/thumbnails", r.documentHandler.GetThumbnail)
|
||||
|
||||
// Chunk routes
|
||||
chunk := v1.Group("/chunk")
|
||||
{
|
||||
|
||||
@@ -21,8 +21,10 @@ import (
|
||||
"fmt"
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/entity"
|
||||
"ragflow/internal/storage"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ragflow/internal/dao"
|
||||
@@ -102,6 +104,27 @@ type DocumentResponse struct {
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
type ThumbnailResponse struct {
|
||||
ID string `json:"id"`
|
||||
Thumbnail *string `json:"thumbnail,omitempty"`
|
||||
KbID string `json:"kb_id"`
|
||||
}
|
||||
|
||||
// GetDocumentImage retrieves an image object from storage.
|
||||
func (s *DocumentService) GetDocumentImage(imageID string) ([]byte, error) {
|
||||
parts := strings.Split(imageID, "-")
|
||||
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
|
||||
return nil, fmt.Errorf("Image not found.")
|
||||
}
|
||||
|
||||
storageImpl := storage.GetStorageFactory().GetStorage()
|
||||
if storageImpl == nil {
|
||||
return nil, fmt.Errorf("storage not initialized")
|
||||
}
|
||||
|
||||
return storageImpl.Get(parts[0], parts[1])
|
||||
}
|
||||
|
||||
// CreateDocument create document
|
||||
func (s *DocumentService) CreateDocument(req *CreateDocumentRequest) (*entity.Document, error) {
|
||||
document := &entity.Document{
|
||||
@@ -182,6 +205,19 @@ func (s *DocumentService) ListDocuments(page, pageSize int) ([]*DocumentResponse
|
||||
return responses, total, nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) GetThumbnail(docID string) (*ThumbnailResponse, error) {
|
||||
document, err := s.documentDAO.GetByID(docID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result ThumbnailResponse
|
||||
result.ID = document.ID
|
||||
result.Thumbnail = document.Thumbnail
|
||||
result.KbID = document.KbID
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ListDocumentsByDatasetID list documents by knowledge base ID
|
||||
func (s *DocumentService) ListDocumentsByDatasetID(kbID string, page, pageSize int) ([]*entity.DocumentListItem, int64, error) {
|
||||
offset := (page - 1) * pageSize
|
||||
@@ -282,7 +318,7 @@ func (s *DocumentService) ParseDocuments(datasetID, userID string, docIDs []stri
|
||||
}
|
||||
|
||||
// Send task to message queue
|
||||
|
||||
|
||||
}
|
||||
|
||||
common.Info(fmt.Sprintf("parse documents, dataset: %s, documents: %v", datasetID, docIDs))
|
||||
@@ -425,7 +461,7 @@ func (s *DocumentService) DeleteDocumentAllMetadata(docID string) error {
|
||||
|
||||
// Build condition to match the document
|
||||
condition := map[string]interface{}{
|
||||
"id": docID,
|
||||
"id": docID,
|
||||
"kb_id": doc.KbID,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user