From 4cb1a1caf5f5bfafa40359d13fb3c703887ac9c1 Mon Sep 17 00:00:00 2001 From: Sangyoo Date: Mon, 16 Jan 2023 16:01:34 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=AA=85=EC=86=8C=20=EB=A7=A4=ED=95=91?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=EC=A4=91=20#44?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AttractionController.java | 49 ++++++++++++++----- .../dto/AttractionDetailResponseDto.java | 30 ++++++++++++ .../dto/AttractionLikesResponseDto.java | 9 ++++ .../attraction/dto/AttractionResponseDto.java | 9 +--- .../domain/attraction/entity/Attraction.java | 14 +++--- .../attraction/mapper/AttractionMapper.java | 20 +++++++- 6 files changed, 105 insertions(+), 26 deletions(-) create mode 100644 server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionDetailResponseDto.java create mode 100644 server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionLikesResponseDto.java 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 2ecba666..ba64a753 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 @@ -1,18 +1,21 @@ package com.main36.picha.domain.attraction.controller; -import com.main36.picha.domain.attraction.dto.AttractionFilterDto; -import com.main36.picha.domain.attraction.dto.AttractionPatchDto; -import com.main36.picha.domain.attraction.dto.AttractionPostDto; -import com.main36.picha.domain.attraction.dto.AttractionResponseDto; +import com.main36.picha.domain.attraction.dto.*; import com.main36.picha.domain.attraction.entity.Attraction; import com.main36.picha.domain.attraction.mapper.AttractionMapper; import com.main36.picha.domain.attraction.service.AttractionService; import com.main36.picha.domain.attraction_file.entity.AttractionImage; import com.main36.picha.domain.attraction_file.service.AttractionImageService; +import com.main36.picha.domain.attraction_likes.repository.AttractionLikesRepository; +import com.main36.picha.domain.member.entity.Member; +import com.main36.picha.domain.member.service.MemberService; +import com.main36.picha.global.auth.jwt.JwtTokenizer; import com.main36.picha.global.config.S3Service; import com.main36.picha.global.response.DataResponseDto; import com.main36.picha.global.response.MultiResponseDto; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; @@ -21,6 +24,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import javax.validation.constraints.Positive; import java.io.File; @@ -38,10 +42,11 @@ @Validated public class AttractionController { - private final S3Service s3Service; private final AttractionService attractionService; private final AttractionMapper mapper; private final AttractionImageService imageService; + private final JwtTokenizer jwtTokenizer; + private final MemberService memberService; // 1. 명소 등록 핸들러 @@ -98,7 +103,7 @@ public ResponseEntity patchAttraction(@PathVariable("attraction-id") @Positive l @GetMapping("/{attraction-id}") public ResponseEntity getAttraction(@PathVariable("attraction-id") @Positive long attractionId){ AttractionResponseDto response = - mapper.attractionToAttractionResponseDto(attractionService.findAttraction(attractionId)); + mapper.attractionToAttractionDe(attractionService.findAttraction(attractionId)); return new ResponseEntity<>(new DataResponseDto<>(response), HttpStatus.OK); } @@ -133,10 +138,32 @@ public ResponseEntity deleteAttraction(@PathVariable("attraction-id") @Positive return new ResponseEntity<>(HttpStatus.NO_CONTENT); } -// @PostMapping("/likes/{attraction-id}") -// public ResponseEntity voteAttraction(@PathVariable("attraction-id") @Positive long attractionId){ -// Attraction attraction = attractionService.findAttraction(attractionId); -// -// } + @PostMapping("/likes/{attraction-id}") + public ResponseEntity voteAttraction(HttpServletRequest request, + @PathVariable("attraction-id") @Positive long attractionId){ + // 회원 정보를 받아온다 + String userEmail = extractedUsername(request); + Member member = memberService.findMember(userEmail); + + // 명소 정보를 찾는다 + Attraction attraction = attractionService.findAttraction(attractionId); + + // 회원과 명소 정보를 바탕으로 좋아요가 눌러져 있다면 true, 아니면 false를 받는다. + boolean status = attractionService.voteAttraction(member, attraction); + + // responseDto 생성 + AttractionLikesResponseDto response = new AttractionLikesResponseDto(); + response.setIsVoted(status); + return new ResponseEntity(new DataResponseDto<>(response), HttpStatus.OK); + } + + private String extractedUsername(HttpServletRequest request) { + String authorization = request.getHeader("authorization"); + String substring = authorization.substring(7); + String secretKey = jwtTokenizer.getSecretKey(); + Jws claims = jwtTokenizer.getClaims(substring, jwtTokenizer.encodeBase64SecretKey(secretKey)); + + return String.valueOf(claims.getBody().get("username")); + } } 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 new file mode 100644 index 00000000..ac47be9f --- /dev/null +++ b/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionDetailResponseDto.java @@ -0,0 +1,30 @@ +package com.main36.picha.domain.attraction.dto; + +import com.main36.picha.domain.post.dto.PostResponseDto; +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +@Data +public class AttractionDetailResponseDto { + private long attractionId; + private int likes; + private boolean isVoted; + private String attractionName; + private String attractionDescription; + private String attractionAddress; + private String attractionImageUrl; + private List posts; + + @Builder + public AttractionDetailResponseDto(long attractionId, int likes, String attractionName, String attractionDescription, String attractionAddress, String attractionImageUrl, List posts) { + this.attractionId = attractionId; + this.likes = likes; + this.attractionName = attractionName; + this.attractionDescription = attractionDescription; + this.attractionAddress = attractionAddress; + this.attractionImageUrl = attractionImageUrl; + this.posts = posts; + } +} diff --git a/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionLikesResponseDto.java b/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionLikesResponseDto.java new file mode 100644 index 00000000..47b22e4b --- /dev/null +++ b/server/src/main/java/com/main36/picha/domain/attraction/dto/AttractionLikesResponseDto.java @@ -0,0 +1,9 @@ +package com.main36.picha.domain.attraction.dto; + +import lombok.Data; +import lombok.Setter; + +@Data +public class AttractionLikesResponseDto { + private Boolean isVoted; +} 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 28e5cf1a..574703f7 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 @@ -15,14 +15,7 @@ @Builder public class AttractionResponseDto { private long attractionId; - + private int likes; private String attractionName; - - private String attractionDescription; - - private String attractionAddress; - private String attractionImageUrl; - - private String province; } 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 054e25d4..fc0935e8 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 @@ -1,6 +1,7 @@ package com.main36.picha.domain.attraction.entity; import com.main36.picha.domain.attraction_file.entity.AttractionImage; +import com.main36.picha.domain.post.entity.Post; import com.main36.picha.global.audit.Auditable; import lombok.*; import org.hibernate.annotations.ColumnDefault; @@ -8,6 +9,8 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; @Getter @@ -16,7 +19,7 @@ @NoArgsConstructor @Builder @Entity -//@DynamicInsert +@DynamicInsert public class Attraction extends Auditable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -26,8 +29,8 @@ public class Attraction extends Auditable { private String attractionName; @Column(name = "likes", nullable = false) -// @ColumnDefault("0") - private int likes =0; + @ColumnDefault("0") + private int likes; @Lob @Column( name = "attraction_description", nullable = false) private String attractionDescription; @@ -44,7 +47,6 @@ public class Attraction extends Auditable { @Column(name = "province", nullable = false) private String province; - - - + @OneToMany(mappedBy = "attraction", cascade = CascadeType.REMOVE) + private List posts = new ArrayList<>(); } 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 cd337006..e0aa8f3f 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 @@ -1,9 +1,11 @@ package com.main36.picha.domain.attraction.mapper; +import com.main36.picha.domain.attraction.dto.AttractionDetailResponseDto; import com.main36.picha.domain.attraction.dto.AttractionPatchDto; import com.main36.picha.domain.attraction.dto.AttractionPostDto; import com.main36.picha.domain.attraction.dto.AttractionResponseDto; import com.main36.picha.domain.attraction.entity.Attraction; +import com.main36.picha.domain.post.dto.PostResponseDto; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.ReportingPolicy; @@ -18,9 +20,25 @@ public interface AttractionMapper { Attraction attractionPostDtoToAttraction(AttractionPostDto postDto); @Mapping(target = "attractionImage", ignore = true) Attraction attractionPatchDtoToAttraction(AttractionPatchDto patchDto); - @Mapping(target = "attractionImageUrl", source = "attractionImage.attractionImageFileUrl") AttractionResponseDto attractionToAttractionResponseDto(Attraction attraction); +// @Mapping(target = "attractionImageUrl", source = "attractionImage.attractionImageFileUrl") +// @Mapping(target = "isVoted", ignore = true) + default AttractionDetailResponseDto attractionToAttractionDetailResponseDto(Attraction attraction){ + AttractionDetailResponseDto.builder() + .attractionId(attraction.getAttractionId()) + .likes(attraction.getLikes()) + .attractionName(attraction.getAttractionName()) + .attractionDescription(attraction.getAttractionAddress()) + .attractionAddress(attraction.getAttractionAddress()) + .attractionImageUrl(attraction.getAttractionImage().getAttractionImageFileUrl()) + .posts(attraction.getPosts().stream() + .map(post -> PostResponseDto.builder() + .memberId(post.getMember().getMemberId()) + .postId(post.getPostId()) + .attractionName(post.getAttraction()))) + + }; List attractionsToAttractionResponses(List attractions); }