Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

좋아요 싫어요 개선 #88

Merged
merged 3 commits into from
Oct 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/com/pyonsnalcolor/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,4 @@ public UserDetailsService userDetailsService() {
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder.build();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.pyonsnalcolor.product.dto.EventProductResponseDto;
import com.pyonsnalcolor.product.dto.ProductFilterRequestDto;
import com.pyonsnalcolor.product.dto.ProductResponseDto;
import com.pyonsnalcolor.product.dto.ReviewDto;
import com.pyonsnalcolor.product.dto.ReviewRequestDto;
import com.pyonsnalcolor.product.enumtype.ProductType;
import com.pyonsnalcolor.product.service.EventProductService;
import io.swagger.v3.oas.annotations.Operation;
Expand Down Expand Up @@ -51,7 +51,7 @@ public ResponseEntity<Page<EventProductResponseDto>> getEventProductsByFilter(
public ResponseEntity<Void> registerReview(
@PathVariable String id,
@RequestPart(value = "imageFile", required = false) MultipartFile imageFile,
@RequestPart(value = "reviewDto") ReviewDto reviewDto
@RequestPart(value = "reviewDto") ReviewRequestDto reviewDto
) throws Throwable {
eventProductService.registerReview(imageFile, reviewDto, id);

Expand All @@ -72,17 +72,19 @@ public ResponseEntity<EventProductResponseDto> getEventProduct(
@Operation(summary = "event 상품 리뷰 좋아요", description = "id에 해당하는 event 상품의 리뷰 좋아요 카운트 증가.")
@PutMapping("/products/event-products/{productId}/reviews/{reviewId}/like")
public ResponseEntity<Void> likeReview(@PathVariable("productId") String productId,
@PathVariable("reviewId") String reviewId) throws Throwable {
eventProductService.likeReview(productId, reviewId);
@PathVariable("reviewId") String reviewId,
@RequestParam("writerId") Long writerId) throws Throwable {
eventProductService.likeReview(productId, reviewId, writerId);

return ResponseEntity.ok().build();
}

@Operation(summary = "event 상품 리뷰 싫어요", description = "id에 해당하는 event 상품의 리뷰 싫어요 카운트 증가.")
@PutMapping("/products/event-products/{productId}/reviews/{reviewId}/hate")
public ResponseEntity<Void> hateReview(@PathVariable("productId") String productId,
@PathVariable("reviewId") String reviewId) throws Throwable {
eventProductService.hateReview(productId, reviewId);
@PathVariable("reviewId") String reviewId,
@RequestParam("writerId") Long writerId) throws Throwable {
eventProductService.hateReview(productId, reviewId, writerId);

return ResponseEntity.ok().build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.pyonsnalcolor.product.dto.PbProductResponseDto;
import com.pyonsnalcolor.product.dto.ProductFilterRequestDto;
import com.pyonsnalcolor.product.dto.ProductResponseDto;
import com.pyonsnalcolor.product.dto.ReviewDto;
import com.pyonsnalcolor.product.dto.ReviewRequestDto;
import com.pyonsnalcolor.product.enumtype.ProductType;
import com.pyonsnalcolor.product.service.PbProductService;
import io.swagger.v3.oas.annotations.Operation;
Expand Down Expand Up @@ -51,7 +51,7 @@ public ResponseEntity<Page<PbProductResponseDto>> getPbProductsByFilter(
public ResponseEntity<Void> registerReview(
@PathVariable String id,
@RequestPart(value = "imageFile", required = false) MultipartFile imageFile,
@RequestPart(value = "reviewDto") ReviewDto reviewDto
@RequestPart(value = "reviewDto") ReviewRequestDto reviewDto
) throws Throwable {
pbProductService.registerReview(imageFile, reviewDto, id);

Expand All @@ -72,17 +72,19 @@ public ResponseEntity<PbProductResponseDto> getPbProduct(
@Operation(summary = "PB 상품 리뷰 좋아요", description = "id에 해당하는 PB 상품의 리뷰 좋아요 카운트 증가.")
@PutMapping("/products/pb-products/{productId}/reviews/{reviewId}/like")
public ResponseEntity<Void> likeReview(@PathVariable("productId") String productId,
@PathVariable("reviewId") String reviewId) throws Throwable {
pbProductService.likeReview(productId, reviewId);
@PathVariable("reviewId") String reviewId,
@RequestParam("writerId") Long writerId) throws Throwable {
pbProductService.likeReview(productId, reviewId, writerId);

return ResponseEntity.ok().build();
}

@Operation(summary = "PB 상품 리뷰 싫어요", description = "id에 해당하는 PB 상품의 리뷰 싫어요 카운트 증가.")
@PutMapping("/products/pb-products/{productId}/reviews/{reviewId}/hate")
public ResponseEntity<Void> hateReview(@PathVariable("productId") String productId,
@PathVariable("reviewId") String reviewId) throws Throwable {
pbProductService.hateReview(productId, reviewId);
@PathVariable("reviewId") String reviewId,
@RequestParam("writerId") Long writerId) throws Throwable {
pbProductService.hateReview(productId, reviewId, writerId);

return ResponseEntity.ok().build();
}
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/com/pyonsnalcolor/product/dto/ReviewDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.pyonsnalcolor.product.entity.HateCount;
import com.pyonsnalcolor.product.entity.LikeCount;
import com.pyonsnalcolor.product.enumtype.Like;
import lombok.AllArgsConstructor;
import lombok.Data;
Expand All @@ -16,6 +18,7 @@
@AllArgsConstructor
@NoArgsConstructor
public class ReviewDto {
private String reviewId;
private Like taste; //맛
private Like quality; //퀄리티
private Like valueForMoney; //가성비
Expand All @@ -32,6 +35,6 @@ public class ReviewDto {
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime updatedTime;
private Long likeCount;
private Long hateCount;
private LikeCount likeCount;
private HateCount hateCount;
}
20 changes: 20 additions & 0 deletions src/main/java/com/pyonsnalcolor/product/dto/ReviewRequestDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.pyonsnalcolor.product.dto;

import com.pyonsnalcolor.product.enumtype.Like;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ReviewRequestDto {
private Like taste; //맛
private Like quality; //퀄리티
private Like valueForMoney; //가성비
private float score; //별점
private String contents; //내용

private Long writerId; //작성자 <- 이후 기능 확장 고려한 필드
private String writerName; // 닉네임
}
16 changes: 16 additions & 0 deletions src/main/java/com/pyonsnalcolor/product/entity/HateCount.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.pyonsnalcolor.product.entity;

import lombok.Data;

import java.util.ArrayList;
import java.util.List;

@Data
public class HateCount {
private List<Long> writerIds = new ArrayList<>();
private Long hateCount = 0L;

public void addWriter(Long writerId) {
this.writerIds.add(writerId);
}
}
16 changes: 16 additions & 0 deletions src/main/java/com/pyonsnalcolor/product/entity/LikeCount.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.pyonsnalcolor.product.entity;

import lombok.Data;

import java.util.ArrayList;
import java.util.List;

@Data
public class LikeCount {
private List<Long> writerIds = new ArrayList<>();
private Long likeCount = 0L;

public void addWriter(Long writerId) {
this.writerIds.add(writerId);
}
}
40 changes: 29 additions & 11 deletions src/main/java/com/pyonsnalcolor/product/entity/Review.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,43 @@ public class Review {
private String writerName;
private LocalDateTime createdTime;
private LocalDateTime updatedTime;
private Long likeCount;
private Long hateCount;
private LikeCount likeCount;
private HateCount hateCount;

public ReviewDto convertToDto() {
return new ReviewDto(taste, quality, valueForMoney, score, contents, image, writerId, writerName,
return new ReviewDto(reviewId, taste, quality, valueForMoney, score, contents, image, writerId, writerName,
createdTime, updatedTime, likeCount, hateCount);
}

public void likeReview() {
if(this.likeCount == null) {
this.likeCount = 0L;
public void likeReview(Long writerId) {
if (this.likeCount == null) {
this.likeCount = new LikeCount();
}
if (this.likeCount.getWriterIds().contains(writerId)) {
return;
}
this.likeCount.addWriter(writerId);
this.likeCount.setLikeCount(this.likeCount.getLikeCount() + 1);

if (this.hateCount != null && this.hateCount.getWriterIds().contains(writerId)) {
this.hateCount.setHateCount(this.hateCount.getHateCount() - 1);
this.hateCount.getWriterIds().remove(writerId);
}
this.likeCount += 1;
}

public void hateReview() {
if(this.hateCount == null) {
this.hateCount = 0L;
public void hateReview(Long writerId) {
if (this.hateCount == null) {
this.hateCount = new HateCount();
}
if (this.hateCount.getWriterIds().contains(writerId)) {
return;
}
this.hateCount.addWriter(writerId);
this.hateCount.setHateCount(this.hateCount.getHateCount() + 1);

if (this.likeCount != null && this.likeCount.getWriterIds().contains(writerId)) {
this.likeCount.setLikeCount(this.likeCount.getLikeCount() - 1);
this.likeCount.getWriterIds().remove(writerId);
}
this.hateCount += 1;
}
}
21 changes: 11 additions & 10 deletions src/main/java/com/pyonsnalcolor/product/service/ProductService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
import com.pyonsnalcolor.product.dto.ProductFilterRequestDto;
import com.pyonsnalcolor.product.dto.ProductResponseDto;
import com.pyonsnalcolor.product.dto.ReviewDto;
import com.pyonsnalcolor.product.entity.BaseProduct;
import com.pyonsnalcolor.product.entity.Review;
import com.pyonsnalcolor.product.entity.UUIDGenerator;
import com.pyonsnalcolor.product.dto.ReviewRequestDto;
import com.pyonsnalcolor.product.entity.*;
import com.pyonsnalcolor.product.enumtype.*;
import com.pyonsnalcolor.product.repository.BasicProductRepository;
import com.pyonsnalcolor.product.repository.ImageRepository;
Expand Down Expand Up @@ -85,7 +84,8 @@ private Criteria createFilterCriteria(List<Recommend> recommends, List<Category>
}

//리뷰 좋아요
public void likeReview(String productId, String reviewId) throws Throwable {
@Transactional
public void likeReview(String productId, String reviewId, Long writerId) throws Throwable {
BaseProduct baseProduct = (BaseProduct) basicProductRepository
.findById(productId)
.orElseThrow(NoSuchElementException::new);
Expand All @@ -95,13 +95,14 @@ public void likeReview(String productId, String reviewId) throws Throwable {
).findFirst()
.orElseThrow(NoSuchElementException::new);

review.likeReview();
review.likeReview(writerId);

basicProductRepository.save(baseProduct);
}

//리뷰 싫어요
public void hateReview(String productId, String reviewId) throws Throwable {
@Transactional
public void hateReview(String productId, String reviewId, Long writerId) throws Throwable {
BaseProduct baseProduct = (BaseProduct) basicProductRepository
.findById(productId)
.orElseThrow(NoSuchElementException::new);
Expand All @@ -111,13 +112,13 @@ public void hateReview(String productId, String reviewId) throws Throwable {
).findFirst()
.orElseThrow(NoSuchElementException::new);

review.hateReview();
review.hateReview(writerId);

basicProductRepository.save(baseProduct);
}

//리뷰 등록
public void registerReview(MultipartFile image, ReviewDto reviewDto, String productId) throws Throwable {
public void registerReview(MultipartFile image, ReviewRequestDto reviewDto, String productId) throws Throwable {
BaseProduct baseProduct = (BaseProduct) basicProductRepository
.findById(productId)
.orElseThrow(NoSuchElementException::new);
Expand All @@ -140,8 +141,8 @@ public void registerReview(MultipartFile image, ReviewDto reviewDto, String prod
.writerName(reviewDto.getWriterName())
.updatedTime(LocalDateTime.now())
.createdTime(LocalDateTime.now())
.hateCount(0L)
.likeCount(0L)
.hateCount(new HateCount())
.likeCount(new LikeCount())
.build();

baseProduct.addReview(review);
Expand Down
Loading