diff --git a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java index 67d5159b..2fe400c5 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java @@ -146,6 +146,9 @@ public Member getLogin() { public Boolean checkMember() { return getLogin().getRole().equals(RoleType.MEMBER); } + public Boolean admin() { + return getLogin().getRole().equals(RoleType.ADMIN); + } public Member getMember() { Member member = getLogin(); if (member.getRole().equals(RoleType.MEMBER)) { @@ -154,6 +157,17 @@ public Member getMember() { throw new MemberNotMatchException("허용된 권한이 아닙니다."); } + public Member getRollMember(){ + Member member=getLogin(); + if(member.getRole().equals(RoleType.MEMBER)){ + return member; + }else if(member.getRole().equals(RoleType.BRAND_ADMIN)){ + return member; + }else if(member.getRole().equals(RoleType.ADMIN)){ + return member; + } + throw new MemberNotMatchException("허용된 권한이 아닙니다."); + } public Member getBrandMember() { Member member = getLogin(); if (member.getRole().equals(RoleType.BRAND_ADMIN)) { @@ -161,6 +175,7 @@ public Member getBrandMember() { } throw new MemberNotMatchException("허용된 권한이 아닙니다."); } + public Boolean checkAdmin() { return !checkMember(); } diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index 0d399693..8e973a6d 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -19,7 +19,7 @@ @Getter @Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) -@Table(name = "index_member", +@Table(name = "member", indexes = {@Index(name = "index_member_email", columnList="email", unique = true)}) public class Member extends BaseTimeEntity { diff --git a/src/main/java/project/trendpick_pro/domain/member/repository/MemberRepository.java b/src/main/java/project/trendpick_pro/domain/member/repository/MemberRepository.java index 1e0612be..53b0532f 100644 --- a/src/main/java/project/trendpick_pro/domain/member/repository/MemberRepository.java +++ b/src/main/java/project/trendpick_pro/domain/member/repository/MemberRepository.java @@ -13,4 +13,6 @@ public interface MemberRepository extends JpaRepository { Optional findByUsername(String username); Optional findByEmail(String email); Page findAllByRoleAndRecentlyAccessDateBetween(RoleType role, LocalDateTime fromDate, LocalDateTime toDate, Pageable pageable); + + Member findByBrand(String brand); } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index ba6225e4..0033f3b8 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -161,7 +161,9 @@ public RsData manageAccount(Member member, String bank_name, String acco public Member findById(Long id) { return memberRepository.findById(id).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); } - + public Member findByBrandMember(String name){ + return memberRepository.findByBrand(name); + } public Optional findByUsername(String username) { return memberRepository.findByUsername(username); } @@ -184,7 +186,7 @@ public static class AddCashRsDataBody { @Transactional public RsData addCash(String brand, long price, Brand relEntity, CashLog.EvenType eventType) { - Member member=rq.getBrandMember(); + Member member=findByBrandMember(brand); if(!member.getBrand().equals(brand)){ return RsData.of("F-1","해당 브랜드와 관리자가 일치하지 않습니다."); } diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 375d99b7..1b84fe93 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -10,8 +10,8 @@ import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.orders.entity.Order; -import project.trendpick_pro.domain.orders.entity.dto.request.ProductOrderRequest; import project.trendpick_pro.domain.orders.entity.dto.request.CartToOrderRequest; +import project.trendpick_pro.domain.orders.entity.dto.request.ProductOrderRequest; import project.trendpick_pro.domain.orders.entity.dto.response.OrderDetailResponse; import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; import project.trendpick_pro.domain.orders.service.OrderService; diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 12ea9abf..aa61fe70 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -114,9 +114,8 @@ public RsData productToOrder(Member member, Long id, int quantity, String @Transactional @KafkaListener(topicPattern = "orders", groupId = "group_id") public void orderToOrder(@Payload String Id) throws JsonProcessingException { - // delay 2sec try { - Thread.sleep(500); + Thread.sleep(750); } catch (InterruptedException e) { e.printStackTrace(); } @@ -125,6 +124,9 @@ public void orderToOrder(@Payload String Id) throws JsonProcessingException { try { for (OrderItem orderItem : order.getOrderItems()) { orderItem.getProduct().getProductOption().decreaseStock(orderItem.getQuantity()); + if (orderItem.getProduct().getProductOption().getStock() == 0) { + productService.deleteCache(orderItem.getProduct().getProductOption()); + } } order.modifyStatus(OrderStatus.ORDERED); sendMessage("Success", order.getId(), member.getEmail()); diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 6c417340..a6483307 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -41,6 +41,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ExecutionException; @Slf4j @Controller @@ -85,7 +86,7 @@ public String registerProduct(@ModelAttribute("ProductRequest") ProductRequest p @PostMapping("/register") public String register(@ModelAttribute @Valid ProductRequest productRequest, @RequestParam("mainFile") MultipartFile mainFile, - @RequestParam("subFiles") List subFiles) throws IOException { + @RequestParam("subFiles") List subFiles) throws IOException, ExecutionException, InterruptedException { RsData id = productService.register(productRequest, mainFile, subFiles); return rq.redirectWithMsg("/trendpick/products/" + id.getData(), id.getMsg()); } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/product/ProductStatus.java b/src/main/java/project/trendpick_pro/domain/product/entity/product/ProductStatus.java new file mode 100644 index 00000000..3ed0cf0c --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/entity/product/ProductStatus.java @@ -0,0 +1,16 @@ +package project.trendpick_pro.domain.product.entity.product; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum ProductStatus { + + SALE("SALE"), + SOLD_OUT("SOLD_OUT"), + STOP("STOP"); + + private String text; + +} diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/product/dto/request/ProductSearchCond.java b/src/main/java/project/trendpick_pro/domain/product/entity/product/dto/request/ProductSearchCond.java index 4c2b0980..5c9c4ccd 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/product/dto/request/ProductSearchCond.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/product/dto/request/ProductSearchCond.java @@ -1,6 +1,7 @@ package project.trendpick_pro.domain.product.entity.product.dto.request; import lombok.Getter; +import project.trendpick_pro.domain.product.entity.product.ProductStatus; @Getter public class ProductSearchCond { @@ -8,13 +9,6 @@ public class ProductSearchCond { private String mainCategory; private String subCategory; private String keyword; - private Integer sortCode; - - public ProductSearchCond(String mainCategory, String subCategory, Integer sortCode) { - this.mainCategory = mainCategory; - this.subCategory = subCategory; - this.sortCode = sortCode; - } public ProductSearchCond(String mainCategory, String subCategory) { this.mainCategory = mainCategory; diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/product/dto/response/ProductListResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/product/dto/response/ProductListResponse.java index af491e98..6d0e6784 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/product/dto/response/ProductListResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/product/dto/response/ProductListResponse.java @@ -3,20 +3,20 @@ import com.querydsl.core.annotations.QueryProjection; import lombok.*; import project.trendpick_pro.domain.product.entity.product.Product; + +import java.io.Serializable; //import project.trendpick_pro.global.search.entity.ProductSearch; @Data @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class ProductListResponse { +public class ProductListResponse implements Serializable { private Long id; private String name; private String brand; private String mainFile; private int price; - private int discountRate; - private int discountedPrice; @Builder @@ -32,15 +32,25 @@ public ProductListResponse(Long id, String name, String brand, String mainFile, } public static ProductListResponse of(Product product) { - return ProductListResponse.builder() - .id(product.getId()) - .name(product.getName()) - .brand(product.getBrand().getName()) - .mainFile(product.getFile().getFileName()) - .price(product.getProductOption().getPrice()) - .discountedPrice(product.getDiscountedPrice()) - .discountRate(product.getDiscountRate()) - .build(); + if (product.getDiscountedPrice() == 0 && product.getDiscountRate() == 0) { + return ProductListResponse.builder() + .id(product.getId()) + .name(product.getName()) + .brand(product.getBrand().getName()) + .mainFile(product.getFile().getFileName()) + .price(product.getProductOption().getPrice()) + .build(); + } else { + return ProductListResponse.builder() + .id(product.getId()) + .name(product.getName()) + .brand(product.getBrand().getName()) + .mainFile(product.getFile().getFileName()) + .price(product.getProductOption().getPrice()) + .discountedPrice(product.getDiscountedPrice()) + .discountRate(product.getDiscountRate()) + .build(); + } } // public static ProductListResponse of(ProductSearch product) { diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/product/dto/response/ProductResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/product/dto/response/ProductResponse.java index fe578661..6be0ddfb 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/product/dto/response/ProductResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/product/dto/response/ProductResponse.java @@ -9,12 +9,13 @@ import project.trendpick_pro.domain.product.entity.product.Product; import project.trendpick_pro.domain.tags.tag.entity.Tag; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @Data @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class ProductResponse { +public class ProductResponse implements Serializable { private Long id; private String name; @@ -27,17 +28,14 @@ public class ProductResponse { private List sizes; private List colors; private int price; - private int stock; - private List tags = new ArrayList<>(); - + private List tags = new ArrayList<>(); private int discountRate; - private int discountedPrice; @Builder @QueryProjection public ProductResponse(Long id, String name, String mainCategory, String subCategory, String brand, String description, - String mainFile, List subFiles, List sizes, List colors, int price, int stock, List tags, double discountRate, int discountedPrice) { + String mainFile, List subFiles, List sizes, List colors, int price, List tags, double discountRate, int discountedPrice) { this.id = id; this.name = name; this.mainCategory = mainCategory; @@ -49,30 +47,45 @@ public ProductResponse(Long id, String name, String mainCategory, String subCate this.sizes = sizes; this.colors = colors; this.price = price; - this.stock = stock; this.tags = tags; this.discountRate = (int) discountRate; this.discountedPrice = discountedPrice; } public static ProductResponse of (Product product) { - return ProductResponse.builder() - .id(product.getId()) - .name(product.getName()) - .mainCategory(product.getMainCategory().getName()) - .subCategory(product.getSubCategory().getName()) - .brand(product.getBrand().getName()) - .description(product.getDescription()) - .mainFile(product.getFile().getFileName()) - .subFiles(subFiles(product.getFile().getChild())) - .sizes(product.getProductOption().getSizes()) - .colors(product.getProductOption().getColors()) - .price(product.getProductOption().getPrice()) - .stock(product.getProductOption().getStock()) - .tags(new ArrayList<>(product.getTags())) - .discountedPrice(product.getDiscountedPrice()) - .discountRate(product.getDiscountRate()) - .build(); + if (product.getDiscountedPrice() == 0 && product.getDiscountRate() == 0) { + return ProductResponse.builder() + .id(product.getId()) + .name(product.getName()) + .mainCategory(product.getMainCategory().getName()) + .subCategory(product.getSubCategory().getName()) + .brand(product.getBrand().getName()) + .description(product.getDescription()) + .mainFile(product.getFile().getFileName()) + .subFiles(subFiles(product.getFile().getChild())) + .sizes(product.getProductOption().getSizes()) + .colors(product.getProductOption().getColors()) + .price(product.getProductOption().getPrice()) + .tags(product.getTags().stream().map(Tag::getName).toList()) + .build(); + } else { + return ProductResponse.builder() + .id(product.getId()) + .name(product.getName()) + .mainCategory(product.getMainCategory().getName()) + .subCategory(product.getSubCategory().getName()) + .brand(product.getBrand().getName()) + .description(product.getDescription()) + .mainFile(product.getFile().getFileName()) + .subFiles(subFiles(product.getFile().getChild())) + .sizes(product.getProductOption().getSizes()) + .colors(product.getProductOption().getColors()) + .price(product.getProductOption().getPrice()) + .tags(product.getTags().stream().map(Tag::getName).toList()) + .discountedPrice(product.getDiscountedPrice()) + .discountRate(product.getDiscountRate()) + .build(); + } } private static List subFiles(List subFiles) { diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/productOption/ProductOption.java b/src/main/java/project/trendpick_pro/domain/product/entity/productOption/ProductOption.java index 4f9137c3..f51c4ff9 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/productOption/ProductOption.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/productOption/ProductOption.java @@ -5,25 +5,27 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.product.entity.product.ProductStatus; import project.trendpick_pro.domain.product.entity.productOption.dto.ProductOptionSaveRequest; import project.trendpick_pro.domain.product.exception.ProductStockOutException; +import java.io.Serializable; import java.util.List; @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class ProductOption { +public class ProductOption implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ElementCollection + @ElementCollection(fetch = FetchType.EAGER) @CollectionTable(name = "product_option_sizes", joinColumns = @JoinColumn(name = "product_option_id")) @Column(name = "size") private List sizes; - @ElementCollection + @ElementCollection(fetch = FetchType.EAGER) @CollectionTable(name = "product_option_colors", joinColumns = @JoinColumn(name = "product_option_id")) @Column(name = "color") private List colors; @@ -34,8 +36,15 @@ public class ProductOption { @Column(name = "price", nullable = false) private int price; + @Enumerated(EnumType.STRING) + private ProductStatus status; + + public void connectStatus(ProductStatus status){ + this.status = status; + } + @Builder - public ProductOption(List size, List color, int stock, int price) { + private ProductOption(List size, List color, int stock, int price) { this.sizes = size; this.colors = color; this.stock = stock; diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/productOption/dto/ProductOptionSaveRequest.java b/src/main/java/project/trendpick_pro/domain/product/entity/productOption/dto/ProductOptionSaveRequest.java index 0fb0cbe7..d30991c3 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/productOption/dto/ProductOptionSaveRequest.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/productOption/dto/ProductOptionSaveRequest.java @@ -24,20 +24,24 @@ public class ProductOptionSaveRequest { @Min(value = 1, message = "가격을 입력해주세요.(1원 이상부터 입력할 수 있습니다.)") private int price; + private String status; + @Builder - public ProductOptionSaveRequest(List sizes, List colors, int stock, int price) { + public ProductOptionSaveRequest(List sizes, List colors, int stock, int price, String status) { this.sizes = sizes; this.colors = colors; this.stock = stock; this.price = price; + this.status = status; } - public static ProductOptionSaveRequest of (List sizes, List colors, int stock, int price) { + public static ProductOptionSaveRequest of (List sizes, List colors, int stock, int price, String status) { return ProductOptionSaveRequest.builder() .sizes(sizes) .colors(colors) .stock(stock) .price(price) + .status(status) .build(); } } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index da158f18..01949e80 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -9,6 +9,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.support.PageableExecutionUtils; +import project.trendpick_pro.domain.product.entity.product.ProductStatus; import project.trendpick_pro.domain.product.entity.product.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.product.dto.response.*; import project.trendpick_pro.domain.product.entity.productOption.QProductOption; @@ -52,8 +53,8 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag .leftJoin(product.productOption, productOption) .leftJoin(product.file, commonFile) .where( - mainCategoryEq(cond) - .and(subCategoryEq(cond)) + mainCategoryEq(cond), + subCategoryEq(cond) ) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 0c05f172..b5abdaff 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -1,10 +1,11 @@ package project.trendpick_pro.domain.product.service; - import com.amazonaws.services.s3.AmazonS3; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; @@ -25,6 +26,7 @@ import project.trendpick_pro.domain.member.entity.RoleType; import project.trendpick_pro.domain.product.entity.dto.ProductRequest; import project.trendpick_pro.domain.product.entity.product.Product; +import project.trendpick_pro.domain.product.entity.product.ProductStatus; import project.trendpick_pro.domain.product.entity.product.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.product.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.product.dto.response.*; @@ -42,10 +44,11 @@ import java.io.IOException; import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; @Slf4j @Service -@Transactional(readOnly = true) @RequiredArgsConstructor public class ProductService { @@ -71,7 +74,7 @@ public class ProductService { private String filePath; @Transactional - public RsData register(ProductRequest request, MultipartFile requestMainFile, List requestSubFiles) throws IOException { + public RsData register(ProductRequest request, MultipartFile requestMainFile, List requestSubFiles) throws IOException, ExecutionException, InterruptedException { rq.checkAdmin(); @@ -90,11 +93,18 @@ public RsData register(ProductRequest request, MultipartFile requestMainFi tags.add(new Tag(tagName)); } - MainCategory mainCategory = mainCategoryService.findByName(productSaveRequest.getMainCategory()); - SubCategory subCategory = subCategoryService.findByName(productSaveRequest.getSubCategory()); - Brand brand = brandService.findByName(productSaveRequest.getBrand()); + CompletableFuture mainCategoryFuture = CompletableFuture.supplyAsync(() -> mainCategoryService.findByName(productSaveRequest.getMainCategory())); + CompletableFuture subCategoryFuture = CompletableFuture.supplyAsync(() -> subCategoryService.findByName(productSaveRequest.getSubCategory())); + CompletableFuture brandFuture = CompletableFuture.supplyAsync(() -> brandService.findByName(productSaveRequest.getBrand())); + + CompletableFuture.allOf(mainCategoryFuture, subCategoryFuture, brandFuture).join(); + + MainCategory mainCategory = mainCategoryFuture.get(); + SubCategory subCategory = subCategoryFuture.get(); + Brand brand = brandFuture.get(); ProductOption productOption = ProductOption.of(optionSaveRequest); + productOption.connectStatus(ProductStatus.SALE); Product product = Product.of(productSaveRequest, mainCategory, subCategory, brand, mainFile, productOption); product.addTag(tags); @@ -144,7 +154,7 @@ public void delete(Long productId) { productRepository.delete(product); } - @Transactional + @Cacheable(value = "product", key = "#productId") public ProductResponse getProduct(Long productId) { Product product = productRepository.findById(productId).orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품입니다.")); @@ -154,10 +164,12 @@ public ProductResponse getProduct(Long productId) { updateFavoriteTag(product); } } + return ProductResponse.of(product); } - public ProductListResponse getProducts(Long productId) { + @Transactional(readOnly = true) + private ProductListResponse getProducts(Long productId) { Product product = productRepository.findById(productId).orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품입니다.")); return ProductListResponse.of(product); } @@ -168,6 +180,13 @@ private void updateFavoriteTag(Product product) { favoriteTagService.updateTag(member, product, TagType.SHOW); } + @Transactional + @CacheEvict(value = "product", key = "#productId") + public void deleteCache(ProductOption productOption) { + productOption.connectStatus(ProductStatus.SOLD_OUT); + } + + @Transactional(readOnly = true) public Page getProducts(int offset, String mainCategory, String subCategory) { ProductSearchCond cond = new ProductSearchCond(mainCategory, subCategory); @@ -185,6 +204,7 @@ public Page getProducts(int offset, String mainCategory, St return new PageImpl<>(list, pageable, listResponses.getTotalElements()); } + @Transactional(readOnly = true) public Page findAllByKeyword(String keyword, int offset) { ProductSearchCond cond = new ProductSearchCond(keyword); @@ -202,12 +222,14 @@ public Page findAllByKeyword(String keyword, int offset) { return new PageImpl<>(list, pageable, listResponses.getTotalElements()); } + @Transactional(readOnly = true) public Page getAllProducts(Pageable pageable) { pageable = PageRequest.of(pageable.getPageNumber(), 18); Page products = productRepository.findAll(pageable); return products.map(this::convertToProductListResponse); } + @Transactional(readOnly = true) public List getRecommendProduct(Member member) { List tags = productRepository.findRecommendProduct(member.getUsername()); @@ -288,10 +310,12 @@ private ProductListResponse convertToProductListResponse(Product product) { ); } + @Transactional(readOnly = true) public Product findById(Long id) { return productRepository.findById(id).orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품입니다.")); } + @Transactional(readOnly = true) public Product findByIdWithBrand(Long productId) { return productRepository.findByIdWithBrand(productId); } diff --git a/src/main/java/project/trendpick_pro/domain/rebate/controller/AdmRebateController.java b/src/main/java/project/trendpick_pro/domain/rebate/controller/AdmRebateController.java index 1181d089..5fc55309 100644 --- a/src/main/java/project/trendpick_pro/domain/rebate/controller/AdmRebateController.java +++ b/src/main/java/project/trendpick_pro/domain/rebate/controller/AdmRebateController.java @@ -29,9 +29,13 @@ public class AdmRebateController { private final RebateService rebateService; private final Rq rq; + @GetMapping("/makeData") @PreAuthorize("hasAuthority({'BRAND_ADMIN'})") public String showMakeData() { + if(!rq.getRollMember().getRole().getValue().equals("BRAND_ADMIN")){ + return rq.historyBack("브랜드 관리자만 접근할 수 있습니다."); + } return "trendpick/admin/makeData"; } @@ -49,6 +53,10 @@ public String makeData(String yearMonth) { @GetMapping("/rebateOrderItemList") @PreAuthorize("hasAuthority({'BRAND_ADMIN'})") public String showRebateOrderItemList(String yearMonth, Model model) { + if(!rq.getRollMember().getRole().getValue().equals("BRAND_ADMIN")){ + return rq.historyBack("브랜드 관리자만 접근할 수 있습니다."); + } + if (!StringUtils.hasText(yearMonth)) { yearMonth = Ut.date.getCurrentYearMonth(); } @@ -75,7 +83,6 @@ public String rebateOne(@PathVariable long orderItemId, HttpServletRequest req) @PostMapping("/rebate") @PreAuthorize("hasAuthority({'BRAND_ADMIN'})") public String rebate(String ids, HttpServletRequest req) { - String[] idsArr = ids.split(","); Arrays.stream(idsArr) diff --git a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java index c2a054e0..efd0abc0 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java @@ -2,6 +2,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; @@ -22,7 +24,6 @@ @Slf4j @Service -@Transactional(readOnly = true) @RequiredArgsConstructor public class RecommendService { @@ -31,6 +32,7 @@ public class RecommendService { private final MemberRepository memberRepository; @Transactional + @CacheEvict(value = "recommendedProducts", allEntries = true) public void select(String username){ Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); @@ -46,6 +48,8 @@ public void select(String username){ } } + @Transactional(readOnly = true) + @Cacheable(value = "recommendedProducts", key = "#member.username + '_' + #offset") public Page getFindAll(Member member, int offset){ PageRequest pageable = PageRequest.of(offset, 18); Page listResponses = recommendRepository.findAllByMemberName(member.getUsername(), pageable); diff --git a/src/main/java/project/trendpick_pro/domain/withdraw/controller/AdmWithdrawController.java b/src/main/java/project/trendpick_pro/domain/withdraw/controller/AdmWithdrawController.java index be2ed8e7..837d7f40 100644 --- a/src/main/java/project/trendpick_pro/domain/withdraw/controller/AdmWithdrawController.java +++ b/src/main/java/project/trendpick_pro/domain/withdraw/controller/AdmWithdrawController.java @@ -23,18 +23,21 @@ public class AdmWithdrawController { private final WithdrawService withdrawService; private final Rq rq; - @PreAuthorize("hasAuthority({'BRAND_ADMIN'})") + @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") @GetMapping("/withDrawList") public String showApplyList(Model model) { - Member member=rq.getBrandMember(); - System.out.println(member.getId()+"!!"); - List withdrawApplies = withdrawService.findByWithdrawApplyId(member.getId()); - + Member member=rq.getRollMember(); + List withdrawApplies; + if(member.getRole().getValue().equals("ADMIN")) { + withdrawApplies = withdrawService.findAll(); + }else{ + withdrawApplies=withdrawService.findByWithdrawApplyId(member.getId()); + } model.addAttribute("withdrawApplies", withdrawApplies); return "trendpick/admin/withDrawList"; } - @PreAuthorize("hasAuthority({'BRAND_ADMIN'})") + @PreAuthorize("hasAuthority({'ADMIN'})") @PostMapping("/{withdrawApplyId}") public String applyDone(@PathVariable Long withdrawApplyId) { RsData withdrawRsData = withdrawService.withdraw(withdrawApplyId); @@ -42,7 +45,7 @@ public String applyDone(@PathVariable Long withdrawApplyId) { return rq.redirectWithMsg("/trendpick/admin/withDrawList", withdrawRsData); } - @PreAuthorize("hasAuthority({'BRAND_ADMIN'})") + @PreAuthorize("hasAuthority({'ADMIN'})") @PostMapping("/{withdrawApplyId}/cancel") public String cancel(@PathVariable Long withdrawApplyId) { RsData withdrawRsData = withdrawService.cancelApply(withdrawApplyId); diff --git a/src/main/java/project/trendpick_pro/domain/withdraw/controller/WithdrawController.java b/src/main/java/project/trendpick_pro/domain/withdraw/controller/WithdrawController.java index 06a209b8..fb93280a 100644 --- a/src/main/java/project/trendpick_pro/domain/withdraw/controller/WithdrawController.java +++ b/src/main/java/project/trendpick_pro/domain/withdraw/controller/WithdrawController.java @@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import project.trendpick_pro.domain.common.base.rq.Rq; +import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.service.MemberService; import project.trendpick_pro.domain.withdraw.entity.WithdrawApply; import project.trendpick_pro.domain.withdraw.entity.dto.WithDrawApplyForm; @@ -27,6 +28,9 @@ public class WithdrawController { @GetMapping("/withDraw") public String showApply(Model model) { + if(!rq.getRollMember().getRole().getValue().equals("BRAND_ADMIN")){ + return rq.historyBack("브랜드 관리자만 접근할 수 있습니다."); + } long actorRestCash = memberService.getRestCash(rq.getBrandMember()); model.addAttribute("actorRestCash", actorRestCash); diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index fa41456f..cdeb8d30 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -30,6 +30,7 @@ import project.trendpick_pro.domain.member.entity.form.JoinForm; import project.trendpick_pro.domain.member.service.MemberService; import project.trendpick_pro.domain.product.entity.product.Product; +import project.trendpick_pro.domain.product.entity.product.ProductStatus; import project.trendpick_pro.domain.product.entity.productOption.ProductOption; import project.trendpick_pro.domain.product.entity.productOption.dto.ProductOptionSaveRequest; import project.trendpick_pro.domain.product.repository.ProductRepository; @@ -116,10 +117,10 @@ public void run(String... args) { accessKeyMap.put("secretKey", secretKey); accessKeyMap.put("bucket", bucket); - int memberCount = 10; - int productCount = 100; - int reviewCount = 100; - int couponCount = 50; + int memberCount = 100; + int productCount = 5000; + int reviewCount = 0; + int couponCount = 0; String brandName = "polo"; saveMembers(memberCount, tagNameService, memberService, recommendService); @@ -291,7 +292,7 @@ private static void saveProducts(int count, Map keys, MainCatego default -> inputSizes.add("FREE"); } - ProductOptionSaveRequest request = ProductOptionSaveRequest.of(inputSizes, selectedColors, stockRandom, priceRandom); + ProductOptionSaveRequest request = ProductOptionSaveRequest.of(inputSizes, selectedColors, stockRandom, priceRandom, ProductStatus.SALE.getText()); ProductOption productOption = ProductOption.of(request); Product product = Product diff --git a/src/main/java/project/trendpick_pro/global/jmeter/JmeterController.java b/src/main/java/project/trendpick_pro/global/jmeter/JmeterController.java index 114e2d6a..fbecc805 100644 --- a/src/main/java/project/trendpick_pro/global/jmeter/JmeterController.java +++ b/src/main/java/project/trendpick_pro/global/jmeter/JmeterController.java @@ -11,8 +11,12 @@ import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.dto.MemberInfoDto; +import project.trendpick_pro.domain.product.entity.dto.ProductRequest; +import project.trendpick_pro.domain.product.entity.product.Product; import project.trendpick_pro.domain.product.entity.product.dto.request.ProductSaveRequest; +import project.trendpick_pro.domain.product.entity.productOption.dto.ProductOptionSaveRequest; import project.trendpick_pro.domain.product.service.ProductService; +import project.trendpick_pro.domain.tags.tag.entity.Tag; import java.io.IOException; import java.util.List; @@ -55,13 +59,22 @@ public ResponseEntity getMemberInfo() { // return orderService.showOrderItems(member, result.getData()).getData(); // } -// @PostMapping("/edit") -// public void modifyProduct(@RequestParam("productId") Long productId, -// @RequestParam("mainFile") MultipartFile mainFile, -// @RequestParam("subFile") List subFiles) throws IOException { -// log.info("productId : {}", productId); -// ProductSaveRequest productSaveRequest = new ProductSaveRequest("제목", "내용", "상의", "반소매티셔츠", "나이키", 50, 1000, List.of("오버핏청바지", "시티보이룩")); -// Long id = productService.modify(productId, productSaveRequest, mainFile, subFiles).getData(); -// log.info("id : {}", id); -// } + @PostMapping("/edit") + public void modifyProduct(@RequestParam("productId") Long productId, + @RequestParam("mainFile") MultipartFile mainFile, + @RequestParam("subFile") List subFiles) throws IOException { + Product product = productService.findById(productId); + + ProductSaveRequest productSaveRequest = new ProductSaveRequest( + product.getName(), product.getDescription(), + product.getMainCategory().getName(), product.getSubCategory().getName(), product.getBrand().getName(), + product.getTags().stream().map(Tag::getName).toList()); + + ProductOptionSaveRequest productOptionSaveRequest = new ProductOptionSaveRequest( + product.getProductOption().getSizes(), product.getProductOption().getColors(), + product.getProductOption().getStock(), product.getProductOption().getPrice(), product.getProductOption().getStatus().getText()); + + ProductRequest productRequest = new ProductRequest(productSaveRequest, productOptionSaveRequest); + productService.modify(productId, productRequest, mainFile, subFiles); + } } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 5e0b350d..b4f5d52b 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -1,5 +1,3 @@ -server: - port: 80 spring: datasource: driver-class-name: ${db.driver} @@ -15,11 +13,11 @@ spring: use_sql_comments: true data: redis: - host: ${redis.host} + host: ${redis.devHost} kafka: - bootstrap-servers: localhost:9092 + bootstrap-servers: localhost:${custom.kafka.devPort} logging.level: org: - hibernate.SQL: debug + hibernate.SQL: error diff --git a/src/main/resources/application-ela.yml b/src/main/resources/application-ela.yml index 70b22e6a..0dbce6df 100644 --- a/src/main/resources/application-ela.yml +++ b/src/main/resources/application-ela.yml @@ -1,24 +1,9 @@ -<<<<<<< HEAD -#spring: -# data: -# elasticsearch: -# client: -# rest: -# uris: ${elasticKey.uris} -# cluster-nodes: ${elasticKey.uris} -# username: ${elasticKey.username} -# password: ${elasticKey.password} -#logging.level: -# org: -# elasticsearch: debug -#======= -#spring: -# data: -# elasticsearch: -# client: -# rest: -# uris: ${elasticKey.uris} -# cluster-nodes: ${elasticKey.uris} -# username: ${elasticKey.username} -# password: ${elasticKey.password} -#>>>>>>> 0efd4fab9e29fd0dc15b3e35217a9546d15541e0 +spring: + data: + elasticsearch: + client: + rest: + uris: ${elasticKey.uris} + cluster-nodes: ${elasticKey.uris} + username: ${elasticKey.username} + password: ${elasticKey.password} \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/admin/withDrawList.html b/src/main/resources/templates/trendpick/admin/withDrawList.html index 5c098e74..4003c949 100644 --- a/src/main/resources/templates/trendpick/admin/withDrawList.html +++ b/src/main/resources/templates/trendpick/admin/withDrawList.html @@ -47,14 +47,14 @@

- 출금 - 취소 diff --git a/src/main/resources/templates/trendpick/orders/order-form.html b/src/main/resources/templates/trendpick/orders/order-form.html index 3b9e568a..e97447a8 100644 --- a/src/main/resources/templates/trendpick/orders/order-form.html +++ b/src/main/resources/templates/trendpick/orders/order-form.html @@ -171,6 +171,8 @@

결제 정보

- - - - - -
- -
- -
-

- 주문을 처리 중입니다. -

-

잠시만 기다려 주세요...

-
- - -
- -
- - - - - diff --git a/src/main/resources/templates/trendpick/products/detailpage.html b/src/main/resources/templates/trendpick/products/detailpage.html index a6b21b53..a221e777 100644 --- a/src/main/resources/templates/trendpick/products/detailpage.html +++ b/src/main/resources/templates/trendpick/products/detailpage.html @@ -34,7 +34,7 @@
- +

@@ -76,7 +76,7 @@

-
@@ -372,7 +372,7 @@

문의 일자

const socket = new SockJS('/websocket'); const stompClient = Stomp.over(socket); - stompClient.connect({}, function (frame) { + stompClient.connect({}, function () { stompClient.subscribe('/user/topic/standByOrder', function (message) { const data = JSON.parse(message.body); if (data.message === 'Success') { diff --git a/src/main/resources/templates/trendpick/products/modify.html b/src/main/resources/templates/trendpick/products/modify.html index 320f3814..27be1514 100644 --- a/src/main/resources/templates/trendpick/products/modify.html +++ b/src/main/resources/templates/trendpick/products/modify.html @@ -328,6 +328,9 @@

Modify My Product

+


+ +

diff --git a/src/main/resources/templates/trendpick/usr/layout/layout.html b/src/main/resources/templates/trendpick/usr/layout/layout.html index 0d9d058f..49c9558e 100644 --- a/src/main/resources/templates/trendpick/usr/layout/layout.html +++ b/src/main/resources/templates/trendpick/usr/layout/layout.html @@ -178,7 +178,7 @@

TrendPick

  • - 출금목록 + 출금신청목록