From 4697ee29aa9a926aa165e4d735a0d5fd486c0f8b Mon Sep 17 00:00:00 2001 From: euvre <93761161+euvre@users.noreply.github.com> Date: Wed, 22 Jul 2026 12:12:23 +0800 Subject: [PATCH] fix: avoid duplicate document names when linking files to datasets (#17181) --- internal/service/document/document_crud.go | 16 ++++++++++++++++ internal/service/document/file2document.go | 14 ++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/internal/service/document/document_crud.go b/internal/service/document/document_crud.go index 61f5282bc0..d482d6324c 100644 --- a/internal/service/document/document_crud.go +++ b/internal/service/document/document_crud.go @@ -306,6 +306,22 @@ func (s *DocumentService) InsertDocument(doc *entity.Document) error { }) } +// UniqueDocumentName returns a non-colliding document name within the dataset, +// mirroring Python duplicate_name(DocumentService.query, name=..., kb_id=...). +// Returns an error when the existing-name lookup fails so callers never write +// blind and risk duplicated document names. +func (s *DocumentService) UniqueDocumentName(kbID, name string) (string, error) { + names, err := s.documentDAO.ListNamesByKbID(kbID) + if err != nil { + return "", err + } + taken := make(map[string]bool, len(names)) + for _, n := range names { + taken[n] = true + } + return uniqueUploadName(name, taken), nil +} + // resolveDocAndKB loads the document and its knowledgebase, returning both or // an error. func (s *DocumentService) resolveDocAndKB(docID string) (*entity.Document, *entity.Knowledgebase, error) { diff --git a/internal/service/document/file2document.go b/internal/service/document/file2document.go index ffe337ba2c..0331d1ef36 100644 --- a/internal/service/document/file2document.go +++ b/internal/service/document/file2document.go @@ -224,8 +224,18 @@ func (s *File2DocumentService) convertFiles(fileIDs, kbIDs []string, userID, mod continue } + // Mirror Python duplicate_name: generate a non-colliding document + // name within the dataset so that linking does not silently create + // duplicate-name documents in the same KB. + docName, err := s.documentSvc.UniqueDocumentName(kbID, file.Name) + if err != nil { + common.Warn("convertFiles: UniqueDocumentName failed", + zap.String("kbID", kbID), zap.String("fileID", fileID), zap.Error(err)) + continue + } + parserID := kb.ParserID - suffix := strings.TrimPrefix(filepath.Ext(file.Name), ".") + suffix := strings.TrimPrefix(filepath.Ext(docName), ".") doc := &entity.Document{ ID: utility.GenerateUUID(), KbID: kb.ID, @@ -233,7 +243,7 @@ func (s *File2DocumentService) convertFiles(fileIDs, kbIDs []string, userID, mod ParserConfig: kb.ParserConfig, CreatedBy: userID, Type: file.Type, - Name: &file.Name, + Name: &docName, Suffix: suffix, Size: file.Size, }