[프로젝트]중고 경매 사이트 - 제시요(물품 리스트 검색)

기능 구현
송송승현's avatar
Dec 24, 2024
[프로젝트]중고 경매 사이트 - 제시요(물품 리스트 검색)

화면

notion image
notion image
notion image

JavaScript

let list = document.querySelector(".my__list__item__box2"); let currentUrl = window.location.href; let paths = currentUrl.split("/"); let pageNum = 2; let line =15; // 페이지가 로드될 때 체크된 상태를 복원 document.addEventListener('DOMContentLoaded', function() { let radios = document.getElementsByName('category'); radios.forEach(radio => { if (radio.value === paths[paths.length - 1]) { radio.checked = true; } }) } ); // 라디오 버튼의 체크된 상태로 페이지 이동 function redirectToUrl(event) { const url = event.target.value; // URL로 이동 window.location.href = "/goods-list/"+url; } // 더보기 버튼 클릭시 url을 보고 카테고리에서 리스트 추가인지 헤더에서 리스트 추가인지 확인해서 비동기 요청 async function moreList(){ let moreBtn = document.querySelector(".t1-more-btn"); let radios = document.getElementsByName('category'); let s=0; let category = 0; radios.forEach(radio => { if (radio.value === paths[paths.length - 1]) { category = radio.value; } }); if (category === 0) { let queryString = window.location.search; let urlParams = new URLSearchParams(queryString); let selectValue = urlParams.get('select'); let keywordValue = urlParams.get('keyword'); moreSearchGoods(selectValue, keywordValue); } else { console.log(category); moreCategoryGoodsList(category); } } // 헤더에서 더보기 리스트 가져오기 async function moreSearchGoods(selectValue, keywordValue){ let uri = `/api/v1/search-goods?select=${selectValue}&keyword=${keywordValue}&page=${pageNum}&line=${line}`; let response = await fetch(uri); let responseData = await response.json(); if(!responseData.success){ throw new Error("네트워크 응답에 문제가 있습니다."); } let data = responseData.data; plusHtml(data); pageNum++; } // 카테고리 별로 물품 리스트 가져오기 async function moreCategoryGoodsList(category){ let uri = `/api/v1/search-goods/${category}?page=${pageNum}&line=${line}`; let response = await fetch(uri); let responseData = await response.json(); if(!responseData.success){ throw new Error("네트워크 응답에 문제가 있습니다."); } let data = responseData.data; plusHtml(data); pageNum++; } // 데이터 html에 담기 function plusHtml(data){ let str =``; for(let i =0; i<data.length ;i++){ str+=` <a href="/goods-detail/${data[i].id}" style="text-decoration: none; color: #f96506;"> <div class="card" style="border: 2px solid orange"> <input type="hidden" class="id" value="{{id}}"> <img class="card__img__top" src="${data[i].imgUrl}" alt="ListCard image"> <div class="card__body"> <h4 class="card__title">${data[i].title}</h4> <p class="card__text">판매자: ${data[i].seller}</p> <p class="card__text">카테고리: ${data[i].category}</p> <p class="card__text">시작 입찰가:${data[i].startingPrice}</p> <p class="card__text">최고 입찰가: ${data[i].tryPrice}</p> <p class="card__text">${data[i].endAt}</p> </div> </div> </a> `; } list.innerHTML+=str; }

Controller

private final GoodsService goodsService; @GetMapping("/goods-list") public String goodsList(@RequestParam("select") String select,@RequestParam(defaultValue = "") String keyword, Model model) { model.addAttribute("category", categoryService.findAllCategory(null)); model.addAttribute("goods", goodsService.searchGoodsList(GoodsRequest.SeacherGoodsDTO.builder().select(select).keyword(keyword).page(1).line(15).build())); model.addAttribute("keyword", new GoodsResponse.KeyWordDTO(keyword)); return "goods-list"; } @GetMapping("/goods-list/{id}") public String goodsList(@PathVariable("id") Integer categoryId, Model model) { model.addAttribute("category", categoryService.findAllCategory(categoryId)); model.addAttribute("goods",goodsService.getGoodsList(categoryId,1,15)); return "goods-list"; } @ResponseBody @GetMapping("/api/v1/search-goods") public ResponseEntity<?> searchGoods(GoodsRequest.SeacherGoodsDTO goodsDTO) { List<GoodsResponse.GoodsDTO> dto = goodsService.searchGoodsList(goodsDTO); CommonResp<List<GoodsResponse.GoodsDTO>> resp = CommonResp.success(dto); return new ResponseEntity<>(resp, HttpStatus.OK); } @ResponseBody @GetMapping("/api/v1/search-goods/{id}") public ResponseEntity<?> categoryGoods(@PathVariable("id") Integer id, Integer page, Integer line) { List<GoodsResponse.GoodsDTO> dto = goodsService.getGoodsList(id,page,line); CommonResp<List<GoodsResponse.GoodsDTO>> resp = CommonResp.success(dto); return new ResponseEntity<>(resp, HttpStatus.OK); }

Service

// 카테고리로 물품 리스트 조회 public List<GoodsResponse.GoodsDTO> getGoodsList(Integer categoryId, Integer page, Integer line) { List<Goods> goodList = goodsRepository.findByCategoryId(categoryId, page, line) .orElseThrow(() -> new Exception404("해당 카테고리의 물품이 존재하지 않습니다.")); List<GoodsResponse.GoodsDTO> goodsList = new ArrayList<>(); for (Goods goods : goodList) { bidRepository.findByGoodsDescIsNull(goods.getId()).ifPresentOrElse(bid -> goodsList.add(GoodsResponse.GoodsDTO.builder() .goods(goods) .bidTryPrice(bid.getTryPrice()) .build()), () -> goodsList.add(GoodsResponse.GoodsDTO.builder() .goods(goods) .bidTryPrice(0) .build())); } return goodsList; } // 제목 및 내용으로 물품 리스트 조회 public List<GoodsResponse.GoodsDTO> searchGoodsList(GoodsRequest.SeacherGoodsDTO dto) { Optional<List<Goods>> searchGoodsList = goodsRepository.searchGoods(dto); List<GoodsResponse.GoodsDTO> goodsList = new ArrayList<>(); for (Goods goods : searchGoodsList.get()) { bidRepository.findByGoodsDescIsNull(goods.getId()).ifPresentOrElse(bid -> goodsList.add(GoodsResponse.GoodsDTO.builder() .goods(goods) .bidTryPrice(bid.getTryPrice()) .build()), () -> goodsList.add(GoodsResponse.GoodsDTO.builder() .goods(goods) .bidTryPrice(0) .build())); } return goodsList; }

Repository

// 카테고리 아이디로 경매중인 물품 리스트 조회 public Optional<List<Goods>> findByCategoryId(Integer categoryId, Integer page, Integer line) { String sql = """ select g from Goods g left join fetch g.seller left join fetch g.category where g.status=:status and g.category.id=:categoryId order by g.id desc limit :line offset :page """; Query query = em.createQuery(sql); query.setParameter("status", 0); query.setParameter("categoryId", categoryId); query.setParameter("line", line); query.setParameter("page", (page-1)*line); return Optional.ofNullable(query.getResultList()); } // 제목 및 내용으로 경매중인 물품 리스트 조회 public Optional<List<Goods>> searchGoods(GoodsRequest.SeacherGoodsDTO dto) { String sql = "select g from Goods g left join fetch g.seller left join fetch g.category where g.status=:status AND "; if(dto.getSelect().equals("title")){ // select가 제목이면 제목으로 물품 리스트를 검색 sql += "g.title like :keyword"; }else if(dto.getSelect().equals("content")){ // select가 content이면 내용으로 검색 sql += "g.content like :keyword"; }else { sql += "g.title like :keyword OR g.content like :keyword"; } sql += " order by g.id desc limit :line offset :page "; Query query = em.createQuery(sql); query.setParameter("status", 0); query.setParameter("keyword", "%"+dto.getKeyword()+"%"); query.setParameter("line", dto.getLine()); query.setParameter("page", (dto.getPage()-1)*dto.getLine()); return Optional.ofNullable(query.getResultList()); }

해설

💡
헤더의 검색창을 에서 select를 이용하여 제목 및 내용에 대한 검색
메인화면 하단 카테고리 및 물품 리스트화면 왼쪽 사이드바의 라디오 버튼을 이용한 검색
더보기 버튼을 클릭하여 추가 물품 리스트 조회
 
Share article

송승현의 블로그