fix: 优化后端各模块 handler

- database_handler, knowledge_handler, model_handler
- neo4j_handler, sub_table_handler
- system_handler, upload_handler
- knowledge_service, upload_service

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 14:26:04 +08:00
parent ecb885ee5e
commit fdd6b2c17d
9 changed files with 427 additions and 60 deletions

View File

@@ -155,9 +155,9 @@ func (s *KnowledgeService) Delete(id string) error {
// 删除每个文档的 MinIO 文件和本地 Markdown 文件
for _, doc := range docs {
// 删除 MinIO 文件
if doc.FileKey != "" && kb.StorageConfig.Type == "minio" {
s.uploadService.DeleteFileWithConfig(doc.FileKey, kb.StorageConfig)
// 删除存储文件(MinIO 或本地)
if doc.FileKey != "" {
s.uploadService.DeleteFileWithConfig(doc.FileKey, kb.StorageConfig, kb.Name)
}
// 删除本地 Markdown 文件
if s.markdownLocalPath != "" {
@@ -215,15 +215,15 @@ func (s *KnowledgeService) UploadDocument(kbID string, file *multipart.FileHeade
// 上传文件(根据知识库的 storage_config 选择存储方式)
var result *UploadResponse
if kb.StorageConfig.Type != "" {
// 使用知识库的存储配置
if kb.StorageConfig.Type != "" && kb.StorageConfig.Type != "local" {
// 使用知识库的存储配置MinIO
knowledgeDebugLog.Printf("[Knowledge Upload] 使用知识库存储配置: type=%s, endpoint=%s, bucket=%s",
kb.StorageConfig.Type, kb.StorageConfig.Endpoint, kb.StorageConfig.Bucket)
result, err = s.uploadService.UploadWithConfig(file, kb.StorageConfig)
} else {
// 使用全局配置
knowledgeDebugLog.Printf("[Knowledge Upload] 使用全局存储配置")
result, err = s.uploadService.Upload(file)
// 本地存储,使用知识库名称作为子目录
knowledgeDebugLog.Printf("[Knowledge Upload] 使用本地存储,路径: resources/%s/", kb.Name)
result, err = s.uploadService.UploadToKnowledgeBase(file, kb.StorageConfig, kb.Name)
}
if err != nil {
knowledgeDebugLog.Printf("[Knowledge Upload] 错误: 上传失败, err=%v", err)
@@ -419,13 +419,8 @@ func (s *KnowledgeService) DeleteDocument(kbID, docID string) error {
if doc.FileKey != "" {
knowledgeDebugLog.Printf("[Knowledge DeleteDocument] 删除文件: kbID=%s, docID=%s, fileKey=%s, storageType=%s",
kbID, docID, doc.FileKey, kb.StorageConfig.Type)
if kb.StorageConfig.Type != "" {
// 使用知识库的存储配置删除
s.uploadService.DeleteFileWithConfig(doc.FileKey, kb.StorageConfig)
} else {
// 使用全局配置删除
s.uploadService.DeleteFile(doc.FileKey)
}
// 使用知识库的存储配置删除(传入知识库名称)
s.uploadService.DeleteFileWithConfig(doc.FileKey, kb.StorageConfig, kb.Name)
}
// 删除文档记录

View File

@@ -94,7 +94,7 @@ func (s *UploadService) Upload(file *multipart.FileHeader) (*UploadResponse, err
if s.cfg.UploadMode == "minio" {
return s.uploadToMinIO(f, filename, fileKey, file.Size)
}
return s.uploadToLocal(f, filename, fileKey)
return s.uploadToLocal(f, filename, fileKey, "")
}
// UploadWithConfig 上传文件(使用指定配置)
@@ -116,7 +116,29 @@ func (s *UploadService) UploadWithConfig(file *multipart.FileHeader, storageConf
return s.uploadToMinIOWithConfig(f, filename, fileKey, file.Size, storageConfig)
}
// 默认使用本地存储
return s.uploadToLocal(f, filename, fileKey)
return s.uploadToLocal(f, filename, fileKey, "")
}
// UploadToKnowledgeBase 上传文件到知识库(本地存储时按知识库名称分类)
func (s *UploadService) UploadToKnowledgeBase(file *multipart.FileHeader, storageConfig model.StorageConfig, knowledgeBaseName string) (*UploadResponse, error) {
// 打开文件
f, err := file.Open()
if err != nil {
return &UploadResponse{Success: false, Message: err.Error()}, nil
}
defer f.Close()
// 生成唯一文件名
ext := filepath.Ext(file.Filename)
filename := fmt.Sprintf("%s%s", uuid.New().String(), ext)
fileKey := strings.TrimSuffix(filename, ext)
// 根据配置选择存储方式
if storageConfig.Type == "minio" {
return s.uploadToMinIOWithConfig(f, filename, fileKey, file.Size, storageConfig)
}
// 本地存储,使用知识库名称作为子目录
return s.uploadToLocal(f, filename, fileKey, knowledgeBaseName)
}
// uploadToMinIOWithConfig 使用指定配置上传到 MinIO
@@ -217,9 +239,18 @@ func (s *UploadService) uploadToMinIO(f multipart.File, filename, fileKey string
}
// uploadToLocal 上传到本地
func (s *UploadService) uploadToLocal(f multipart.File, filename, fileKey string) (*UploadResponse, error) {
// 确保目录存在
uploadPath := s.cfg.UploadLocalPath
// knowledgeBaseName: 知识库名称,如果为空则使用全局配置目录,否则使用 resources/{知识库名称}/
func (s *UploadService) uploadToLocal(f multipart.File, filename, fileKey string, knowledgeBaseName string) (*UploadResponse, error) {
// 确定存储路径
var uploadPath string
if knowledgeBaseName != "" {
// 使用 resources/{知识库名称}/ 路径
uploadPath = filepath.Join("resources", knowledgeBaseName)
} else {
// 使用全局配置路径
uploadPath = s.cfg.UploadLocalPath
}
if err := os.MkdirAll(uploadPath, 0755); err != nil {
return &UploadResponse{Success: false, Message: fmt.Sprintf("failed to create directory: %v", err)}, nil
}
@@ -259,7 +290,8 @@ func (s *UploadService) DeleteFile(filename string) error {
}
// DeleteFileWithConfig 使用指定配置删除文件
func (s *UploadService) DeleteFileWithConfig(filename string, storageConfig model.StorageConfig) error {
// 注意:此方法需要知识库名称才能正确删除本地文件
func (s *UploadService) DeleteFileWithConfig(filename string, storageConfig model.StorageConfig, knowledgeBaseName string) error {
if storageConfig.Type == "minio" {
// 创建 MinIO 客户端
client, err := minio.New(storageConfig.Endpoint, &minio.Options{
@@ -275,7 +307,12 @@ func (s *UploadService) DeleteFileWithConfig(filename string, storageConfig mode
}
// 本地删除
path := filepath.Join(s.cfg.UploadLocalPath, filename)
var path string
if knowledgeBaseName != "" {
path = filepath.Join("resources", knowledgeBaseName, filename)
} else {
path = filepath.Join(s.cfg.UploadLocalPath, filename)
}
return os.Remove(path)
}