import_service_url.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package service
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "log"
  7. "github.com/2930134478/AI-CS/backend/models"
  8. import_service "github.com/2930134478/AI-CS/backend/service/import"
  9. )
  10. // ImportFromUrls 从 URL 导入文档
  11. func (s *ImportService) ImportFromUrls(ctx context.Context, knowledgeBaseID uint, urls []string) (*ImportResult, error) {
  12. log.Printf("[导入] URL 导入开始 knowledge_base_id=%d urls=%d", knowledgeBaseID, len(urls))
  13. // 验证知识库是否存在
  14. _, err := s.kbRepo.GetByID(knowledgeBaseID)
  15. if err != nil {
  16. return nil, errors.New("知识库不存在")
  17. }
  18. result := &ImportResult{
  19. SuccessCount: 0,
  20. FailedCount: 0,
  21. FailedFiles: []string{},
  22. Errors: []string{},
  23. }
  24. // 创建 URL 解析器
  25. urlParser := import_service.NewURLParser()
  26. // 解析 URL
  27. documents := make([]*models.Document, 0)
  28. for _, url := range urls {
  29. if !urlParser.Supports(url) {
  30. result.FailedCount++
  31. result.FailedFiles = append(result.FailedFiles, url)
  32. result.Errors = append(result.Errors, fmt.Sprintf("%s: 无效的 URL", url))
  33. continue
  34. }
  35. // 解析 URL
  36. parsed, err := urlParser.Parse(url)
  37. if err != nil {
  38. result.FailedCount++
  39. result.FailedFiles = append(result.FailedFiles, url)
  40. result.Errors = append(result.Errors, fmt.Sprintf("%s: %v", url, err))
  41. continue
  42. }
  43. // 创建文档
  44. doc := &models.Document{
  45. KnowledgeBaseID: knowledgeBaseID,
  46. Title: parsed.Title,
  47. Content: parsed.Content,
  48. Type: "url",
  49. Status: "draft",
  50. EmbeddingStatus: "pending",
  51. }
  52. documents = append(documents, doc)
  53. }
  54. // 批量创建文档
  55. docIDs := make([]uint, 0, len(documents))
  56. for _, doc := range documents {
  57. if err := s.docRepo.Create(doc); err != nil {
  58. result.FailedCount++
  59. result.FailedFiles = append(result.FailedFiles, doc.Title)
  60. result.Errors = append(result.Errors, fmt.Sprintf("文档 %s: 创建失败: %v", doc.Title, err))
  61. continue
  62. }
  63. docIDs = append(docIDs, doc.ID)
  64. result.SuccessCount++
  65. }
  66. // 批量向量化(异步)
  67. if len(docIDs) > 0 {
  68. ids := make([]uint, len(docIDs))
  69. copy(ids, docIDs)
  70. go func(ids []uint) {
  71. log.Printf("[导入] URL 导入已创建 %d 条文档,开始批量向量化", len(ids))
  72. _, err := s.BatchEmbedDocuments(context.Background(), ids)
  73. if err != nil {
  74. log.Printf("[导入] 批量向量化失败: %v", err)
  75. return
  76. }
  77. log.Printf("[导入] 批量向量化完成,%d 条文档已写入向量库", len(ids))
  78. }(ids)
  79. }
  80. return result, nil
  81. }