diff --git a/backend/streetdrop-api/src/main/java/com/depromeet/domains/music/service/MusicService.java b/backend/streetdrop-api/src/main/java/com/depromeet/domains/music/service/MusicService.java index 1a994115..c18ed170 100644 --- a/backend/streetdrop-api/src/main/java/com/depromeet/domains/music/service/MusicService.java +++ b/backend/streetdrop-api/src/main/java/com/depromeet/domains/music/service/MusicService.java @@ -9,7 +9,7 @@ import com.depromeet.domains.music.event.CreateSongGenreEvent; import com.depromeet.domains.music.song.repository.SongRepository; import com.depromeet.domains.recommend.dto.response.MusicInfoResponseDto; -import com.depromeet.domains.recommend.dto.response.RecommendCategoryDto; +import com.depromeet.domains.recommend.dto.response.SearchRecommendCategoryDto; import com.depromeet.domains.recommend.constant.RecommendType; import com.depromeet.music.album.Album; import com.depromeet.music.album.AlbumCover; @@ -125,11 +125,11 @@ public MusicResponseDto getMusic(Long songId) { } @Transactional(readOnly = true) - public RecommendCategoryDto getRecentMusic(RecommendType recommendType) { + public SearchRecommendCategoryDto getRecentMusic(RecommendType recommendType) { var recentSongs = songRepository.findRecentSongs(recommendType.getLimit()); List musicInfoResponseDtos = recentSongs.stream() .map(MusicInfoResponseDto::ofSong) .toList(); - return RecommendCategoryDto.ofMusicInfoResponseDto(recommendType, musicInfoResponseDtos); + return SearchRecommendCategoryDto.ofMusicInfoResponseDto(recommendType, musicInfoResponseDtos); } } diff --git a/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/constant/RecommendType.java b/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/constant/RecommendType.java index 13b155f6..dbd4abac 100644 --- a/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/constant/RecommendType.java +++ b/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/constant/RecommendType.java @@ -6,11 +6,13 @@ @Getter @AllArgsConstructor public enum RecommendType { - POPULAR_CHART_SONG("지금 인기 있는 음악", 30, true), - RECENT_SONGS("최근 드랍된 음악", 15, true), - CHART_ARTIST("아티스트", 10, false); + POPULAR_CHART_SONG("지금 인기 있는 음악", "basic", "애플 뮤직의 '지금 인기 있는 곡' 리스트를 반영했어요.", 30, true), + RECENT_SONGS("최근 드랍된 음악", "basic", null, 15, true), + CHART_ARTIST("아티스트", "keyword", null, 10, false); private final String title; + private final String type; + private final String description; private final int limit; private final boolean nextPage; } diff --git a/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/controller/SearchRecommendController.java b/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/controller/SearchRecommendController.java index 4aab2d0c..5b71cfab 100644 --- a/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/controller/SearchRecommendController.java +++ b/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/controller/SearchRecommendController.java @@ -1,7 +1,7 @@ package com.depromeet.domains.recommend.controller; import com.depromeet.common.dto.ResponseDto; -import com.depromeet.domains.recommend.dto.response.RecommendResponseDto; +import com.depromeet.domains.recommend.dto.response.SearchRecommendResponseDto; import com.depromeet.domains.recommend.dto.response.SearchTermRecommendResponseDto; import com.depromeet.domains.recommend.service.SearchRecommendService; import io.swagger.v3.oas.annotations.Operation; @@ -29,7 +29,7 @@ public ResponseEntity recommendSearchTerm() { @Operation(summary = "검색어 추천 v2") @GetMapping("/v2/search-term/recommend") - public ResponseEntity recommendSearchTerm2() { + public ResponseEntity recommendSearchTerm2() { var response = searchRecommendService.recommendSearchSongs(); return ResponseDto.ok(response); } diff --git a/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/ContentTypeResponseDto.java b/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/ContentTypeResponseDto.java new file mode 100644 index 00000000..df81a34d --- /dev/null +++ b/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/ContentTypeResponseDto.java @@ -0,0 +1,23 @@ +package com.depromeet.domains.recommend.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.List; + +@Getter +@AllArgsConstructor +public class ContentTypeResponseDto { + + @Getter + @AllArgsConstructor + public static class BasicTypeResponseDto { + List basic; + } + + @Getter + @AllArgsConstructor + public static class KeywordTypeResponseDto { + List keyword; + } +} diff --git a/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/RecommendCategoryDto.java b/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/RecommendCategoryDto.java deleted file mode 100644 index 026bd1dd..00000000 --- a/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/RecommendCategoryDto.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.depromeet.domains.recommend.dto.response; - -import com.depromeet.domains.recommend.constant.RecommendType; -import com.depromeet.external.applemusic.dto.response.catalogchart.AppleMusicAlbumChartResponseDto; -import com.depromeet.external.applemusic.dto.response.catalogchart.AppleMusicSongChartResponseDto; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -@Getter -@AllArgsConstructor -public class RecommendCategoryDto { - private String title; - private List content; - private boolean nextPage; - - public static RecommendCategoryDto ofMusicInfoResponseDto(RecommendType recommendType, List musicInfoResponseDto) { - return new RecommendCategoryDto(recommendType.getTitle(), musicInfoResponseDto, recommendType.isNextPage()); - } - - - public static RecommendCategoryDto ofAppleMusicResponseDto(RecommendType recommendType, AppleMusicSongChartResponseDto appleMusicSongChartResponseDto) { - List musicInfoList = Optional.ofNullable(appleMusicSongChartResponseDto.results.songs) - .filter(songs -> !songs.isEmpty()) - .map(songs -> songs.get(0).data.stream() - .map(MusicInfoResponseDto::fromAppleMusicResponse) - .toList() - ) - .orElse(Collections.emptyList()); - return new RecommendCategoryDto(recommendType.getTitle(), musicInfoList, recommendType.isNextPage()); - } - - public static RecommendCategoryDto ofAppleMusicResponseDto(RecommendType recommendType, AppleMusicAlbumChartResponseDto appleMusicAlbumChartResponseDto) { - List artistInfoList = - Optional.ofNullable(appleMusicAlbumChartResponseDto.results.albums) - .filter(albums -> !albums.isEmpty()) - .map(albums -> albums.get(0).data.stream() - .map(ArtistInfoResponseDto::fromAppleMusicResponse) - .toList() - ) - .orElse(Collections.emptyList()); - return new RecommendCategoryDto(recommendType.getTitle(), artistInfoList, recommendType.isNextPage()); - } -} diff --git a/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/SearchRecommendCategoryDto.java b/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/SearchRecommendCategoryDto.java new file mode 100644 index 00000000..41eb54d6 --- /dev/null +++ b/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/SearchRecommendCategoryDto.java @@ -0,0 +1,80 @@ +package com.depromeet.domains.recommend.dto.response; + +import com.depromeet.domains.recommend.constant.RecommendType; +import com.depromeet.external.applemusic.dto.response.catalogchart.AppleMusicAlbumChartResponseDto; +import com.depromeet.external.applemusic.dto.response.catalogchart.AppleMusicSongChartResponseDto; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +@Getter +@AllArgsConstructor +public class SearchRecommendCategoryDto { + private String title; + private String type; + private String description; + private Object content; + private boolean nextPage; + + public static SearchRecommendCategoryDto ofMusicInfoResponseDto(RecommendType recommendType, List musicInfoResponseDto) { + return new SearchRecommendCategoryDto( + recommendType.getTitle(), + recommendType.getType(), + recommendType.getDescription(), + getContentTypeResponseDto(musicInfoResponseDto), + recommendType.isNextPage() + ); + } + + + public static SearchRecommendCategoryDto ofAppleMusicResponseDto(RecommendType recommendType, AppleMusicSongChartResponseDto appleMusicSongChartResponseDto) { + return new SearchRecommendCategoryDto( + recommendType.getTitle(), + recommendType.getType(), + recommendType.getDescription(), + getContentTypeResponseDto(appleMusicSongChartResponseDto), + recommendType.isNextPage() + ); + } + + public static SearchRecommendCategoryDto ofAppleMusicResponseDto(RecommendType recommendType, AppleMusicAlbumChartResponseDto appleMusicAlbumChartResponseDto) { + return new SearchRecommendCategoryDto( + recommendType.getTitle(), + recommendType.getType(), + recommendType.getDescription(), + getContentTypeResponseDto(appleMusicAlbumChartResponseDto), + recommendType.isNextPage() + ); + } + + private static ContentTypeResponseDto.BasicTypeResponseDto getContentTypeResponseDto(List musicInfoResponseDto) { + return new ContentTypeResponseDto.BasicTypeResponseDto(musicInfoResponseDto); + } + + private static ContentTypeResponseDto.BasicTypeResponseDto getContentTypeResponseDto(AppleMusicSongChartResponseDto appleMusicSongChartResponseDto) { + List musicInfoList = Optional.ofNullable(appleMusicSongChartResponseDto.results.songs) + .filter(songs -> !songs.isEmpty()) + .map(songs -> songs.get(0).data.stream() + .map(MusicInfoResponseDto::fromAppleMusicResponse) + .toList() + ) + .orElse(Collections.emptyList()); + return new ContentTypeResponseDto.BasicTypeResponseDto(musicInfoList); + } + + + private static ContentTypeResponseDto.KeywordTypeResponseDto getContentTypeResponseDto(AppleMusicAlbumChartResponseDto appleMusicAlbumChartResponseDto) { + List artistInfoList = + Optional.ofNullable(appleMusicAlbumChartResponseDto.results.albums) + .filter(albums -> !albums.isEmpty()) + .map(albums -> albums.get(0).data.stream() + .map(ArtistInfoResponseDto::fromAppleMusicResponse) + .toList() + ) + .orElse(Collections.emptyList()); + return new ContentTypeResponseDto.KeywordTypeResponseDto(artistInfoList); + } +} diff --git a/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/RecommendResponseDto.java b/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/SearchRecommendResponseDto.java similarity index 64% rename from backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/RecommendResponseDto.java rename to backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/SearchRecommendResponseDto.java index a0f689b3..3cc9c55e 100644 --- a/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/RecommendResponseDto.java +++ b/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/dto/response/SearchRecommendResponseDto.java @@ -7,6 +7,6 @@ @Getter @AllArgsConstructor -public class RecommendResponseDto { - private List data; +public class SearchRecommendResponseDto { + private List data; } diff --git a/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/service/SearchRecommendService.java b/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/service/SearchRecommendService.java index ac8d4531..4cad9b4e 100644 --- a/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/service/SearchRecommendService.java +++ b/backend/streetdrop-api/src/main/java/com/depromeet/domains/recommend/service/SearchRecommendService.java @@ -37,8 +37,8 @@ public SearchTermRecommendResponseDto recommendSearchTerm() { return new SearchTermRecommendResponseDto(description, termList); } - public RecommendResponseDto recommendSearchSongs() { - return new RecommendResponseDto( + public SearchRecommendResponseDto recommendSearchSongs() { + return new SearchRecommendResponseDto( List.of( appleMusicService.getCategoryChart(RecommendType.POPULAR_CHART_SONG), musicService.getRecentMusic(RecommendType.RECENT_SONGS), diff --git a/backend/streetdrop-api/src/main/java/com/depromeet/external/applemusic/service/AppleMusicService.java b/backend/streetdrop-api/src/main/java/com/depromeet/external/applemusic/service/AppleMusicService.java index 99c91788..f5429422 100644 --- a/backend/streetdrop-api/src/main/java/com/depromeet/external/applemusic/service/AppleMusicService.java +++ b/backend/streetdrop-api/src/main/java/com/depromeet/external/applemusic/service/AppleMusicService.java @@ -2,7 +2,7 @@ import com.depromeet.common.error.dto.CommonErrorCode; import com.depromeet.common.error.exception.internal.BusinessException; -import com.depromeet.domains.recommend.dto.response.RecommendCategoryDto; +import com.depromeet.domains.recommend.dto.response.SearchRecommendCategoryDto; import com.depromeet.domains.recommend.constant.RecommendType; import com.depromeet.external.feign.client.AppleMusicFeignClient; import lombok.RequiredArgsConstructor; @@ -14,15 +14,15 @@ public class AppleMusicService { private final AppleMusicFeignClient appleMusicFeignClient; - public RecommendCategoryDto getCategoryChart(RecommendType recommendType) { + public SearchRecommendCategoryDto getCategoryChart(RecommendType recommendType) { return switch (recommendType) { case POPULAR_CHART_SONG -> { var response = appleMusicFeignClient.getSongCharts("songs", recommendType.getLimit()); - yield RecommendCategoryDto.ofAppleMusicResponseDto(recommendType, response); + yield SearchRecommendCategoryDto.ofAppleMusicResponseDto(recommendType, response); } case CHART_ARTIST -> { var response = appleMusicFeignClient.getAlbumCharts("albums", recommendType.getLimit()); - yield RecommendCategoryDto.ofAppleMusicResponseDto(recommendType, response); + yield SearchRecommendCategoryDto.ofAppleMusicResponseDto(recommendType, response); } default -> throw new BusinessException(CommonErrorCode.UNSUPPORTED_TYPE); };