1. ItemRepository
@Repository
public interface ItemRepository extends JpaRepository<Item,Long> {
//상품 생성 시 이름이 중복되는지 체크하기 위해
Boolean existsByName(String name);
//상품 검색 시 해당 이름을 포함한 모든 상품을 찾기 위해
Page<Item> findAllByNameContains(String name, PageRequest pageRequest);
//카테고리로 상품을 찾기 위해
Page<Item> findAllByItemCategory(ItemCategory itemCategory,PageRequest pageRequest);
}
2. ItemService
@Service
@RequiredArgsConstructor
public class ItemService {
private final ItemRepository itemRepository;
private final UploadImageService uploadImageService;
private final UploadImageRepository uploadImageRepository;
private final LikeRepository likeRepository;
private final OrderItemRepository orderItemRepository;
//상품 생성 시 유효성 검사
public BindingResult saveValid(ItemJoinRequest req, BindingResult bindingResult){
System.out.println(req.getStock()+" "+req.getUploadImages());
if(req.getName().isEmpty()){
bindingResult.addError(new FieldError("req","name","상품명이 비어있습니다."));
}else if(itemRepository.existsByName(req.getName())){
bindingResult.addError(new FieldError("req","name","상품명이 중복됩니다."));
}
if(req.getPrice()==null){
bindingResult.addError(new FieldError("req","price","가격은 필수입력사항 입니다."));
}else if(req.getPrice()<=0){
bindingResult.addError(new FieldError("req","price","가격은 0원 이상이어야 합니다."));
}
if(req.getDelivery_price()==null){
bindingResult.addError(new FieldError("req","delivery_price","배송비는 필수입력사항 입니다."));
}else if(req.getDelivery_price()<=0){
bindingResult.addError(new FieldError("req","delivery_price","배송비는 0원 이상이어야 합니다."));
}if(req.getStock()==null) {
bindingResult.addError(new FieldError("req", "stock", "수량은 0개 이상이어야 합니다."));
}else if(req.getStock()<=0) {
bindingResult.addError(new FieldError("req", "stock", "수량은 0개 이상이어야 합니다."));
}
if(req.getUploadImages()==null) {
bindingResult.addError(new FieldError("req", "uploadImages", "상품 이미지는 1개 이상이어야 합니다."));
}else if(req.getUploadImages().isEmpty()) {
bindingResult.addError(new FieldError("req", "uploadImages", "상품 이미지는 1개 이상이어야 합니다."));
}
return bindingResult;
}
//이미지 업로드 하기 위한 메소드
@Transactional
public Item updateItemImages(List<MultipartFile> multipartFiles,Long itemId) throws IOException{
Item item = itemRepository.findById(itemId).get();
for (MultipartFile image: multipartFiles) {
UploadImage uploadImage = this.uploadImageService.saveImage(image, item);
item.getUploadImages().add(uploadImage);
}
System.out.println("success");
return item;
}
//상품 저장
@Transactional
public Item saveItem(ItemJoinRequest req) throws IOException {
Item saveItem = itemRepository.save(req.toEntity());
// 업로드된 이미지들을 저장
for (MultipartFile file : req.getUploadImages()) {
UploadImage uploadImage = this.uploadImageService.saveImage(file, saveItem);
saveItem.getUploadImages().add(uploadImage);
}
return saveItem;
}
//아이디로 상품을 찾기위한 메소드
public Item findItem(Long itemId){
return itemRepository.findById(itemId).get();
}
//아이디로 상품 찾은 후 ItemDto로 변환 후 반환
public ItemDto findById(Long itemId){
Optional<Item> findItem = itemRepository.findById(itemId);
//id에 해당하는 상품 없으면 null return
if(findItem.isEmpty()){
return null;
}
return ItemDto.of(findItem.get());
}
//모든 상품 조회
public Page<Item> findItems(PageRequest pageRequest){
Page<Item> allItems = itemRepository.findAll(pageRequest);
return allItems;
}
//특정 name을 포함한 모든 상품 조회
public Page<Item> findAllByItemName(String name,PageRequest pageRequest){
if(name!=null) {
return itemRepository.findAllByNameContains(name, pageRequest);
} else{
return itemRepository.findAll(pageRequest);
}
}
//해당 카테고리에 속한 모든 상품 조회
public Page<Item> findAllByItemCategory(ItemCategory itemCategory,PageRequest pageRequest){
return itemRepository.findAllByItemCategory(itemCategory,pageRequest);
}
//위시리스트에 들어있는 상품들 조회
public Page<Item> findAllWishlist(Authentication auth,PageRequest pageRequest){
Page<Like> likes = likeRepository.findAllByMemberEmail(pageRequest,auth.getName());
List<Item> likeItems = new ArrayList<>();
for(Like like:likes){
likeItems.add(like.getItem());
}
return new PageImpl<>(likeItems, pageRequest, likes.getTotalElements());
}
//상품 수정
@Transactional
public Item itemEdit(Long itemId,ItemDto itemDto) {
System.out.println(itemId);
Item item = itemRepository.findById(itemId).get();
item.edit(itemDto.getPrice(),itemDto.getItemCategory(),itemDto.getStock(),itemDto.getItemTip(),itemDto.getSizeTip());
return item;
}
//상품 삭제
@Transactional
public Boolean itemDelete(Long itemId) {
if(orderItemRepository.existsByItemId(itemId)){
System.out.println("itemDelete false");
return false;
}
Item item = itemRepository.findById(itemId).orElseThrow(EntityNotFoundException::new);
List<UploadImage> uploadImages = item.getUploadImages();
for(UploadImage uploadImage:uploadImages){
uploadImageRepository.delete(uploadImage);
}
itemRepository.delete(item);
System.out.println("itemDelete true");
return true;
}
}
3. ItemController
@Controller
@RequiredArgsConstructor
@SessionAttributes("keyword")
@RequestMapping("/items")
public class ItemController {
private final ItemService itemService;
private final UploadImageService uploadImageService;
private final LikeService likeService;
@GetMapping(value={"","/"})
public String itemListPage(Model model,
@RequestParam(required = false,defaultValue = "1") int page,
@RequestParam(name = "keyword", required = false) String keyword){
PageRequest pageRequest = PageRequest.of(page - 1, 10, Sort.by("id").descending());
System.out.println(keyword);
model.addAttribute("items",itemService.findAllByItemName(keyword,pageRequest));
return "items/list";
}
//특정 카테고리에 속한 상품 출력 페이지
@GetMapping("/{category}")
public String itemListPage(@PathVariable String category, Model model,
@RequestParam(required = false,defaultValue = "1") int page
){
ItemCategory itemCategory = ItemCategory.of(category);
if(itemCategory==null){
model.addAttribute("message","카테고리가 존재하지 않습니다.");
model.addAttribute("nextUrl","/");
return "printMessage";
}
PageRequest pageRequest = PageRequest.of(page - 1, 10, Sort.by("id").descending());
model.addAttribute("items",itemService.findAllByItemCategory(itemCategory,pageRequest));
model.addAttribute("category",category);
return "items/list";
}
//상품 상세페이지
@GetMapping("/{itemId}/detail")
public String itemDetailPage(@PathVariable Long itemId, Model model,Authentication auth){
if(auth!=null){
model.addAttribute("likeCheck",likeService.checkLike(auth.getName(),itemId));
model.addAttribute("loginUserLoginId",auth.getName());
}
ItemDto itemDto = itemService.findById(itemId);
System.out.println(itemDto.getUploadImages().size());
//id에 해당하는 게시글이 없거나 카테고리가 일치하지 않는경우
if(itemDto==null){
model.addAttribute("message","해당 게시글이 존재하지 않습니다.");
model.addAttribute("nextUrl","/items");
return "printMessage";
}
model.addAttribute("itemDto",itemDto);
return "items/detail";
}
@GetMapping("/create")
public String itemCreatePage(Model model){
model.addAttribute("itemJoinRequest",new ItemJoinRequest());
return "items/create";
}
@PostMapping("/create")
public String itemCreate(@Valid @ModelAttribute ItemJoinRequest req, BindingResult bindingResult,Model model) throws IOException {
if(itemService.saveValid(req,bindingResult).hasErrors()){
return "items/create";
}
itemService.saveItem(req);
model.addAttribute("message","상품이 등록되었습니다!");
model.addAttribute("nextUrl","/items");
return "printMessage";
}
@GetMapping("/{itemId}/edit")
public String itemEditPage(@PathVariable Long itemId, Model model){
ItemDto itemDto = itemService.findById(itemId);
model.addAttribute("itemDto",itemDto);
return "items/edit";
}
@PostMapping("/{itemId}/edit")
public String itemEdit(@PathVariable Long itemId,@Valid @ModelAttribute ItemDto itemDto,Model model){
itemService.itemEdit(itemId,itemDto);
model.addAttribute("message","상품이 수정되었습니다!");
model.addAttribute("nextUrl","/items/"+itemId+"/detail");
return "printMessage";
}
@PostMapping("/{itemId}/delete")
public String itemDelete(@PathVariable Long itemId,Model model){
if(itemService.itemDelete(itemId)){
model.addAttribute("message","상품이 삭제되었습니다!");
model.addAttribute("nextUrl","/items");
}
else{
model.addAttribute("message","주문된 상품은 삭제할 수 없습니다.");
model.addAttribute("nextUrl","/items/"+itemId+"/detail");
}
return "printMessage";
}
//이미지 삭제시 호출되는 메서드
@PostMapping("/deleteImage/{itemId}/{delImageId}")
public String deleteImage(@PathVariable Long itemId,@PathVariable Long delImageId, Model model) throws IOException{
UploadImage delImage = uploadImageService.findById(delImageId);
uploadImageService.deleteImage(delImage);
model.addAttribute("message","해당 이미지가 삭제되었습니다.");
model.addAttribute("nextUrl","/items/"+itemId+"/edit");
return "printMessage";
}
//이미지 등록시 호출되는 메서드
@PostMapping("/uploadImages/{itemId}")
public String updateImages(@PathVariable Long itemId, @RequestParam("uploadImages") MultipartFile[] files,Model model) throws IOException{
List<MultipartFile> fileList = Arrays.asList(files);
itemService.updateItemImages(fileList,itemId);
ItemDto itemDto = itemService.findById(itemId);
model.addAttribute("itemDto",itemDto);
return "items/edit";
}
@ResponseBody
@GetMapping("/images/{filename}")
public Resource showImage(@PathVariable String filename) throws MalformedURLException {
return new UrlResource("file:"+uploadImageService.getFullPath(filename));
}
}
4. ItemJoinRequest
- 상품 생성 시 사용되는 DTO
@Data
@NoArgsConstructor
public class ItemJoinRequest {
private String name; //상품 이름
private Integer price; //상품 가격
private Integer delivery_price; //배송비
private ItemCategory itemCategory; //상품 종류
private Integer stock; //재고
private String itemTip; //상품 설명
private String sizeTip; //사이즈 설명
private List<MultipartFile> uploadImages;
public Item toEntity(){
return Item.builder()
.name(name)
.price(price)
.itemCategory(itemCategory)
.itemTip(itemTip)
.sizeTip(sizeTip)
.stockQuantity(stock)
.uploadImages(new ArrayList<>())
.delivery_price(delivery_price)
.build();
}
}
5. ItemDto
- 상품 조회 시 사용되는 DTO
@Data
@Builder
public class ItemDto {
private Long id;
private String name; //상품 이름
private Integer price; //상품 가격
private Integer delivery_price; //배송비
private ItemCategory itemCategory; //상품 종류
private String itemTip; //상품 설명
private String sizeTip; //크기 설명
private Integer stock; //재고
private List<UploadImage> uploadImages;
public static ItemDto of(Item item){
ItemDto itemDto = ItemDto.builder()
.id(item.getId())
.name(item.getName())
.price(item.getPrice())
.delivery_price(item.getDelivery_price())
.itemTip(item.getItemTip())
.itemCategory(item.getItemCategory())
.stock(item.getStockQuantity())
.sizeTip(item.getSizeTip())
.uploadImages(new ArrayList<>(item.getUploadImages()))
.build();
return itemDto;
}
}
'web > Bakery Shop Project' 카테고리의 다른 글
쇼핑몰 구현 11 - 위시리스트 기능 (0) | 2024.02.23 |
---|---|
쇼핑몰 구현 10 - 장바구니 기능 (0) | 2024.02.23 |
쇼핑몰 구현 8 - 회원 기능 (0) | 2024.02.23 |
쇼핑몰 구현 7 - 환경설정 (0) | 2024.02.23 |
쇼핑몰 구현 6 - 라이브러리 설치, Entity 생성 (0) | 2024.02.23 |