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/BE] 제품에 카테고리를 추가 #258

Merged
merged 5 commits into from
Jul 28, 2022
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 backend/src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@

include::auth.adoc[]
include::members.adoc[]
include::keyboards.adoc[]
include::products.adoc[]
include::reviews.adoc[]
include::inventoryProducts.adoc[]
16 changes: 0 additions & 16 deletions backend/src/docs/asciidoc/keyboards.adoc

This file was deleted.

25 changes: 25 additions & 0 deletions backend/src/docs/asciidoc/products.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[[Product]]
== Product API

=== 제품 단일 상품 조회

operation::products-get[snippets='http-request,http-response']

=== 제품 목록 페이지 조회

==== category 조건

- `keyboard` (키보드)
- `mouse` (마우스)
- `monitor` (모니터)
- `stand` (거치대)
- `software` (소프트웨어)
- 없을 경우 모든 제품 조회

==== sort 조건

- `rating,desc`(평점순)
- `reviewCount,desc`(리뷰 많은순)
- 없을 경우 등록 순서

operation::products-page-get[snippets='http-request,http-response']

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.woowacourse.f12.application.product;

import com.woowacourse.f12.domain.product.Category;
import com.woowacourse.f12.domain.product.Product;
import com.woowacourse.f12.domain.product.ProductRepository;
import com.woowacourse.f12.dto.response.product.ProductPageResponse;
import com.woowacourse.f12.dto.response.product.ProductResponse;
import com.woowacourse.f12.exception.notfound.KeyboardNotFoundException;
import com.woowacourse.f12.presentation.product.CategoryConstant;
import java.util.Objects;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true)
public class ProductService {

private final ProductRepository productRepository;

public ProductService(final ProductRepository productRepository) {
this.productRepository = productRepository;
}

public ProductResponse findById(final Long id) {
final Product product = productRepository.findById(id)
.orElseThrow(KeyboardNotFoundException::new);
return ProductResponse.from(product);
}

public ProductPageResponse findPage(final CategoryConstant categoryConstant, final Pageable pageable) {
if (Objects.isNull(categoryConstant)) {
return ProductPageResponse.from(productRepository.findPageBy(pageable));
}

final Category category = categoryConstant.toCategory();
return ProductPageResponse.from(productRepository.findPageByCategory(category, pageable));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import com.woowacourse.f12.domain.inventoryproduct.InventoryProductRepository;
import com.woowacourse.f12.domain.member.Member;
import com.woowacourse.f12.domain.member.MemberRepository;
import com.woowacourse.f12.domain.product.Keyboard;
import com.woowacourse.f12.domain.product.KeyboardRepository;
import com.woowacourse.f12.domain.product.Product;
import com.woowacourse.f12.domain.product.ProductRepository;
import com.woowacourse.f12.domain.review.Review;
import com.woowacourse.f12.domain.review.ReviewRepository;
import com.woowacourse.f12.dto.request.review.ReviewRequest;
Expand All @@ -26,15 +26,15 @@
public class ReviewService {

private final ReviewRepository reviewRepository;
private final KeyboardRepository keyboardRepository;
private final ProductRepository productRepository;
private final MemberRepository memberRepository;
private final InventoryProductRepository inventoryProductRepository;

public ReviewService(final ReviewRepository reviewRepository, final KeyboardRepository keyboardRepository,
public ReviewService(final ReviewRepository reviewRepository, final ProductRepository productRepository,
final MemberRepository memberRepository,
final InventoryProductRepository inventoryProductRepository) {
this.reviewRepository = reviewRepository;
this.keyboardRepository = keyboardRepository;
this.productRepository = productRepository;
this.memberRepository = memberRepository;
this.inventoryProductRepository = inventoryProductRepository;
}
Expand All @@ -44,33 +44,33 @@ public Long saveReviewAndInventoryProduct(final Long productId, final Long membe
final ReviewRequest reviewRequest) {
final Member member = memberRepository.findById(memberId)
.orElseThrow(MemberNotFoundException::new);
final Keyboard keyboard = keyboardRepository.findById(productId)
final Product product = productRepository.findById(productId)
.orElseThrow(KeyboardNotFoundException::new);
final Long reviewId = saveReview(reviewRequest, member, keyboard);
saveInventoryProduct(memberId, keyboard);
final Long reviewId = saveReview(reviewRequest, member, product);
saveInventoryProduct(memberId, product);
return reviewId;
}

private Long saveReview(final ReviewRequest reviewRequest, final Member member, final Keyboard keyboard) {
validateNotWritten(member, keyboard);
final Review review = reviewRequest.toReview(keyboard, member);
private Long saveReview(final ReviewRequest reviewRequest, final Member member, final Product product) {
validateNotWritten(member, product);
final Review review = reviewRequest.toReview(product, member);
return reviewRepository.save(review)
.getId();
}

private void validateNotWritten(final Member member, final Keyboard keyboard) {
if (reviewRepository.existsByMemberAndKeyboard(member, keyboard)) {
private void validateNotWritten(final Member member, final Product product) {
if (reviewRepository.existsByMemberAndProduct(member, product)) {
throw new AlreadyWrittenReviewException();
}
}

private void saveInventoryProduct(final Long memberId, final Keyboard keyboard) {
if (inventoryProductRepository.existsByMemberIdAndKeyboard(memberId, keyboard)) {
private void saveInventoryProduct(final Long memberId, final Product product) {
if (inventoryProductRepository.existsByMemberIdAndProduct(memberId, product)) {
return;
}
final InventoryProduct inventoryProduct = InventoryProduct.builder()
.memberId(memberId)
.keyboard(keyboard)
.product(product)
.build();
inventoryProductRepository.save(inventoryProduct);
}
Expand All @@ -82,7 +82,7 @@ public ReviewPageResponse findPageByProductId(final Long productId, final Pageab
}

private void validateKeyboardExists(final Long productId) {
if (!keyboardRepository.existsById(productId)) {
if (!productRepository.existsById(productId)) {
throw new KeyboardNotFoundException();
}
}
Expand All @@ -95,7 +95,7 @@ public ReviewWithProductPageResponse findPage(final Pageable pageable) {
@Transactional
public void update(final Long reviewId, final Long memberId, final ReviewRequest updateRequest) {
final Review target = findTarget(reviewId, memberId);
final Review updateReview = updateRequest.toReview(target.getKeyboard(), target.getMember());
final Review updateReview = updateRequest.toReview(target.getProduct(), target.getMember());
target.update(updateReview);
}

Expand Down
13 changes: 12 additions & 1 deletion backend/src/main/java/com/woowacourse/f12/config/WebConfig.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.woowacourse.f12.config;

import com.woowacourse.f12.presentation.ViewConstant;
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.HttpHeaders;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.HandlerInterceptor;
Expand All @@ -16,10 +19,13 @@ public class WebConfig implements WebMvcConfigurer {

private final List<HandlerInterceptor> interceptors;
private final List<HandlerMethodArgumentResolver> resolvers;
private final List<Converter<String, ViewConstant>> converters;

public WebConfig(List<HandlerInterceptor> interceptors, List<HandlerMethodArgumentResolver> resolvers) {
public WebConfig(final List<HandlerInterceptor> interceptors, final List<HandlerMethodArgumentResolver> resolvers,
final List<Converter<String, ViewConstant>> converters) {
this.interceptors = interceptors;
this.resolvers = resolvers;
this.converters = converters;
}

@Override
Expand All @@ -38,4 +44,9 @@ public void addCorsMappings(final CorsRegistry registry) {
public void addArgumentResolvers(final List<HandlerMethodArgumentResolver> resolvers) {
resolvers.addAll(this.resolvers);
}

@Override
public void addFormatters(final FormatterRegistry registry) {
converters.forEach(registry::addConverter);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.woowacourse.f12.domain.inventoryproduct;

import com.woowacourse.f12.domain.product.Keyboard;
import com.woowacourse.f12.domain.product.Product;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
Expand Down Expand Up @@ -30,18 +30,18 @@ public class InventoryProduct {
private Long memberId;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "keyboard_id")
private Keyboard keyboard;
@JoinColumn(name = "product_id")
private Product product;

protected InventoryProduct() {
}

@Builder
private InventoryProduct(final Long id, final boolean selected, final Long memberId, final Keyboard keyboard) {
private InventoryProduct(final Long id, final boolean selected, final Long memberId, final Product product) {
this.id = id;
this.selected = selected;
this.memberId = memberId;
this.keyboard = keyboard;
this.product = product;
}

public void updateSelected(boolean selected) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.woowacourse.f12.domain.inventoryproduct;

import com.woowacourse.f12.domain.product.Keyboard;
import com.woowacourse.f12.domain.product.Product;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;

public interface InventoryProductRepository extends JpaRepository<InventoryProduct, Long> {

List<InventoryProduct> findByMemberId(Long memberId);

boolean existsByMemberIdAndKeyboard(Long memberId, Keyboard keyboard);
boolean existsByMemberIdAndProduct(Long memberId, Product product);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.woowacourse.f12.domain.product;

public enum Category {
KEYBOARD,
MOUSE,
MONITOR,
STAND,
SOFTWARE;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
Expand All @@ -13,10 +15,10 @@
import org.hibernate.annotations.Formula;

@Entity
@Table(name = "keyboard", uniqueConstraints = {
@Table(name = "product", uniqueConstraints = {
@UniqueConstraint(name = "NAME_UNIQUE", columnNames = {"name"})})
@Getter
public class Keyboard {
public class Product {

private static final int MAXIMUM_IMAGE_URL_LENGTH = 65535;

Expand All @@ -36,26 +38,31 @@ public class Keyboard {
@Formula("(SELECT IFNULL(AVG(r.rating), 0) FROM review r WHERE r.product_id = id)")
private double rating;

protected Keyboard() {
@Column(name = "category", nullable = false)
@Enumerated(value = EnumType.STRING)
private Category category;

protected Product() {
}

@Builder
private Keyboard(final Long id, final String name, final String imageUrl) {
private Product(final Long id, final String name, final String imageUrl, final Category category) {
this.id = id;
this.name = name;
this.imageUrl = imageUrl;
this.category = category;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Keyboard)) {
if (!(o instanceof Product)) {
return false;
}
final Keyboard keyboard = (Keyboard) o;
return Objects.equals(id, keyboard.getId());
final Product product = (Product) o;
return Objects.equals(id, product.getId());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.repository.JpaRepository;

public interface KeyboardRepository extends JpaRepository<Keyboard, Long> {
public interface ProductRepository extends JpaRepository<Product, Long> {

Slice<Keyboard> findPageBy(Pageable pageable);
Slice<Product> findPageBy(Pageable pageable);

Slice<Product> findPageByCategory(Category category, Pageable pageable);
}
Loading