화면



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