diff --git a/internal/controller/library.go b/internal/controller/library.go index b3de030..6c43bbc 100644 --- a/internal/controller/library.go +++ b/internal/controller/library.go @@ -51,6 +51,21 @@ func (c *LibraryController) Create(w http.ResponseWriter, r *http.Request) { jsonMsg(w, "Add library successfully.") } +func (c *LibraryController) GetByID(w http.ResponseWriter, r *http.Request) { + idParam := chi.URLParam(r, "id") + id, err := strconv.Atoi(idParam) + if err != nil { + jsonError(w, err.Error(), http.StatusBadRequest) + return + } + l, err := c.service.GetByID(id) + if err != nil { + jsonError(w, err.Error(), http.StatusInternalServerError) + return + } + jsonResponse(w, l, http.StatusOK) +} + func (c *LibraryController) UpdateName(w http.ResponseWriter, r *http.Request) { idParam := chi.URLParam(r, "id") id, err := strconv.Atoi(idParam) diff --git a/internal/controller/song.go b/internal/controller/song.go index aeb6ed4..94e916f 100644 --- a/internal/controller/song.go +++ b/internal/controller/song.go @@ -25,6 +25,21 @@ func (c *SongController) GetAllWithDetails(w http.ResponseWriter, r *http.Reques jsonResponse(w, songs, http.StatusOK) } +func (c *SongController) GetByIDWithDetails(w http.ResponseWriter, r *http.Request) { + paramID := chi.URLParam(r, "id") + id, err := strconv.Atoi(paramID) + if err != nil { + http.Error(w, "无效的歌曲 ID", http.StatusBadRequest) + return + } + song, err := c.service.GetByIDWithDetails(id) + if err != nil { + jsonError(w, err.Error(), http.StatusInternalServerError) + return + } + jsonResponse(w, song, http.StatusOK) +} + func (c *SongController) Stream(w http.ResponseWriter, r *http.Request) { paramID := chi.URLParam(r, "id") id, err := strconv.Atoi(paramID) diff --git a/internal/repository/song_repo.go b/internal/repository/song_repo.go index ce052a9..acc8e48 100644 --- a/internal/repository/song_repo.go +++ b/internal/repository/song_repo.go @@ -63,6 +63,21 @@ func (r *SongRepository) GetAllWithDetails() ([]SongDetail, error) { return songs, nil } +func (r *SongRepository) GetWithDetails(id int) (model.SongDetail, error) { + var song model.SongDetail + err := r.db.QueryRow(` + SELECT s.id, s.title, a.name as artist_name, al.title as album_title, s.duration, mf.path + FROM songs s WHERE id = ? + INNER JOIN media_files mf ON s.media_file_id = mf.id + INNER JOIN artists a ON s.artist_id = a.id + INNER JOIN albums al ON s.album_id = al.id + `, id).Scan(&song.ID, &song.Title, &song.Artist, &song.Album, &song.Duration, &song.Path) + if err != nil { + return model.SongDetail{}, err + } + return song, nil +} + func (r *SongRepository) Get(id int) (model.Song, error) { var song model.Song err := r.db.QueryRow(` diff --git a/internal/service/song_svc.go b/internal/service/song_svc.go index 5f2b853..63e5e0f 100644 --- a/internal/service/song_svc.go +++ b/internal/service/song_svc.go @@ -25,6 +25,10 @@ func (s *SongService) GetAllWithDetails() ([]repository.SongDetail, error) { return s.songRepo.GetAllWithDetails() } +func (s *SongService) GetByIDWithDetails(id int) (repository.SongDetail, error) { + return s.songRepo.GetWithDetails(id) +} + // GetMediaFilePath returns the file path of a song by its song ID. func (s *SongService) GetMediaFile(id int) (model.MediaFile, error) { song, err := s.songRepo.Get(id) diff --git a/main.go b/main.go index 52ad768..de4cd9b 100644 --- a/main.go +++ b/main.go @@ -37,16 +37,18 @@ func main() { r.Route("/api/libraries", func(r chi.Router) { r.Get("/", libraryController.GetAll) r.Post("/", libraryController.Create) + r.Get("/{id}", libraryController.GetByID) + r.Delete("/{id}", libraryController.Delete) r.Put("/{id}/name", libraryController.UpdateName) r.Put("/{id}/path", libraryController.UpdatePath) r.Post("/{id}/scan", libraryController.Scan) - r.Get("/scan-status", libraryController.GetScanStatus) - r.Delete("/{id}", libraryController.Delete) r.Get("/{id}/songs", libraryController.GetSongs) + r.Get("/scan-status", libraryController.GetScanStatus) }) r.Route("/api/songs", func(r chi.Router) { r.Get("/", songController.GetAllWithDetails) + r.Get("/{id}", songController.GetByIDWithDetails) r.Get("/{id}/stream", songController.Stream) r.Get("/{id}/cover", songController.Cover) })