Skip to content

Commit b5f535d

Browse files
authored
Merge pull request #40 from Leafly-app/feat/#39
✨ feat : 카테고리 검색
2 parents 3e55afc + 8f041e9 commit b5f535d

5 files changed

Lines changed: 76 additions & 12 deletions

File tree

src/main/java/com/hansung/leafly/domain/book/entity/enums/BookGenre.java

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,29 @@
55

66
@RequiredArgsConstructor
77
public enum BookGenre {
8-
FICTION("소설/시/희곡"),
9-
ESSAY("에세이"),
10-
SELF_IMPROVEMENT("자기계발"),
11-
SCIENCE("과학"),
12-
HISTORY("역사"),
13-
ECONOMY("경제경영"),
14-
ART("예술/대중문화"),
15-
HUMANITIES("인문학"),
16-
HOME("가정/요리/뷰티"),
17-
TRAVEL("여행"),
18-
HEALTH("건강/취미/레저");
8+
FICTION("소설/시/희곡", "1"),
9+
ESSAY("에세이", "55889"),
10+
SELF_IMPROVEMENT("자기계발", "336"),
11+
SCIENCE("과학", "987"),
12+
HISTORY("역사", "74"),
13+
ECONOMY("경제경영", "170"),
14+
ART("예술/대중문화", "517"),
15+
HUMANITIES("인문학", "656"),
16+
HOME("가정/요리/뷰티", "1230"),
17+
TRAVEL("여행", "1196"),
18+
HEALTH("건강/취미/레저", "55890"),
1919

20-
private final String value;
20+
ALL("전체", null);
21+
22+
private final String value; // 한글 노출 이름
23+
private final String categoryId; // Aladin CategoryId
2124

2225
@JsonValue
2326
public String getValue() {
2427
return value;
2528
}
29+
30+
public String getCategoryId() {
31+
return categoryId;
32+
}
2633
}

src/main/java/com/hansung/leafly/domain/book/service/BookService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.hansung.leafly.domain.book.service;
22

3+
import com.hansung.leafly.domain.book.entity.enums.BookGenre;
34
import com.hansung.leafly.domain.book.web.dto.BookFilterReq;
45
import com.hansung.leafly.domain.book.web.dto.BookInfoRes;
56
import com.hansung.leafly.domain.book.web.dto.SearchRes;
@@ -14,4 +15,6 @@ public interface BookService {
1415
BookInfoRes details(Long isbn, Member member);
1516

1617
BookInfoRes ocr(MultipartFile file, Member member);
18+
19+
List<SearchRes> category(BookGenre genre, Member member);
1720
}

src/main/java/com/hansung/leafly/domain/book/service/BookServiceImpl.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import lombok.RequiredArgsConstructor;
1616
import lombok.extern.slf4j.Slf4j;
1717
import org.springframework.stereotype.Service;
18+
import org.springframework.transaction.annotation.Transactional;
1819
import org.springframework.web.multipart.MultipartFile;
1920

2021
import java.util.HashSet;
@@ -25,6 +26,7 @@
2526

2627
@Service
2728
@RequiredArgsConstructor
29+
@Transactional(readOnly = true)
2830
@Slf4j
2931
public class BookServiceImpl implements BookService {
3032
private final AladinClient aladinClient;
@@ -101,6 +103,35 @@ public BookInfoRes ocr(MultipartFile file, Member member) {
101103
return details(isbn, member);
102104
}
103105

106+
@Override
107+
public List<SearchRes> category(BookGenre genre, Member member) {
108+
AladinSearchRes response;
109+
110+
if (genre == BookGenre.ALL) {
111+
// 전체 → 인기 도서 탐색
112+
response = aladinClient.bestSeller();
113+
} else {
114+
// 장르 검색
115+
response = aladinClient.searchByCategory(genre.getCategoryId());
116+
}
117+
118+
if (response == null || response.item() == null) {
119+
return List.of();
120+
}
121+
122+
Set<Long> bookmarkedSet = new HashSet<>(
123+
bookmarkRepository.findIsbnsByMemberId(member.getId())
124+
);
125+
126+
return response.item().stream()
127+
.filter(item -> item.isbn13() != null && !item.isbn13().isBlank())
128+
.map(item -> SearchRes.from(
129+
item,
130+
bookmarkedSet.contains(Long.parseLong(item.isbn13()))
131+
))
132+
.toList();
133+
}
134+
104135
//카테고리 필터링
105136
private boolean matchesGenre(AladinBookItem item, List<BookGenre> targetGenres) {
106137
String middle = extractMiddleCategory(item.categoryName());

src/main/java/com/hansung/leafly/domain/book/web/controller/BookController.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.hansung.leafly.domain.book.web.controller;
22

3+
import com.hansung.leafly.domain.book.entity.enums.BookGenre;
34
import com.hansung.leafly.domain.book.service.BookService;
45
import com.hansung.leafly.domain.book.web.dto.BookFilterReq;
56
import com.hansung.leafly.domain.book.web.dto.BookInfoRes;
@@ -54,4 +55,12 @@ public ResponseEntity<SuccessResponse<BookInfoRes>> ocr(
5455
return ResponseEntity.status(HttpStatus.OK).body(SuccessResponse.from(res));
5556
}
5657

58+
@GetMapping("/category")
59+
public ResponseEntity<SuccessResponse<List<SearchRes>>> category(
60+
@RequestParam BookGenre genre,
61+
@AuthenticationPrincipal CustomMemberDetails memberDetails
62+
){
63+
List<SearchRes> res = bookService.category(genre, memberDetails.getMember());
64+
return ResponseEntity.status(HttpStatus.OK).body(SuccessResponse.from(res));
65+
}
5766
}

src/main/java/com/hansung/leafly/infra/aladin/AladinClient.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,19 @@ public AladinSearchRes searchByCategory(String categoryId) {
6666

6767
return restTemplate.getForObject(uri, AladinSearchRes.class);
6868
}
69+
70+
public AladinSearchRes bestSeller() {
71+
String uri = UriComponentsBuilder.fromHttpUrl(SEARCH_URL)
72+
.queryParam("ttbkey", TTB_KEY)
73+
.queryParam("QueryType", "Bestseller")
74+
.queryParam("SearchTarget", "Book")
75+
.queryParam("MaxResults", 20)
76+
.queryParam("output", "js")
77+
.queryParam("Version", "20131101")
78+
.build()
79+
.toUriString();
80+
81+
return restTemplate.getForObject(uri, AladinSearchRes.class);
82+
}
6983
}
7084

0 commit comments

Comments
 (0)