diff --git a/server/src/main/java/com/main36/picha/domain/attraction/controller/AttractionController.java b/server/src/main/java/com/main36/picha/domain/attraction/controller/AttractionController.java index 6fff3db2..a82fe9a0 100644 --- a/server/src/main/java/com/main36/picha/domain/attraction/controller/AttractionController.java +++ b/server/src/main/java/com/main36/picha/domain/attraction/controller/AttractionController.java @@ -102,7 +102,7 @@ public ResponseEntity patchAttraction(@PathVariable("attraction-id") @Positive l } // 3. 명소 1개 정보 요청을 처리하는 핸들러 - // 반환하는 정보 : 명소 정보(Id,이름, 설명, 주소, 이미지 주소), 좋아요 수, 좋아요 눌렀는지 + // 반환하는 정보 : 명소 정보(Id,이름, 설명, 주소, 이미지 주소), 좋아요 수, 좋아요 눌렀는지, 즐겨찾기 수, 즐겨찾기 눌렀는지 @GetMapping("/{attraction-id}") public ResponseEntity getAttraction(HttpServletRequest request, @PathVariable("attraction-id") @Positive long attractionId){ @@ -111,6 +111,7 @@ public ResponseEntity getAttraction(HttpServletRequest request, AttractionDetailResponseDto response = mapper.attractionToAttractionDetailResponseDto(attraction); response.setIsVoted(attractionService.isVoted(member, attraction)); + response.setIsSaved(attractionService.isSaved(member,attraction)); return new ResponseEntity<>(new DataResponseDto<>(response), HttpStatus.OK); } @@ -124,18 +125,18 @@ public ResponseEntity getFilteredAttractions(@Positive @RequestParam(required = Page attractionPage = attractionService.findFilteredAttractions(filterDto.getProvinces(), page-1, size); List attractions = attractionPage.getContent(); return new ResponseEntity<>(new MultiResponseDto<>( - mapper.attractionsToAttractionResponses(attractions),attractionPage), HttpStatus.OK); + mapper.attractionsToAttractionResponseDtos(attractions),attractionPage), HttpStatus.OK); } // 5. 명소 Id를 기준으로 명소 여러개의 정보 요청을 처리하는 핸들러 - // 반환하는 정보 : 명소 정보(id, 이름, 이미지 주소), 좋아요 수, 즐겨찾기 수(아직 구현안됨) + // 반환하는 정보 : 명소 정보(id, 이름, 이미지 주소), 좋아요 수, 즐겨찾기 수 @GetMapping public ResponseEntity getAttractions(@Positive @RequestParam(required = false, defaultValue = "1") int page, @Positive @RequestParam(required = false, defaultValue = "9") int size){ Page attractionPage = attractionService.findAttractions(page-1, size); List attractions = attractionPage.getContent(); return new ResponseEntity(new MultiResponseDto<>( - mapper.attractionsToAttractionResponses(attractions),attractionPage), HttpStatus.OK); + mapper.attractionsToAttractionResponseDtos(attractions),attractionPage), HttpStatus.OK); } @@ -167,6 +168,23 @@ public ResponseEntity voteAttraction(HttpServletRequest request, return new ResponseEntity(new DataResponseDto<>(response), HttpStatus.OK); } + // 8. 명소 즐겨찾기 + @PostMapping("/saves/{attraction-id}") + public ResponseEntity saveAttraction(HttpServletRequest request, + @PathVariable("attraction-id") @Positive long attractionId){ + String userEmail = extractedUsername(request); + Member member = memberService.findMember(userEmail); + + // 명소 정보를 찾는다 + Attraction attraction = attractionService.findAttraction(attractionId); + + boolean status = attractionService.saveAttraction(member, attraction); + + AttractionSaveResponseDto response = new AttractionSaveResponseDto(); + response.setIsSaved(status); + return new ResponseEntity(new DataResponseDto<>(response), HttpStatus.OK); + } + private String extractedUsername(HttpServletRequest request) { String authorization = request.getHeader("authorization"); String substring = authorization.substring(7); diff --git a/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionDetailResponseDto.java b/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionDetailResponseDto.java index bd4ca68c..ff20f618 100644 --- a/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionDetailResponseDto.java +++ b/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionDetailResponseDto.java @@ -11,11 +11,9 @@ public class AttractionDetailResponseDto { private Long attractionId; private Long likes; - -// private Long saves; + private Long saves; private Boolean isVoted; - -// private Boolean isSaved; + private Boolean isSaved; private String attractionName; private String attractionDescription; private String attractionAddress; diff --git a/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionResponseDto.java b/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionResponseDto.java index c9770683..c793b08c 100644 --- a/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionResponseDto.java +++ b/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionResponseDto.java @@ -19,7 +19,7 @@ public class AttractionResponseDto { private String attractionName; private String attractionImageUrl; private Long likes; -// private Long postNumber; + private Long saves; -// private Long saves; +// private Long postNumber; } diff --git a/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionSaveResponseDto.java b/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionSaveResponseDto.java new file mode 100644 index 00000000..a15beca5 --- /dev/null +++ b/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionSaveResponseDto.java @@ -0,0 +1,8 @@ +package com.main36.picha.domain.attraction.dto; + +import lombok.Data; + +@Data +public class AttractionSaveResponseDto { + private Boolean isSaved; +} diff --git a/server/src/main/java/com/main36/picha/domain/attraction/entity/Attraction.java b/server/src/main/java/com/main36/picha/domain/attraction/entity/Attraction.java index 121f94de..4abcb809 100644 --- a/server/src/main/java/com/main36/picha/domain/attraction/entity/Attraction.java +++ b/server/src/main/java/com/main36/picha/domain/attraction/entity/Attraction.java @@ -32,9 +32,9 @@ public class Attraction extends Auditable { @ColumnDefault("0") private Long likes; -// @Column(name = "saves", nullable = false) -// @ColumnDefault("0") -// private Long saves; + @Column(name = "saves", nullable = false) + @ColumnDefault("0") + private Long saves; @Lob @Column( name = "attraction_description", nullable = false) private String attractionDescription; diff --git a/server/src/main/java/com/main36/picha/domain/attraction/mapper/AttractionMapper.java b/server/src/main/java/com/main36/picha/domain/attraction/mapper/AttractionMapper.java index 50a03067..5ad9936f 100644 --- a/server/src/main/java/com/main36/picha/domain/attraction/mapper/AttractionMapper.java +++ b/server/src/main/java/com/main36/picha/domain/attraction/mapper/AttractionMapper.java @@ -37,7 +37,7 @@ default AttractionDetailResponseDto attractionToAttractionDetailResponseDto(Attr .build(); }; - List attractionsToAttractionResponses(List attractions); + List attractionsToAttractionResponseDtos(List attractions); } /*@Component diff --git a/server/src/main/java/com/main36/picha/domain/attraction/service/AttractionService.java b/server/src/main/java/com/main36/picha/domain/attraction/service/AttractionService.java index ff517bad..858ac7c5 100644 --- a/server/src/main/java/com/main36/picha/domain/attraction/service/AttractionService.java +++ b/server/src/main/java/com/main36/picha/domain/attraction/service/AttractionService.java @@ -6,6 +6,8 @@ import com.main36.picha.domain.attraction_likes.entity.AttractionLikes; import com.main36.picha.domain.attraction_likes.repository.AttractionLikesRepository; import com.main36.picha.domain.member.entity.Member; +import com.main36.picha.domain.save.entity.Save; +import com.main36.picha.domain.save.repository.SaveRepository; import com.main36.picha.global.exception.BusinessLogicException; import com.main36.picha.global.exception.ExceptionCode; import lombok.RequiredArgsConstructor; @@ -25,8 +27,8 @@ public class AttractionService { private final AttractionRepository attractionRepository; private final AttractionImageService attractionImageService; - private final AttractionLikesRepository attractionLikesRepository; + private final SaveRepository saveRepository; public Attraction createAttraction(Attraction attraction){ @@ -110,6 +112,35 @@ public boolean isVoted(Member member, Attraction attraction) { return likes.isPresent(); } + public boolean saveAttraction(Member member, Attraction attraction){ + // 즐겨찾기를 누른적이 있나? + Optional save = saveRepository.findByMemberAndAttraction(member, attraction); + + // 즐겨찾기를 이미 눌렀다면 + if(save.isPresent()){ + // 즐겨찾기 데이터를 삭제하고 + saveRepository.delete(save.get()); + // 명소의 saves를 하나 감소시킨다 + attraction.setSaves(attraction.getSaves()-1); + // 지금은 즐겨찾기를 누르지 않은 상태라는것을 반환한다. + return false; + } + // 즐겨찾기를 누르지 않았으면 + else{ + // 즐겨찾기 데이터를 생성하고 + saveRepository.save(Save.builder().attraction(attraction).member(member).build()); + // 명소의 saves를 하나 증가시킨다. + attraction.setSaves(attraction.getSaves()+1); + // 지금은 즐겨찾기를 누른 상태라는것을 반환한다. + return true; + } + } + + public boolean isSaved(Member member, Attraction attraction) { + Optional save = saveRepository.findByMemberAndAttraction(member, attraction); + return save.isPresent(); + } + private Attraction findVerifiedAttraction(long attractionId){ return attractionRepository.findById(attractionId) .orElseThrow(()-> new BusinessLogicException(ExceptionCode.ATTRACTION_NOT_FOUND)); diff --git a/server/src/main/java/com/main36/picha/domain/member/dto/OauthMemberDto.java b/server/src/main/java/com/main36/picha/domain/member/dto/OauthMemberDto.java index 2031c522..d447b865 100644 --- a/server/src/main/java/com/main36/picha/domain/member/dto/OauthMemberDto.java +++ b/server/src/main/java/com/main36/picha/domain/member/dto/OauthMemberDto.java @@ -1,14 +1,10 @@ package com.main36.picha.domain.member.dto; -import com.main36.picha.domain.post.entity.Post; -import com.main36.picha.domain.save.entity.Save; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import javax.persistence.*; -import java.util.ArrayList; -import java.util.List; @Data @Builder diff --git a/server/src/main/java/com/main36/picha/domain/member/entity/Member.java b/server/src/main/java/com/main36/picha/domain/member/entity/Member.java index 4f07bb50..2912162c 100644 --- a/server/src/main/java/com/main36/picha/domain/member/entity/Member.java +++ b/server/src/main/java/com/main36/picha/domain/member/entity/Member.java @@ -4,11 +4,8 @@ import com.main36.picha.domain.save.entity.Save; import com.main36.picha.global.audit.Auditable; import lombok.*; -import org.hibernate.annotations.DynamicInsert; import javax.persistence.*; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; diff --git a/server/src/main/java/com/main36/picha/domain/save/controller/SaveController.java b/server/src/main/java/com/main36/picha/domain/save/controller/SaveController.java deleted file mode 100644 index 6141e2a3..00000000 --- a/server/src/main/java/com/main36/picha/domain/save/controller/SaveController.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.main36.picha.domain.save.controller; - -public class SaveController { -} diff --git a/server/src/main/java/com/main36/picha/domain/save/repository/SaveRepository.java b/server/src/main/java/com/main36/picha/domain/save/repository/SaveRepository.java index 5d436415..844f09a5 100644 --- a/server/src/main/java/com/main36/picha/domain/save/repository/SaveRepository.java +++ b/server/src/main/java/com/main36/picha/domain/save/repository/SaveRepository.java @@ -1,7 +1,13 @@ package com.main36.picha.domain.save.repository; +import com.main36.picha.domain.attraction.entity.Attraction; +import com.main36.picha.domain.attraction_likes.entity.AttractionLikes; +import com.main36.picha.domain.member.entity.Member; import com.main36.picha.domain.save.entity.Save; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface SaveRepository extends JpaRepository { + Optional findByMemberAndAttraction(Member member, Attraction attraction); } diff --git a/server/src/main/java/com/main36/picha/domain/save/service/SaveService.java b/server/src/main/java/com/main36/picha/domain/save/service/SaveService.java deleted file mode 100644 index 3a56d97e..00000000 --- a/server/src/main/java/com/main36/picha/domain/save/service/SaveService.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.main36.picha.domain.save.service; - -import org.springframework.stereotype.Service; - -import javax.transaction.Transactional; - -@Service -@Transactional -public class SaveService { -}