Files
common/ragflow/document.go

165 lines
6.2 KiB
Go
Raw Normal View History

2025-11-27 09:50:12 +08:00
package ragflow
import (
"context"
"fmt"
2025-12-02 14:59:07 +08:00
"strings"
2025-11-27 09:50:12 +08:00
)
2025-11-27 17:38:42 +08:00
// 数据集内文件管理
// 参考: https://ragflow.com.cn/docs/dev/http_api_reference#数据集内文件管理
2025-12-02 14:59:07 +08:00
// ... (rest of the code remains the same)
2025-11-27 09:50:12 +08:00
type Document struct {
Id string `json:"id"`
DatasetId string `json:"dataset_id"`
Name string `json:"name"`
Size int64 `json:"size"`
Location string `json:"location"`
CreatedBy string `json:"created_by"`
CreateTime int64 `json:"create_time"`
Thumbnail string `json:"thumbnail"`
Type string `json:"type"`
RunStatus string `json:"run_status"` // 对应 API 返回的 "run" 字段,可能需要确认
Status string `json:"status"`
ChunkMethod string `json:"chunk_method"`
ParserConfig map[string]interface{} `json:"parser_config"`
TokenNum int `json:"token_num"`
ChunkCount int `json:"chunk_count"`
ProcessBegin int64 `json:"process_begin"`
ProcessDu int64 `json:"process_du"`
Progress float64 `json:"progress"`
ProgressMsg string `json:"progress_msg"`
}
// UploadDocumentReq 上传文档请求
// 注意:上传文件通常需要 multipart/form-data这里仅定义结构实际逻辑在方法中处理
type UploadDocumentReq struct {
FilePaths []string // 本地文件路径列表
}
// ListDocumentsReq 列出文档请求
type ListDocumentsReq struct {
2025-12-02 14:59:07 +08:00
Page int `json:"page,omitempty"` // 页码,默认 1
PageSize int `json:"page_size,omitempty"` // 每页数量,默认 30
OrderBy string `json:"orderby,omitempty"` // 排序字段create_time默认或 update_time
Desc bool `json:"desc,omitempty"` // 是否降序,默认 true
Keywords string `json:"keywords,omitempty"` // 关键词过滤(匹配文档标题)
Id string `json:"id,omitempty"` // 文档 ID 过滤
Name string `json:"name,omitempty"` // 文档名称过滤
CreateTimeFrom int64 `json:"create_time_from,omitempty"` // 创建时间起始Unix 时间戳0 表示无限制
CreateTimeTo int64 `json:"create_time_to,omitempty"` // 创建时间截止Unix 时间戳0 表示无限制
Suffix []string `json:"suffix,omitempty"` // 文件后缀过滤,如 ["pdf", "txt", "docx"]
Run []string `json:"run,omitempty"` // 处理状态过滤,支持 ["UNSTART", "RUNNING", "CANCEL", "DONE", "FAIL"] 或数字格式 ["0", "1", "2", "3", "4"]
2025-11-27 09:50:12 +08:00
}
// ListDocumentsRes 列出文档响应
2025-12-02 14:59:07 +08:00
// 注意:响应结构与其他 List 接口不同data 是一个对象而非数组
2025-11-27 09:50:12 +08:00
type ListDocumentsRes struct {
2025-12-02 14:59:07 +08:00
Code int `json:"code"` // 状态码0 表示成功
Data struct {
Docs []*Document `json:"docs"` // 文档列表
TotalDatasets int `json:"total_datasets"` // 总文档数
} `json:"data"`
2025-11-27 09:50:12 +08:00
}
// DeleteDocumentsReq 删除文档请求
type DeleteDocumentsReq struct {
Ids []string `json:"ids"`
}
// ListDocuments 列出文档
func (c *Client) ListDocuments(ctx context.Context, datasetId string, req *ListDocumentsReq) (*ListDocumentsRes, error) {
2025-12-02 14:59:07 +08:00
path := fmt.Sprintf("/api/v1/datasets/%s/documents", datasetId)
2025-11-27 09:50:12 +08:00
params := map[string]interface{}{}
if req.Page > 0 {
params["page"] = req.Page
}
if req.PageSize > 0 {
params["page_size"] = req.PageSize
}
if req.OrderBy != "" {
params["orderby"] = req.OrderBy
}
if req.Desc {
params["desc"] = "true"
} else {
params["desc"] = "false"
}
if req.Keywords != "" {
params["keywords"] = req.Keywords
}
if req.Id != "" {
params["id"] = req.Id
}
if req.Name != "" {
params["name"] = req.Name
}
if req.CreateTimeFrom > 0 {
params["create_time_from"] = req.CreateTimeFrom
}
if req.CreateTimeTo > 0 {
params["create_time_to"] = req.CreateTimeTo
}
2025-12-02 14:59:07 +08:00
// 构造查询字符串
2025-11-27 17:38:42 +08:00
query := buildQueryString(params)
2025-12-02 14:59:07 +08:00
var queryParts []string
2025-11-27 17:38:42 +08:00
if query != "" {
2025-12-02 14:59:07 +08:00
queryParts = append(queryParts, query)
2025-11-27 09:50:12 +08:00
}
2025-12-02 14:59:07 +08:00
// 处理数组参数suffix文件后缀过滤
// API 要求多个值时重复参数名suffix=pdf&suffix=txt
// 这里使用 fmt.Sprintf 来构造每个参数值
for _, suffix := range req.Suffix {
queryParts = append(queryParts, fmt.Sprintf("suffix=%s", suffix))
}
// 处理数组参数run处理状态过滤
// 支持数字格式("0"-"4")或文本格式("UNSTART", "RUNNING", "CANCEL", "DONE", "FAIL"
// 这里使用 fmt.Sprintf 来构造每个参数值
for _, run := range req.Run {
queryParts = append(queryParts, fmt.Sprintf("run=%s", run))
}
// 构造最终请求路径
if len(queryParts) > 0 {
path += "?" + strings.Join(queryParts, "&")
}
// 发送请求并处理响应
2025-11-27 09:50:12 +08:00
var res ListDocumentsRes
if err := c.request(ctx, "GET", path, nil, &res); err != nil {
return nil, err
}
if res.Code != 0 {
return nil, fmt.Errorf("list documents failed: code=%d", res.Code)
}
return &res, nil
}
// UploadDocument 上传文档
// 注意:此方法需要特殊处理 multipart/form-data目前的 request 方法可能不支持
// 我们需要扩展 request 方法或在此处单独实现
func (c *Client) UploadDocument(ctx context.Context, datasetId string, filePaths []string) error {
// TODO: 实现文件上传逻辑,需要使用 gclient 的 UploadFile 功能
// 由于 request 方法封装了 JSON 处理,这里可能需要绕过 request 方法直接使用 c.Client
// 暂时留空或仅做简单提示,待完善 Client 封装以支持文件上传
return fmt.Errorf("upload document not implemented yet")
}
// DeleteDocument 删除文档
func (c *Client) DeleteDocument(ctx context.Context, datasetId string, ids []string) error {
req := DeleteDocumentsReq{Ids: ids}
var res CommonResponse
path := fmt.Sprintf("/api/v1/datasets/%s/documents", datasetId)
if err := c.request(ctx, "DELETE", path, req, &res); err != nil {
return err
}
if !res.IsSuccess() {
return fmt.Errorf("delete document failed: %s", res.Message)
}
return nil
}