From e684f879941f78b92cede8ac9a71f0eeb894416e Mon Sep 17 00:00:00 2001 From: bokyeong Date: Wed, 13 Nov 2024 13:34:43 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat=20:=20[#99]=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=EC=8B=9C=20=EC=8D=B8=EB=84=A4=EC=9D=BC=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/helpmeCookies/product/entity/Product.java | 3 ++- .../java/com/helpmeCookies/product/service/ProductService.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/helpmeCookies/product/entity/Product.java b/src/main/java/com/helpmeCookies/product/entity/Product.java index 7f07fa3..f7352d6 100644 --- a/src/main/java/com/helpmeCookies/product/entity/Product.java +++ b/src/main/java/com/helpmeCookies/product/entity/Product.java @@ -58,7 +58,7 @@ public class Product extends BaseTimeEntity { public Product() {} @Builder - public Product(String name, Category category, String size, Long price, String description, String preferredLocation, List hashTags, ArtistInfo artistInfo) { + public Product(String name, Category category, String size, Long price, String description, String preferredLocation, List hashTags, ArtistInfo artistInfo,String thumbnailUrl) { this.name = name; this.category = category; this.size = size; @@ -66,6 +66,7 @@ public Product(String name, Category category, String size, Long price, String d this.description = description; this.preferredLocation = preferredLocation; this.hashTags = hashTags; + this.thumbnailUrl = thumbnailUrl; this.artistInfo = artistInfo; } diff --git a/src/main/java/com/helpmeCookies/product/service/ProductService.java b/src/main/java/com/helpmeCookies/product/service/ProductService.java index 1abd3e7..013361d 100644 --- a/src/main/java/com/helpmeCookies/product/service/ProductService.java +++ b/src/main/java/com/helpmeCookies/product/service/ProductService.java @@ -37,7 +37,7 @@ public ProductPage.Paging getProductsWithRandomPaging(Pageable pageable) { public Product save(ProductRequest productSaveRequest) { ArtistInfo artistInfo = artistInfoRepository.findById(productSaveRequest.artistInfoId()) .orElseThrow(() -> new IllegalArgumentException("유효하지 않은 작가 정보입니다.")); - Product product = productSaveRequest.toEntity(artistInfo); + Product product = productSaveRequest.toEntity(artistInfo,productSaveRequest.getThumbnailImage()); productRepository.save(product); return product; } From c23609049011799ddae2b24fd987bbbc2410964d Mon Sep 17 00:00:00 2001 From: bokyeong Date: Wed, 13 Nov 2024 13:55:26 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat=20:=20[#93]=20=EC=A2=8B=EC=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=83=81=ED=92=88=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/WishController.java | 27 +++++++++++++++++++ .../product/dto/ProductPage.java | 18 +++++++++++++ .../product/dto/ProductRequest.java | 7 ++++- .../helpmeCookies/product/entity/Like.java | 4 +++ .../helpmeCookies/product/entity/Product.java | 4 +++ .../product/service/ProductLikeService.java | 18 +++++++++++-- 6 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/helpmeCookies/product/controller/WishController.java diff --git a/src/main/java/com/helpmeCookies/product/controller/WishController.java b/src/main/java/com/helpmeCookies/product/controller/WishController.java new file mode 100644 index 0000000..7027151 --- /dev/null +++ b/src/main/java/com/helpmeCookies/product/controller/WishController.java @@ -0,0 +1,27 @@ +package com.helpmeCookies.product.controller; + +import com.helpmeCookies.global.ApiResponse.ApiResponse; +import com.helpmeCookies.global.ApiResponse.SuccessCode; +import com.helpmeCookies.global.jwt.JwtUser; +import com.helpmeCookies.product.dto.ProductPage.Paging; +import com.helpmeCookies.product.service.ProductLikeService; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/v1/wishes") +@RequiredArgsConstructor +public class WishController { + private ProductLikeService productLikeService; + + @GetMapping + public ResponseEntity> getAllMyLikeProducts( + @AuthenticationPrincipal JwtUser jwtUser, Pageable pageable) { + return ResponseEntity.ok(ApiResponse.success(SuccessCode.OK,productLikeService.getLikeProducts(jwtUser.getId(),pageable))); + } +} diff --git a/src/main/java/com/helpmeCookies/product/dto/ProductPage.java b/src/main/java/com/helpmeCookies/product/dto/ProductPage.java index 9778e2f..8a1316e 100644 --- a/src/main/java/com/helpmeCookies/product/dto/ProductPage.java +++ b/src/main/java/com/helpmeCookies/product/dto/ProductPage.java @@ -1,5 +1,6 @@ package com.helpmeCookies.product.dto; +import com.helpmeCookies.product.entity.Product; import com.helpmeCookies.product.repository.dto.ProductSearch; import java.util.List; import org.springframework.data.domain.Page; @@ -23,6 +24,16 @@ public static Info from(ProductSearch productSearch) { ); } + public static Info fromProduct(Product product) { + return new Info( + product.getId(), + product.getName(), + product.getArtistInfo().getNickname(), + product.getPrice(), + product.getThumbnailUrl() + ); + } + public static List of(List content) { return content.stream() .map(Info::from) @@ -41,6 +52,13 @@ public static Paging from(Page productPage) { Info.of(productPage.getContent()) ); } + + public static Paging fromProduct(Page productPage) { + return new Paging( + productPage.hasNext(), + productPage.map(Info::fromProduct).toList() + ); + } } } diff --git a/src/main/java/com/helpmeCookies/product/dto/ProductRequest.java b/src/main/java/com/helpmeCookies/product/dto/ProductRequest.java index b0f73d5..8c65164 100644 --- a/src/main/java/com/helpmeCookies/product/dto/ProductRequest.java +++ b/src/main/java/com/helpmeCookies/product/dto/ProductRequest.java @@ -19,7 +19,7 @@ public record ProductRequest( List imageUrls ) { - public Product toEntity(ArtistInfo artistInfo) { + public Product toEntity(ArtistInfo artistInfo,String thumbnailImage) { return Product.builder() .name(name) .category(Category.fromString(category)) @@ -29,6 +29,11 @@ public Product toEntity(ArtistInfo artistInfo) { .preferredLocation(preferredLocation) .hashTags(hashTags) .artistInfo(artistInfo) + .thumbnailUrl(thumbnailImage) .build(); } + + public String getThumbnailImage() { + return imageUrls.get(0); + } } diff --git a/src/main/java/com/helpmeCookies/product/entity/Like.java b/src/main/java/com/helpmeCookies/product/entity/Like.java index 77fe3a6..533e6bc 100644 --- a/src/main/java/com/helpmeCookies/product/entity/Like.java +++ b/src/main/java/com/helpmeCookies/product/entity/Like.java @@ -31,4 +31,8 @@ public Like(User user, Product product) { this.user = user; this.product = product; } + + public Product getProduct() { + return product; + } } diff --git a/src/main/java/com/helpmeCookies/product/entity/Product.java b/src/main/java/com/helpmeCookies/product/entity/Product.java index f7352d6..15ef63e 100644 --- a/src/main/java/com/helpmeCookies/product/entity/Product.java +++ b/src/main/java/com/helpmeCookies/product/entity/Product.java @@ -106,6 +106,10 @@ public ArtistInfo getArtistInfo() { return artistInfo; } + public String getThumbnailUrl() { + return thumbnailUrl; + } + public void update(String name, Category category, String size, Long price, String description, String preferredLocation, List hashTags, ArtistInfo artistInfo) { this.name = name; this.category = category; diff --git a/src/main/java/com/helpmeCookies/product/service/ProductLikeService.java b/src/main/java/com/helpmeCookies/product/service/ProductLikeService.java index 78b450f..3a65423 100644 --- a/src/main/java/com/helpmeCookies/product/service/ProductLikeService.java +++ b/src/main/java/com/helpmeCookies/product/service/ProductLikeService.java @@ -1,5 +1,6 @@ package com.helpmeCookies.product.service; +import com.helpmeCookies.product.dto.ProductPage; import com.helpmeCookies.product.entity.Like; import com.helpmeCookies.product.entity.Product; import com.helpmeCookies.product.repository.ProductLikeRepository; @@ -7,6 +8,8 @@ import com.helpmeCookies.user.entity.User; import com.helpmeCookies.user.repository.UserRepository; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,18 +22,29 @@ public class ProductLikeService { @Transactional public void productLike(Long userId, Long productId) { - User user = userRepository.findById(userId).orElseThrow(() -> new IllegalArgumentException("유효하지 않은 유저Id입니다." + userId)); + User user = getUser(userId); Product product = productRepository.findById(productId).orElseThrow(() -> new IllegalArgumentException("유효하지 않은 상품Id입니다." + productId)); Like like = new Like(user, product); productLikeRepository.save(like); } + @Transactional(readOnly = true) + public ProductPage.Paging getLikeProducts(Long userId, Pageable pageable) { + User user = getUser(userId); + Page productPage = productLikeRepository.findAllByUser(user,pageable).map(Like::getProduct); + return ProductPage.Paging.fromProduct(productPage); + } + @Transactional public void deleteProductLike(Long userId, Long productId) { - User user = userRepository.findById(userId).orElseThrow(() -> new IllegalArgumentException("유효하지 않은 유저Id입니다." + userId)); + User user = getUser(userId); Product product = productRepository.findById(productId).orElseThrow(() -> new IllegalArgumentException("유효하지 않은 상품Id입니다." + productId)); Like like = productLikeRepository.findDistinctFirstByUserAndProduct(user,product).orElseThrow(() -> new IllegalArgumentException("존재하지 않는 상품 찜 항목입니다.")); productLikeRepository.delete(like); } + + private User getUser(Long userId) { + return userRepository.findById(userId).orElseThrow(() -> new IllegalArgumentException("유효하지 않은 유저Id입니다." + userId)); + } } From ba4238eb22e2ac4e579b13d761a3a201caaab5b9 Mon Sep 17 00:00:00 2001 From: bokyeong Date: Wed, 13 Nov 2024 14:02:15 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat=20:=20[#99]=20=EC=83=81=ED=92=88?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=88=98=EC=A0=95=20=EC=8B=9C=20?= =?UTF-8?q?=EC=8D=B8=EB=84=A4=EC=9D=BC=EB=8F=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 22 ++++++++----------- .../product/service/ProductService.java | 7 ++++++ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/helpmeCookies/product/controller/ProductController.java b/src/main/java/com/helpmeCookies/product/controller/ProductController.java index 56fcb37..8ef84d1 100644 --- a/src/main/java/com/helpmeCookies/product/controller/ProductController.java +++ b/src/main/java/com/helpmeCookies/product/controller/ProductController.java @@ -40,36 +40,31 @@ public class ProductController implements ProductApiDocs { private final ReviewService reviewService; private final ProductLikeService productLikeService; - @PostMapping("/successTest") - public ResponseEntity> saveTest() { - return ResponseEntity.ok(ApiResponse.success(SuccessCode.OK)); - } - @PostMapping - public ResponseEntity saveProduct(@RequestBody ProductRequest productRequest) { + public ResponseEntity> saveProduct(@RequestBody ProductRequest productRequest) { Product product = productService.save(productRequest); productImageService.saveImages(product.getId(),productRequest.imageUrls()); - return ResponseEntity.ok().build(); + return ResponseEntity.ok(ApiResponse.success(SuccessCode.OK)); } @PostMapping("/images") - public ResponseEntity uploadImages(List files) { + public ResponseEntity> uploadImages(List files) { List responses = productImageService.uploadMultiFiles(files); - return ResponseEntity.ok(new ProductImageResponse(responses.stream().map(ImageUpload::photoUrl).toList())); + return ResponseEntity.ok(ApiResponse.success(SuccessCode.OK,new ProductImageResponse(responses.stream().map(ImageUpload::photoUrl).toList()))); } @GetMapping("/{productId}") - public ResponseEntity getProductInfo(@PathVariable("productId") Long productId) { + public ResponseEntity> getProductInfo(@PathVariable("productId") Long productId) { Product product = productService.find(productId); List urls = productImageService.getImages(productId); - return ResponseEntity.ok(ProductResponse.from(product,urls)); + return ResponseEntity.ok(ApiResponse.success(SuccessCode.OK,ProductResponse.from(product,urls))); } @PutMapping("/{productId}") - public ResponseEntity editProductInfo(@PathVariable("productId") Long productId, + public ResponseEntity> editProductInfo(@PathVariable("productId") Long productId, @RequestBody ProductRequest productRequest) { productService.edit(productId, productRequest); - return ResponseEntity.ok().build(); + return ResponseEntity.ok(ApiResponse.success(SuccessCode.OK)); } @PutMapping("/{productId}/images") @@ -77,6 +72,7 @@ public ResponseEntity editImages(@PathVariable("productId") Long productId productImageService.editImages(productId, files); List images = productImageService.uploadMultiFiles(files).stream() .map(ImageUpload::photoUrl).toList(); + productService.editThumbnailImage(productId,images); productImageService.saveImages(productId,images); return ResponseEntity.ok().build(); } diff --git a/src/main/java/com/helpmeCookies/product/service/ProductService.java b/src/main/java/com/helpmeCookies/product/service/ProductService.java index 013361d..f3d3fc9 100644 --- a/src/main/java/com/helpmeCookies/product/service/ProductService.java +++ b/src/main/java/com/helpmeCookies/product/service/ProductService.java @@ -8,6 +8,7 @@ import com.helpmeCookies.user.entity.ArtistInfo; import com.helpmeCookies.user.repository.ArtistInfoRepository; import com.helpmeCookies.product.dto.ProductPage; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -62,6 +63,12 @@ public void edit(Long productId, ProductRequest productRequest) { artistInfo); } + @Transactional + public void editThumbnailImage(Long productId, List images) { + Product product = productRepository.findById(productId).orElseThrow(() -> new IllegalArgumentException("유효하지 않은 id입니다")); + product.updateThumbnail(images.getFirst()); + } + public void delete(Long productId) { Product product = productRepository.findById(productId).orElseThrow(() -> new IllegalArgumentException("유효하지 않은 id입니다")); productRepository.delete(product); From ef536d53e41880891dda1887c69c60026bf84e29 Mon Sep 17 00:00:00 2001 From: bokyeong Date: Wed, 13 Nov 2024 14:06:18 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat=20:=20[#85]=20ProductController=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20=ED=98=95=EC=8B=9D=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/helpmeCookies/product/controller/ProductController.java b/src/main/java/com/helpmeCookies/product/controller/ProductController.java index 8ef84d1..eccbf6f 100644 --- a/src/main/java/com/helpmeCookies/product/controller/ProductController.java +++ b/src/main/java/com/helpmeCookies/product/controller/ProductController.java @@ -9,6 +9,7 @@ import com.helpmeCookies.product.controller.docs.ProductApiDocs; import com.helpmeCookies.product.dto.ProductImageResponse; import com.helpmeCookies.product.dto.ProductPage; +import com.helpmeCookies.product.dto.ProductPage.Paging; import com.helpmeCookies.product.dto.ProductRequest; import com.helpmeCookies.product.dto.ProductResponse; import com.helpmeCookies.product.entity.Product; @@ -68,23 +69,23 @@ public ResponseEntity> editProductInfo(@PathVariable("productI } @PutMapping("/{productId}/images") - public ResponseEntity editImages(@PathVariable("productId") Long productId, List files) { + public ResponseEntity> editImages(@PathVariable("productId") Long productId, List files) { productImageService.editImages(productId, files); List images = productImageService.uploadMultiFiles(files).stream() .map(ImageUpload::photoUrl).toList(); productService.editThumbnailImage(productId,images); productImageService.saveImages(productId,images); - return ResponseEntity.ok().build(); + return ResponseEntity.ok(ApiResponse.success(SuccessCode.OK)); } @DeleteMapping("/{productId}") - public ResponseEntity deleteProduct(@PathVariable("productId") Long productId) { + public ResponseEntity> deleteProduct(@PathVariable("productId") Long productId) { productService.delete(productId); - return ResponseEntity.noContent().build(); + return ResponseEntity.ok(ApiResponse.success(SuccessCode.NO_CONTENT)); } @GetMapping - public ResponseEntity getProductsByPage( + public ResponseEntity getProductsByPage( @RequestParam("query") String query, @RequestParam(name = "size", required = false, defaultValue = "20") int size, @RequestParam("page") int page, @@ -97,11 +98,11 @@ public ResponseEntity getProductsByPage( } @GetMapping("/feed") - public ResponseEntity getProductsWithRandomPaging( + public ResponseEntity> getProductsWithRandomPaging( @RequestParam(name = "size", required = false, defaultValue = "20") int size ) { Pageable pageable = PageRequest.of(0, size); - return ResponseEntity.ok(productService.getProductsWithRandomPaging(pageable)); + return ResponseEntity.ok(ApiResponse.success(SuccessCode.OK,productService.getProductsWithRandomPaging(pageable))); } @GetMapping("/{productId}/reviews") From 5017310026799ab32a890791bb502edac435c9c5 Mon Sep 17 00:00:00 2001 From: bokyeong Date: Wed, 13 Nov 2024 14:10:03 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat=20:=20[#85]=20errorHandler=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=8F=99=EC=9D=BC=ED=95=9C=20=ED=98=95=EC=8B=9D=20?= =?UTF-8?q?=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/exception/GlobalExceptionHandler.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/helpmeCookies/global/exception/GlobalExceptionHandler.java b/src/main/java/com/helpmeCookies/global/exception/GlobalExceptionHandler.java index 9705e08..a80c49d 100644 --- a/src/main/java/com/helpmeCookies/global/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/helpmeCookies/global/exception/GlobalExceptionHandler.java @@ -21,4 +21,9 @@ public ResponseEntity> handleResourceNotFoundException() { public String handleDuplicateRequestException() { return "이미 생성되었거나 중복된 요청입니다."; } + + @ExceptionHandler(IllegalArgumentException.class) + public ResponseEntity> handleIllegalArgumentException(IllegalArgumentException e) { + return ResponseEntity.badRequest().body(ApiResponse.error(HttpStatus.BAD_REQUEST,e.getMessage())); + } } From 95233c8821fd0ef26431171b25e789e1c9d87ba4 Mon Sep 17 00:00:00 2001 From: bokyeong Date: Wed, 13 Nov 2024 14:10:51 +0900 Subject: [PATCH 6/7] =?UTF-8?q?refactor=20:=20[#85]=20errorHandler?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=8F=99=EC=9D=BC=ED=95=9C=20=ED=98=95?= =?UTF-8?q?=EC=8B=9D=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/exception/GlobalExceptionHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/helpmeCookies/global/exception/GlobalExceptionHandler.java b/src/main/java/com/helpmeCookies/global/exception/GlobalExceptionHandler.java index a80c49d..ea4c2de 100644 --- a/src/main/java/com/helpmeCookies/global/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/helpmeCookies/global/exception/GlobalExceptionHandler.java @@ -18,8 +18,8 @@ public ResponseEntity> handleResourceNotFoundException() { } @ExceptionHandler(DuplicateRequestException.class) - public String handleDuplicateRequestException() { - return "이미 생성되었거나 중복된 요청입니다."; + public ResponseEntity> handleDuplicateRequestException() { + return ResponseEntity.badRequest().body(ApiResponse.error(HttpStatus.BAD_REQUEST,"이미 생성되었거나 중복된 요청입니다.")); } @ExceptionHandler(IllegalArgumentException.class) From 33236832828478f3f88a522951c77380345d6deb Mon Sep 17 00:00:00 2001 From: bokyeong Date: Wed, 13 Nov 2024 14:48:37 +0900 Subject: [PATCH 7/7] =?UTF-8?q?feat=20:=20[#100]=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EC=A3=BC=EB=AC=B8=20=EC=83=81=ED=83=9C=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../helpmeCookies/product/entity/OrderStatus.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/helpmeCookies/product/entity/OrderStatus.java b/src/main/java/com/helpmeCookies/product/entity/OrderStatus.java index 84b5866..748135c 100644 --- a/src/main/java/com/helpmeCookies/product/entity/OrderStatus.java +++ b/src/main/java/com/helpmeCookies/product/entity/OrderStatus.java @@ -1,5 +1,17 @@ package com.helpmeCookies.product.entity; public enum OrderStatus { - ORDER, CANCEL + ORDER("핀매 중"), + DONE("거래 완료"), + RESERVED("예약 중"); + + private final String orderStatusType; + + OrderStatus(String orderStatusType) { + this.orderStatusType = orderStatusType; + } + + public String getOrderStatusType() { + return orderStatusType; + } }