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

[FEATURE-72] 리뷰 등록 API 구현 #75

Merged
merged 2 commits into from
Nov 9, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.betteriter.bo_domain.menufacturer.service;

import com.example.betteriter.bo_domain.menufacturer.domain.Manufacturer;
import com.example.betteriter.bo_domain.menufacturer.exception.ManufacturerHandler;
import com.example.betteriter.bo_domain.menufacturer.repository.ManufacturerRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import static com.example.betteriter.global.error.exception.ErrorCode._MANUFACTURER_NOT_FOUND;

@Slf4j
@RequiredArgsConstructor
@Service
public class ManufacturerService {
private final ManufacturerRepository manufacturerRepository;

public Manufacturer findManufacturerById(Long id) {
return this.manufacturerRepository.findById(id)
.orElseThrow(() -> new ManufacturerHandler(_MANUFACTURER_NOT_FOUND));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
import com.example.betteriter.bo_domain.news.dto.CreateITNewsRequestDto;
import com.example.betteriter.bo_domain.news.dto.ITNewsResponseDto;
import com.example.betteriter.bo_domain.news.dto.UpdateITNewsRequestDto;
import com.example.betteriter.bo_domain.news.exception.NewsHandler;
import com.example.betteriter.bo_domain.news.service.NewsService;
import com.example.betteriter.global.common.response.ResponseDto;
import com.example.betteriter.global.error.exception.ErrorCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
Expand All @@ -22,8 +26,10 @@ public class NewsController {

@PostMapping
public ResponseDto<Long> createITNews(
@Valid @RequestBody CreateITNewsRequestDto request
@Valid @RequestBody CreateITNewsRequestDto request,
BindingResult bindingResult
) {
this.checkRequestValidation(bindingResult);
return ResponseDto.onSuccess(this.newsService.createITNews(request));
}

Expand All @@ -35,7 +41,9 @@ public ResponseDto<List<ITNewsResponseDto>> getITNews() {
@PutMapping("/{id}")
public ResponseDto<Void> updateITNews(
@Valid @RequestBody UpdateITNewsRequestDto request,
@PathVariable Long id) {
@PathVariable Long id,
BindingResult bindingResult) {
this.checkRequestValidation(bindingResult);
this.newsService.updateITNews(id, request);
return ResponseDto.onSuccess();
}
Expand All @@ -46,4 +54,11 @@ public ResponseDto<Void> deleteITNews(@PathVariable Long id) {
return ResponseDto.onSuccess();
}

private void checkRequestValidation(BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
FieldError fieldError = bindingResult.getFieldErrors().get(0);
log.debug("fieldError occurs : {}", fieldError.getDefaultMessage());
throw new NewsHandler(ErrorCode._METHOD_ARGUMENT_ERROR);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,44 @@
package com.example.betteriter.fo_domain.review.controller;

import com.example.betteriter.fo_domain.review.dto.CreateReviewRequestDto;
import com.example.betteriter.fo_domain.review.exception.ReviewHandler;
import com.example.betteriter.fo_domain.review.service.ReviewService;
import com.example.betteriter.global.common.response.ResponseDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

import static com.example.betteriter.global.error.exception.ErrorCode._METHOD_ARGUMENT_ERROR;

@Slf4j
@RequestMapping("/follow")
@RequestMapping("/review")
@RequiredArgsConstructor
@RestController
public class ReviewController {
private final ReviewService reviewService;

@PostMapping
public ResponseDto<Long> createReview(
@Valid @RequestBody CreateReviewRequestDto request,
BindingResult bindingResult
) {
this.checkRequestValidation(bindingResult);
return ResponseDto.onSuccess(this.reviewService.createReview(request));
}


private void checkRequestValidation(BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
FieldError fieldError = bindingResult.getFieldErrors().get(0);
log.debug("fieldError occurs : {}", fieldError.getDefaultMessage());
throw new ReviewHandler(_METHOD_ARGUMENT_ERROR);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import lombok.extern.slf4j.Slf4j;

import javax.persistence.*;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.List;

@Slf4j
Expand All @@ -28,12 +28,12 @@ public class Review extends BaseEntity {
@ManyToOne(fetch = FetchType.LAZY)
private User writer;

@JoinColumn(name = "made_by_id")
@JoinColumn(name = "manufacturer_id")
@ManyToOne(fetch = FetchType.LAZY)
private Manufacturer madeBy;
private Manufacturer manufacturer;

@Enumerated(EnumType.STRING)
private Category category; // 리뷰 카테고리
private Category category;

@Column(name = "product_name", nullable = false)
private String productName;
Expand All @@ -42,20 +42,23 @@ public class Review extends BaseEntity {
private int amount;

@Column(name = "store_name", nullable = false)
private String storeName;
private int storeName;

@Column(name = "bought_at", nullable = false)
private Timestamp boughtAt;
private LocalDate boughtAt;

@Column(name = "star_point", nullable = false)
private int starPoint;

@Column(name = "shot_review", nullable = false)
private String shotReview;
@Column(name = "short_review", nullable = false)
private String shortReview;


@Lob // 최대 500 자
@Column(name = "good_point", nullable = false)
private String goodPoint;

@Lob // 최대 500 자
@Column(name = "bad_point", nullable = false)
private String badPoint;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.example.betteriter.fo_domain.review.dto;

import com.example.betteriter.bo_domain.menufacturer.domain.Manufacturer;
import com.example.betteriter.fo_domain.review.domain.Review;
import com.example.betteriter.fo_domain.review.domain.ReviewImage;
import com.example.betteriter.global.constant.Category;
import lombok.*;

import javax.validation.constraints.NotBlank;
import java.time.LocalDate;
import java.util.List;

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CreateReviewRequestDto {
@NotBlank(message = "카테고리는 필수 입력 값입니다.")
private String category; // 카테고리
private String productName; // 상품명
private LocalDate boughtAt; // 구매 일자
private Long manufacturerId; // 제조사 아이디
private int amount; // 가격
private int storeName; // 구매처
private String shortReview; //
private int starPoint; // 별점
private String goodPoint; // 좋은 점
private String badPoint; // 나쁜 점
private List<CreateReviewImageRequestDto> images; // 리뷰 이미지

public Review toEntity(Manufacturer manufacturer) {
return Review.builder()
.category(this.toCategory())
.productName(productName)
.boughtAt(boughtAt)
.manufacturer(manufacturer)
.amount(amount)
.storeName(storeName)
.shortReview(shortReview)
.starPoint(starPoint)
.goodPoint(goodPoint)
.badPoint(badPoint)
.build();
}

private Category toCategory() {
for (Category category : Category.values()) {
if (this.category.equals(category.getName())) {
return category;
}
}
return null;
}

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class CreateReviewImageRequestDto {
private String imgUrl;

public ReviewImage toEntity(int orderNum, Review review) {
return ReviewImage.builder()
.imgUrl(imgUrl)
.review(review)
.orderNum(orderNum)
.build();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.example.betteriter.fo_domain.review.service;

import com.example.betteriter.bo_domain.menufacturer.domain.Manufacturer;
import com.example.betteriter.bo_domain.menufacturer.service.ManufacturerService;
import com.example.betteriter.fo_domain.review.domain.Review;
import com.example.betteriter.fo_domain.review.dto.CreateReviewRequestDto;
import com.example.betteriter.fo_domain.review.dto.CreateReviewRequestDto.CreateReviewImageRequestDto;
import com.example.betteriter.fo_domain.review.dto.ReviewResponseDto;
import com.example.betteriter.fo_domain.review.repository.ReviewImageRepository;
import com.example.betteriter.fo_domain.review.repository.ReviewRepository;
Expand All @@ -11,6 +15,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedHashMap;
import java.util.List;
Expand All @@ -21,9 +26,21 @@
@RequiredArgsConstructor
@Service
public class ReviewService {
private final UserService userService;
private final ManufacturerService manufacturerService;

private final ReviewRepository reviewRepository;
private final ReviewImageRepository reviewImageRepository;
private final UserService userService;


/* 리뷰 등록 */
@Transactional
public Long createReview(CreateReviewRequestDto request) {
Manufacturer manufacturer = this.manufacturerService.findManufacturerById(request.getManufacturerId());
Review review = this.reviewRepository.save(request.toEntity(manufacturer));
this.saveReviewImagesFromRequest(request, review);
return review.getId();
}

/* 유저가 관심 등록한 카테고리 리뷰 리스트 조회 메소드 */
public Map<String, List<ReviewResponseDto>> getUserCategoryReviews() {
Expand Down Expand Up @@ -67,4 +84,11 @@ private User getCurrentUser() {
private String getFirstImageWithReview(Review review) {
return this.reviewImageRepository.findFirstImageWithReview(review);
}

private void saveReviewImagesFromRequest(CreateReviewRequestDto request, Review review) {
List<CreateReviewImageRequestDto> images = request.getImages();
for (CreateReviewImageRequestDto image : images) {
reviewImageRepository.save(image.toEntity(images.indexOf(image), review));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ public ResponseDto<Boolean> checkNickname(
private void checkRequestValidation(BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
FieldError fieldError = bindingResult.getFieldErrors().get(0);
log.debug("filedError occurs : {}", fieldError.getDefaultMessage());
log.debug("fieldError occurs : {}", fieldError.getDefaultMessage());
throw new UserHandler(_METHOD_ARGUMENT_ERROR);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ public enum ErrorCode {


// News
_NEWS_NOT_FOUND(HttpStatus.BAD_REQUEST, "NEWS_400", "일치하는 뉴스 정보를 찾을 수 없습니다.");
_NEWS_NOT_FOUND(HttpStatus.BAD_REQUEST, "NEWS_400", "일치하는 뉴스 정보를 찾을 수 없습니다."),


// Manufacturer
_MANUFACTURER_NOT_FOUND(HttpStatus.BAD_REQUEST, "MANUFACTURER_400", "일치하는 제조사 정보를 찾을 수 없습니다.");


private final HttpStatus httpStatus;
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ spring:
## 개발 환경 = debug
logging:
level:
org.hibernate.sql: debug
org.hibernate.SQL: debug
org.hibernate.type: trace

2 changes: 1 addition & 1 deletion src/main/resources/application-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ spring:
## 운영 환경 = info
logging:
level:
org.hibernate.sql: info
org.hibernate.SQL: info
org.hibernate.type: info
Loading