diff --git a/build.gradle b/build.gradle index e7c6d52..f3672aa 100644 --- a/build.gradle +++ b/build.gradle @@ -42,6 +42,7 @@ dependencies { implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.postgresql:postgresql:42.7.2' + implementation group: 'org.zeroturnaround', name: 'zt-exec', version: '1.12' } tasks.named('test') { diff --git a/src/main/java/Graduated/Task/C2C/C2CApplication.java b/src/main/java/Graduated/Task/C2C/C2CApplication.java index e2274ba..6f41ae9 100644 --- a/src/main/java/Graduated/Task/C2C/C2CApplication.java +++ b/src/main/java/Graduated/Task/C2C/C2CApplication.java @@ -10,4 +10,6 @@ public static void main(String[] args) { SpringApplication.run(C2CApplication.class, args); } + + } diff --git a/src/main/java/Graduated/Task/C2C/Category/CategoryService.java b/src/main/java/Graduated/Task/C2C/Category/CategoryService.java deleted file mode 100644 index fa0c904..0000000 --- a/src/main/java/Graduated/Task/C2C/Category/CategoryService.java +++ /dev/null @@ -1,13 +0,0 @@ -package Graduated.Task.C2C.Category; - -import Graduated.Task.C2C.Category.Repository.CategoryRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class CategoryService { - private final CategoryRepository categoryRepository; -} diff --git a/src/main/java/Graduated/Task/C2C/Category/Dto/categoryDto.java b/src/main/java/Graduated/Task/C2C/Category/Dto/categoryDto.java new file mode 100644 index 0000000..1b70b58 --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/Category/Dto/categoryDto.java @@ -0,0 +1,11 @@ +package Graduated.Task.C2C.Category.Dto; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class categoryDto { + private Long categoryId; + private String categoryName; +} diff --git a/src/main/java/Graduated/Task/C2C/Category/Dto/categoryPriceDto.java b/src/main/java/Graduated/Task/C2C/Category/Dto/categoryPriceDto.java new file mode 100644 index 0000000..0c0ed2d --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/Category/Dto/categoryPriceDto.java @@ -0,0 +1,11 @@ +package Graduated.Task.C2C.Category.Dto; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class categoryPriceDto { + private int recommendedMinPrice; + private int recommendedMaxPrice; +} diff --git a/src/main/java/Graduated/Task/C2C/Category/Dto/priceFindDto.java b/src/main/java/Graduated/Task/C2C/Category/Dto/priceFindDto.java new file mode 100644 index 0000000..9f01caa --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/Category/Dto/priceFindDto.java @@ -0,0 +1,12 @@ +package Graduated.Task.C2C.Category.Dto; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class priceFindDto { + + private String category; + private int itemState; +} diff --git a/src/main/java/Graduated/Task/C2C/Category/Entity/Category.java b/src/main/java/Graduated/Task/C2C/Category/Entity/Category.java index 1f1a515..f360686 100644 --- a/src/main/java/Graduated/Task/C2C/Category/Entity/Category.java +++ b/src/main/java/Graduated/Task/C2C/Category/Entity/Category.java @@ -8,19 +8,36 @@ import lombok.NoArgsConstructor; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; @Entity @Getter -@NoArgsConstructor(access = AccessLevel.PUBLIC) +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Category extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="categoryNo") private Long No; - private int minPrice; - private int maxPrice; @OneToMany(mappedBy = "category") private List item = new ArrayList<>(); + + private String name; + + @OneToMany(mappedBy = "category") + private List categoryPrices = new ArrayList<>(); + + private int itemCount; + + + public void plusCount(){ + this.itemCount++; + } + + public Category(String name, int itemCount) { + this.name = name; + this.itemCount = itemCount; + } } diff --git a/src/main/java/Graduated/Task/C2C/Category/Entity/categoryPrice.java b/src/main/java/Graduated/Task/C2C/Category/Entity/categoryPrice.java new file mode 100644 index 0000000..bad1762 --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/Category/Entity/categoryPrice.java @@ -0,0 +1,22 @@ +package Graduated.Task.C2C.Category.Entity; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class categoryPrice { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private int status; + private int maxPrice; + private int minPrice; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="categoryNo") + private Category category; +} diff --git a/src/main/java/Graduated/Task/C2C/Category/Repository/CategoryRepository.java b/src/main/java/Graduated/Task/C2C/Category/Repository/CategoryRepository.java index 75b9ddb..f0b1d66 100644 --- a/src/main/java/Graduated/Task/C2C/Category/Repository/CategoryRepository.java +++ b/src/main/java/Graduated/Task/C2C/Category/Repository/CategoryRepository.java @@ -2,6 +2,22 @@ import Graduated.Task.C2C.Category.Entity.Category; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; public interface CategoryRepository extends JpaRepository,CategoryRepositoryCustom { -} + + @Transactional + @Modifying + @Query(value = "INSERT INTO category_price (max_price, min_price, status, category_no, id)" + + "VALUES " + + " (879097, 586064, 5, 1, 11)," + + " (814445, 542963, 4, 1, 12)," + + " (765314, 510209, 3, 1, 13)," + + " (760524, 507016, 2, 1, 14)," + + " (584241, 389494, 1, 1, 15)", nativeQuery = true) + int findAllPost(); +} \ No newline at end of file diff --git a/src/main/java/Graduated/Task/C2C/Category/Repository/CategoryRepositoryCustom.java b/src/main/java/Graduated/Task/C2C/Category/Repository/CategoryRepositoryCustom.java index 52b5f30..db1ffbb 100644 --- a/src/main/java/Graduated/Task/C2C/Category/Repository/CategoryRepositoryCustom.java +++ b/src/main/java/Graduated/Task/C2C/Category/Repository/CategoryRepositoryCustom.java @@ -1,4 +1,14 @@ package Graduated.Task.C2C.Category.Repository; +import Graduated.Task.C2C.Category.Entity.Category; +import Graduated.Task.C2C.Category.Entity.categoryPrice; +import Graduated.Task.C2C.Item.Entity.Item; + +import java.util.List; +import java.util.Optional; + public interface CategoryRepositoryCustom { + Optional findCategoryPrice(Long categoryNo, int state); + Optional findByCategoryName(String categoryName); + Optional findCategoryPriceByName(String name,int state); } diff --git a/src/main/java/Graduated/Task/C2C/Category/Repository/CategoryRepositoryImpl.java b/src/main/java/Graduated/Task/C2C/Category/Repository/CategoryRepositoryImpl.java index e9e4984..6354d8f 100644 --- a/src/main/java/Graduated/Task/C2C/Category/Repository/CategoryRepositoryImpl.java +++ b/src/main/java/Graduated/Task/C2C/Category/Repository/CategoryRepositoryImpl.java @@ -1,12 +1,22 @@ package Graduated.Task.C2C.Category.Repository; import Graduated.Task.C2C.Category.Entity.Category; +import Graduated.Task.C2C.Category.Entity.QCategory; +import Graduated.Task.C2C.Category.Entity.QcategoryPrice; +import Graduated.Task.C2C.Category.Entity.categoryPrice; +import Graduated.Task.C2C.Item.Entity.Item; import Graduated.Task.C2C.core.Querydsl4RepositorySupport; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; import lombok.Getter; import org.springframework.stereotype.Repository; +import java.util.List; +import java.util.Optional; + +import static Graduated.Task.C2C.Category.Entity.QCategory.category; +import static Graduated.Task.C2C.Item.Entity.QItem.item; + @Repository @Getter public class CategoryRepositoryImpl extends Querydsl4RepositorySupport implements CategoryRepositoryCustom { @@ -15,4 +25,20 @@ public CategoryRepositoryImpl(EntityManager em) { super(Category.class); this.jpaQueryFactory = new JPAQueryFactory(em); } + public Optional findCategoryPrice(Long categoryNo,int state){ + return Optional.ofNullable(selectFrom(QcategoryPrice.categoryPrice) + .where(QcategoryPrice.categoryPrice.category.No.eq(categoryNo), QcategoryPrice.categoryPrice.status.eq(state)) + .join(QcategoryPrice.categoryPrice.category).fetchJoin() + .fetchOne()); + } + public Optional findCategoryPriceByName(String category,int state){ + return Optional.ofNullable(selectFrom(QcategoryPrice.categoryPrice) + .where(QcategoryPrice.categoryPrice.category.name.eq(category), QcategoryPrice.categoryPrice.status.eq(state)) + .join(QcategoryPrice.categoryPrice.category).fetchJoin() + .fetchOne()); + } + public Optional findByCategoryName(String categoryName){ + return Optional.ofNullable(selectFrom(category).where(category.name.eq(categoryName)).fetchOne()); + } + } diff --git a/src/main/java/Graduated/Task/C2C/Category/Service/CategoryService.java b/src/main/java/Graduated/Task/C2C/Category/Service/CategoryService.java new file mode 100644 index 0000000..6159d13 --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/Category/Service/CategoryService.java @@ -0,0 +1,33 @@ +package Graduated.Task.C2C.Category.Service; + +import Graduated.Task.C2C.Category.Dto.categoryDto; +import Graduated.Task.C2C.Category.Dto.categoryPriceDto; +import Graduated.Task.C2C.Category.Entity.Category; +import Graduated.Task.C2C.Category.Entity.categoryPrice; +import Graduated.Task.C2C.Category.Repository.CategoryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class CategoryService { + private final CategoryRepository categoryRepository; + + + public List findCategory(){ + return categoryRepository.findAll().stream().map(this::getCategoryDto).toList(); + } + + private categoryDto getCategoryDto(Category category) { + return new categoryDto(category.getNo(), category.getName()); + } + public categoryPriceDto findCategoryPrice(String name, int status){ + categoryPrice categoryPriceByName = categoryRepository.findCategoryPriceByName(name, status).orElseThrow(() -> new NullPointerException("존재하지 않는 카테고리입니다")); + return new categoryPriceDto(categoryPriceByName.getMinPrice(),categoryPriceByName.getMaxPrice()); + } + +} diff --git a/src/main/java/Graduated/Task/C2C/Category/categoryController.java b/src/main/java/Graduated/Task/C2C/Category/categoryController.java new file mode 100644 index 0000000..4045c09 --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/Category/categoryController.java @@ -0,0 +1,32 @@ +package Graduated.Task.C2C.Category; + +import Graduated.Task.C2C.Category.Dto.categoryPriceDto; +import Graduated.Task.C2C.Category.Dto.priceFindDto; +import Graduated.Task.C2C.Category.Service.CategoryService; +import Graduated.Task.C2C.Item.Dto.ItemDto; +import Graduated.Task.C2C.Item.Service.ItemService; +import Graduated.Task.C2C.User.responseDto.TokenDto; +import Graduated.Task.C2C.core.Message; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +public class categoryController { + + private final CategoryService categoryService; + @PostMapping("/recommended-price") + public ResponseEntity getCategoryPrice(@RequestBody priceFindDto priceFindDto){ + categoryPriceDto categoryPrice = categoryService.findCategoryPrice(priceFindDto.getCategory(), priceFindDto.getItemState()); + Message message = Message.of(200, categoryPrice); + return new ResponseEntity<>(message, HttpStatus.OK); + + } + + + +} diff --git a/src/main/java/Graduated/Task/C2C/Item/Controller/itemController.java b/src/main/java/Graduated/Task/C2C/Item/Controller/itemController.java new file mode 100644 index 0000000..1d37313 --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/Item/Controller/itemController.java @@ -0,0 +1,142 @@ +package Graduated.Task.C2C.Item.Controller; + +import Graduated.Task.C2C.Item.Dto.ItemDetailDto; +import Graduated.Task.C2C.Item.Dto.ItemDto; +import Graduated.Task.C2C.Item.Dto.itemRequestDto; +import Graduated.Task.C2C.Item.Dto.joinItemDto; +import Graduated.Task.C2C.Item.Service.ItemService; +import Graduated.Task.C2C.core.ErrorMessage; +import Graduated.Task.C2C.core.JwtTokenUtil; +import Graduated.Task.C2C.core.Message; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.NoSuchElementException; + +@RestController +@RequiredArgsConstructor +public class itemController { + private final ItemService itemService; + private final JwtTokenUtil jwtTokenUtil; + @GetMapping(value = {"/api/{categoryNo}/{page}"}) + public ResponseEntity CategoryItem(@PathVariable("categoryNo") Long categoryNo, @PathVariable("page") int page) { + List itemDtos = itemService.viewCategoryItem(categoryNo, page, 10); + Message> message = Message.of(200, itemDtos); + return new ResponseEntity<>(message, HttpStatus.OK); + } + + @GetMapping(value = {"/search/{item}/{page}"}) + public ResponseEntity SearchItem(@PathVariable("item") String word,@PathVariable("page") Integer page){ + if(page==null) { + page = 1; + } + List itemDtos = itemService.searchItem(word, page, 10); + Message> message = Message.of(200, itemDtos); + return new ResponseEntity<>(message, HttpStatus.OK); + } + + @GetMapping("/itemInfo/{ItemNo}") + public ResponseEntity itemDetail(@PathVariable("ItemNo") Long itemNo){ + try { + ItemDetailDto itemDetailDto = itemService.itemInformation(itemNo); + Message itemDetailDtoMessage = Message.of(200, itemDetailDto); + return new ResponseEntity<>(itemDetailDtoMessage,HttpStatus.OK); + } + catch (NullPointerException e){ + ErrorMessage errorMessage = ErrorMessage.of(404, e.getMessage()); + return new ResponseEntity<>(errorMessage,HttpStatus.NOT_FOUND); + } + catch (NoSuchElementException e){ + ErrorMessage errorMessage = ErrorMessage.of(401, e.getMessage()); + return new ResponseEntity<>(errorMessage,HttpStatus.UNAUTHORIZED);} + catch (Exception e){ + ErrorMessage errorMessage = ErrorMessage.of(500, "다시 시도해주십시오"); + return new ResponseEntity<>(errorMessage,HttpStatus.INTERNAL_SERVER_ERROR); + } + } + @PostMapping("/item/create") + public ResponseEntity createItem(@RequestBody joinItemDto joinItemDto, HttpServletRequest request){ + System.out.println(joinItemDto); + String accessToken = jwtTokenUtil.resolveAccessToken(request); + String userId = jwtTokenUtil.getclaims(accessToken).getSubject(); + try{ + Long itemNo = itemService.addItem(joinItemDto.getItemName(), joinItemDto.getImages(), joinItemDto.getPrice(), userId, joinItemDto.getCategory(), joinItemDto.getItemState(), + joinItemDto.isPriceSimilar()); + Message message = Message.of(201,new itemRequestDto(itemNo,"상품이 성공적으로 등록되었습니다.")); + return new ResponseEntity<>(message,HttpStatus.CREATED); + } + catch (NullPointerException e) { + ErrorMessage errorMessage = ErrorMessage.of(404, e.getMessage()); + return new ResponseEntity<>(errorMessage,HttpStatus.NOT_FOUND); + } + catch (Exception e){ + ErrorMessage errorMessage = ErrorMessage.of(500, "다시 시도해주십시오"); + return new ResponseEntity<>(errorMessage,HttpStatus.INTERNAL_SERVER_ERROR); + } + } + @PatchMapping("/item/patch/{itemNo}") + public ResponseEntity changeItem(@PathVariable("itemNo") Long itemNo, @RequestBody joinItemDto joinItemDto,HttpServletRequest request){ + try{ + itemService.changeItem(itemNo, joinItemDto.getItemName(), joinItemDto.getPrice(), joinItemDto.getCategory(), joinItemDto.getItemState(), + joinItemDto.isPriceSimilar()); + + Message message = Message.of(200,new itemRequestDto(itemNo,"상품이 성공적으로 수정되었습니다.")); + return new ResponseEntity<>(message,HttpStatus.OK); + } + catch (NullPointerException e) { + ErrorMessage errorMessage = ErrorMessage.of(404, e.getMessage()); + return new ResponseEntity<>(errorMessage,HttpStatus.NOT_FOUND); + } + catch (Exception e){ + ErrorMessage errorMessage = ErrorMessage.of(500, "다시 시도해주십시오"); + return new ResponseEntity<>(errorMessage,HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + @DeleteMapping("/item/delete/{itemNo}") + public ResponseEntity deleteItem(@PathVariable("itemNo") Long itemNo){ + try{ + itemService.deleteItem(itemNo); + Message message = Message.of(200,"상품이 성공적으로 삭제되었습니다."); + return new ResponseEntity<>(message,HttpStatus.OK); + } + catch (NullPointerException e) { + ErrorMessage errorMessage = ErrorMessage.of(404, e.getMessage()); + return new ResponseEntity<>(errorMessage,HttpStatus.NOT_FOUND); + } + catch (Exception e){ + ErrorMessage errorMessage = ErrorMessage.of(500, "다시 시도해주십시오"); + return new ResponseEntity<>(errorMessage,HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + @PostMapping("/userInfo/sellItems") + public ResponseEntity sellItems(HttpServletRequest request) { + String accessToken = jwtTokenUtil.resolveAccessToken(request); + String userId = jwtTokenUtil.getclaims(accessToken).getSubject(); + List itemDtos = itemService.userSellerItem(userId); + Message> message = Message.of(200, itemDtos); + return new ResponseEntity<>(message,HttpStatus.OK); + } + + @PostMapping("/userInfo/buyItems") + public ResponseEntity buyItems(HttpServletRequest request) { + String accessToken = jwtTokenUtil.resolveAccessToken(request); + String userId = jwtTokenUtil.getclaims(accessToken).getSubject(); + List itemDtos = itemService.userBuyItem(userId); + Message> message = Message.of(200, itemDtos); + return new ResponseEntity<>(message,HttpStatus.OK); + } + @PostMapping("/userInfo/soldItems") + public ResponseEntity soldItems(HttpServletRequest request) { + String accessToken = jwtTokenUtil.resolveAccessToken(request); + String userId = jwtTokenUtil.getclaims(accessToken).getSubject(); + List itemDtos = itemService.userSoldItem(userId); + Message> message = Message.of(200, itemDtos); + return new ResponseEntity<>(message,HttpStatus.OK); + } +} diff --git a/src/main/java/Graduated/Task/C2C/Item/Dto/ItemDetailDto.java b/src/main/java/Graduated/Task/C2C/Item/Dto/ItemDetailDto.java new file mode 100644 index 0000000..52a9a8b --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/Item/Dto/ItemDetailDto.java @@ -0,0 +1,28 @@ +package Graduated.Task.C2C.Item.Dto; + +import lombok.Data; + +@Data +public class ItemDetailDto { + private Long itemId; + private String images; + private String itemName; + private int price; + private String category; + private int minPrice; + private int maxPrice; + private int itemState; + + public ItemDetailDto(Long itemId, String image,String itemName, int price, String category, int minPrice, int maxPrice, int itemState) { + this.itemId = itemId; + this.images = image; + this.itemName = itemName; + this.price = price; + this.category = category; + this.minPrice = minPrice; + this.maxPrice = maxPrice; + this.itemState = itemState; + } + + +} diff --git a/src/main/java/Graduated/Task/C2C/Item/Dto/ItemDto.java b/src/main/java/Graduated/Task/C2C/Item/Dto/ItemDto.java new file mode 100644 index 0000000..0409fb8 --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/Item/Dto/ItemDto.java @@ -0,0 +1,34 @@ +package Graduated.Task.C2C.Item.Dto; + +import Graduated.Task.C2C.Item.Entity.Item; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class ItemDto { + private Long itemId; + + private String image; + + private String itemName; + + private int price; + + private boolean priceSimilar; + + private LocalDateTime time; + + public ItemDto(Long itemId, String image,String itemName, int price, boolean priceSimilar, LocalDateTime time) { + this.itemId = itemId; + this.image=image; + this.itemName = itemName; + this.price = price; + this.priceSimilar = priceSimilar; + this.time = time; + } +} diff --git a/src/main/java/Graduated/Task/C2C/Item/Dto/itemRequestDto.java b/src/main/java/Graduated/Task/C2C/Item/Dto/itemRequestDto.java new file mode 100644 index 0000000..559e2c5 --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/Item/Dto/itemRequestDto.java @@ -0,0 +1,11 @@ +package Graduated.Task.C2C.Item.Dto; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class itemRequestDto { + private Long itemId; + private String message; +} diff --git a/src/main/java/Graduated/Task/C2C/Item/Dto/joinItemDto.java b/src/main/java/Graduated/Task/C2C/Item/Dto/joinItemDto.java new file mode 100644 index 0000000..321192a --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/Item/Dto/joinItemDto.java @@ -0,0 +1,18 @@ +package Graduated.Task.C2C.Item.Dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; + +@Data +@Getter +@AllArgsConstructor +public class joinItemDto { + private String images; + private String itemName; + private int price; + private String category; + private int itemState; + private boolean priceSimilar; + +} diff --git a/src/main/java/Graduated/Task/C2C/Item/Entity/Item.java b/src/main/java/Graduated/Task/C2C/Item/Entity/Item.java index 3a70464..1f85e32 100644 --- a/src/main/java/Graduated/Task/C2C/Item/Entity/Item.java +++ b/src/main/java/Graduated/Task/C2C/Item/Entity/Item.java @@ -1,7 +1,7 @@ package Graduated.Task.C2C.Item.Entity; import Graduated.Task.C2C.Category.Entity.Category; -import Graduated.Task.C2C.User.Entity.Users; +import Graduated.Task.C2C.User.Entity.User; import Graduated.Task.C2C.core.BaseEntity; import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.*; @@ -9,10 +9,12 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.ToString; @Entity @Getter @NoArgsConstructor(access = AccessLevel.PUBLIC) +@ToString public class Item extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -28,26 +30,60 @@ public class Item extends BaseEntity { @Enumerated(EnumType.STRING) private State type; + private String image; + private Boolean priceSimilar; + + private int itemState; private int viewCount; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="seller_user_no") @JsonIgnore //개발 과정에서만 사용 , 추후 DTO 변환과정에서는 삭제예정 - private Users seller; + private User seller; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="buyer_user_no") @JsonIgnore//개발 과정에서만 사용 , 추후 DTO 변환과정에서는 삭제예정 - private Users buyer; + private User buyer; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "categoryNo") @JsonIgnore//개발 과정에서만 사용 , 추후 DTO 변환과정에서는 삭제예정 private Category category; + public Item(String name, String image,int price, User seller, Category category,int itemState,boolean priceSimilar) { + this.name = name; + this.image=image; + this.price = price; + this.seller = seller; + this.category = category; + this.type = State.sale; + this.itemState = itemState; + this.priceSimilar=priceSimilar; + seller.getSellItem().add(this); + category.getItem().add(this); + } + public void plusView(){ + this.viewCount+=1; + } + public void changeItem(String name, int price, Boolean priceSimilar, int itemState, Category category) { + this.name = name; + this.image=""; + this.price = price; + this.priceSimilar = priceSimilar; + this.itemState = itemState; + this.category = category; + + } + public enum State{ sold,sale } - + public void setSold(User seller, User buyer) { + this.seller = seller; + this.buyer = buyer; + this.type = State.sold; + buyer.getBuyItem().add(this); + } } diff --git a/src/main/java/Graduated/Task/C2C/Item/Repository/ItemRepositoryCustom.java b/src/main/java/Graduated/Task/C2C/Item/Repository/ItemRepositoryCustom.java index d7528bd..ae68af1 100644 --- a/src/main/java/Graduated/Task/C2C/Item/Repository/ItemRepositoryCustom.java +++ b/src/main/java/Graduated/Task/C2C/Item/Repository/ItemRepositoryCustom.java @@ -1,4 +1,17 @@ package Graduated.Task.C2C.Item.Repository; +import Graduated.Task.C2C.Item.Entity.Item; + +import java.util.List; +import java.util.Optional; + public interface ItemRepositoryCustom { + List searchItem(String word,final int startPage, final int PageSize); + List findCategoryWithItem(Long categoryNo,final int startPage, final int PageSize); + Optional findItemWithCategory(Long itemId); + List findBySellerItem(String userid); + List findByBuyerItem(String userid); + List findPopularItem(); + List findRecentItem(); + List findBySoldItem(String userid); } diff --git a/src/main/java/Graduated/Task/C2C/Item/Repository/ItemRepositoryImpl.java b/src/main/java/Graduated/Task/C2C/Item/Repository/ItemRepositoryImpl.java index 5b7a1d3..d83c08f 100644 --- a/src/main/java/Graduated/Task/C2C/Item/Repository/ItemRepositoryImpl.java +++ b/src/main/java/Graduated/Task/C2C/Item/Repository/ItemRepositoryImpl.java @@ -2,11 +2,20 @@ import Graduated.Task.C2C.Item.Entity.Item; import Graduated.Task.C2C.core.Querydsl4RepositorySupport; +import com.querydsl.core.BooleanBuilder; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; import lombok.Getter; import org.springframework.stereotype.Repository; +import java.util.List; +import java.util.Optional; + +import static Graduated.Task.C2C.Category.Entity.QCategory.category; +import static Graduated.Task.C2C.Item.Entity.QItem.item; +import static Graduated.Task.C2C.User.Entity.QUser.user; + + @Repository @Getter public class ItemRepositoryImpl extends Querydsl4RepositorySupport implements ItemRepositoryCustom { @@ -16,4 +25,43 @@ public ItemRepositoryImpl(EntityManager em) { super(Item.class); this.jpaQueryFactory = new JPAQueryFactory(em); } + + public List findCategoryWithItem(Long categoryNo,final int startPage, final int PageSize) { + System.out.println(startPage); + return select(item).from(item).where(item.category.No.eq(categoryNo)).where(item.type.eq(Item.State.sale)).orderBy(item.createdDate.desc()).offset(startPage) + .limit(PageSize).fetch(); + } + public Optional findItemWithCategory(Long itemId){ + return Optional.ofNullable(selectFrom(item).where(item.No.eq(itemId)).join(item.category).fetchJoin().fetchOne()); + } + public List searchItem(String word,final int startPage, final int PageSize){ + BooleanBuilder booleanBuilder = new BooleanBuilder(); + if(word!=null){ + booleanBuilder.and(item.name.like("%" + word + "%")); + } + return selectFrom(item).where(booleanBuilder,item.type.eq(Item.State.sale)).offset(startPage).limit(PageSize).fetch(); + } + public List findPopularItem(){ + return selectFrom(item).orderBy(item.viewCount.desc()).limit(6).fetch(); + } + public List findRecentItem(){ + return selectFrom(item).orderBy(item.createdDate.asc()).limit(6).fetch(); + } + + + @Override + public List findBySellerItem(String userid) { + return select(item).from(user).join(user.sellItem,item).fetchJoin().where(user.id.eq(userid),item.type.eq(Item.State.sale)).fetch(); + } + + @Override + public List findBySoldItem(String userid) { + return select(item).from(user).join(user.sellItem,item).fetchJoin().where(user.id.eq(userid),item.type.eq(Item.State.sold)).fetch(); + } + + @Override + public List findByBuyerItem(String userid) { + return select(item).from(user).join(user.buyItem, item).fetchJoin().where(user.id.eq(userid)).fetch(); + } + } diff --git a/src/main/java/Graduated/Task/C2C/Item/Service/ItemService.java b/src/main/java/Graduated/Task/C2C/Item/Service/ItemService.java index 6a88812..ec84506 100644 --- a/src/main/java/Graduated/Task/C2C/Item/Service/ItemService.java +++ b/src/main/java/Graduated/Task/C2C/Item/Service/ItemService.java @@ -1,10 +1,25 @@ package Graduated.Task.C2C.Item.Service; +import Graduated.Task.C2C.Category.Entity.Category; +import Graduated.Task.C2C.Category.Entity.categoryPrice; +import Graduated.Task.C2C.Category.Repository.CategoryRepository; +import Graduated.Task.C2C.Item.Dto.ItemDetailDto; +import Graduated.Task.C2C.Item.Dto.ItemDto; +import Graduated.Task.C2C.Item.Entity.Item; import Graduated.Task.C2C.Item.Repository.ItemRepository; -import lombok.Getter; +import Graduated.Task.C2C.User.Entity.User; +import Graduated.Task.C2C.User.Repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.zeroturnaround.exec.ProcessExecutor; +import org.zeroturnaround.exec.ProcessResult; + +import java.io.IOException; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; @Service @RequiredArgsConstructor @@ -12,4 +27,86 @@ public class ItemService { private final ItemRepository itemRepository; + private final UserRepository userRepository; + private final CategoryRepository categoryRepository; + + @Transactional + public Long addItem(String name, String image,int price, String userId, String categoryNo, int itemState, boolean priceSimilar) throws Exception { + User user = userRepository.findByUserId(userId).orElseThrow(()->new NullPointerException("존재하지않는 사용자입니다")); + Category category = categoryRepository.findByCategoryName(categoryNo).orElseThrow(()->new NullPointerException("존재하지않는 카테고리입니다.")); + Item item = new Item(name,image,price,user,category,itemState,priceSimilar); + itemRepository.save(item); + if (category.getItemCount()%20 ==0 ){ + String category_no = String.valueOf(category.getNo()); + Future python3 = new ProcessExecutor().command("python3", "home/ubuntu/Random_Forest_Model.py",category_no) + .redirectOutput(System.out) + .redirectError(System.out).start().getFuture(); + } + return item.getNo(); + } + + + @Transactional + public void deleteItem(Long itemId){ + Item item = itemRepository.findById(itemId).orElseThrow(() -> new NullPointerException("존재하지않는 아이템입니다.")); + itemRepository.delete(item); + } + + @Transactional + public void SellItem(Long userNo, Long itemNo) throws Exception { + User buyer = userRepository.findById(userNo).orElseThrow(()->new Exception("존재하지않는 사용자입니다")); + Item item = itemRepository.findById(itemNo).orElseThrow(()->new Exception("존재하지않는 아이템입니다")); + User seller = item.getSeller(); + item.setSold(seller,buyer); + } + + @Transactional + public void changeItem(Long itemId,String name, int price, String categoryNo,int itemState,boolean priceSimilar) { + Item item = itemRepository.findById(itemId).orElseThrow(() -> new NullPointerException("존재하지않는 아이템입니다.")); + Category category = categoryRepository.findByCategoryName(categoryNo).orElseThrow(()->new NullPointerException("존재하지않는 카테고리입니다.")); + item.changeItem(name,price,priceSimilar,itemState,category); + itemRepository.save(item); + } + + public List viewCategoryItem(Long categoryNo, final int startPage, final int PageSize) { + List categoryItem = itemRepository.findCategoryWithItem(categoryNo, startPage*10, PageSize); + return categoryItem.stream().map(this::getItemDto).toList(); + } + public List searchItem(String word,final int startPage, final int PageSize){ + List searchItem = itemRepository.searchItem(word,startPage*10, PageSize); + return searchItem.stream().map(this::getItemDto).toList(); + } + @Transactional + public ItemDetailDto itemInformation(Long itemId){ + Item item = itemRepository.findItemWithCategory(itemId).orElseThrow(() -> new NullPointerException("존재하지 않는 아이템입니다")); + item.plusView(); + int state = item.getItemState(); + categoryPrice categoryPrice = categoryRepository.findCategoryPrice(item.getCategory().getNo(), state).orElseThrow(() -> new NoSuchElementException("잘못된 접근입니다.")); + int maxPrice = categoryPrice.getMaxPrice(); + int minPrice = categoryPrice.getMinPrice(); + String name = item.getCategory().getName(); + return new ItemDetailDto(item.getNo(),item.getImage(),item.getName(),item.getPrice(),name,minPrice,maxPrice,item.getItemState()); + } + private ItemDto getItemDto(Item item) { + return new ItemDto(item.getNo(),item.getImage(),item.getName(),item.getPrice(),item.getPriceSimilar(),item.getCreatedDate()); + } + public List findPopularItem(){ + return itemRepository.findPopularItem().stream().map(this::getItemDto).toList(); + } + public List findRecentItem(){ + return itemRepository.findPopularItem().stream().map(this::getItemDto).toList(); + } + + public List AllItem(){ + return itemRepository.findAll(); + } + public List userBuyItem(String userId){ + return itemRepository.findByBuyerItem(userId).stream().map(this::getItemDto).toList(); + } + public List userSellerItem(String userNo){ + return itemRepository.findBySellerItem(userNo).stream().map(this::getItemDto).toList(); + } + public List userSoldItem(String userNo){ + return itemRepository.findBySoldItem(userNo).stream().map(this::getItemDto).toList(); + } } diff --git a/src/main/java/Graduated/Task/C2C/User/Controller/UserController.java b/src/main/java/Graduated/Task/C2C/User/Controller/UserController.java new file mode 100644 index 0000000..63542ff --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/User/Controller/UserController.java @@ -0,0 +1,64 @@ +package Graduated.Task.C2C.User.Controller; + +import Graduated.Task.C2C.User.Service.UserService; +import Graduated.Task.C2C.User.requestDto.loginDto; +import Graduated.Task.C2C.User.responseDto.TokenDto; +import Graduated.Task.C2C.User.responseDto.userInfoDto; +import Graduated.Task.C2C.core.JwtTokenUtil; +import Graduated.Task.C2C.core.Message; +import Graduated.Task.C2C.core.ErrorMessage; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + + +@RestController +@RequiredArgsConstructor +public class UserController { + private final UserService userService; + private final JwtTokenUtil jwtTokenUtil; + @PostMapping("/login") + public ResponseEntity login(@RequestBody loginDto loginDto) { + try { + System.out.println(loginDto); + String accessToken = userService.login(loginDto.getId(), loginDto.getPassword()); + TokenDto tokenDto = new TokenDto(accessToken,"성공적으로 로그인 하였습니다."); + Message message = Message.of(200, tokenDto); + return new ResponseEntity<>(message,HttpStatus.OK); + } catch (Exception e) { + ErrorMessage errorMessage = ErrorMessage.of(404, e.getMessage()); + return new ResponseEntity<>(errorMessage, HttpStatus.NOT_FOUND); + } + } + + @PostMapping("/logout") + public ResponseEntity logout(HttpServletRequest request){ + String accessToken = jwtTokenUtil.resolveAccessToken(request); + userService.logout(accessToken); + Message message = Message.of(200,"성공적으로 로그아웃 하였습니다."); + return new ResponseEntity<>(message,HttpStatus.OK); + } + + @PostMapping("/userInfo") + public ResponseEntity userInfo(HttpServletRequest request) { + String accessToken = jwtTokenUtil.resolveAccessToken(request); + try{ + userInfoDto userinfo = userService.userinfo(accessToken); + Message message = Message.of(200,userinfo); + return new ResponseEntity<>(message,HttpStatus.OK); + } + catch (NullPointerException e){ + ErrorMessage errorMessage = ErrorMessage.of(404, e.getMessage()); + return new ResponseEntity<>(errorMessage, HttpStatus.NOT_FOUND); + } + catch (Exception e){ + ErrorMessage errorMessage = ErrorMessage.of(500, "다시 시도해주십시오"); + return new ResponseEntity<>(errorMessage,HttpStatus.INTERNAL_SERVER_ERROR); + } + } +} diff --git a/src/main/java/Graduated/Task/C2C/User/Entity/Users.java b/src/main/java/Graduated/Task/C2C/User/Entity/User.java similarity index 79% rename from src/main/java/Graduated/Task/C2C/User/Entity/Users.java rename to src/main/java/Graduated/Task/C2C/User/Entity/User.java index c678996..57f951f 100644 --- a/src/main/java/Graduated/Task/C2C/User/Entity/Users.java +++ b/src/main/java/Graduated/Task/C2C/User/Entity/User.java @@ -15,7 +15,8 @@ @Entity @Getter @NoArgsConstructor(access = AccessLevel.PUBLIC) -public class Users extends BaseEntity { +@Table(name = "Users") +public class User extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="userNo") @@ -36,5 +37,9 @@ public class Users extends BaseEntity { @OneToMany(mappedBy = "buyer") List buyItem = new ArrayList<>(); - + public User(String id, String password, String name) { + this.id = id; + this.password = password; + this.name = name; + } } \ No newline at end of file diff --git a/src/main/java/Graduated/Task/C2C/User/Repository/UserRepository.java b/src/main/java/Graduated/Task/C2C/User/Repository/UserRepository.java index 18d3f86..07f06e8 100644 --- a/src/main/java/Graduated/Task/C2C/User/Repository/UserRepository.java +++ b/src/main/java/Graduated/Task/C2C/User/Repository/UserRepository.java @@ -1,11 +1,8 @@ package Graduated.Task.C2C.User.Repository; -import Graduated.Task.C2C.User.Entity.Users; -import Graduated.Task.C2C.core.Querydsl4RepositorySupport; -import lombok.Getter; +import Graduated.Task.C2C.User.Entity.User; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -public interface UserRepository extends JpaRepository , UserRepositoryCustom { +public interface UserRepository extends JpaRepository , UserRepositoryCustom { } diff --git a/src/main/java/Graduated/Task/C2C/User/Repository/UserRepositoryCustom.java b/src/main/java/Graduated/Task/C2C/User/Repository/UserRepositoryCustom.java index f1d0bb2..c02ce04 100644 --- a/src/main/java/Graduated/Task/C2C/User/Repository/UserRepositoryCustom.java +++ b/src/main/java/Graduated/Task/C2C/User/Repository/UserRepositoryCustom.java @@ -1,9 +1,9 @@ package Graduated.Task.C2C.User.Repository; -import Graduated.Task.C2C.User.Entity.Users; +import Graduated.Task.C2C.User.Entity.User; import java.util.Optional; public interface UserRepositoryCustom { - Optional findByUserEmail(String email); + Optional findByUserId(String userId); } diff --git a/src/main/java/Graduated/Task/C2C/User/Repository/UserRepositoryImpl.java b/src/main/java/Graduated/Task/C2C/User/Repository/UserRepositoryImpl.java index 71c6e01..3c23a88 100644 --- a/src/main/java/Graduated/Task/C2C/User/Repository/UserRepositoryImpl.java +++ b/src/main/java/Graduated/Task/C2C/User/Repository/UserRepositoryImpl.java @@ -1,6 +1,6 @@ package Graduated.Task.C2C.User.Repository; -import Graduated.Task.C2C.User.Entity.Users; +import Graduated.Task.C2C.User.Entity.User; import Graduated.Task.C2C.core.Querydsl4RepositorySupport; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; @@ -9,20 +9,19 @@ import java.util.Optional; -import static Graduated.Task.C2C.User.Entity.QUsers.users; +import static Graduated.Task.C2C.User.Entity.QUser.user; + @Repository @Getter public class UserRepositoryImpl extends Querydsl4RepositorySupport implements UserRepositoryCustom{ private final JPAQueryFactory query; public UserRepositoryImpl(EntityManager em) { - super(Users.class); + super(User.class); this.query = new JPAQueryFactory(em); } - - @Override - public Optional findByUserEmail(String email) { - return Optional.ofNullable(selectFrom(users).where(users.id.eq(email)).fetchOne()); + public Optional findByUserId(String userId) { + return Optional.ofNullable(selectFrom(user).where(user.id.eq(userId)).fetchOne()); } } diff --git a/src/main/java/Graduated/Task/C2C/User/Service/UserService.java b/src/main/java/Graduated/Task/C2C/User/Service/UserService.java index bd7d54e..898e63d 100644 --- a/src/main/java/Graduated/Task/C2C/User/Service/UserService.java +++ b/src/main/java/Graduated/Task/C2C/User/Service/UserService.java @@ -1,7 +1,8 @@ package Graduated.Task.C2C.User.Service; -import Graduated.Task.C2C.User.Entity.Users; +import Graduated.Task.C2C.User.Entity.User; import Graduated.Task.C2C.User.Repository.UserRepository; +import Graduated.Task.C2C.User.responseDto.userInfoDto; import Graduated.Task.C2C.core.JwtTokenUtil; import Graduated.Task.C2C.core.RedisConfig; import lombok.RequiredArgsConstructor; @@ -21,8 +22,8 @@ public class UserService { private Long expireTimeMs = 100*60*60L; @Transactional public String login(String email, String password) throws Exception { - Users user = userRepository.findByUserEmail(email).orElseThrow(() -> new Exception("존재하지 않는 id입니다.")); - if (Objects.equals(user.getPassword(), password)){ + User user = userRepository.findByUserId(email).orElseThrow(() -> new Exception("존재하지 않는 id입니다.")); + if (!Objects.equals(user.getPassword(), password)){ throw new Exception("비밀번호가 틀렷습니다"); } String Access_token = jwtTokenUtil.createToken(user.getId(),expireTimeMs); @@ -30,4 +31,15 @@ public String login(String email, String password) throws Exception { redisConfig.redisTemplate().opsForValue().set(user.getId(),reFresh_token, Duration.ofHours(3)); return Access_token; } + @Transactional + public void logout(String AccessToken){ + String subject = jwtTokenUtil.getclaims(AccessToken).getSubject(); + redisConfig.redisTemplate().delete(subject); + } + + public userInfoDto userinfo(String accessToken){ + String userId = jwtTokenUtil.getclaims(accessToken).getSubject(); + User user = userRepository.findByUserId(userId).orElseThrow(() -> new NullPointerException("잘못된 사용자 입니다.")); + return new userInfoDto(user.getNo(),user.getName(),user.getId(),user.getCreatedDate()); + } } diff --git a/src/main/java/Graduated/Task/C2C/User/requestDto/loginDto.java b/src/main/java/Graduated/Task/C2C/User/requestDto/loginDto.java new file mode 100644 index 0000000..a1201a4 --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/User/requestDto/loginDto.java @@ -0,0 +1,11 @@ +package Graduated.Task.C2C.User.requestDto; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class loginDto { + String id; + String password; +} diff --git a/src/main/java/Graduated/Task/C2C/User/responseDto/TokenDto.java b/src/main/java/Graduated/Task/C2C/User/responseDto/TokenDto.java new file mode 100644 index 0000000..04e3bd1 --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/User/responseDto/TokenDto.java @@ -0,0 +1,11 @@ +package Graduated.Task.C2C.User.responseDto; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class TokenDto { + String accessToken; + String message; +} diff --git a/src/main/java/Graduated/Task/C2C/User/responseDto/userInfoDto.java b/src/main/java/Graduated/Task/C2C/User/responseDto/userInfoDto.java new file mode 100644 index 0000000..cd25b35 --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/User/responseDto/userInfoDto.java @@ -0,0 +1,15 @@ +package Graduated.Task.C2C.User.responseDto; + +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@AllArgsConstructor +public class userInfoDto { + private Long userId; + private String username; + private String id; + private LocalDateTime joinedDate; +} diff --git a/src/main/java/Graduated/Task/C2C/core/BaseEntity.java b/src/main/java/Graduated/Task/C2C/core/BaseEntity.java index e889b17..3ddbb63 100644 --- a/src/main/java/Graduated/Task/C2C/core/BaseEntity.java +++ b/src/main/java/Graduated/Task/C2C/core/BaseEntity.java @@ -7,6 +7,7 @@ import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import java.time.LocalDateTime; @@ -14,6 +15,7 @@ @NoArgsConstructor @MappedSuperclass // 아래 필드를 컬럼으로 인식하게 함 @EntityListeners(AuditingEntityListener.class) +@EnableJpaAuditing public abstract class BaseEntity { @CreatedDate diff --git a/src/main/java/Graduated/Task/C2C/core/ErrorMessage.java b/src/main/java/Graduated/Task/C2C/core/ErrorMessage.java new file mode 100644 index 0000000..790fbba --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/core/ErrorMessage.java @@ -0,0 +1,11 @@ +package Graduated.Task.C2C.core; + +import lombok.*; + +@Getter +@Setter +@RequiredArgsConstructor(staticName = "of") +public class ErrorMessage { + private final int resultCode; + private final String message; +} \ No newline at end of file diff --git a/src/main/java/Graduated/Task/C2C/core/JwtTokenUtil.java b/src/main/java/Graduated/Task/C2C/core/JwtTokenUtil.java index d6b6c7a..3492e9a 100644 --- a/src/main/java/Graduated/Task/C2C/core/JwtTokenUtil.java +++ b/src/main/java/Graduated/Task/C2C/core/JwtTokenUtil.java @@ -14,9 +14,14 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Component; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.List; +import java.util.concurrent.TimeoutException; @Getter @Slf4j @@ -26,37 +31,38 @@ public class JwtTokenUtil { @Value("${jwt.token.secret}") private String secretKey; - public Boolean isExpired(String token){ + public Boolean isExpired(String token) { byte[] accessSecret = secretKey.getBytes(StandardCharsets.UTF_8); return Jwts.parser().setSigningKey(Keys.hmacShaKeyFor(accessSecret)).parseClaimsJws(token).getBody() .getExpiration().before(new Date()); } - public String createToken(String email, long expireTimeMs){ - Claims claims = Jwts.claims().setSubject(email); - claims.put("roles","user"); + + public String createToken(String no, long expireTimeMs) { + Claims claims = Jwts.claims().setSubject(no); + claims.put("roles", "user"); byte[] accessSecret = secretKey.getBytes(StandardCharsets.UTF_8); return Jwts.builder() .setClaims(claims)//정보를 넣어줌 claims가 포함된 jwt빌더를 반환 .setIssuedAt(new Date(System.currentTimeMillis()))//시작시간 - .setExpiration(new Date(System.currentTimeMillis()+expireTimeMs))//만료시간 + .setExpiration(new Date(System.currentTimeMillis() + expireTimeMs))//만료시간 .signWith(Keys.hmacShaKeyFor(accessSecret)) .compact(); } - public Claims getclaims(String token){ + + public Claims getclaims(String token) { byte[] parser_key = secretKey.getBytes(StandardCharsets.UTF_8); try { Claims body = Jwts.parser().setSigningKey(Keys.hmacShaKeyFor(parser_key)).parseClaimsJws(token) .getBody(); return body; - } - catch (ExpiredJwtException e){ + } catch (ExpiredJwtException e) { return e.getClaims(); } } - public String createReFreshToken(String email,Long expireTimeMs) { + public String createReFreshToken(String email, Long expireTimeMs) { byte[] accessSecret = secretKey.getBytes(StandardCharsets.UTF_8); Claims claims = Jwts.claims().setSubject(email); return Jwts.builder() @@ -66,11 +72,13 @@ public String createReFreshToken(String email,Long expireTimeMs) { .signWith(Keys.hmacShaKeyFor(accessSecret)) .compact(); } + public String resolveAccessToken(HttpServletRequest request) { - if(request.getHeader("authorization") != null ) + if (request.getHeader("authorization") != null) return request.getHeader("authorization").substring(7); return null; } + public boolean validateToken(String jwtToken) { byte[] accessSecret = secretKey.getBytes(StandardCharsets.UTF_8); try { @@ -81,12 +89,13 @@ public boolean validateToken(String jwtToken) { return false; } } + public UsernamePasswordAuthenticationToken getAuthentication(String token) { Object no = this.getclaims(token).getSubject(); return new UsernamePasswordAuthenticationToken(no, "", List.of(new SimpleGrantedAuthority("user"))); } + public void setHeaderAccessToken(HttpServletResponse response, String accessToken) { - response.setHeader("authorization", "Bearer "+ accessToken); + response.setHeader("authorization", "Bearer " + accessToken); } - } diff --git a/src/main/java/Graduated/Task/C2C/core/Message.java b/src/main/java/Graduated/Task/C2C/core/Message.java new file mode 100644 index 0000000..68340d3 --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/core/Message.java @@ -0,0 +1,15 @@ +package Graduated.Task.C2C.core; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@RequiredArgsConstructor(staticName = "of") +public class Message { + + private final int resultCode; + private final D data; + +} \ No newline at end of file diff --git a/src/main/java/Graduated/Task/C2C/core/SecurityConfig.java b/src/main/java/Graduated/Task/C2C/core/SecurityConfig.java index 78cb859..01b6069 100644 --- a/src/main/java/Graduated/Task/C2C/core/SecurityConfig.java +++ b/src/main/java/Graduated/Task/C2C/core/SecurityConfig.java @@ -14,6 +14,11 @@ import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.Arrays; @EnableWebSecurity @Configuration @@ -38,7 +43,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti ) .sessionManagement((sessionManagement) -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS) - ) + ) .addFilterBefore(new JwtFilter(jwtTokenUtil,redisConfig), UsernamePasswordAuthenticationFilter.class); // .ExceptionHandlingDsl((exceptionConfig)-> // exceptionConfig.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))); diff --git a/src/main/java/Graduated/Task/C2C/core/WebConfig.java b/src/main/java/Graduated/Task/C2C/core/WebConfig.java new file mode 100644 index 0000000..638cc59 --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/core/WebConfig.java @@ -0,0 +1,25 @@ +package Graduated.Task.C2C.core; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +@Configuration +public class WebConfig { + + @Bean + public CorsFilter corsFilter() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration config = new CorsConfiguration(); + + config.setAllowCredentials(true); + config.addAllowedOriginPattern("*"); // 특정 도메인을 허용하려면 예: "https://example.com" + config.addAllowedHeader("*"); + config.addAllowedMethod("*"); + + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } +} diff --git a/src/main/java/Graduated/Task/C2C/main/MainDto.java b/src/main/java/Graduated/Task/C2C/main/MainDto.java new file mode 100644 index 0000000..1a27594 --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/main/MainDto.java @@ -0,0 +1,16 @@ +package Graduated.Task.C2C.main; + +import Graduated.Task.C2C.Category.Dto.categoryDto; +import Graduated.Task.C2C.Item.Dto.ItemDto; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.List; + +@Data +@AllArgsConstructor +public class MainDto { + private List categories; + private List popularItems; + private List recentItems; +} diff --git a/src/main/java/Graduated/Task/C2C/main/mainController.java b/src/main/java/Graduated/Task/C2C/main/mainController.java new file mode 100644 index 0000000..aac9be6 --- /dev/null +++ b/src/main/java/Graduated/Task/C2C/main/mainController.java @@ -0,0 +1,39 @@ +package Graduated.Task.C2C.main; + +import Graduated.Task.C2C.Category.Dto.categoryDto; +import Graduated.Task.C2C.Category.Service.CategoryService; +import Graduated.Task.C2C.Item.Dto.ItemDto; +import Graduated.Task.C2C.Item.Service.ItemService; +import Graduated.Task.C2C.core.ErrorMessage; +import Graduated.Task.C2C.core.Message; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +public class mainController { + private final ItemService itemService; + private final CategoryService categoryService; + + @GetMapping("/main") + public ResponseEntity home(){ + try { + List popularItem = itemService.findPopularItem(); + List recentItem = itemService.findRecentItem(); + List category = categoryService.findCategory(); + MainDto mainDto = new MainDto(category, popularItem, recentItem); + Message message = Message.of(200, mainDto); + return new ResponseEntity<>(message, HttpStatus.OK); + } + catch (Exception e){ + ErrorMessage errorMessage = ErrorMessage.of(500, "다시 시도해주십시오"); + return new ResponseEntity<>(errorMessage,HttpStatus.INTERNAL_SERVER_ERROR); + } + } + +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 21256bb..813b975 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -5,11 +5,11 @@ spring: datasource: url: jdbc:postgresql://localhost:5432/test username: 'root' - password: '3174' + password: '1234' driver-class-name: org.postgresql.Driver jpa: hibernate: - ddl-auto: create + ddl-auto: update properties: hibernate: default_batch_fetch_size: 1000 diff --git a/src/test/java/Graduated/Task/C2C/C2CApplicationTests.java b/src/test/java/Graduated/Task/C2C/C2CApplicationTests.java index 385e897..8b48298 100644 --- a/src/test/java/Graduated/Task/C2C/C2CApplicationTests.java +++ b/src/test/java/Graduated/Task/C2C/C2CApplicationTests.java @@ -1,14 +1,32 @@ package Graduated.Task.C2C; +import Graduated.Task.C2C.User.Entity.User; +import Graduated.Task.C2C.User.Repository.UserRepository; +import Graduated.Task.C2C.User.Service.UserService; +import jakarta.persistence.EntityManager; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class C2CApplicationTests { + @Autowired + UserService userService; - @Test - void contextLoads() { - } + @Autowired + UserRepository userRepository; + + @Autowired + EntityManager em; + +// @Test +// void contextLoads() throws Exception { +// User user = new User("1","1","1"); +// userRepository.save(user); +// em.clear(); +// String login = userService.login("1", "1"); +// System.out.println(login); +// } } diff --git a/src/test/java/Graduated/Task/C2C/itemTest.java b/src/test/java/Graduated/Task/C2C/itemTest.java new file mode 100644 index 0000000..344b705 --- /dev/null +++ b/src/test/java/Graduated/Task/C2C/itemTest.java @@ -0,0 +1,131 @@ +package Graduated.Task.C2C; + +import Graduated.Task.C2C.Category.Entity.Category; +import Graduated.Task.C2C.Category.Repository.CategoryRepository; +import Graduated.Task.C2C.Category.Service.CategoryService; +import Graduated.Task.C2C.Item.Dto.ItemDetailDto; +import Graduated.Task.C2C.Item.Dto.ItemDto; +import Graduated.Task.C2C.Item.Service.ItemService; +import Graduated.Task.C2C.User.Entity.User; +import Graduated.Task.C2C.User.Repository.UserRepository; +import Graduated.Task.C2C.User.Service.UserService; +import Graduated.Task.C2C.User.responseDto.userInfoDto; +import jakarta.persistence.EntityManager; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.zeroturnaround.exec.ProcessExecutor; +import org.zeroturnaround.exec.ProcessResult; + +import java.util.List; +import java.util.concurrent.Future; + +@SpringBootTest +class itemTest { + @Autowired + UserService userService; + + @Autowired + ItemService itemService; + + @Autowired + UserRepository userRepository; + @Autowired + CategoryService categoryService; + + @Autowired + CategoryRepository categoryRepository; + + @Autowired + EntityManager em; + + @Test + void itemAdd() throws Exception { + User user = new User("1","1","1"); + userRepository.save(user); + Category category = new Category("test",0); + categoryRepository.save(category); + em.clear(); + Long l = itemService.addItem("1", "",3000, user.getId(), category.getName(), 2, true); + System.out.println(l); + } + @Test + void deleteItem() throws Exception { + User user = new User("1","1","1"); + userRepository.save(user); + Category category = new Category("test",0); + categoryRepository.save(category); + Long l = itemService.addItem("1", "",3000, user.getId(), category.getName(), 2, true); + em.clear(); + itemService.deleteItem(l); + } + + @Test + void changeItem() throws Exception { + User user = new User("1","1","1"); + userRepository.save(user); + Category category = new Category("test",0); + categoryRepository.save(category); + Long l = itemService.addItem("1", "",3000, user.getId(), category.getName(), 2, true); + em.clear(); + itemService.changeItem(l,"2",4000, category.getName(), 3,true); + } + + @Test + void categoryItem() throws Exception { + User user = new User("1","1","1"); + userRepository.save(user); + Category category = new Category("test",0); + categoryRepository.save(category); + Long l = itemService.addItem("1", "",3000, user.getId(), category.getName(), 2, true); + em.clear(); + List itemDtos = itemService.viewCategoryItem(l, 0, 10); + System.out.println(itemDtos); + } + @Test + void searchItem() throws Exception { + User user = new User("1","1","1"); + userRepository.save(user); + Category category = new Category("test",0); + categoryRepository.save(category); + Long l = itemService.addItem("1", "",3000, user.getId(), category.getName(), 2, true); + em.clear(); + List itemDtos = itemService.searchItem("1", 0, 10); + System.out.println(itemDtos); + } + + @Test + void popluarItem() throws Exception { + User user = new User("1","1","1"); + userRepository.save(user); + Category category = new Category("test",0); + categoryRepository.save(category); + Long l = itemService.addItem("1", "",3000, user.getId(), category.getName(), 2, true); + em.clear(); + List itemDetailDto = itemService.findPopularItem(); + System.out.println(itemDetailDto); + } + + @Test + void recentItem() throws Exception { + User user = new User("1","1","1"); + userRepository.save(user); + Category category = new Category("test",0); + categoryRepository.save(category); + Long l = itemService.addItem("1", "",3000, user.getId(), category.getName(), 2, true); + em.clear(); + categoryRepository.findAllPost(); + List itemDetailDto = itemService.findRecentItem(); + System.out.println(itemDetailDto); + } + @Test + void Iteminfo() throws Exception { + ItemDetailDto itemDetailDto = itemService.itemInformation(1L); + System.out.println(itemDetailDto); + } + @Test + void categoryPrice() throws Exception { + System.out.println(categoryService.findCategoryPrice("test",1)); + } +} + diff --git a/src/test/java/Graduated/Task/C2C/user_Test.java b/src/test/java/Graduated/Task/C2C/user_Test.java new file mode 100644 index 0000000..fc09b08 --- /dev/null +++ b/src/test/java/Graduated/Task/C2C/user_Test.java @@ -0,0 +1,52 @@ +package Graduated.Task.C2C; + +import Graduated.Task.C2C.User.Entity.User; +import Graduated.Task.C2C.User.Repository.UserRepository; +import Graduated.Task.C2C.User.Service.UserService; +import Graduated.Task.C2C.User.responseDto.userInfoDto; +import jakarta.persistence.EntityManager; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class user_Test { + @Autowired + UserService userService; + + @Autowired + UserRepository userRepository; + + @Autowired + EntityManager em; + + @Test + void login() throws Exception { + User user = new User("3","1","1"); + userRepository.save(user); + em.clear(); + String login = userService.login("3", "1"); + } + @Test + void logout() throws Exception { + User user = new User("1","1","1"); + userRepository.save(user); + em.clear(); + String login = userService.login("1", "1"); + em.clear(); + userService.logout(login); + } + + @Test + void userinfo() throws Exception { + User user = new User("1","1","1"); + userRepository.save(user); + em.clear(); + String login = userService.login("1", "1"); + em.clear(); + userInfoDto userinfo = userService.userinfo(login); + System.out.println(userinfo); + } + +} +