diff --git a/internal/repository/library_repository.go b/internal/repository/library_repository.go index 987a553..4a1a328 100644 --- a/internal/repository/library_repository.go +++ b/internal/repository/library_repository.go @@ -31,9 +31,16 @@ func (r *LibraryRepository) CreateWithRoots(ctx context.Context, l *model.Librar if roots[i].SortOrder == 0 { roots[i].SortOrder = i } + enabled := roots[i].Enabled if err := tx.Create(&roots[i]).Error; err != nil { return err } + if !enabled { + if err := tx.Model(&model.LibraryRoot{}).Where("id = ?", roots[i].ID).Update("enabled", false).Error; err != nil { + return err + } + roots[i].Enabled = false + } } l.Roots = roots return nil @@ -113,7 +120,19 @@ func (r *LibraryRepository) CreateRoot(ctx context.Context, root *model.LibraryR if !r.hasLibraryRootsTable() { return nil } - return r.db.WithContext(ctx).Create(root).Error + enabled := root.Enabled + return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { + if err := tx.Create(root).Error; err != nil { + return err + } + if !enabled { + if err := tx.Model(&model.LibraryRoot{}).Where("id = ?", root.ID).Update("enabled", false).Error; err != nil { + return err + } + root.Enabled = false + } + return nil + }) } func (r *LibraryRepository) UpdateRoot(ctx context.Context, root *model.LibraryRoot, updates map[string]any) error { diff --git a/internal/service/filemanager.go b/internal/service/filemanager.go index cf7e892..52ee806 100644 --- a/internal/service/filemanager.go +++ b/internal/service/filemanager.go @@ -335,6 +335,19 @@ func (s *FileManagerService) allowedRoots() (map[string]string, error) { libs, err := s.repo.Library.List(context.Background()) if err == nil { for _, l := range libs { + if len(l.Roots) > 0 { + for i, root := range l.Roots { + if !root.Enabled { + continue + } + label := strings.TrimSpace(root.Name) + if label == "" { + label = fmt.Sprintf("路径%d", i+1) + } + add("library:"+l.Name+":"+label, root.Path) + } + continue + } add("library:"+l.Name, l.Path) } } diff --git a/internal/service/filemanager_test.go b/internal/service/filemanager_test.go index d84d76b..9e76ae2 100644 --- a/internal/service/filemanager_test.go +++ b/internal/service/filemanager_test.go @@ -140,3 +140,43 @@ func TestFileManagerIncludesConfiguredOrganizeRoots(t *testing.T) { } } } + +func TestFileManagerIncludesAllLibraryRoots(t *testing.T) { + rootA := t.TempDir() + rootB := t.TempDir() + nestedB := filepath.Join(rootB, "second-root") + if err := os.MkdirAll(nestedB, 0o755); err != nil { + t.Fatal(err) + } + db := newServiceTestDB(t, &model.Library{}, &model.LibraryRoot{}, &model.Media{}, &model.Setting{}) + repos := repository.New(db) + lib := &model.Library{Name: "电影", Path: rootA, Type: "movie", Enabled: true} + if err := repos.Library.CreateWithRoots(t.Context(), lib, []model.LibraryRoot{ + {Name: "硬盘1", Path: rootA, Enabled: true}, + {Name: "硬盘2", Path: rootB, Enabled: true, SortOrder: 1}, + }); err != nil { + t.Fatal(err) + } + cfg := &config.Config{} + cfg.App.DataDir = t.TempDir() + cfg.Cache.CacheDir = t.TempDir() + svc := NewFileManagerService(cfg, zap.NewNop(), repos) + + listing, err := svc.List("", 100) + if err != nil { + t.Fatal(err) + } + got := map[string]string{} + for _, root := range listing.Roots { + got[root.Label] = root.Path + } + if got["library:电影:硬盘1"] != filepath.Clean(rootA) { + t.Fatalf("root A missing from listing: %#v", listing.Roots) + } + if got["library:电影:硬盘2"] != filepath.Clean(rootB) { + t.Fatalf("root B missing from listing: %#v", listing.Roots) + } + if _, err := svc.List(nestedB, 100); err != nil { + t.Fatalf("list second library root: %v", err) + } +} diff --git a/internal/service/service_builder.go b/internal/service/service_builder.go index c4dbebb..3fec2b8 100644 --- a/internal/service/service_builder.go +++ b/internal/service/service_builder.go @@ -180,6 +180,15 @@ func (b *serviceContainerBuilder) libraryRoots() []string { } roots := make([]string, 0, len(libs)) for _, l := range libs { + if len(l.Roots) > 0 { + for _, root := range l.Roots { + if !root.Enabled || strings.TrimSpace(root.Path) == "" { + continue + } + roots = append(roots, root.Path) + } + continue + } if strings.TrimSpace(l.Path) != "" { roots = append(roots, l.Path) } diff --git a/internal/service/service_builder_library_roots_test.go b/internal/service/service_builder_library_roots_test.go new file mode 100644 index 0000000..92e179b --- /dev/null +++ b/internal/service/service_builder_library_roots_test.go @@ -0,0 +1,46 @@ +package service + +import ( + "path/filepath" + "testing" + + "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MediaStationGo/internal/repository" +) + +func TestServiceBuilderLibraryRootsIncludesAllEnabledRoots(t *testing.T) { + rootA := t.TempDir() + rootB := t.TempDir() + rootDisabled := t.TempDir() + db := newServiceTestDB(t, &model.Library{}, &model.LibraryRoot{}) + repos := repository.New(db) + lib := &model.Library{Name: "电影", Path: rootA, Type: "movie", Enabled: true} + if err := repos.Library.CreateWithRoots(t.Context(), lib, []model.LibraryRoot{ + {Name: "硬盘1", Path: rootA, Enabled: true}, + {Name: "硬盘2", Path: rootB, Enabled: true, SortOrder: 1}, + {Name: "离线", Path: rootDisabled, Enabled: false, SortOrder: 2}, + }); err != nil { + t.Fatal(err) + } + disabledOnly := &model.Library{Name: "禁用库", Path: rootDisabled, Type: "movie", Enabled: true} + if err := repos.Library.CreateWithRoots(t.Context(), disabledOnly, []model.LibraryRoot{ + {Name: "离线", Path: rootDisabled, Enabled: false}, + }); err != nil { + t.Fatal(err) + } + + got := (&serviceContainerBuilder{repos: repos}).libraryRoots() + want := map[string]bool{ + filepath.Clean(rootA): true, + filepath.Clean(rootB): true, + } + for _, path := range got { + delete(want, filepath.Clean(path)) + if filepath.Clean(path) == filepath.Clean(rootDisabled) { + t.Fatalf("disabled root was returned: %#v", got) + } + } + if len(want) != 0 { + t.Fatalf("missing enabled roots %v from %#v", want, got) + } +}