-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[FEAT] 플레이리스트 API
- Loading branch information
Showing
17 changed files
with
1,561 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
src/main/java/com/cabin/plat/domain/playlist/controller/PlaylistController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package com.cabin.plat.domain.playlist.controller; | ||
|
||
import com.cabin.plat.config.AuthMember; | ||
import com.cabin.plat.domain.member.entity.Member; | ||
import com.cabin.plat.domain.playlist.dto.PlaylistRequest; | ||
import com.cabin.plat.domain.playlist.dto.PlaylistResponse; | ||
import com.cabin.plat.domain.playlist.service.PlaylistService; | ||
import com.cabin.plat.global.common.BaseResponse; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping("/playlists") | ||
@Tag(name = "플레이리스트 API", description = "플레이리스트 관련 API 입니다.") | ||
public class PlaylistController { | ||
|
||
private final PlaylistService playlistService; | ||
|
||
@Operation(summary = "플레이리스트 생성", description = "플레이리스트를 생성한다.") | ||
@PostMapping | ||
public BaseResponse<PlaylistResponse.PlayListId> addPlaylist( | ||
@AuthMember Member member, | ||
@RequestBody PlaylistRequest.PlaylistUpload playlistUpload) { | ||
|
||
return BaseResponse.onSuccess(playlistService.addPlaylist(member, playlistUpload)); | ||
} | ||
|
||
@Operation(summary = "플레이리스트 목록 조회", description = "사용자의 모든 플레이리스트를 가져온다. 페이지네이션을 지원합니다. page 파라미터에 페이지 번호를 입력해주세요.") | ||
@GetMapping | ||
public BaseResponse<PlaylistResponse.Playlists> getPlaylists( | ||
@AuthMember Member member, | ||
@RequestParam(defaultValue = "0") int page, | ||
@RequestParam(defaultValue = "20") int size) { | ||
|
||
return BaseResponse.onSuccess(playlistService.getPlaylists(member, page, size)); | ||
} | ||
|
||
@Operation(summary = "플레이리스트 목록 검색", description = "사용자의 플레이리스트를 제목으로 검색해서 가져온다. 페이지네이션을 지원합니다. page 파라미터에 페이지 번호를 입력해주세요.") | ||
@GetMapping("/search") | ||
public BaseResponse<PlaylistResponse.Playlists> getPlaylists( | ||
@AuthMember Member member, | ||
@RequestParam(defaultValue = "") String title, | ||
@RequestParam(defaultValue = "0") int page, | ||
@RequestParam(defaultValue = "20") int size) { | ||
|
||
return BaseResponse.onSuccess(playlistService.getSearchedPlaylists(member, title, page, size)); | ||
} | ||
|
||
@Operation(summary = "플레이리스트 삭제", description = "플레이리스트를 삭제한다.") | ||
@DeleteMapping("/{playlistId}") | ||
public BaseResponse<PlaylistResponse.PlayListId> deletePlaylist( | ||
@AuthMember Member member, | ||
@PathVariable("playlistId") Long playlistId) { | ||
|
||
return BaseResponse.onSuccess(playlistService.deletePlaylist(member, playlistId)); | ||
} | ||
|
||
@Operation(summary = "플레이리스트 디테일 조회", description = "사용자의 플레이리스트 하나의 정보를 가져온다. 내부 트랙의 정보도 모두 가져온다.") | ||
@GetMapping("/{playlistId}/detail") | ||
public BaseResponse<PlaylistResponse.PlaylistDetail> getPlaylistDetail( | ||
@AuthMember Member member, | ||
@PathVariable("playlistId") Long playlistId) { | ||
|
||
return BaseResponse.onSuccess(playlistService.getPlaylistDetail(member, playlistId)); | ||
} | ||
|
||
@Operation(summary = "플레이리스트 정보 수정", description = "플레이리스트 사진과 제목을 편집한다.") | ||
@PatchMapping("/{playlistId}") | ||
public BaseResponse<PlaylistResponse.PlayListId> updatePlaylist( | ||
@AuthMember Member member, | ||
@PathVariable("playlistId") Long playlistId, | ||
@RequestBody PlaylistRequest.PlaylistEdit playlistEdit) { | ||
|
||
return BaseResponse.onSuccess(playlistService.updatePlaylistTitleAndImage(member, playlistId, playlistEdit)); | ||
} | ||
|
||
@Operation(summary = "플레이리스트에 트랙 추가", description = "플레이리스트에 트랙을 추가한다.") | ||
@PostMapping("/{playlistId}") | ||
public BaseResponse<PlaylistResponse.PlayListId> addTrackToPlaylist( | ||
@AuthMember Member member, | ||
@PathVariable("playlistId") Long playlistId, | ||
@RequestBody PlaylistRequest.TrackId trackId) { | ||
|
||
return BaseResponse.onSuccess(playlistService.addTrackToPlaylist(member, playlistId, trackId)); | ||
} | ||
|
||
@Operation(summary = "플레이리스트 트랙 순서 변경", description = "플레이리스트 내부의 트랙의 순서를 변경한다.") | ||
@PatchMapping("/{playlistId}/tracks/order") | ||
public BaseResponse<PlaylistResponse.PlayListId> updateTrackOrders( | ||
@AuthMember Member member, | ||
@PathVariable("playlistId") Long playlistId, | ||
@RequestBody PlaylistRequest.PlaylistOrders playlistOrders) { | ||
|
||
return BaseResponse.onSuccess(playlistService.updateTrackOrders(member, playlistId, playlistOrders)); | ||
} | ||
|
||
@Operation(summary = "플레이리스트에서 트랙 삭제", description = "플레이리스트 내부의 트랙을 삭제합니다.") | ||
@DeleteMapping("/{playlistId}/tracks/{trackId}") | ||
public BaseResponse<PlaylistResponse.PlayListId> deleteTrackFromPlaylist( | ||
@AuthMember Member member, | ||
@PathVariable("playlistId") Long playlistId, | ||
@PathVariable("trackId") Long trackId) { | ||
|
||
return BaseResponse.onSuccess(playlistService.deleteTrackFromPlaylist(member, playlistId, trackId)); | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
src/main/java/com/cabin/plat/domain/playlist/dto/PlaylistRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package com.cabin.plat.domain.playlist.dto; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import java.util.List; | ||
import lombok.*; | ||
|
||
public class PlaylistRequest { | ||
|
||
@Getter | ||
@Builder | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public static class PlaylistEdit { | ||
@Schema(description = "플레이리스트 제목", example = "플레이리스트 제목") | ||
private String title; | ||
|
||
@Schema(description = "플레이리스트 이미지 URL", example = "https://s3.amazonaws.com/mybucket/images/sample.jpg") | ||
private String playlistImageUrl; | ||
} | ||
|
||
@Getter | ||
@Builder | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public static class PlaylistOrders { | ||
private List<TrackOrder> tracks; | ||
} | ||
|
||
@Getter | ||
@Builder | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public static class PlaylistUpload { | ||
@Schema(description = "플레이리스트 제목", example = "플레이리스트 제목") | ||
private String title; | ||
|
||
@Schema(description = "플레이리스트 이미지 URL", example = "https://s3.amazonaws.com/mybucket/images/sample.jpg") | ||
private String playlistImageUrl; | ||
|
||
private List<TrackOrder> tracks; | ||
} | ||
|
||
@Getter | ||
@Builder | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public static class TrackOrder { | ||
@Schema(description = "트랙 고유 ID", example = "1") | ||
private Long trackId; | ||
|
||
@Schema(description = "플레이리스트에서 트랙의 순서", example = "0") | ||
private int orderIndex; | ||
} | ||
|
||
@Getter | ||
@Builder | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
public static class TrackId { | ||
@Schema(description = "트랙 고유 ID", example = "1") | ||
private Long trackId; | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
src/main/java/com/cabin/plat/domain/playlist/dto/PlaylistResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package com.cabin.plat.domain.playlist.dto; | ||
|
||
import com.cabin.plat.domain.track.dto.TrackResponse.TrackDetail; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
import java.util.Set; | ||
import lombok.*; | ||
|
||
public class PlaylistResponse { | ||
@Getter | ||
@Builder | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
public static class PlayListId { | ||
@Schema(description = "플레이리스트 고유 ID", example = "1") | ||
private Long playlistId; | ||
} | ||
|
||
@Getter | ||
@Builder | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
public static class Playlists { | ||
private List<PlaylistInfo> playlists; | ||
|
||
@Getter | ||
@Builder | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
public static class PlaylistInfo { | ||
@Schema(description = "플레이리스트 고유 ID", example = "1") | ||
private Long playlistId; | ||
|
||
@Schema(description = "플레이리스트 제목", example = "플레이리스트 제목") | ||
private String title; | ||
|
||
@Schema(description = "플레이리스트 이미지 URL", example = "https://s3.amazonaws.com/mybucket/images/sample.jpg") | ||
private String playlistImageUrl; | ||
|
||
@Schema(description = "플레이리스트 생성일", example = "2024-09-22T07:23:09.102Z") | ||
private LocalDateTime createdAt; | ||
|
||
private Set<String> uploaderNicknames; | ||
} | ||
} | ||
|
||
@Getter | ||
@Builder | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
public static class PlaylistDetail { | ||
@Schema(description = "플레이리스트 고유 ID", example = "1") | ||
private Long playlistId; | ||
|
||
@Schema(description = "플레이리스트 제목", example = "플레이리스트 제목") | ||
private String title; | ||
|
||
@Schema(description = "플레이리스트 이미지 URL", example = "https://s3.amazonaws.com/mybucket/images/sample.jpg") | ||
private String playlistImageUrl; | ||
|
||
@Schema(description = "플레이리스트 생성일", example = "2024-09-22T07:23:09.102Z") | ||
private LocalDateTime createdAt; | ||
|
||
private List<TrackDetailOrder> tracks; | ||
} | ||
|
||
@Getter | ||
@Builder | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
public static class TrackDetailOrder { | ||
@Schema(description = "트랙 순서", example = "1") | ||
private int orderIndex; | ||
|
||
@Schema(description = "트랙 상세 정보") | ||
private TrackDetail trackDetail; | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
src/main/java/com/cabin/plat/domain/playlist/entity/Playlist.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.cabin.plat.domain.playlist.entity; | ||
|
||
import com.cabin.plat.domain.member.entity.Member; | ||
import com.cabin.plat.global.common.BaseEntity; | ||
import jakarta.persistence.*; | ||
import java.util.Set; | ||
import lombok.*; | ||
import org.hibernate.annotations.SQLRestriction; | ||
|
||
@Getter | ||
@Builder | ||
@Entity | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor | ||
@SQLRestriction("deleted_at is null") | ||
public class Playlist extends BaseEntity { | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "playlist_id") | ||
private Long id; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "member_id", nullable = false) | ||
private Member member; | ||
|
||
@Column(nullable = false) | ||
private String title; | ||
|
||
private String playlistImageUrl; | ||
|
||
@OneToMany(mappedBy = "playlist", cascade = CascadeType.ALL) | ||
private Set<PlaylistTrack> playlistTracks; | ||
|
||
public void updatePlaylist(String title, String playlistImageUrl) { | ||
this.title = title; | ||
this.playlistImageUrl = playlistImageUrl; | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
src/main/java/com/cabin/plat/domain/playlist/entity/PlaylistTrack.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.cabin.plat.domain.playlist.entity; | ||
|
||
import com.cabin.plat.domain.track.entity.Track; | ||
import com.cabin.plat.global.common.BaseEntity; | ||
import jakarta.persistence.*; | ||
import lombok.*; | ||
import org.hibernate.annotations.SQLRestriction; | ||
|
||
@Getter | ||
@Builder | ||
@Entity | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor | ||
@SQLRestriction("deleted_at is null") | ||
public class PlaylistTrack extends BaseEntity { | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "track_playlist_id") | ||
private Long id; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "playlist_id", nullable = false) | ||
private Playlist playlist; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "track_id", nullable = false) | ||
private Track track; | ||
|
||
@Setter | ||
@Column(name = "order_index", nullable = false) | ||
private int orderIndex; | ||
} |
Oops, something went wrong.