Go: align document list response (#14982)

### What problem does this PR solve?

align document list response

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
buua436
2026-05-18 20:00:11 +08:00
committed by GitHub
parent 3290257014
commit d7fb4bdb4e
5 changed files with 151 additions and 16 deletions

View File

@ -86,15 +86,25 @@ func (dao *DocumentDAO) List(offset, limit int) ([]*entity.Document, int64, erro
}
// ListByKBID list documents by knowledge base ID
func (dao *DocumentDAO) ListByKBID(kbID string, offset, limit int) ([]*entity.Document, int64, error) {
var documents []*entity.Document
func (dao *DocumentDAO) ListByKBID(kbID string, offset, limit int) ([]*entity.DocumentListItem, int64, error) {
var documents []*entity.DocumentListItem
var total int64
if err := DB.Model(&entity.Document{}).Where("kb_id = ?", kbID).Count(&total).Error; err != nil {
return nil, 0, err
}
err := DB.Where("kb_id = ?", kbID).Offset(offset).Limit(limit).Find(&documents).Error
err := DB.Table("document").
Select(`document.*, user_canvas.title as pipeline_name, user.nickname`).
Joins("JOIN file2document ON file2document.document_id = document.id").
Joins("JOIN file ON file.id = file2document.file_id").
Joins("LEFT JOIN user_canvas ON document.pipeline_id = user_canvas.id").
Joins("LEFT JOIN user ON document.created_by = user.id").
Where("document.kb_id = ?", kbID).
Order("document.create_time DESC").
Offset(offset).
Limit(limit).
Scan(&documents).Error
return documents, total, err
}

View File

@ -46,6 +46,39 @@ type Document struct {
BaseModel
}
// DocumentListItem represents a document list row with joined fields.
type DocumentListItem struct {
ID string `gorm:"column:id" json:"id"`
Thumbnail *string `gorm:"column:thumbnail" json:"thumbnail,omitempty"`
KbID string `gorm:"column:kb_id" json:"kb_id"`
ParserID string `gorm:"column:parser_id" json:"parser_id"`
PipelineID *string `gorm:"column:pipeline_id" json:"pipeline_id,omitempty"`
PipelineName *string `gorm:"column:pipeline_name" json:"pipeline_name,omitempty"`
ParserConfig string `gorm:"column:parser_config" json:"parser_config"`
SourceType string `gorm:"column:source_type" json:"source_type"`
Type string `gorm:"column:type" json:"type"`
CreatedBy string `gorm:"column:created_by" json:"created_by"`
Nickname *string `gorm:"column:nickname" json:"nickname,omitempty"`
Name *string `gorm:"column:name" json:"name,omitempty"`
Location *string `gorm:"column:location" json:"location,omitempty"`
Size int64 `gorm:"column:size" json:"size"`
TokenNum int64 `gorm:"column:token_num" json:"token_num"`
ChunkNum int64 `gorm:"column:chunk_num" json:"chunk_num"`
Progress float64 `gorm:"column:progress" json:"progress"`
ProgressMsg *string `gorm:"column:progress_msg" json:"progress_msg,omitempty"`
ProcessBeginAt *time.Time `gorm:"column:process_begin_at" json:"process_begin_at,omitempty"`
ProcessDuration float64 `gorm:"column:process_duration" json:"process_duration"`
ContentHash *string `gorm:"column:content_hash" json:"content_hash,omitempty"`
MetaFields *string `gorm:"column:meta_fields" json:"meta_fields,omitempty"`
Suffix string `gorm:"column:suffix" json:"suffix"`
Run *string `gorm:"column:run" json:"run,omitempty"`
Status *string `gorm:"column:status" json:"status,omitempty"`
CreateTime *int64 `gorm:"column:create_time" json:"create_time,omitempty"`
CreateDate *time.Time `gorm:"column:create_date" json:"create_date,omitempty"`
UpdateTime *int64 `gorm:"column:update_time" json:"update_time,omitempty"`
UpdateDate *time.Time `gorm:"column:update_date" json:"update_date,omitempty"`
}
// TableName specify table name
func (Document) TableName() string {
return "document"

View File

@ -21,8 +21,10 @@ import (
"fmt"
"net/http"
"ragflow/internal/common"
"ragflow/internal/entity"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
@ -241,15 +243,7 @@ func (h *DocumentHandler) ListDocuments(c *gin.Context) {
metaFields = make(map[string]interface{})
}
docs = append(docs, map[string]interface{}{
"id": doc.ID,
"name": doc.Name,
"size": doc.Size,
"type": doc.Type,
"status": doc.Status,
"created_at": doc.CreatedAt,
"meta_fields": metaFields,
})
docs = append(docs, mapDocumentListItem(doc, metaFields))
}
c.JSON(http.StatusOK, gin.H{
@ -262,6 +256,104 @@ func (h *DocumentHandler) ListDocuments(c *gin.Context) {
})
}
func mapDocumentListItem(doc *entity.DocumentListItem, metaFields map[string]interface{}) map[string]interface{} {
item := map[string]interface{}{
"id": doc.ID,
"dataset_id": doc.KbID,
"name": stringValue(doc.Name),
"thumbnail": stringValue(doc.Thumbnail),
"size": doc.Size,
"type": doc.Type,
"created_by": doc.CreatedBy,
"location": stringValue(doc.Location),
"token_count": doc.TokenNum,
"chunk_count": doc.ChunkNum,
"progress": doc.Progress,
"progress_msg": stringValue(doc.ProgressMsg),
"process_begin_at": formatTimePtr(doc.ProcessBeginAt),
"process_duration": doc.ProcessDuration,
"suffix": doc.Suffix,
"run": mapRunStatus(doc.Run),
"status": stringValue(doc.Status),
"chunk_method": doc.ParserID,
"parser_id": doc.ParserID,
"pipeline_id": stringValue(doc.PipelineID),
"pipeline_name": stringValue(doc.PipelineName),
"nickname": stringValue(doc.Nickname),
"parser_config": decodeJSONMap(string(doc.ParserConfig)),
"meta_fields": metaFields,
"create_time": int64(0),
"create_date": "",
"update_time": int64(0),
"update_date": "",
}
if doc.CreateTime != nil {
item["create_time"] = *doc.CreateTime
}
if doc.CreateDate != nil {
item["create_date"] = doc.CreateDate.Format("2006-01-02 15:04:05")
}
if doc.UpdateTime != nil {
item["update_time"] = *doc.UpdateTime
}
if doc.UpdateDate != nil {
item["update_date"] = doc.UpdateDate.Format("2006-01-02 15:04:05")
}
return item
}
func decodeJSONMap(raw string) map[string]interface{} {
if strings.TrimSpace(raw) == "" {
return map[string]interface{}{}
}
var data map[string]interface{}
if err := json.Unmarshal([]byte(raw), &data); err != nil {
return map[string]interface{}{}
}
return data
}
func mapRunStatus(run *string) string {
if run == nil {
return "UNSTART"
}
switch strings.TrimSpace(*run) {
case "0":
return "UNSTART"
case "1":
return "RUNNING"
case "2":
return "CANCEL"
case "3":
return "DONE"
case "4":
return "FAIL"
default:
return strings.TrimSpace(*run)
}
}
func formatTimePtr(value *time.Time) string {
if value == nil {
return ""
}
return value.Format("2006-01-02 15:04:05")
}
func stringValue(value *string) string {
if value == nil {
return ""
}
return *value
}
// GetDocumentsByAuthorID get documents by author ID
// @Summary Get Author Documents
// @Description Get paginated document list by author ID

View File

@ -176,16 +176,16 @@ func (s *DocumentService) ListDocuments(page, pageSize int) ([]*DocumentResponse
}
// ListDocumentsByDatasetID list documents by knowledge base ID
func (s *DocumentService) ListDocumentsByDatasetID(kbID string, page, pageSize int) ([]*DocumentResponse, int64, error) {
func (s *DocumentService) ListDocumentsByDatasetID(kbID string, page, pageSize int) ([]*entity.DocumentListItem, int64, error) {
offset := (page - 1) * pageSize
documents, total, err := s.documentDAO.ListByKBID(kbID, offset, pageSize)
if err != nil {
return nil, 0, err
}
responses := make([]*DocumentResponse, len(documents))
responses := make([]*entity.DocumentListItem, len(documents))
for i, doc := range documents {
responses[i] = s.toResponse(doc)
responses[i] = doc
}
return responses, total, nil

View File

@ -10,7 +10,7 @@ export const FileIconMap = {
jpeg: 'jpg',
png: 'png',
txt: 'text',
csv: 'pdf',
csv: 'excel',
md: 'md',
mdx: 'md',
mp4: 'mp4',