diff --git a/src/main/java/com/teamjo/techeermarket/domain/mypage/controller/MyPageController.java b/src/main/java/com/teamjo/techeermarket/domain/mypage/controller/MyPageController.java index 4c9a159..8cccc6a 100644 --- a/src/main/java/com/teamjo/techeermarket/domain/mypage/controller/MyPageController.java +++ b/src/main/java/com/teamjo/techeermarket/domain/mypage/controller/MyPageController.java @@ -1,4 +1,17 @@ package com.teamjo.techeermarket.domain.mypage.controller; +import com.teamjo.techeermarket.domain.mypage.service.MyPageService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +//@RequiredArgsConstructor +//@RestController +//@RequestMapping("/api/mypage") public class MyPageController { + + + } + diff --git a/src/main/java/com/teamjo/techeermarket/domain/mypage/entity/UserLike.java b/src/main/java/com/teamjo/techeermarket/domain/mypage/entity/UserLike.java index d4228ab..8c6e487 100644 --- a/src/main/java/com/teamjo/techeermarket/domain/mypage/entity/UserLike.java +++ b/src/main/java/com/teamjo/techeermarket/domain/mypage/entity/UserLike.java @@ -2,10 +2,7 @@ import com.teamjo.techeermarket.domain.products.entity.Products; import com.teamjo.techeermarket.domain.users.entity.Users; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import javax.persistence.*; @@ -14,6 +11,7 @@ @Getter @AllArgsConstructor @Entity +@Setter @Builder @NoArgsConstructor @Table(name="user_product_like") diff --git a/src/main/java/com/teamjo/techeermarket/domain/mypage/entity/UserPurchase.java b/src/main/java/com/teamjo/techeermarket/domain/mypage/entity/UserPurchase.java index 8a8b54e..a4074db 100644 --- a/src/main/java/com/teamjo/techeermarket/domain/mypage/entity/UserPurchase.java +++ b/src/main/java/com/teamjo/techeermarket/domain/mypage/entity/UserPurchase.java @@ -3,10 +3,7 @@ import com.teamjo.techeermarket.domain.products.entity.Products; import com.teamjo.techeermarket.domain.users.entity.Users; import com.teamjo.techeermarket.global.common.BaseEntity; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import javax.persistence.*; @@ -14,6 +11,7 @@ @AllArgsConstructor @Entity @Builder +@Setter @NoArgsConstructor @Table(name="user_purchase") public class UserPurchase extends BaseEntity { diff --git a/src/main/java/com/teamjo/techeermarket/domain/mypage/mapper/UserPurchaseMapper.java b/src/main/java/com/teamjo/techeermarket/domain/mypage/mapper/UserPurchaseMapper.java index bb70dbf..9154d19 100644 --- a/src/main/java/com/teamjo/techeermarket/domain/mypage/mapper/UserPurchaseMapper.java +++ b/src/main/java/com/teamjo/techeermarket/domain/mypage/mapper/UserPurchaseMapper.java @@ -1,4 +1,9 @@ package com.teamjo.techeermarket.domain.mypage.mapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor public class UserPurchaseMapper { } diff --git a/src/main/java/com/teamjo/techeermarket/domain/mypage/repository/UserLikeRepository.java b/src/main/java/com/teamjo/techeermarket/domain/mypage/repository/UserLikeRepository.java index daa00b2..66dab8a 100644 --- a/src/main/java/com/teamjo/techeermarket/domain/mypage/repository/UserLikeRepository.java +++ b/src/main/java/com/teamjo/techeermarket/domain/mypage/repository/UserLikeRepository.java @@ -1,7 +1,14 @@ package com.teamjo.techeermarket.domain.mypage.repository; import com.teamjo.techeermarket.domain.mypage.entity.UserLike; +import com.teamjo.techeermarket.domain.products.entity.Products; +import com.teamjo.techeermarket.domain.users.entity.Users; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface UserLikeRepository extends JpaRepository { + boolean existsByUsersAndProducts(Users users, Products products); + + Optional findByUsersAndProducts(Users users, Products products); } diff --git a/src/main/java/com/teamjo/techeermarket/domain/mypage/repository/UserPurchaseRepository.java b/src/main/java/com/teamjo/techeermarket/domain/mypage/repository/UserPurchaseRepository.java index 428c35d..f181fa3 100644 --- a/src/main/java/com/teamjo/techeermarket/domain/mypage/repository/UserPurchaseRepository.java +++ b/src/main/java/com/teamjo/techeermarket/domain/mypage/repository/UserPurchaseRepository.java @@ -1,8 +1,12 @@ package com.teamjo.techeermarket.domain.mypage.repository; import com.teamjo.techeermarket.domain.mypage.entity.UserPurchase; +import com.teamjo.techeermarket.domain.products.entity.Products; +import com.teamjo.techeermarket.domain.users.entity.Users; import org.springframework.data.jpa.repository.JpaRepository; public interface UserPurchaseRepository extends JpaRepository { + boolean existsBySellerIdAndProducts(Users sellerId, Products products); + } diff --git a/src/main/java/com/teamjo/techeermarket/domain/mypage/service/MyPageService.java b/src/main/java/com/teamjo/techeermarket/domain/mypage/service/MyPageService.java index 87002c0..8bf185e 100644 --- a/src/main/java/com/teamjo/techeermarket/domain/mypage/service/MyPageService.java +++ b/src/main/java/com/teamjo/techeermarket/domain/mypage/service/MyPageService.java @@ -1,4 +1,15 @@ package com.teamjo.techeermarket.domain.mypage.service; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +//@Service +//@RequiredArgsConstructor public class MyPageService { + + + + + + } diff --git a/src/main/java/com/teamjo/techeermarket/domain/products/controller/ProductController.java b/src/main/java/com/teamjo/techeermarket/domain/products/controller/ProductController.java index 45dad83..9ac542d 100644 --- a/src/main/java/com/teamjo/techeermarket/domain/products/controller/ProductController.java +++ b/src/main/java/com/teamjo/techeermarket/domain/products/controller/ProductController.java @@ -1,18 +1,22 @@ package com.teamjo.techeermarket.domain.products.controller; import com.teamjo.techeermarket.domain.products.dto.request.ProductRequestDto; +import com.teamjo.techeermarket.domain.products.entity.ProductState; import com.teamjo.techeermarket.domain.products.service.ProductService; +import com.teamjo.techeermarket.domain.products.service.ProductSubService; import com.teamjo.techeermarket.global.config.UserDetailsImpl; +import com.teamjo.techeermarket.global.exception.product.InvalidProductStateException; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.io.IOException; +import java.util.Map; + +import static com.teamjo.techeermarket.global.exception.ErrorCode.INVALID_PRODUCT_STATE; @RequiredArgsConstructor @@ -21,6 +25,7 @@ public class ProductController { private final ProductService productService; + private final ProductSubService productSubService; @PostMapping public HttpStatus saveProduct (@Validated @ModelAttribute ProductRequestDto productRequstDto, @@ -29,8 +34,8 @@ public HttpStatus saveProduct (@Validated @ModelAttribute ProductRequestDto prod // 상품 DB에 저장 Long productId = productService.saveProduct(productRequstDto, email); - // UserPurchase DB에 저장 - // 상품 id + userid(seller-id) 만 저장 + // UserPurchase DB에 => 상품 id + (seller-id) 만 저장 + productSubService.updateProductSeller(email,productId); // 상품 상세 조회로 redirect // redirectAttributes.addAttribute("productId", productId); @@ -40,5 +45,53 @@ public HttpStatus saveProduct (@Validated @ModelAttribute ProductRequestDto prod } + /* + // 상품 게시물 상태 변경 + */ + @PutMapping("/state/{productId}") + public ResponseEntity updateProductState( + @PathVariable Long productId, + @RequestBody Map requestBody, + @AuthenticationPrincipal UserDetailsImpl userDetailsImpl) { + String email = userDetailsImpl.getUsername(); + // 요청 바디에서 state 값을 가져옴 + String state = requestBody.get("state"); + // 상태가 올바른지 확인 + try{ + ProductState productState = ProductState.valueOf(state); + } catch (IllegalArgumentException e) { + throw new InvalidProductStateException() ; } + + // 서비스를 통해 상태 변경 + productSubService.updateProductState(productId, ProductState.valueOf(state),email); + return ResponseEntity.status(HttpStatus.OK).body("Product state updated successfully"); + } + + + + /* + // 게시물 좋아요 누르기 + */ + @PostMapping("/like/{productId}") + public HttpStatus likeProduct (@PathVariable Long productId, + @AuthenticationPrincipal UserDetailsImpl userDetailsImpl) throws IOException { + String email = userDetailsImpl.getUsername(); + productSubService.likeProduct(email, productId); + return HttpStatus.OK; + } + + + /* + // 게시물 좋아요 취소 누르기 + */ + @DeleteMapping("/like/{productId}") + public HttpStatus unlikeProduct (@PathVariable Long productId, + @AuthenticationPrincipal UserDetailsImpl userDetailsImpl) throws IOException { + String email = userDetailsImpl.getUsername(); + productSubService.unlikeProduct(email, productId); + return HttpStatus.OK; + } + + } \ No newline at end of file diff --git a/src/main/java/com/teamjo/techeermarket/domain/products/service/ProductService.java b/src/main/java/com/teamjo/techeermarket/domain/products/service/ProductService.java index 75595b0..9f4a0b0 100644 --- a/src/main/java/com/teamjo/techeermarket/domain/products/service/ProductService.java +++ b/src/main/java/com/teamjo/techeermarket/domain/products/service/ProductService.java @@ -43,10 +43,13 @@ public class ProductService { private final ProductImageRepository productImageRepository; - // 상품 저장 ( = 게시물 저장) + /* + // 상품 저장 ( = 게시물 저장) + */ @Transactional public Long saveProduct(ProductRequestDto request, String email) throws IOException { - Users findUsers = userRepository.findByEmail(email); + Users findUsers = userRepository.findUserByEmail(email) + .orElseThrow(UserNotFoundException::new); Categorys findCategory = categoryRepository.findIdByName(request.getCategoryName()); Products products = productMapper.saveToEntity(request, findCategory); @@ -71,12 +74,10 @@ public Long saveProduct(ProductRequestDto request, String email) throws IOExcept ProductImage productImage = new ProductImage(); productImage.setProducts(products); // products가 Products 엔터티의 인스턴스여야 합니다. productImage.setImageUrl(imageUrls.get(i)); - // 이미지 이름 설정 productImage.setImageName(newProductID +"Image#" + (i+1)); // 이미지 번호 설정 productImage.setImageNum(i+1); - // ProductImage 저장 productImageRepository.save(productImage); } @@ -86,41 +87,24 @@ public Long saveProduct(ProductRequestDto request, String email) throws IOExcept + + + /* + // 상품 게시물 상세 조회 + */ + + + + + // 게시물 전체 조회 - // 썸네일 업데이트 -// @Transactional -// public void updateThumbnail(List images, Long productId) { -// Products product = productRepository.findById(productId).get(); -// product.setThumbnail(images); -// } - // 게시물에서 이미지 저장 -// @Transactional -// public List getProductImage(List productImages, Products product){ -// return productImages.stream() -// .map((image) -> { -// try { -// s3Service.uploadProductImageList(BucketDir.PRODUCT, imageFiles); -// return ProductImage.builder() -// .imageUrl(url) -// .fileName(s3Uploader.getFileName(url)) -// .product(product) -// .build(); -// return productImageService.save(productImageService.convert(image, product)); -// } catch (IOException e) { -// throw new RuntimeException(e); -// } -// }) -// .collect(Collectors.toList()); -// } -// List imageFiles = request.getProductImages(); -// List imageUrls = s3Service.uploadProductImageList(BucketDir.PRODUCT, imageFiles); } \ No newline at end of file diff --git a/src/main/java/com/teamjo/techeermarket/domain/products/service/ProductSubService.java b/src/main/java/com/teamjo/techeermarket/domain/products/service/ProductSubService.java new file mode 100644 index 0000000..8737088 --- /dev/null +++ b/src/main/java/com/teamjo/techeermarket/domain/products/service/ProductSubService.java @@ -0,0 +1,145 @@ +package com.teamjo.techeermarket.domain.products.service; + +import com.teamjo.techeermarket.domain.images.repository.ProductImageRepository; +import com.teamjo.techeermarket.domain.images.service.ProductImageService; +import com.teamjo.techeermarket.domain.mypage.entity.UserLike; +import com.teamjo.techeermarket.domain.mypage.entity.UserPurchase; +import com.teamjo.techeermarket.domain.mypage.repository.UserLikeRepository; +import com.teamjo.techeermarket.domain.mypage.repository.UserPurchaseRepository; +import com.teamjo.techeermarket.domain.products.entity.ProductState; +import com.teamjo.techeermarket.domain.products.entity.Products; +import com.teamjo.techeermarket.domain.products.mapper.ProductMapper; +import com.teamjo.techeermarket.domain.products.repository.CategoryRepository; +import com.teamjo.techeermarket.domain.products.repository.ProductRepository; +import com.teamjo.techeermarket.domain.users.entity.Users; +import com.teamjo.techeermarket.domain.users.repository.UserRepository; +import com.teamjo.techeermarket.global.S3.S3Service; +import com.teamjo.techeermarket.global.exception.product.NotYourProductException; +import com.teamjo.techeermarket.global.exception.product.ProductNotFoundException; +import com.teamjo.techeermarket.global.exception.user.UserNotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityNotFoundException; + +@Service +@RequiredArgsConstructor +public class ProductSubService { + + private final ProductRepository productRepository; + private final ProductImageService productImageService; + private final UserLikeRepository userLikeRepository; + private final UserPurchaseRepository userPurchaseRepository; + private final UserRepository userRepository; + @Autowired + private final ProductMapper productMapper; + @Autowired + private final S3Service s3Service; + @Autowired + private final CategoryRepository categoryRepository; + @Autowired + private final ProductImageRepository productImageRepository; + + + /* + // 게시물 작성후 userPurchase table에 추가 + */ + @Transactional + public void updateProductSeller(String email, Long productId){ + // 유저 정보 가져옴 + Users seller = userRepository.findUserByEmail(email) + .orElseThrow(UserNotFoundException::new); + // 상품 정보를 가져옴 + Products products = productRepository.findById(productId) + .orElseThrow(ProductNotFoundException::new); + // UserPurchase 테이블에 저장 + if (!userPurchaseRepository.existsBySellerIdAndProducts(seller, products)){ + UserPurchase userPurchase = new UserPurchase(); + userPurchase.setProducts(products); + userPurchase.setSellerId(seller); + userPurchaseRepository.save(userPurchase); + } + } + + + + /* + // 게시물 조회수 업데이트 + */ + @Transactional + public void increaseViewCount (Long productId) { + // 상품을 데이터베이스에서 찾음 + Products product = productRepository.findById(productId) + .orElseThrow(ProductNotFoundException::new); + int views = product.getViews(); + product.setViews(views+1); + + productRepository.save(product); + } + + + /* + // 상품 게시물 상태 변경 + */ + @Transactional + public void updateProductState(Long productId, ProductState newState, String email) { + Users findUsers = userRepository.findUserByEmail(email) + .orElseThrow(UserNotFoundException::new); + // 상품을 데이터베이스에서 찾음 + Products product = productRepository.findById(productId) + .orElseThrow(ProductNotFoundException::new); + + // 현재 로그인한 사용자의 게시물인지 확인 + if (!product.getUsers().getEmail().equals(email)) { + throw new NotYourProductException(); + } + // 상태 업데이트 + product.setProductState(newState); + productRepository.save(product); + } + + + /* + // 상품에 좋아요를 누르는 메서드 + */ + public void likeProduct(String email, Long productId) { + // 유저 정보 가져옴 + Users users = userRepository.findUserByEmail(email) + .orElseThrow(UserNotFoundException::new); + // 상품 정보를 가져옴 + Products products = productRepository.findById(productId) + .orElseThrow(ProductNotFoundException::new); + + // 사용자가 해당 상품에 이미 좋아요를 누른 적이 없으면 + if (!userLikeRepository.existsByUsersAndProducts(users, products)) { + // 좋아요 정보를 생성하여 저장 + UserLike userLike = new UserLike(); + userLike.setUsers(users); + userLike.setProducts(products); + userLikeRepository.save(userLike); + } + } + + + + /* + // 상품에 좋아요를 취소하는 메서드 + */ + public void unlikeProduct(String email, Long productId) { + // 유저 정보 가져옴 + Users users = userRepository.findUserByEmail(email) + .orElseThrow(UserNotFoundException::new); + // 상품 정보를 가져옴 + Products products = productRepository.findById(productId) + .orElseThrow(ProductNotFoundException::new); + + // 사용자가 해당 상품에 좋아요를 누른 적이 있다면 + userLikeRepository.findByUsersAndProducts(users, products) + .ifPresent(userLikeRepository::delete); // 좋아요 정보를 삭제 + } + + + +} diff --git a/src/main/java/com/teamjo/techeermarket/global/config/CorsConfig.java b/src/main/java/com/teamjo/techeermarket/global/config/CorsConfig.java index 42dfbe9..86c8e53 100644 --- a/src/main/java/com/teamjo/techeermarket/global/config/CorsConfig.java +++ b/src/main/java/com/teamjo/techeermarket/global/config/CorsConfig.java @@ -18,9 +18,9 @@ public CorsFilter corsFilter() { config.addAllowedOriginPattern("*"); // 모든 IP에 응답 허용 config.addAllowedOrigin("http://localhost:8080"); - config.addExposedHeader("Set-Cookie"); - config.addExposedHeader("cookie"); - config.addExposedHeader("authorization"); +// config.addExposedHeader("Set-Cookie"); + config.addExposedHeader("*"); +// config.addExposedHeader("authorization"); config.addAllowedHeader("*"); // 모든 헤더 응답에 허용 config.addAllowedMethod("*"); diff --git a/src/main/java/com/teamjo/techeermarket/global/exception/ErrorCode.java b/src/main/java/com/teamjo/techeermarket/global/exception/ErrorCode.java index 7fad431..79d0d98 100644 --- a/src/main/java/com/teamjo/techeermarket/global/exception/ErrorCode.java +++ b/src/main/java/com/teamjo/techeermarket/global/exception/ErrorCode.java @@ -10,14 +10,18 @@ public enum ErrorCode { // 유저 USER_NOT_FOUND(HttpStatus.UNAUTHORIZED, "U001", "사용자를 찾을 수 없습니다."), - INVALIED_TOKEN_EXCEPTION (HttpStatus.UNAUTHORIZED, "U002", "토큰이 유효하지 않습니다."), + INVALID_TOKEN_EXCEPTION (HttpStatus.UNAUTHORIZED, "U002", "토큰이 유효하지 않습니다."), EMAIL_ALREADY_EXISTS(HttpStatus.BAD_REQUEST, "U003", "이미 존재하는 이메일입니다."), THERE_IS_NO_TOKEN (HttpStatus.BAD_REQUEST, "U004", "입력된 토큰이 없습니다."), REFRESH_TOKEN_IS_INVALID(HttpStatus.UNAUTHORIZED, "U005","리프레시 토큰이 유효하지 않습니다."), + PRODUCT_IS_NOT_YOURS(HttpStatus.UNAUTHORIZED, "U006","해당 상품이 사용자의 것이 아닙니다."), + // 상품 관련 + PRODUCT_NOT_FOUND (HttpStatus.NOT_FOUND, "P001", "상품을 찾을 수 없습니다."), CATEGORY_NOT_FOUND(HttpStatus.BAD_REQUEST, "P002", "카테고리를 찾을 수 없습니다."), + INVALID_PRODUCT_STATE (HttpStatus.BAD_REQUEST, "P003", "상품 상태 정보가 올바르지 않습니다."), // 이미지 관련 IMAGE_NOT_FOUND(HttpStatus.BAD_REQUEST, "I001", "유효하지 않은 이미지입니다."); diff --git a/src/main/java/com/teamjo/techeermarket/global/exception/product/InvalidProductStateException.java b/src/main/java/com/teamjo/techeermarket/global/exception/product/InvalidProductStateException.java new file mode 100644 index 0000000..ac1e840 --- /dev/null +++ b/src/main/java/com/teamjo/techeermarket/global/exception/product/InvalidProductStateException.java @@ -0,0 +1,10 @@ +package com.teamjo.techeermarket.global.exception.product; + +import com.teamjo.techeermarket.global.exception.CustomException; +import com.teamjo.techeermarket.global.exception.ErrorCode; + +public class InvalidProductStateException extends CustomException { + + public InvalidProductStateException() {super(ErrorCode.INVALID_PRODUCT_STATE); } + +} diff --git a/src/main/java/com/teamjo/techeermarket/global/exception/product/NotYourProductException.java b/src/main/java/com/teamjo/techeermarket/global/exception/product/NotYourProductException.java new file mode 100644 index 0000000..3b6fea8 --- /dev/null +++ b/src/main/java/com/teamjo/techeermarket/global/exception/product/NotYourProductException.java @@ -0,0 +1,8 @@ +package com.teamjo.techeermarket.global.exception.product; + +import com.teamjo.techeermarket.global.exception.CustomException; +import com.teamjo.techeermarket.global.exception.ErrorCode; + +public class NotYourProductException extends CustomException { + public NotYourProductException() {super(ErrorCode.PRODUCT_IS_NOT_YOURS); } +} diff --git a/src/main/java/com/teamjo/techeermarket/global/exception/product/ProductNotFoundException.java b/src/main/java/com/teamjo/techeermarket/global/exception/product/ProductNotFoundException.java new file mode 100644 index 0000000..34ad4e5 --- /dev/null +++ b/src/main/java/com/teamjo/techeermarket/global/exception/product/ProductNotFoundException.java @@ -0,0 +1,9 @@ +package com.teamjo.techeermarket.global.exception.product; + +import com.teamjo.techeermarket.global.exception.CustomException; +import com.teamjo.techeermarket.global.exception.ErrorCode; + +public class ProductNotFoundException extends CustomException { + + public ProductNotFoundException() {super(ErrorCode.PRODUCT_NOT_FOUND); } +} diff --git a/src/main/java/com/teamjo/techeermarket/global/exception/user/InvalidTokenException.java b/src/main/java/com/teamjo/techeermarket/global/exception/user/InvalidTokenException.java index e3e0b3f..4c6a79a 100644 --- a/src/main/java/com/teamjo/techeermarket/global/exception/user/InvalidTokenException.java +++ b/src/main/java/com/teamjo/techeermarket/global/exception/user/InvalidTokenException.java @@ -5,6 +5,6 @@ public class InvalidTokenException extends CustomException { public InvalidTokenException() { - super(ErrorCode.INVALIED_TOKEN_EXCEPTION); + super(ErrorCode.INVALID_TOKEN_EXCEPTION); } }