From 87ead9dec44807d96a7e65cceec1dcb36d02f19c Mon Sep 17 00:00:00 2001 From: wizardchen Date: Thu, 25 Dec 2025 10:41:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9EFAQ=E6=9D=A1=E7=9B=AE?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E6=9B=B4=E6=96=B0=E6=8E=92=E9=99=A4=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E6=94=AF=E6=8C=81=E5=9C=A8ByTag=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E4=B8=AD=E6=8E=92=E9=99=A4=E6=8C=87=E5=AE=9AID?= =?UTF-8?q?=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/faq.go | 6 ++++-- internal/application/repository/chunk.go | 10 ++++++++++ internal/application/service/knowledge.go | 2 +- internal/types/faq.go | 2 ++ internal/types/interfaces/chunk.go | 2 +- 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/client/faq.go b/client/faq.go index 039016fe5..55b50264a 100644 --- a/client/faq.go +++ b/client/faq.go @@ -69,6 +69,8 @@ type FAQEntryFieldsBatchRequest struct { ByID map[string]FAQEntryFieldsUpdate `json:"by_id,omitempty"` // ByTag updates all entries under a tag, key is tag ID (empty string for uncategorized) ByTag map[string]FAQEntryFieldsUpdate `json:"by_tag,omitempty"` + // ExcludeIDs IDs to exclude from the ByTag update + ExcludeIDs []string `json:"exclude_ids,omitempty"` } // FAQEntryTagBatchRequest updates tags in bulk. @@ -255,10 +257,10 @@ func (c *Client) UpdateFAQEntry(ctx context.Context, // - byID: update by entry ID, key is entry ID // - byTag: update all entries under a tag, key is tag ID (empty string for uncategorized) func (c *Client) UpdateFAQEntryFieldsBatch(ctx context.Context, - knowledgeBaseID string, byID map[string]FAQEntryFieldsUpdate, byTag map[string]FAQEntryFieldsUpdate, + knowledgeBaseID string, byID map[string]FAQEntryFieldsUpdate, byTag map[string]FAQEntryFieldsUpdate, excludeIDs []string, ) error { path := fmt.Sprintf("/api/v1/knowledge-bases/%s/faq/entries/fields", knowledgeBaseID) - resp, err := c.doRequest(ctx, http.MethodPut, path, &FAQEntryFieldsBatchRequest{ByID: byID, ByTag: byTag}, nil) + resp, err := c.doRequest(ctx, http.MethodPut, path, &FAQEntryFieldsBatchRequest{ByID: byID, ByTag: byTag, ExcludeIDs: excludeIDs}, nil) if err != nil { return err } diff --git a/internal/application/repository/chunk.go b/internal/application/repository/chunk.go index b7a71ea71..7cb423c30 100644 --- a/internal/application/repository/chunk.go +++ b/internal/application/repository/chunk.go @@ -569,6 +569,7 @@ func (r *chunkRepository) UpdateChunkFieldsByTagID( isEnabled *bool, setFlags types.ChunkFlags, clearFlags types.ChunkFlags, + excludeIDs []string, ) ([]string, error) { // First, get the IDs of chunks that will be affected (for is_enabled sync) var affectedIDs []string @@ -583,6 +584,11 @@ func (r *chunkRepository) UpdateChunkFieldsByTagID( } else { query = query.Where("tag_id = ?", tagID) } + + if len(excludeIDs) > 0 { + query = query.Where("id NOT IN ?", excludeIDs) + } + // Only get chunks that need to change query = query.Where("is_enabled != ?", *isEnabled) if err := query.Find(&chunks).Error; err != nil { @@ -612,6 +618,10 @@ func (r *chunkRepository) UpdateChunkFieldsByTagID( query = query.Where("tag_id = ?", tagID) } + if len(excludeIDs) > 0 { + query = query.Where("id NOT IN ?", excludeIDs) + } + // Handle flags update if setFlags != 0 || clearFlags != 0 { flagsExpr := "flags" diff --git a/internal/application/service/knowledge.go b/internal/application/service/knowledge.go index 3d21dc89b..926d31a2c 100644 --- a/internal/application/service/knowledge.go +++ b/internal/application/service/knowledge.go @@ -3570,7 +3570,7 @@ func (s *knowledgeService) UpdateFAQEntryFieldsBatch(ctx context.Context, // Update all chunks with this tag affectedIDs, err := s.chunkRepo.UpdateChunkFieldsByTagID( ctx, tenantID, kb.ID, tagID, - update.IsEnabled, setFlags, clearFlags, + update.IsEnabled, setFlags, clearFlags, req.ExcludeIDs, ) if err != nil { return err diff --git a/internal/types/faq.go b/internal/types/faq.go index 96f1c03bc..912653dc5 100644 --- a/internal/types/faq.go +++ b/internal/types/faq.go @@ -245,6 +245,8 @@ type FAQEntryFieldsBatchUpdate struct { ByID map[string]FAQEntryFieldsUpdate `json:"by_id,omitempty"` // ByTag 按Tag批量更新,key为TagID(空字符串表示未分类) ByTag map[string]FAQEntryFieldsUpdate `json:"by_tag,omitempty"` + // ExcludeIDs 在ByTag操作中需要排除的ID列表 + ExcludeIDs []string `json:"exclude_ids,omitempty"` } // FAQImportTaskStatus 导入任务状态 diff --git a/internal/types/interfaces/chunk.go b/internal/types/interfaces/chunk.go index a704bb002..475a3c0f7 100644 --- a/internal/types/interfaces/chunk.go +++ b/internal/types/interfaces/chunk.go @@ -64,7 +64,7 @@ type ChunkRepository interface { UpdateChunkFlagsBatch(ctx context.Context, tenantID uint64, kbID string, setFlags map[string]types.ChunkFlags, clearFlags map[string]types.ChunkFlags) error // UpdateChunkFieldsByTagID updates fields for all chunks with the specified tag ID. // Supports updating is_enabled and flags fields. - UpdateChunkFieldsByTagID(ctx context.Context, tenantID uint64, kbID string, tagID string, isEnabled *bool, setFlags types.ChunkFlags, clearFlags types.ChunkFlags) ([]string, error) + UpdateChunkFieldsByTagID(ctx context.Context, tenantID uint64, kbID string, tagID string, isEnabled *bool, setFlags types.ChunkFlags, clearFlags types.ChunkFlags, excludeIDs []string) ([]string, error) // FAQChunkDiff compares FAQ chunks between two knowledge bases and returns the differences. // Returns: chunksToAdd (content_hash in src but not in dst), chunksToDelete (content_hash in dst but not in src) FAQChunkDiff(ctx context.Context, srcTenantID uint64, srcKBID string, dstTenantID uint64, dstKBID string) (chunksToAdd []string, chunksToDelete []string, err error)