diff --git a/src/main/java/io/company/localhost/service/localbordService.java b/src/main/java/io/company/localhost/service/localbordService.java index 0eccd8a..8c595cd 100644 --- a/src/main/java/io/company/localhost/service/localbordService.java +++ b/src/main/java/io/company/localhost/service/localbordService.java @@ -55,13 +55,17 @@ public class localbordService { private final PasswordEncoder passwordEncoder; public List selectNotices(MapDto map) { + String keyword = map.getString("searchKeyword"); + map.put("searchKeyword", null); + List posts = boardMapper.selectNotices(map); enrichPostsWithAdditionalData(posts); - return posts; + + return filterPostsByKeyword(posts, keyword); } + public PageInfo selectGeneralPosts(MapDto map) { - System.out.println(map); int page = map.getString("page") != null ? Integer.parseInt(map.getString("page")) : 1; int size = map.getString("size") != null ? Integer.parseInt(map.getString("size")) : 10; @@ -70,12 +74,27 @@ public class localbordService { map.put("orderBy", "date"); } - PageHelper.startPage(page, size); + String keyword = map.getString("searchKeyword"); + map.put("searchKeyword", null); // MyBatis에 전달하지 않음 + // 넉넉히 많이 가져온 후 Java에서 필터링 + PageHelper.startPage(1, 1000); // 최대 1000개까지만 조회 List result = boardMapper.selectGeneralPosts(map); + enrichPostsWithAdditionalData(result); - return PageUtil.redefineNavigation(new PageInfo<>(result, size)); + // 키워드 필터링 적용 + List filtered = filterPostsByKeyword(result, keyword); + + // 원하는 페이지만 잘라서 리턴 + int fromIndex = (page - 1) * size; + int toIndex = Math.min(fromIndex + size, filtered.size()); + List pageList = fromIndex >= filtered.size() ? new ArrayList<>() : filtered.subList(fromIndex, toIndex); + + PageInfo pageInfo = new PageInfo<>(pageList); + pageInfo.setTotal(filtered.size()); + + return PageUtil.redefineNavigation(pageInfo); } public void updateIncrementViewCount(Long boardId) { @@ -314,17 +333,66 @@ public class localbordService { return null; // 이미지가 없는 경우 } - private boolean procIsValidJson(String json) { + public String extractPlainText(String deltaJson) { + StringBuilder sb = new StringBuilder(); + ObjectMapper mapper = new ObjectMapper(); + try { - final ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.readTree(json); // JSON 파싱 시도 - return true; // JSON이 유효하면 true 반환 + JsonNode root = mapper.readTree(deltaJson); + JsonNode ops = root.get("ops"); + + if (ops != null && ops.isArray()) { + for (JsonNode op : ops) { + JsonNode insertNode = op.get("insert"); + + // insert가 문자열일 경우만 추출 + if (insertNode != null && insertNode.isTextual()) { + String text = insertNode.asText(); + if (!"\n".equals(text.trim())) { // 줄바꿈 제외 + sb.append(text).append(" "); + } + } + // insert가 객체면 image일 가능성 → 제외 + } + } + } catch (Exception e) { - return false; // 유효하지 않은 경우 false 반환 + e.printStackTrace(); // 실제 운영에서는 로깅 처리 } + + return sb.toString().trim(); + } + + /** + * 검색어로 순수 텍스트 기준 게시글 필터링 + */ + private List filterPostsByKeyword(List posts, String keyword) { + if (keyword == null || keyword.trim().isEmpty()) return posts; + + keyword = keyword.trim(); + + List filtered = new ArrayList<>(); + + for (MapDto post : posts) { + String title = post.getString("title"); + String author = post.getString("author"); + String contentJson = BlobUtil.procBlobToString(post.get("content")); // Blob 처리 + String plainText = extractPlainText(contentJson); + + // 포함 여부 판단 (title, author, content 순수 텍스트) + if ((title != null && title.contains(keyword)) || + (author != null && author.contains(keyword)) || + plainText.contains(keyword)) { + + post.put("content", contentJson); // content는 원래대로 복원 + filtered.add(post); + } + } + + return filtered; } - + private void enrichBoardDetail(MapDto boardDetail) { if(boardDetail == null) return; diff --git a/src/main/resources/mapper/localbordMapper.xml b/src/main/resources/mapper/localbordMapper.xml index 93e9710..6f0d15e 100644 --- a/src/main/resources/mapper/localbordMapper.xml +++ b/src/main/resources/mapper/localbordMapper.xml @@ -14,13 +14,6 @@ FROM localbord b LEFT JOIN netmember m ON b.MEMBERSEQ = m.MEMBERSEQ WHERE LOCBRDTYP = '300103' - - AND ( - LOCBRDTTL LIKE CONCAT('%', #{searchKeyword}, '%') - OR LOCBRDCON LIKE CONCAT('%', #{searchKeyword}, '%') - OR MEMBERNAM LIKE CONCAT('%', #{searchKeyword}, '%') - ) - ORDER BY LOCBRDUDT DESC @@ -37,13 +30,6 @@ FROM localbord b LEFT JOIN netmember m ON b.MEMBERSEQ = m.MEMBERSEQ WHERE b.LOCBRDTYP IN ('300101', '300102') - - AND ( - LOCBRDTTL LIKE CONCAT('%', #{searchKeyword}, '%') - OR LOCBRDCON LIKE CONCAT('%', #{searchKeyword}, '%') - OR MEMBERNAM LIKE CONCAT('%', #{searchKeyword}, '%') - ) - ORDER BY b.LOCBRDUDT DESC