diff --git a/src/main/java/sws/songpin/domain/bookmark/controller/BookmarkController.java b/src/main/java/sws/songpin/domain/bookmark/controller/BookmarkController.java index 8f701a1a..73b77256 100644 --- a/src/main/java/sws/songpin/domain/bookmark/controller/BookmarkController.java +++ b/src/main/java/sws/songpin/domain/bookmark/controller/BookmarkController.java @@ -7,7 +7,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import sws.songpin.domain.bookmark.dto.request.BookmarkAddRequestDto; +import sws.songpin.domain.bookmark.dto.request.BookmarkRequestDto; import sws.songpin.domain.bookmark.service.BookmarkService; @Tag(name = "Bookmark", description = "Bookmark 관련 API입니다.") @@ -17,16 +17,16 @@ public class BookmarkController { private final BookmarkService bookmarkService; - @Operation(summary = "북마크 생성", description = "플레이리스트에 북마크 생성") - @PostMapping - public ResponseEntity createBookmark(@RequestBody @Valid BookmarkAddRequestDto requestDto){ - return ResponseEntity.status(HttpStatus.CREATED).body(bookmarkService.createBookmark(requestDto)); - } - - @Operation(summary = "북마크 삭제", description = "플레이리스트의 북마크 제거") - @DeleteMapping("/{bookmarkId}") - public ResponseEntity deleteBookmark(@PathVariable("bookmarkId") final Long bookmarkId){ - bookmarkService.deleteBookmark(bookmarkId); - return ResponseEntity.ok().build(); + @Operation(summary = "북마크 상태 변경", description = "북마크가 없으면 생성하고, 있으면 삭제") + @PutMapping + public ResponseEntity changeBookmark(@RequestBody @Valid BookmarkRequestDto requestDto){ + boolean isCreated = bookmarkService.changeBookmark(requestDto); + if(isCreated){ + // 북마크 생성 + return ResponseEntity.status(HttpStatus.CREATED).build(); + } else{ + // 북마크 삭제 + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } } } diff --git a/src/main/java/sws/songpin/domain/bookmark/dto/request/BookmarkAddRequestDto.java b/src/main/java/sws/songpin/domain/bookmark/dto/request/BookmarkRequestDto.java similarity index 92% rename from src/main/java/sws/songpin/domain/bookmark/dto/request/BookmarkAddRequestDto.java rename to src/main/java/sws/songpin/domain/bookmark/dto/request/BookmarkRequestDto.java index 3a939ff2..f2e40e04 100644 --- a/src/main/java/sws/songpin/domain/bookmark/dto/request/BookmarkAddRequestDto.java +++ b/src/main/java/sws/songpin/domain/bookmark/dto/request/BookmarkRequestDto.java @@ -5,7 +5,7 @@ import sws.songpin.domain.member.entity.Member; import sws.songpin.domain.playlist.entity.Playlist; -public record BookmarkAddRequestDto( +public record BookmarkRequestDto( @NotNull Long playlistId ){ diff --git a/src/main/java/sws/songpin/domain/bookmark/dto/response/BookmarkAddResponseDto.java b/src/main/java/sws/songpin/domain/bookmark/dto/response/BookmarkAddResponseDto.java deleted file mode 100644 index 6c501895..00000000 --- a/src/main/java/sws/songpin/domain/bookmark/dto/response/BookmarkAddResponseDto.java +++ /dev/null @@ -1,13 +0,0 @@ -package sws.songpin.domain.bookmark.dto.response; - -import sws.songpin.domain.bookmark.entity.Bookmark; - -public record BookmarkAddResponseDto( - Long bookmarkId -) { - - public static BookmarkAddResponseDto from(Bookmark bookmark) { - return new BookmarkAddResponseDto(bookmark.getBookmarkId()); - } - -} diff --git a/src/main/java/sws/songpin/domain/bookmark/service/BookmarkService.java b/src/main/java/sws/songpin/domain/bookmark/service/BookmarkService.java index 93a8a9fc..baea3efd 100644 --- a/src/main/java/sws/songpin/domain/bookmark/service/BookmarkService.java +++ b/src/main/java/sws/songpin/domain/bookmark/service/BookmarkService.java @@ -4,8 +4,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import sws.songpin.domain.bookmark.dto.request.BookmarkAddRequestDto; -import sws.songpin.domain.bookmark.dto.response.BookmarkAddResponseDto; +import sws.songpin.domain.bookmark.dto.request.BookmarkRequestDto; import sws.songpin.domain.bookmark.entity.Bookmark; import sws.songpin.domain.bookmark.repository.BookmarkRepository; import sws.songpin.domain.member.entity.Member; @@ -31,29 +30,26 @@ public class BookmarkService { private final MemberService memberService; private final PlaylistService playlistService; - // 북마크 생성 - public BookmarkAddResponseDto createBookmark(BookmarkAddRequestDto requestDto) { + // 북마크 상태 변경 + public boolean changeBookmark(BookmarkRequestDto requestDto) { Member member = memberService.getCurrentMember(); Playlist playlist = playlistService.findPlaylistById(requestDto.playlistId()); if (!member.equals(playlist.getCreator()) && playlist.getVisibility() == Visibility.PRIVATE) { throw new CustomException(ErrorCode.UNAUTHORIZED_REQUEST); } - getBookmarkByPlaylistAndMember(playlist, member).ifPresent(bookmark -> { - throw new CustomException(ErrorCode.BOOKMARK_ALREADY_EXISTS); - }); - Bookmark bookmark = requestDto.toEntity(member, playlist); - Bookmark savedBookmark = bookmarkRepository.save(bookmark); - return BookmarkAddResponseDto.from(savedBookmark); - } - - // 북마크 삭제 - public void deleteBookmark(Long bookmarkId) { - Bookmark bookmark = findBookmarkById(bookmarkId); - Member currentMember = memberService.getCurrentMember(); - if (!bookmark.getMember().equals(currentMember)) { - throw new CustomException(ErrorCode.UNAUTHORIZED_REQUEST); + Optional bookmark = getBookmarkByPlaylistAndMember(playlist, member); + if(bookmark.isPresent()){ + bookmark.ifPresent(bookmarkRepository::delete); + return false; + } + else{ + Bookmark newBookmark = Bookmark.builder() + .member(member) + .playlist(playlist) + .build(); + bookmarkRepository.save(newBookmark); + return true; } - bookmarkRepository.delete(bookmark); } // 내 모든 북마크된 플레이리스트 조회 @@ -74,12 +70,6 @@ public Optional getBookmarkByPlaylistAndMember(Playlist playlist, Memb return bookmarkRepository.findByPlaylistAndMember(playlist, member); } - @Transactional(readOnly = true) - public Bookmark findBookmarkById(Long bookmarkId) { - return bookmarkRepository.findById(bookmarkId) - .orElseThrow(() -> new CustomException(ErrorCode.BOOKMARK_NOT_FOUND)); - } - public void deleteAllBookmarksOfMember(Member member){ bookmarkRepository.deleteAllByMember(member); } diff --git a/src/main/java/sws/songpin/domain/follow/controller/FollowController.java b/src/main/java/sws/songpin/domain/follow/controller/FollowController.java index f84814fb..a75a595e 100644 --- a/src/main/java/sws/songpin/domain/follow/controller/FollowController.java +++ b/src/main/java/sws/songpin/domain/follow/controller/FollowController.java @@ -4,9 +4,10 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import sws.songpin.domain.follow.dto.request.FollowAddRequestDto; +import sws.songpin.domain.follow.dto.request.FollowRequestDto; import sws.songpin.domain.follow.service.FollowService; @Tag(name = "Follow", description = "Follow 관련 API입니다.") @@ -16,16 +17,21 @@ public class FollowController { private final FollowService followService; - @Operation(summary = "타 유저를 팔로잉", description = "다른 유저를 팔로잉합니다.") - @PostMapping - public ResponseEntity followAdd(@RequestBody @Valid FollowAddRequestDto followAddRequestDto) { - return ResponseEntity.ok(followService.addFollow(followAddRequestDto)); + @Operation(summary = "팔로잉 상태 변경", description = "다른 유저를 팔로잉 또는 팔로우 취소합니다.") + @PutMapping + public ResponseEntity changeFollow(@RequestBody @Valid FollowRequestDto requestDto) { + boolean isCreated = followService.createOrDeleteFollow(requestDto); + if (isCreated) { + return ResponseEntity.status(HttpStatus.CREATED).build(); + } else { + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } } - @Operation(summary = "팔로잉 취소 또는 팔로워 삭제", description = "나의 팔로잉을 취소하거나 팔로워를 삭제합니다.") - @DeleteMapping("/{followId}") - public ResponseEntity followRemove(@PathVariable final Long followId) { - followService.deleteFollow(followId); - return ResponseEntity.noContent().build(); + @Operation(summary = "팔로워 삭제", description = "나의 팔로워를 삭제합니다.") + @DeleteMapping("/followers") + public ResponseEntity deleteFollower(@RequestBody @Valid FollowRequestDto requestDto) { + followService.deleteFollower(requestDto); + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); } } diff --git a/src/main/java/sws/songpin/domain/follow/dto/request/FollowAddRequestDto.java b/src/main/java/sws/songpin/domain/follow/dto/request/FollowRequestDto.java similarity index 84% rename from src/main/java/sws/songpin/domain/follow/dto/request/FollowAddRequestDto.java rename to src/main/java/sws/songpin/domain/follow/dto/request/FollowRequestDto.java index 3a6fc9c4..c8be5a9f 100644 --- a/src/main/java/sws/songpin/domain/follow/dto/request/FollowAddRequestDto.java +++ b/src/main/java/sws/songpin/domain/follow/dto/request/FollowRequestDto.java @@ -4,8 +4,8 @@ import sws.songpin.domain.follow.entity.Follow; import sws.songpin.domain.member.entity.Member; -public record FollowAddRequestDto( - @NotNull Long targetMemberId +public record FollowRequestDto( + @NotNull Long memberId ){ public static Follow toEntity(Member follower, Member following) { return Follow.builder() diff --git a/src/main/java/sws/songpin/domain/follow/dto/response/FollowAddResponseDto.java b/src/main/java/sws/songpin/domain/follow/dto/response/FollowAddResponseDto.java deleted file mode 100644 index 4dd7256c..00000000 --- a/src/main/java/sws/songpin/domain/follow/dto/response/FollowAddResponseDto.java +++ /dev/null @@ -1,11 +0,0 @@ -package sws.songpin.domain.follow.dto.response; - -import sws.songpin.domain.follow.entity.Follow; - -public record FollowAddResponseDto( - Long followId -){ - public static FollowAddResponseDto from(Follow follow) { - return new FollowAddResponseDto(follow.getFollowId()); - } -} \ No newline at end of file diff --git a/src/main/java/sws/songpin/domain/follow/dto/response/FollowDto.java b/src/main/java/sws/songpin/domain/follow/dto/response/FollowDto.java index b0a5e155..0b7df9da 100644 --- a/src/main/java/sws/songpin/domain/follow/dto/response/FollowDto.java +++ b/src/main/java/sws/songpin/domain/follow/dto/response/FollowDto.java @@ -3,22 +3,20 @@ import sws.songpin.domain.member.entity.Member; import sws.songpin.domain.member.entity.ProfileImg; -public record FollowDto( // FollowerListResponseDto, FollowingListResponseDto에서 사용하는 레코드 +public record FollowDto( Long memberId, ProfileImg profileImg, String nickname, String handle, - Boolean isFollowing, - Long followId + Boolean isFollowing ) { - public static FollowDto from (Member member, Boolean isFollowing, Long followId) { + public static FollowDto from (Member member, Boolean isFollowing) { return new FollowDto( member.getMemberId(), member.getProfileImg(), member.getNickname(), member.getHandle(), - isFollowing, - followId // currentMember가 팔로잉하는 경우 currentMember와의 followId 삽입 + isFollowing ); } } \ No newline at end of file diff --git a/src/main/java/sws/songpin/domain/follow/repository/FollowRepository.java b/src/main/java/sws/songpin/domain/follow/repository/FollowRepository.java index f12c49f4..d7d34b0a 100644 --- a/src/main/java/sws/songpin/domain/follow/repository/FollowRepository.java +++ b/src/main/java/sws/songpin/domain/follow/repository/FollowRepository.java @@ -8,7 +8,6 @@ import java.util.Optional; public interface FollowRepository extends JpaRepository { - Boolean existsByFollowerAndFollowing(Member follower, Member following); List findAllByFollowing(Member following); List findAllByFollower(Member follower); Long countByFollowing(Member following); diff --git a/src/main/java/sws/songpin/domain/follow/service/FollowService.java b/src/main/java/sws/songpin/domain/follow/service/FollowService.java index 08ab1fa5..9e8bdd87 100644 --- a/src/main/java/sws/songpin/domain/follow/service/FollowService.java +++ b/src/main/java/sws/songpin/domain/follow/service/FollowService.java @@ -4,14 +4,12 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import sws.songpin.domain.alarm.service.AlarmService; -import sws.songpin.domain.follow.dto.request.FollowAddRequestDto; -import sws.songpin.domain.follow.dto.response.FollowAddResponseDto; +import sws.songpin.domain.follow.dto.request.FollowRequestDto; import sws.songpin.domain.follow.dto.response.FollowDto; import sws.songpin.domain.follow.dto.response.FollowListResponseDto; import sws.songpin.domain.follow.entity.Follow; import sws.songpin.domain.follow.repository.FollowRepository; import sws.songpin.domain.member.entity.Member; -import sws.songpin.domain.member.entity.Status; import sws.songpin.domain.member.service.MemberService; import sws.songpin.global.exception.CustomException; import sws.songpin.global.exception.ErrorCode; @@ -19,6 +17,7 @@ import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; @Service @@ -29,32 +28,61 @@ public class FollowService { private final MemberService memberService; private final AlarmService alarmService; - // 팔로우 추가 - public FollowAddResponseDto addFollow(FollowAddRequestDto followAddRequestDto){ - Member follower = memberService.getCurrentMember(); - Member following = memberService.getActiveMemberById(followAddRequestDto.targetMemberId()); + public boolean createOrDeleteFollow(FollowRequestDto requestDto) { + Member currentMember = memberService.getCurrentMember(); + Member targetMember = memberService.getActiveMemberById(requestDto.memberId()); - if (!follower.equals(memberService.getCurrentMember())){ // follower가 자신이어야 함 - throw new CustomException(ErrorCode.UNAUTHORIZED_REQUEST); - } else if (follower.equals(following)){ // follower가 following과 동일하면 팔로우 불가 + if (currentMember.equals(targetMember)) { // follower가 following과 동일하면 팔로우 불가 throw new CustomException(ErrorCode.FOLLOW_BAD_REQUEST); - } else if (checkFollowExists(follower, following)){ // follow가 이미 존재하면 팔로우 불가 - throw new CustomException(ErrorCode.FOLLOW_ALREADY_EXISTS); } - Follow follow = followRepository.save(FollowAddRequestDto.toEntity(follower, following)); - alarmService.createFollowAlarm(follower, following); - return FollowAddResponseDto.from(follow); + + Optional followOptional = followRepository.findByFollowerAndFollowing(currentMember, targetMember); + if (checkIfFollowExists(targetMember, currentMember)) { // 팔로우가 존재하면 삭제 + followRepository.delete(followOptional.get()); + return false; + } else { // 팔로우 추가 + followRepository.save(FollowRequestDto.toEntity(currentMember, targetMember)); + alarmService.createFollowAlarm(currentMember, targetMember); + return true; + } + } + + public void deleteFollower(FollowRequestDto requestDto){ + Member currentMember = memberService.getCurrentMember(); + Member targetMember = memberService.getActiveMemberById(requestDto.memberId()); + + if (currentMember.equals(targetMember)) { + throw new CustomException(ErrorCode.FOLLOW_BAD_REQUEST); + } + + Optional followOptional = followRepository.findByFollowerAndFollowing(targetMember, currentMember); + if (followOptional.isPresent()) { // 팔로우가 존재하면 삭제 + followRepository.delete(followOptional.get()); + } else { + throw new CustomException(ErrorCode.FOLLOW_NOT_FOUND); + } + } + + public Boolean checkIfFollowing(Member targetMember){ + Member currentMember = memberService.getCurrentMember(); + return checkIfFollowExists(currentMember, targetMember); } - // 팔로우 삭제 - public void deleteFollow(Long followId) { - Follow follow = findFollowById(followId); + public Boolean checkIfFollower(Member targetMember) { Member currentMember = memberService.getCurrentMember(); - boolean isFollowerOrFollowing = currentMember.equals(follow.getFollower()) || currentMember.equals(follow.getFollowing()); - if (!isFollowerOrFollowing) { // 자신이 follower거나 following이 아니면 follow 삭제 불가능 - throw new CustomException(ErrorCode.UNAUTHORIZED_REQUEST); + return checkIfFollowExists(targetMember, currentMember); + } + + public Boolean checkIfFollowExists(Member follower, Member following) { + if (follower.equals(following)) { + return null; + } + Optional followOptional = followRepository.findByFollowerAndFollowing(follower, following); + if (followOptional.isPresent()) { + return true; + } else { + return false; } - followRepository.delete(follow); } // 특정 사용자의 팔로잉/팔로워 목록 조회 @@ -67,14 +95,12 @@ public FollowListResponseDto getFollowList(Long memberId, boolean isFollowingLis List followDtoList = followList.stream() .map(follow -> { Member member = isFollowingList ? follow.getFollowing() : follow.getFollower(); - Long followId = currentMemberFollowingCache.get(member); // isFollowing: 로그인한 사용자의 member 팔로잉 여부 (null: 자신) - Boolean isFollowing = member.equals(currentMember) ? null : followId != null; - return FollowDto.from(member, isFollowing, followId); + Boolean isFollowing = member.equals(currentMember) ? null : currentMemberFollowingCache.get(member) != null; + return FollowDto.from(member, isFollowing); }) - // 우선순위대로 정렬 (1차: null > true > false, 2차: followId 높은 것부터) - .sorted(Comparator.comparing(FollowDto::isFollowing, Comparator.nullsFirst(Comparator.reverseOrder())) - .thenComparing(FollowDto::followId, Comparator.nullsLast(Comparator.reverseOrder()))) + // 우선순위대로 정렬 (null > true > false) + .sorted(Comparator.comparing(FollowDto::isFollowing, Comparator.nullsFirst(Comparator.reverseOrder()))) .collect(Collectors.toList()); return FollowListResponseDto.from(targetMember.equals(currentMember), targetMember.getHandle(), followDtoList); } @@ -86,17 +112,6 @@ public Map getMemberFollowingCache(Member member) { .collect(Collectors.toMap(Follow::getFollowing, Follow::getFollowId)); } - @Transactional(readOnly = true) - public Follow findFollowById(Long followId){ - return followRepository.findById(followId) - .orElseThrow(() -> new CustomException(ErrorCode.FOLLOW_NOT_FOUND)); - } - - @Transactional(readOnly = true) - public boolean checkFollowExists(Member follower, Member following) { - return followRepository.existsByFollowerAndFollowing(follower, following).booleanValue(); - } - // member의 팔로워들 @Transactional(readOnly = true) public List findAllFollowersOfMember(Member member){ @@ -119,12 +134,6 @@ public long getFollowingCount(Member member){ return followRepository.countByFollower(member); } - @Transactional(readOnly = true) - public Long getFollowId(Member follower, Member following){ - return followRepository.findByFollowerAndFollowing(follower,following) - .orElseThrow(()-> new CustomException(ErrorCode.FOLLOW_NOT_FOUND)).getFollowId(); - } - //회원의 팔로워 및 팔로잉 모두 삭제 public void deleteAllFollowsOfMember(Member member){ followRepository.deleteAllByFollower(member); diff --git a/src/main/java/sws/songpin/domain/member/controller/AuthController.java b/src/main/java/sws/songpin/domain/member/controller/AuthController.java index a66774e7..405f21e7 100644 --- a/src/main/java/sws/songpin/domain/member/controller/AuthController.java +++ b/src/main/java/sws/songpin/domain/member/controller/AuthController.java @@ -47,13 +47,6 @@ public ResponseEntity login(@Valid @RequestBody LoginRequestDto requestDto, H return ResponseEntity.ok(new LoginResponseDto(tokenDto.accessToken())); } - @Operation(summary = "로그아웃", description = "Redis와 쿠키에 저장되었던 회원의 Refresh Token을 삭제합니다.") - @PostMapping("/logout") - public ResponseEntity logout(HttpServletResponse response){ - - return ResponseEntity.ok().build(); - } - @Operation(summary = "토큰 재발급", description = "Access Token 만료 시 Refresh Token 을 이용하여 Access Token 및 Refresh Token 재발급") @PostMapping("/token") public ResponseEntity reissue(HttpServletRequest request, HttpServletResponse response){ diff --git a/src/main/java/sws/songpin/domain/member/dto/response/MemberProfileResponseDto.java b/src/main/java/sws/songpin/domain/member/dto/response/MemberProfileResponseDto.java index 90d3ac8d..40d0472c 100644 --- a/src/main/java/sws/songpin/domain/member/dto/response/MemberProfileResponseDto.java +++ b/src/main/java/sws/songpin/domain/member/dto/response/MemberProfileResponseDto.java @@ -9,9 +9,10 @@ public record MemberProfileResponseDto( String handle, long followerCount, long followingCount, - Long followId + Boolean isFollowing, + Boolean isFollower ) { - public static MemberProfileResponseDto from(Member member, long followerCount, long followingCount, Long followId){ - return new MemberProfileResponseDto(member.getProfileImg(), member.getNickname(), member.getHandle(), followerCount, followingCount, followId); + public static MemberProfileResponseDto from(Member member, long followerCount, long followingCount, Boolean isFollowing, Boolean isFollower){ + return new MemberProfileResponseDto(member.getProfileImg(), member.getNickname(), member.getHandle(), followerCount, followingCount, isFollowing, isFollower); } } diff --git a/src/main/java/sws/songpin/domain/member/service/ProfileService.java b/src/main/java/sws/songpin/domain/member/service/ProfileService.java index b07910cd..7bf01243 100644 --- a/src/main/java/sws/songpin/domain/member/service/ProfileService.java +++ b/src/main/java/sws/songpin/domain/member/service/ProfileService.java @@ -38,7 +38,7 @@ public MemberProfileResponseDto getMemberProfile(Long memberId){ Member currentMember = memberService.getCurrentMember(); //조회하려는 회원이 본인인 경우 예외 처리 - if(member.equals(currentMember)){ + if (member.equals(currentMember)){ throw new CustomException(ErrorCode.MEMBER_BAD_REQUEST); } @@ -48,14 +48,13 @@ public MemberProfileResponseDto getMemberProfile(Long memberId){ //팔로잉 수 long followingCount = followService.getFollowingCount(member); - //팔로우 여부 (팔로우ID) - Long followId = null; - if(followService.checkFollowExists(currentMember,member)){ - followId = followService.getFollowId(currentMember,member); - } + //내가 팔로잉중인지 여부 + Boolean isFollowing = followService.checkIfFollowing(member); - return MemberProfileResponseDto.from(member, followerCount, followingCount, followId); + //해당 유저가 나의 팔로워인지 여부 + Boolean isFollower = followService.checkIfFollower(member); + return MemberProfileResponseDto.from(member, followerCount, followingCount, isFollowing, isFollower); } @Transactional(readOnly = true) @@ -72,26 +71,30 @@ public MyProfileResponseDto getMyProfile(){ } public void updateProfile(ProfileUpdateRequestDto requestDto){ - Member member = memberService.getCurrentMember(); - //핸들 중복 검사 - if(memberService.checkMemberExistsByHandle(requestDto.handle()) && !(member.getHandle().equals(requestDto.handle()))){ + if (memberService.checkMemberExistsByHandle(requestDto.handle()) && !(member.getHandle().equals(requestDto.handle()))){ throw new CustomException(ErrorCode.HANDLE_ALREADY_EXISTS); } - member.modifyProfile(ProfileImg.from(requestDto.profileImg()), requestDto.nickname(), requestDto.handle()); - memberService.saveMember(member); + } + public void updatePassword(PasswordUpdateRequestDto requestDto){ + Member member = memberService.getCurrentMember(); + //비밀번호 일치 검사 + if (!requestDto.password().equals(requestDto.confirmPassword())) { + throw new CustomException(ErrorCode.PASSWORD_MISMATCH); + } + member.modifyPassword(authService.encodePassword(requestDto.password())); + memberService.saveMember(member); } public void deactivateProfile(ProfileDeactivateRequestDto requestDto){ - Member member = memberService.getCurrentMember(); //패스워드 검사 - if(!(authService.checkPassword(member, requestDto.password()))){ + if (!(authService.checkPassword(member, requestDto.password()))){ throw new CustomException(ErrorCode.PASSWORD_MISMATCH); } @@ -117,17 +120,4 @@ public void deactivateProfile(ProfileDeactivateRequestDto requestDto){ redisService.deleteValues(member.getEmail()); } - public void updatePassword(PasswordUpdateRequestDto requestDto){ - Member member = memberService.getCurrentMember(); - - //비밀번호 일치 검사 - if (!requestDto.password().equals(requestDto.confirmPassword())) { - throw new CustomException(ErrorCode.PASSWORD_MISMATCH); - } - - member.modifyPassword(authService.encodePassword(requestDto.password())); - - memberService.saveMember(member); - } - } diff --git a/src/main/java/sws/songpin/domain/place/controller/PlaceController.java b/src/main/java/sws/songpin/domain/place/controller/PlaceController.java index 4bfdc7bf..5303e955 100644 --- a/src/main/java/sws/songpin/domain/place/controller/PlaceController.java +++ b/src/main/java/sws/songpin/domain/place/controller/PlaceController.java @@ -30,8 +30,7 @@ public ResponseEntity placeDetails(@PathVariable final Long placeId) { @GetMapping public ResponseEntity placeSearch(@RequestParam final String keyword, @RequestParam(defaultValue = "ACCURACY") final String sortBy, - @PageableDefault(size = 20) final Pageable pageable) throws UnsupportedEncodingException { - String decodedKeyword = URLDecoder.decode(keyword, "UTF-8"); - return ResponseEntity.ok().body(placeService.searchPlaces(decodedKeyword, SortBy.from(sortBy), pageable)); + @PageableDefault(size = 20) final Pageable pageable) { + return ResponseEntity.ok().body(placeService.searchPlaces(keyword, SortBy.from(sortBy), pageable)); } } diff --git a/src/main/java/sws/songpin/domain/playlist/dto/response/PlaylistDetailsResponseDto.java b/src/main/java/sws/songpin/domain/playlist/dto/response/PlaylistDetailsResponseDto.java index 476a401c..fd43aaa4 100644 --- a/src/main/java/sws/songpin/domain/playlist/dto/response/PlaylistDetailsResponseDto.java +++ b/src/main/java/sws/songpin/domain/playlist/dto/response/PlaylistDetailsResponseDto.java @@ -15,10 +15,10 @@ public record PlaylistDetailsResponseDto( LocalDate updatedDate, Visibility visibility, List imgPathList, - Long bookmarkId, + Boolean isBookmarked, List pinList) { - public static PlaylistDetailsResponseDto from(Playlist playlist, List imgPathList, List pinList, Boolean isMine, Long bookmarkId) { + public static PlaylistDetailsResponseDto from(Playlist playlist, List imgPathList, List pinList, Boolean isMine, Boolean isBookmarked) { return new PlaylistDetailsResponseDto( isMine, playlist.getPlaylistName(), @@ -28,7 +28,7 @@ public static PlaylistDetailsResponseDto from(Playlist playlist, List im playlist.getModifiedTime().toLocalDate(), playlist.getVisibility(), imgPathList, - bookmarkId, + isBookmarked, pinList ); } diff --git a/src/main/java/sws/songpin/domain/playlist/dto/response/PlaylistUnitDto.java b/src/main/java/sws/songpin/domain/playlist/dto/response/PlaylistUnitDto.java index fbcfdb3b..25ea94c9 100644 --- a/src/main/java/sws/songpin/domain/playlist/dto/response/PlaylistUnitDto.java +++ b/src/main/java/sws/songpin/domain/playlist/dto/response/PlaylistUnitDto.java @@ -15,9 +15,9 @@ public record PlaylistUnitDto( LocalDateTime updatedDate, Visibility visibility, List imgPathList, - Long bookmarkId + Boolean isBookmarked ) { - public static PlaylistUnitDto from (Playlist playlist, List imgPathList, Long bookmarkId) { + public static PlaylistUnitDto from (Playlist playlist, List imgPathList, boolean isBookmarked) { return new PlaylistUnitDto( playlist.getPlaylistId(), playlist.getPlaylistName(), @@ -26,7 +26,7 @@ public static PlaylistUnitDto from (Playlist playlist, List imgPathList, playlist.getModifiedTime(), playlist.getVisibility(), imgPathList, - bookmarkId + isBookmarked ); } } diff --git a/src/main/java/sws/songpin/domain/playlist/service/PlaylistService.java b/src/main/java/sws/songpin/domain/playlist/service/PlaylistService.java index 4b6d39a8..4e4376cf 100644 --- a/src/main/java/sws/songpin/domain/playlist/service/PlaylistService.java +++ b/src/main/java/sws/songpin/domain/playlist/service/PlaylistService.java @@ -76,9 +76,9 @@ public PlaylistDetailsResponseDto getPlaylist(Long playlistId) { imgPathList.add(playlistPin.getPin().getSong().getImgPath()); } }); - // bookmarkId - Long bookmarkId = getBookmarkIdForPlaylistAndMember(playlist, currentMember); - return PlaylistDetailsResponseDto.from(playlist, imgPathList, pinList, isMine, bookmarkId); + // isBookmarked + boolean isBookmarked = isPlaylistBookmarkedByMember(playlist, currentMember); + return PlaylistDetailsResponseDto.from(playlist, imgPathList, pinList, isMine, isBookmarked); } // 플레이리스트 편집 @@ -223,15 +223,13 @@ public PlaylistUnitDto convertToPlaylistUnitDto(Playlist playlist, Member curren .map(playlistPin -> playlistPin.getPin().getSong().getImgPath()) .limit(3) .collect(Collectors.toList()); - Long bookmarkId = getBookmarkIdForPlaylistAndMember(playlist, currentMember); - return PlaylistUnitDto.from(playlist, imgPathList, bookmarkId); + boolean isBookmarked = isPlaylistBookmarkedByMember(playlist, currentMember); + return PlaylistUnitDto.from(playlist, imgPathList, isBookmarked); } @Transactional(readOnly = true) - public Long getBookmarkIdForPlaylistAndMember(Playlist playlist, Member member) { - return bookmarkRepository.findByPlaylistAndMember(playlist, member) - .map(Bookmark::getBookmarkId) - .orElse(null); + public boolean isPlaylistBookmarkedByMember(Playlist playlist, Member member) { + return bookmarkRepository.findByPlaylistAndMember(playlist, member).isPresent(); } public void deleteAllPlaylistsOfMember(Member member) {