package io.company.localhost.service; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; import org.springframework.stereotype.Service; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import io.company.localhost.common.dto.MapDto; import io.company.localhost.mapper.localbordMapper; import io.company.localhost.utils.PageUtil; import lombok.RequiredArgsConstructor; @Service @RequiredArgsConstructor public class localbordService { private final localbordMapper boardMapper; public List getNotices(MapDto map) { List posts = boardMapper.getNotices(map); enrichPostsWithAdditionalData(posts); return posts; } public PageInfo getGeneralPosts(MapDto 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; String orderBy = map.getString("orderBy"); if (orderBy == null || (!orderBy.equals("date") && !orderBy.equals("views"))) { map.put("orderBy", "date"); } PageHelper.startPage(page, size); List result = boardMapper.getGeneralPosts(map); enrichPostsWithAdditionalData(result); return PageUtil.redefineNavigation(new PageInfo<>(result, size)); } public void incrementViewCount(Long boardId) { boardMapper.incrementViewCount(boardId); } public BigInteger createBoard(MapDto map) { boardMapper.createBoard(map); return (BigInteger) map.get("LOCBRDSEQ"); } public void addAttachment(MapDto map) { boardMapper.addAttachment(map); } public MapDto getBoardDetail(Long boardId) { MapDto boardDetail = boardMapper.selectBoardDetail(boardId); if (boardDetail != null) { enrichBoardDetail(boardDetail); } return boardDetail; } public List getAttachments(Long boardId) { return boardMapper.selectAttachments(boardId); } public void deleteBoard(MapDto map) { boardMapper.deleteCommentsByBoardId(map); boardMapper.deleteBoard(map); } public void updateBoard(MapDto map) { boardMapper.updateBoard(map); } public void reactToBoard(MapDto map) { MapDto existingReaction = boardMapper.findReaction(map); if (existingReaction != null) { boardMapper.updateReaction(map); } else { boardMapper.insertReaction(map); } } public List getComments(int boardSeq) { return boardMapper.getComments(boardSeq); } public void addCommentOrReply(MapDto map) { if (map.get("LOCCMTPNT") == null) { map.put("LOCCMTPNT", null); } boardMapper.addCommentOrReply(map); } public void updateComment(MapDto map) { boardMapper.updateComment(map); } public void deleteComment(MapDto map) { boolean isReply = boardMapper.isReply(map); if (isReply) { boardMapper.deleteReply(map); } else { boolean hasReplies = boardMapper.hasReplies(map); if (hasReplies) { boardMapper.softDeleteComment(map); } else { boardMapper.deleteComment(map); } } } public String getCommentPassword(int commentId) { return boardMapper.selectCommentPassword(commentId); } public String getBoardPassword(int boardId) { return boardMapper.selectBoardPassword(boardId); } public MapDto getCommentById(int commentId) { return boardMapper.getCommentById(commentId); } public int getCommentCount(Long boardId) { return boardMapper.countComments(boardId); } public boolean hasAttachments(Long boardId) { int count = boardMapper.countAttachments(boardId); return count > 0; } public MapDto getBoardReactions(Long boardId) { return boardMapper.getBoardReactions(boardId); } public List getCommentReactions(Long boardId) { return boardMapper.getCommentReactions(boardId); } private void enrichBoardDetail(MapDto boardDetail) { long boardId = ((Number) boardDetail.get("id")).longValue(); boardDetail.put("hasAttachment", hasAttachments(boardId)); boardDetail.put("commentCount", getCommentCount(boardId)); MapDto reactions = getBoardReactions(boardId); boardDetail.put("likeCount", reactions.getOrDefault("likeCount", 0)); boardDetail.put("dislikeCount", reactions.getOrDefault("dislikeCount", 0)); // Blob 데이터를 문자열로 변환 Object content = boardDetail.get("content"); if (content != null) { String contentString = convertBlobToString(content); // Blob을 문자열로 변환 boardDetail.put("content", contentString); // JSON 변환 가능 } } private String convertBlobToString(Object blob) { try { if (blob instanceof String) { return (String) blob; // 이미 문자열인 경우 반환 } else if (blob instanceof java.sql.Blob) { java.sql.Blob sqlBlob = (java.sql.Blob) blob; long blobLength = sqlBlob.length(); byte[] blobBytes = sqlBlob.getBytes(1, (int) blobLength); return new String(blobBytes, StandardCharsets.UTF_8); } else if (blob instanceof ByteArrayInputStream) { ByteArrayInputStream inputStream = (ByteArrayInputStream) blob; byte[] bytes = inputStream.readAllBytes(); return new String(bytes, StandardCharsets.UTF_8); } else { System.err.println("Unsupported blob type: " + blob.getClass()); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Failed to convert Blob to String: " + e.getMessage(), e); } return null; } private String extractFirstImageUrl(String jsonContent) { try { ObjectMapper objectMapper = new ObjectMapper(); JsonNode rootNode = objectMapper.readTree(jsonContent); if (!rootNode.isArray()) { System.err.println("JSON content is not an array"); return null; } for (JsonNode node : rootNode) { JsonNode insertNode = node.get("insert"); if (insertNode != null && insertNode.has("image")) { return insertNode.get("image").asText(); // 첫 번째 이미지 URL 반환 } } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Failed to extract first image URL: " + e.getMessage(), e); } return null; // 이미지가 없는 경우 } private String extractPlainTextFromJson(String jsonContent) { StringBuilder plainTextBuilder = new StringBuilder(); try { ObjectMapper objectMapper = new ObjectMapper(); JsonNode rootNode = objectMapper.readTree(jsonContent); // JSON 배열인지 확인 if (!rootNode.isArray()) { System.err.println("JSON content is not an array"); return ""; } // JSON 노드 순회 for (JsonNode node : rootNode) { JsonNode insertNode = node.get("insert"); // insert 노드가 텍스트인지 확인 if (insertNode != null && insertNode.isTextual()) { String text = insertNode.asText(); // '\n' 제거하고 순수 텍스트만 추가 if (!text.trim().isEmpty() && !text.trim().equals("\n")) { plainTextBuilder.append(text.trim()); } } } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Failed to extract plain text: " + e.getMessage(), e); } return plainTextBuilder.toString(); } private void enrichPostsWithAdditionalData(List posts) { for (MapDto post : posts) { Object idObject = post.get("id"); if (idObject instanceof Number) { long postId = ((Number) idObject).longValue(); post.put("commentCount", getCommentCount(postId)); post.put("hasAttachment", hasAttachments(postId)); MapDto reactions = getBoardReactions(postId); post.put("likeCount", reactions.getOrDefault("likeCount", 0)); post.put("dislikeCount", reactions.getOrDefault("dislikeCount", 0)); Object content = post.get("content"); if (content != null) { String contentString = convertBlobToString(content); post.put("content", contentString); // 첫 번째 이미지 URL 및 순수 텍스트 추출 String firstImageUrl = extractFirstImageUrl(contentString); post.put("firstImageUrl", firstImageUrl); String plainContent = extractPlainTextFromJson(contentString); post.put("plainContent", plainContent); } } else { post.put("commentCount", 0); } } } }