diff --git a/internal/dao/document.go b/internal/dao/document.go index 49ef0e88dc..2fa2fa5b0a 100644 --- a/internal/dao/document.go +++ b/internal/dao/document.go @@ -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 } diff --git a/internal/entity/document.go b/internal/entity/document.go index 3601219666..9b25ff4663 100644 --- a/internal/entity/document.go +++ b/internal/entity/document.go @@ -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" diff --git a/internal/handler/document.go b/internal/handler/document.go index fd7e775dfa..9b3307a724 100644 --- a/internal/handler/document.go +++ b/internal/handler/document.go @@ -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 diff --git a/internal/service/document.go b/internal/service/document.go index 29ed2d4b69..aeef7fb004 100644 --- a/internal/service/document.go +++ b/internal/service/document.go @@ -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 diff --git a/web/src/constants/file.ts b/web/src/constants/file.ts index 8d488c9713..9b713e3d70 100644 --- a/web/src/constants/file.ts +++ b/web/src/constants/file.ts @@ -10,7 +10,7 @@ export const FileIconMap = { jpeg: 'jpg', png: 'png', txt: 'text', - csv: 'pdf', + csv: 'excel', md: 'md', mdx: 'md', mp4: 'mp4',