1. 상품 검색 기능 구현
1-1) execSearch, addHTML 함수 만들기
- 검색창 입력값 가져오기
- 검색창 입력값을 검사하고, 입력하지 않았을 경우 focus.
- GET /api/search?query=${query} 요청 (ajax로 데이터 요청)
- for 문마다 itemDto를 꺼내서 HTML 만들고 검색결과 목록에 붙이기! (response로 받은 데이터 각각 추출)
- addHTML 완성하기
- 검색 버튼 눌렀을 때 기존 아이템 삭제
- 가격에 3번째 자리마다 콤마 넣어주기(정규식 사용)
** 특이사항
- itemDto의 형태는 JSON, onclick 이벤트로 실행되는 addProduct()의 괄호안에서는 문자열을 사용함
따라서 JSON 데이터를 그냥 던지면 오류가 난다.
-> JSON.stringify로 JSON타입의 데이터를 문자열로 바꾸어 던져준다.
<img src="images/icon-save.png" alt="" onclick='addProduct(${JSON.stringify(itemDto)})'>
가격 콤마 처리 - 정규식
// 숫자를 넣으면 콤마를 반환
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
엔터 누르면 실행
// id 가 query 인 녀석 위에서 엔터를 누르면 execSearch() 함수를 실행하라는 뜻입니다.
$('#query').on('keypress', function (e) {
if (e.key == 'Enter') {
execSearch();
}
});
2. 관심 상품 등록 기능 구현
2-1) addProduct 함수 만들기
function addProduct(itemDto) {
/**
* // 파라미터를 받을때 문자열이 JSON 형태면 자바스크립트가 자동으로 다시 JSON으로 바꿔버린다
* // 따라서 서버로 던질 때 다시 문자열 처리해줘야 한다.
- 관심 상품 생성 요청
- modal 뜨게 하기
- targetId = response.id
- 최저가 설정 -- 숙제
3. 관심 상품 보여주기
3-1) showProduct, addProductItem 만들기
- GET /api/products 요청
- 관심상품 목록, 검색결과 목록 비우기
- for 문마다 관심 상품 HTML 만들어서 관심상품 목록에 붙이기!
- link, image, title, lprice, myprice 변수 활용하기
- 삼항연산자를 이용하여 내가 지정한 가격보다 현재가격이 높다면 none 클레스 추가
<div class="isgood ${product.lprice <= product.myprice ? '' : 'none'}">
최저가
</div>
# css
.none {
display: none;
}
4. 스케줄러 만들기
4-1) 요구기능
- 매일 새벽 1시에 관심 상품 목록 제목으로 검색해서, 최저가 정보를 업데이트하는 스케줄러 생성
4-2) 구현
- Scheduler 클래스
@RequiredArgsConstructor // final 멤버 변수를 자동으로 생성합니다.
@Component // 스프링이 필요 시 자동으로 생성하는 클래스 목록에 추가합니다.
public class Scheduler {
private final ProductRepository productRepository;
private final ProductService productService;
private final NaverShopSearch naverShopSearch;
// 초, 분, 시, 일, 월, 주 순서
@Scheduled(cron = "0 0 1 * * *")
public void updatePrice() throws InterruptedException { // 스케쥴링하다 오류발생하면 InterruptedException를 띄워라
System.out.println("가격 업데이트 실행");
// 저장된 모든 관심상품을 조회합니다.
List<Product> productList = productRepository.findAll();
for (int i=0; i<productList.size(); i++) {
// 1초에 한 상품 씩 조회합니다 (Naver 제한)
TimeUnit.SECONDS.sleep(1);
// i 번째 관심 상품을 꺼냅니다.
Product p = productList.get(i);
// i 번째 관심 상품의 제목으로 검색을 실행합니다.
String title = p.getTitle();
String resultString = naverShopSearch.search(title);
// i 번째 관심 상품의 검색 결과 목록 중에서 첫 번째 결과를 꺼냅니다.
List<ItemDto> itemDtoList = naverShopSearch.fromJSONtoItems(resultString);
ItemDto itemDto = itemDtoList.get(0);
// i 번째 관심 상품 정보를 업데이트합니다.
Long id = p.getId();
productService.updateBySearch(id, itemDto);
}
}
}
2. ProductService 클래스
@Transactional
public Long updateBySearch(Long id, ItemDto itemDto){
Product product = productRepository.findById(id).orElseThrow(
() -> new IllegalArgumentException("아이디가 존재하지 않습니다")
);
product.updateByItemDto(itemDto);
return id;
}
3. product 클래스
public void updateByItemDto(ItemDto itemDto){
this.lprice = itemDto.getLprice();
}
4. application에 어노테이션 추가
@EnableScheduling // 스프링 부트에서 스케줄러가 작동하게 합니다.
@EnableJpaAuditing // 시간 자동 변경이 가능하도록 합니다.
@SpringBootApplication // 스프링 부트임을 선언합니다.
public class Week04Application {
public static void main(String[] args) {
SpringApplication.run(Week04Application.class, args);
}
}
'프로그래밍 > SpringBoot' 카테고리의 다른 글
Controller, Service, Repository의 역할 (0) | 2022.05.29 |
---|---|
Controller의 이해 (0) | 2022.05.29 |
나만의 셀렉샵 API (1) - 프로젝트 설계 및 API 구현 (0) | 2022.05.25 |
JPA 아키텍처 (0) | 2022.05.22 |
REST API - GET/POST/PUT/DELETE - Controller (0) | 2022.05.22 |