본문 이미지 수정
This commit is contained in:
parent
9386b18ec4
commit
d42e4fa0ca
@ -16,25 +16,11 @@
|
|||||||
package io.company.localhost.controller.api;
|
package io.company.localhost.controller.api;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.sql.Blob;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
import com.github.pagehelper.PageSerializable;
|
|
||||||
|
|
||||||
import io.company.localhost.common.annotation.Member;
|
import io.company.localhost.common.annotation.Member;
|
||||||
import io.company.localhost.common.annotation.ParameterCheck;
|
import io.company.localhost.common.annotation.ParameterCheck;
|
||||||
@ -50,36 +36,19 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class BoardController {
|
public class BoardController {
|
||||||
|
|
||||||
private final localbordService boardService;
|
private final localbordService boardService;
|
||||||
private final PasswordEncoder passwordEncoder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 공지사항 목록 조회
|
* 공지사항 목록 조회
|
||||||
* @ReqMap map 요청 파라미터 (searchKeyword)
|
* @ReqMap map 요청 파라미터 (searchKeyword)
|
||||||
* @return 전체 공지사항 목록
|
* @return 전체 공지사항 목록
|
||||||
*/
|
*/
|
||||||
@Member
|
@Member
|
||||||
@ParameterCheck
|
@ParameterCheck
|
||||||
@GetMapping("/notices")
|
@GetMapping("/notices")
|
||||||
public ApiResponse<List<MapDto>> getNotices(@ReqMap MapDto map) {
|
public ApiResponse<List<MapDto>> getNotices(@ReqMap MapDto map) {
|
||||||
List<MapDto> posts = boardService.getNotices(map);
|
return ApiResponse.ok(boardService.getNotices(map));
|
||||||
|
|
||||||
// Blob 데이터를 처리 (문자열로 변환)
|
|
||||||
for (MapDto post : posts) {
|
|
||||||
Object content = post.get("content");
|
|
||||||
if (content instanceof Blob) {
|
|
||||||
Blob blob = (Blob) content;
|
|
||||||
post.put("content", safeBlobToString(blob));
|
|
||||||
}
|
|
||||||
|
|
||||||
// "id" 값을 Number로 받고 longValue()로 변환
|
|
||||||
Object idObject = post.get("id");
|
|
||||||
long postId = ((Number) idObject).longValue();
|
|
||||||
post.put("hasAttachment", boardService.hasAttachments(postId));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return ApiResponse.ok(posts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,335 +57,169 @@ public class BoardController {
|
|||||||
* @return 페이징된 자유/익명 게시판 목록
|
* @return 페이징된 자유/익명 게시판 목록
|
||||||
*/
|
*/
|
||||||
@Member
|
@Member
|
||||||
@ParameterCheck
|
@ParameterCheck
|
||||||
@GetMapping("/general")
|
@GetMapping("/general")
|
||||||
public ApiResponse<PageInfo<MapDto>> getGeneralPosts(@ReqMap MapDto map) {
|
public ApiResponse<PageInfo<MapDto>> getGeneralPosts(@ReqMap MapDto map) {
|
||||||
PageInfo<MapDto> posts = boardService.getGeneralPosts(map);
|
return ApiResponse.ok(boardService.getGeneralPosts(map));
|
||||||
|
|
||||||
// Blob 데이터를 처리 (문자열로 변환)
|
|
||||||
for (MapDto post : posts.getList()) {
|
|
||||||
Object content = post.get("content");
|
|
||||||
if (content instanceof Blob) {
|
|
||||||
Blob blob = (Blob) content;
|
|
||||||
post.put("content", safeBlobToString(blob));
|
|
||||||
}
|
|
||||||
|
|
||||||
// "id" 값을 Number로 받고 longValue()로 변환
|
|
||||||
Object idObject = post.get("id");
|
|
||||||
if (idObject instanceof Number) {
|
|
||||||
long postId = ((Number) idObject).longValue();
|
|
||||||
post.put("commentCount", boardService.getCommentCount(postId));
|
|
||||||
post.put("hasAttachment", boardService.hasAttachments(postId));
|
|
||||||
MapDto reactions = boardService.getBoardReactions(postId);
|
|
||||||
post.put("likeCount", reactions.getOrDefault("likeCount", 0));
|
|
||||||
post.put("dislikeCount", reactions.getOrDefault("dislikeCount", 0));
|
|
||||||
} else {
|
|
||||||
post.put("commentCount", 0); // id가 없거나 잘못된 경우 기본값 설정
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ApiResponse.ok(posts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 안전하게 Blob 데이터를 문자열로 변환하는 메서드
|
|
||||||
* @ReqMap
|
|
||||||
* @return 변환된 문자열 또는 null
|
|
||||||
*/
|
|
||||||
private String safeBlobToString(Blob blob) {
|
|
||||||
if (blob == null) {
|
|
||||||
return null; // Blob이 null이면 null 반환
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
long blobLength = blob.length();
|
|
||||||
if (blobLength > Integer.MAX_VALUE) {
|
|
||||||
throw new IllegalArgumentException("Blob is too large to process.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new String(blob.getBytes(1, (int) blobLength), StandardCharsets.UTF_8);
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println("Failed to convert Blob to String: " + e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
return null; // 변환 실패 시 null 반환
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 게시물 작성
|
* 게시물 작성
|
||||||
* @ReqMap map 요청 파라미터 (LOCBRDTTL, LOCBRDCON, MEMBERSEQ, LOCBRDTYP,
|
* @ReqMap map 요청 파라미터 (LOCBRDTTL, LOCBRDCON, MEMBERSEQ, LOCBRDTYP,
|
||||||
* LOCBRDPWD(익명일떄에만), LOCBRDCAT(지식커뮤니티만))
|
* LOCBRDPWD(익명일 때만), LOCBRDCAT(지식커뮤니티만))
|
||||||
* @return 작성된 게시물의 ID
|
* @return 작성된 게시물의 ID
|
||||||
*/
|
*/
|
||||||
@Member
|
@Member
|
||||||
@ParameterCheck
|
@ParameterCheck
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public ApiResponse<?> createBoard(@ReqMap MapDto map) {
|
public ApiResponse<BigInteger> createBoard(@ReqMap MapDto map) {
|
||||||
// 비밀번호 암호화
|
return ApiResponse.ok(boardService.createBoard(map));
|
||||||
if (map.containsKey("LOCBRDPWD")) {
|
|
||||||
String rawPassword = map.getString("LOCBRDPWD");
|
|
||||||
String encodedPassword = passwordEncoder.encode(rawPassword);
|
|
||||||
map.put("LOCBRDPWD", encodedPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
// <--- 프론드 단에서 해줌 할필요 없음 삭제 --->
|
|
||||||
// LOCBRDCON 필드를 JSON 문자열로 변환
|
|
||||||
// ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
// if (map.containsKey("LOCBRDCON")) {
|
|
||||||
// try {
|
|
||||||
// String jsonContent = objectMapper.writeValueAsString(map.get("LOCBRDCON"));
|
|
||||||
// map.put("LOCBRDCON", jsonContent); // JSON 문자열로 변환된 값 설정
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// throw new RuntimeException("Error serializing LOCBRDCON field", e);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//로그인 미개발 ->임시
|
|
||||||
map.put("MEMBERSEQ", 1);
|
|
||||||
|
|
||||||
BigInteger createdIdx = boardService.createBoard(map); // 작성된 게시물의 idx를 반환
|
|
||||||
Map<String, Object> responseData = new HashMap<>();
|
|
||||||
responseData.put("CMNBRDSEQ", createdIdx);
|
|
||||||
responseData.put("message", "게시물이 작성되었습니다.");
|
|
||||||
return ApiResponse.ok(responseData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 첨부파일 추가
|
|
||||||
* @ReqMap map 요청 파라미터 (CMNFLEREG, CMNFLESIZ, CMNFLEEXT, CMNFLEORG, CMNFLENAM, CMNFLEPAT, CMNBRDSEQ)
|
|
||||||
* @return 첨부파일 저장 결과 메시지
|
|
||||||
*/
|
|
||||||
@Member
|
|
||||||
@ParameterCheck
|
|
||||||
@PostMapping("/{CMNBRDSEQ}/attachments")
|
|
||||||
public ApiResponse<String> uploadAttachment(@ReqMap MapDto map) {
|
|
||||||
String filename = UUID.randomUUID().toString();
|
|
||||||
map.put("CMNFLENAM", filename);
|
|
||||||
map.put("CMNFLEREG", 1);
|
|
||||||
// 파일 데이터 저장
|
|
||||||
boardService.addAttachment(map);
|
|
||||||
|
|
||||||
return ApiResponse.ok("첨부파일이 저장되었습니다.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 게시물 상세보기
|
* 게시물 상세보기
|
||||||
* @param boardId 게시물 ID
|
* @param boardId 게시물 ID
|
||||||
* @return 게시물 상세정보, 첨부파일 목록, 댓글 목록
|
* @return 게시물 상세정보
|
||||||
*/
|
*/
|
||||||
@Member
|
@Member
|
||||||
@ParameterCheck
|
@ParameterCheck
|
||||||
@GetMapping("/{boardId}")
|
@GetMapping("/{boardId}")
|
||||||
public ApiResponse<MapDto> getBoardDetail(@PathVariable("boardId") Long boardId) {
|
public ApiResponse<MapDto> getBoardDetail(@PathVariable("boardId") Long boardId) {
|
||||||
log.info("Fetching details for board ID: {}", boardId);
|
return ApiResponse.ok(boardService.getBoardDetail(boardId));
|
||||||
|
|
||||||
// 조회수 증가
|
|
||||||
boardService.incrementViewCount(boardId);
|
|
||||||
|
|
||||||
// 게시물 상세정보 조회
|
|
||||||
MapDto boardDetail = boardService.getBoardDetail(boardId);
|
|
||||||
if (boardDetail == null) {
|
|
||||||
throw new IllegalArgumentException("Board not found for ID: " + boardId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blob 데이터를 문자열로 변환
|
|
||||||
if (boardDetail.get("content") instanceof Blob) {
|
|
||||||
try {
|
|
||||||
Blob blob = (Blob) boardDetail.get("content");
|
|
||||||
String contentString = new String(blob.getBytes(1, (int) blob.length()), StandardCharsets.UTF_8);
|
|
||||||
boardDetail.put("content", contentString);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Failed to process Blob content", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MapDto reactions = boardService.getBoardReactions(boardId);
|
|
||||||
boardDetail.put("likeCount", reactions.getOrDefault("likeCount", 0));
|
|
||||||
boardDetail.put("dislikeCount", reactions.getOrDefault("dislikeCount", 0));
|
|
||||||
|
|
||||||
List<MapDto> attachments = boardService.getAttachments(boardId);
|
|
||||||
List<MapDto> comments = boardService.getComments(boardId.intValue());
|
|
||||||
|
|
||||||
List<MapDto> commentReactions = boardService.getCommentReactions(boardId);
|
|
||||||
for (MapDto comment : comments) {
|
|
||||||
Integer commentId = (Integer) comment.get("LOCCMTSEQ");
|
|
||||||
for (MapDto reaction : commentReactions) {
|
|
||||||
if (reaction.get("LOCCMTSEQ").equals(commentId)) {
|
|
||||||
comment.put("likeCount", reaction.getOrDefault("likeCount", 0));
|
|
||||||
comment.put("dislikeCount", reaction.getOrDefault("dislikeCount", 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 결과 조합
|
|
||||||
MapDto result = new MapDto();
|
|
||||||
result.put("boardDetail", boardDetail);
|
|
||||||
result.put("attachments", attachments);
|
|
||||||
result.put("comments", comments);
|
|
||||||
result.put("commentCount", boardService.getCommentCount(boardId));
|
|
||||||
result.put("hasAttachment", boardService.hasAttachments(boardId));
|
|
||||||
|
|
||||||
return ApiResponse.ok(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 게시물 삭제
|
* 게시물 삭제
|
||||||
* @param boardId 게시물 ID
|
* @param boardId 게시물 ID
|
||||||
* @return 삭제 결과 메시지
|
* @return 삭제 결과 메시지
|
||||||
*/
|
*/
|
||||||
@Member
|
@Member
|
||||||
@ParameterCheck
|
@ParameterCheck
|
||||||
@DeleteMapping("/{boardId}")
|
@DeleteMapping("/{boardId}")
|
||||||
public ApiResponse<String> deleteBoard(@PathVariable("boardId") Long boardId, @ReqMap MapDto map) {
|
public ApiResponse<String> deleteBoard(@PathVariable("boardId") Long boardId, @ReqMap MapDto map) {
|
||||||
map.put("LOCBRDSEQ", boardId);
|
map.put("LOCBRDSEQ", boardId);
|
||||||
log.info("Deleting board with ID: {}", boardId);
|
|
||||||
boardService.deleteBoard(map);
|
boardService.deleteBoard(map);
|
||||||
return ApiResponse.ok("게시물이 삭제되었습니다.");
|
return ApiResponse.ok("게시물이 삭제되었습니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 게시물 수정
|
* 게시물 수정
|
||||||
* @param boardId 게시물 ID
|
* @param boardId 게시물 ID
|
||||||
* @ReqMap map 수정 데이터 (LOCBRDTTL, LOCBRDCON)
|
* @ReqMap map 수정 데이터 (LOCBRDTTL, LOCBRDCON)
|
||||||
* @return 수정 결과 메시지
|
* @return 수정 결과 메시지
|
||||||
*/
|
*/
|
||||||
@Member
|
@Member
|
||||||
@ParameterCheck
|
@ParameterCheck
|
||||||
@PutMapping("/{boardId}")
|
@PutMapping("/{boardId}")
|
||||||
public ApiResponse<String> updateBoard(@PathVariable("boardId") Long boardId,@ReqMap MapDto map) {
|
public ApiResponse<String> updateBoard(@PathVariable("boardId") Long boardId, @ReqMap MapDto map) {
|
||||||
map.put("LOCBRDSEQ", boardId);
|
map.put("LOCBRDSEQ", boardId);
|
||||||
boardService.updateBoard(map);
|
boardService.updateBoard(map);
|
||||||
return ApiResponse.ok("게시물이 수정되었습니다.");
|
return ApiResponse.ok("게시물이 수정되었습니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 게시물,댓글 좋아요/싫어요 추가
|
* 첨부파일 추가
|
||||||
|
* @ReqMap map 요청 파라미터 (CMNFLEREG, CMNFLESIZ, CMNFLEEXT, CMNFLEORG, CMNFLENAM, CMNFLEPAT, CMNBRDSEQ)
|
||||||
|
* @return 첨부파일 저장 결과 메시지
|
||||||
|
*/
|
||||||
|
@Member
|
||||||
|
@ParameterCheck
|
||||||
|
@PostMapping("/{CMNBRDSEQ}/attachments")
|
||||||
|
public ApiResponse<String> uploadAttachment(@ReqMap MapDto map) {
|
||||||
|
boardService.addAttachment(map);
|
||||||
|
return ApiResponse.ok("첨부파일이 저장되었습니다.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 게시물, 댓글 좋아요/싫어요 추가
|
||||||
* @ReqMap map 데이터 (LOCCMTSEQ, MEMBERSEQ, LOCGOBGOD, LOCGOBBAD, LOCBRDSEQ)
|
* @ReqMap map 데이터 (LOCCMTSEQ, MEMBERSEQ, LOCGOBGOD, LOCGOBBAD, LOCBRDSEQ)
|
||||||
* @return 반응 추가 결과 메시지
|
* @return 반응 추가 결과 메시지
|
||||||
*/
|
*/
|
||||||
@Member
|
@Member
|
||||||
@ParameterCheck
|
@ParameterCheck
|
||||||
@PostMapping("/{LOCBRDSEQ}/{LOCCMTSEQ}/reaction")
|
@PostMapping("/{LOCBRDSEQ}/{LOCCMTSEQ}/reaction")
|
||||||
public ApiResponse<String> reactToBoard(@ReqMap MapDto map) {
|
public ApiResponse<String> reactToBoard(@ReqMap MapDto map) {
|
||||||
//로그인 미개발 ->임시
|
|
||||||
map.put("MEMBERSEQ", 1);
|
|
||||||
boardService.reactToBoard(map);
|
boardService.reactToBoard(map);
|
||||||
return ApiResponse.ok("반응이 성공적으로 처리되었습니다.");
|
return ApiResponse.ok("반응이 성공적으로 처리되었습니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 댓글/대댓글 조회
|
* 댓글/대댓글 조회
|
||||||
* @param boardId 게시물 ID
|
* @param boardId 게시물 ID
|
||||||
* @return 댓글과 대댓글의 계층 구조 데이터
|
* @return 댓글과 대댓글의 계층 구조 데이터
|
||||||
*/
|
*/
|
||||||
@Member
|
@Member
|
||||||
@ParameterCheck
|
@ParameterCheck
|
||||||
@GetMapping("/{boardId}/comments")
|
@GetMapping("/{boardId}/comments")
|
||||||
public ApiResponse<List<MapDto>> getComments(@PathVariable("boardId") int boardId) {
|
public ApiResponse<List<MapDto>> getComments(@PathVariable("boardId") int boardId) {
|
||||||
// 모든 댓글과 대댓글 조회
|
return ApiResponse.ok(boardService.getComments(boardId));
|
||||||
List<MapDto> comments = boardService.getComments(boardId);
|
|
||||||
|
|
||||||
return ApiResponse.ok(comments);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
|
||||||
* 댓글/대댓글 작성
|
* 댓글/대댓글 작성
|
||||||
* @param boardId 게시물 ID
|
* @param boardId 게시물 ID
|
||||||
* @ReqMap map 댓글 데이터 (LOCBRDSEQ, LOCCMTRPY, LOCCMTPNT, LOCCMTPWD, MEMBERSEQ 등)
|
* @ReqMap map 댓글 데이터 (LOCBRDSEQ, LOCCMTRPY, LOCCMTPNT, LOCCMTPWD, MEMBERSEQ 등)
|
||||||
* @return 작성 결과 메시지
|
* @return 작성 결과 메시지
|
||||||
*/
|
*/
|
||||||
@Member
|
@Member
|
||||||
@ParameterCheck
|
@ParameterCheck
|
||||||
@PostMapping("/{LOCBRDSEQ}/comment")
|
@PostMapping("/{LOCBRDSEQ}/comment")
|
||||||
public ApiResponse<String> addCommentOrReply(@ReqMap MapDto map) {
|
public ApiResponse<String> addCommentOrReply(@ReqMap MapDto map) {
|
||||||
//로그인 미개발 ->임시
|
|
||||||
map.put("MEMBERSEQ", 1);
|
|
||||||
|
|
||||||
// 비밀번호 암호화 (비밀번호가 있는 경우에만)
|
|
||||||
if (map.containsKey("LOCCMTPWD")) {
|
|
||||||
String rawPassword = map.getString("LOCCMTPWD");
|
|
||||||
String encodedPassword = passwordEncoder.encode(rawPassword);
|
|
||||||
map.put("LOCCMTPWD", encodedPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
boardService.addCommentOrReply(map);
|
boardService.addCommentOrReply(map);
|
||||||
return ApiResponse.ok("댓글 또는 대댓글이 작성되었습니다.");
|
return ApiResponse.ok("댓글 또는 대댓글이 작성되었습니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 댓글/대댓글 수정
|
* 댓글/대댓글 수정
|
||||||
* @param commentId 댓글 ID
|
* @param commentId 댓글 ID
|
||||||
* @ReqMap map 수정 데이터 (LOCCMTSEQ, LOCCMTRPY )
|
* @ReqMap map 수정 데이터 (LOCCMTSEQ, LOCCMTRPY)
|
||||||
* @return 수정 결과 메시지
|
* @return 수정 결과 메시지
|
||||||
*/
|
*/
|
||||||
@Member
|
@Member
|
||||||
@ParameterCheck
|
@ParameterCheck
|
||||||
@PutMapping("/comment/{commentId}")
|
@PutMapping("/comment/{commentId}")
|
||||||
public ApiResponse<String> updateComment(@PathVariable("commentId") int commentId, @ReqMap MapDto map) {
|
public ApiResponse<String> updateComment(@PathVariable("commentId") int commentId, @ReqMap MapDto map) {
|
||||||
// 기존 댓글 조회
|
|
||||||
MapDto existingComment = boardService.getCommentById(commentId);
|
|
||||||
if (existingComment == null) {
|
|
||||||
throw new IllegalArgumentException("Comment not found for ID: " + commentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
map.put("LOCCMTSEQ", commentId);
|
|
||||||
boardService.updateComment(map);
|
boardService.updateComment(map);
|
||||||
|
|
||||||
return ApiResponse.ok("댓글이 수정되었습니다.");
|
return ApiResponse.ok("댓글이 수정되었습니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 댓글/대댓글 삭제
|
* 댓글/대댓글 삭제
|
||||||
* @param commentId 댓글 ID
|
* @param commentId 댓글 ID
|
||||||
|
* @ReqMap map 삭제 데이터
|
||||||
* @return 삭제 결과 메시지
|
* @return 삭제 결과 메시지
|
||||||
*/
|
*/
|
||||||
@Member
|
@Member
|
||||||
@ParameterCheck
|
@ParameterCheck
|
||||||
@DeleteMapping("/comment/{commentId}")
|
@DeleteMapping("/comment/{commentId}")
|
||||||
public ApiResponse<String> deleteComment(@PathVariable("commentId") int commentId, @ReqMap MapDto map) {
|
public ApiResponse<String> deleteComment(@PathVariable("commentId") int commentId, @ReqMap MapDto map) {
|
||||||
map.put("LOCCMTSEQ", commentId);
|
|
||||||
boardService.deleteComment(map);
|
boardService.deleteComment(map);
|
||||||
|
|
||||||
return ApiResponse.ok("댓글이 삭제되었습니다.");
|
return ApiResponse.ok("댓글이 삭제되었습니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 댓글 비밀번호 확인
|
* 댓글 비밀번호 확인
|
||||||
* @param commentId 댓글 ID
|
* @param commentId 댓글 ID
|
||||||
* @ReqMap map 비밀번호 데이터
|
* @ReqMap map 비밀번호 데이터
|
||||||
* @return 비밀번호 확인 결과
|
* @return 비밀번호 확인 결과
|
||||||
*/
|
*/
|
||||||
@Member
|
@Member
|
||||||
@ParameterCheck
|
@ParameterCheck
|
||||||
@PostMapping("/comment/{commentId}/password")
|
@PostMapping("/comment/{commentId}/password")
|
||||||
public ApiResponse<Boolean> checkCommentPassword(@PathVariable("commentId") int commentId, @ReqMap MapDto map) {
|
public ApiResponse<Boolean> checkCommentPassword(@PathVariable("commentId") int commentId, @ReqMap MapDto map) {
|
||||||
// DB에서 암호화된 비밀번호 조회
|
return ApiResponse.ok(boardService.getCommentPassword(commentId).equals(map.getString("LOCCMTPWD")));
|
||||||
String storedPassword = boardService.getCommentPassword(commentId);
|
|
||||||
String rawPassword = map.getString("LOCCMTPWD");
|
|
||||||
|
|
||||||
// 비밀번호 검증
|
|
||||||
boolean isMatch = passwordEncoder.matches(rawPassword, storedPassword);
|
|
||||||
return ApiResponse.ok(isMatch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 게시물 비밀번호 확인
|
* 게시물 비밀번호 확인
|
||||||
* @param boardId 게시물 ID
|
* @param boardId 게시물 ID
|
||||||
* @ReqMap map 비밀번호 데이터
|
* @ReqMap map 비밀번호 데이터
|
||||||
* @return 비밀번호 확인 결과
|
* @return 비밀번호 확인 결과
|
||||||
*/
|
*/
|
||||||
@Member
|
@Member
|
||||||
@ParameterCheck
|
@ParameterCheck
|
||||||
@PostMapping("/{boardId}/password")
|
@PostMapping("/{boardId}/password")
|
||||||
public ApiResponse<Boolean> checkBoardPassword(@PathVariable("boardId") int boardId, @ReqMap MapDto map) {
|
public ApiResponse<Boolean> checkBoardPassword(@PathVariable("boardId") int boardId, @ReqMap MapDto map) {
|
||||||
// DB에서 암호화된 비밀번호 조회
|
return ApiResponse.ok(boardService.getBoardPassword(boardId).equals(map.getString("LOCBRDPWD")));
|
||||||
String storedPassword = boardService.getBoardPassword(boardId);
|
|
||||||
String rawPassword = map.getString("LOCBRDPWD");
|
|
||||||
|
|
||||||
// 비밀번호 검증
|
|
||||||
boolean isMatch = passwordEncoder.matches(rawPassword, storedPassword);
|
|
||||||
return ApiResponse.ok(isMatch);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
@ -1,11 +1,15 @@
|
|||||||
package io.company.localhost.service;
|
package io.company.localhost.service;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
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.PageHelper;
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
|
|
||||||
@ -20,13 +24,15 @@ public class localbordService {
|
|||||||
private final localbordMapper boardMapper;
|
private final localbordMapper boardMapper;
|
||||||
|
|
||||||
public List<MapDto> getNotices(MapDto map) {
|
public List<MapDto> getNotices(MapDto map) {
|
||||||
return boardMapper.getNotices(map);
|
List<MapDto> posts = boardMapper.getNotices(map);
|
||||||
|
enrichPostsWithAdditionalData(posts);
|
||||||
|
return posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PageInfo<MapDto> getGeneralPosts(MapDto map) {
|
public PageInfo<MapDto> getGeneralPosts(MapDto map) {
|
||||||
int page = map.getString("page") != null ? Integer.parseInt(map.getString("page")) : 1;
|
int page = map.getString("page") != null ? Integer.parseInt(map.getString("page")) : 1;
|
||||||
int size = map.getString("size") != null ? Integer.parseInt(map.getString("size")) : 10;
|
int size = map.getString("size") != null ? Integer.parseInt(map.getString("size")) : 10;
|
||||||
|
|
||||||
String orderBy = map.getString("orderBy");
|
String orderBy = map.getString("orderBy");
|
||||||
if (orderBy == null || (!orderBy.equals("date") && !orderBy.equals("views"))) {
|
if (orderBy == null || (!orderBy.equals("date") && !orderBy.equals("views"))) {
|
||||||
map.put("orderBy", "date");
|
map.put("orderBy", "date");
|
||||||
@ -35,33 +41,38 @@ public class localbordService {
|
|||||||
PageHelper.startPage(page, size);
|
PageHelper.startPage(page, size);
|
||||||
|
|
||||||
List<MapDto> result = boardMapper.getGeneralPosts(map);
|
List<MapDto> result = boardMapper.getGeneralPosts(map);
|
||||||
|
enrichPostsWithAdditionalData(result);
|
||||||
|
|
||||||
return PageUtil.redefineNavigation(new PageInfo<>(result, size));
|
return PageUtil.redefineNavigation(new PageInfo<>(result, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void incrementViewCount(Long boardId) {
|
public void incrementViewCount(Long boardId) {
|
||||||
boardMapper.incrementViewCount(boardId);
|
boardMapper.incrementViewCount(boardId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigInteger createBoard(MapDto map) {
|
public BigInteger createBoard(MapDto map) {
|
||||||
boardMapper.createBoard(map);
|
boardMapper.createBoard(map);
|
||||||
return (BigInteger) map.get("LOCBRDSEQ"); // Mapper에서 자동 생성된 key를 가져옴
|
return (BigInteger) map.get("LOCBRDSEQ");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAttachment(MapDto map) {
|
public void addAttachment(MapDto map) {
|
||||||
boardMapper.addAttachment(map);
|
boardMapper.addAttachment(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapDto getBoardDetail(Long boardId) {
|
public MapDto getBoardDetail(Long boardId) {
|
||||||
return boardMapper.selectBoardDetail(boardId);
|
MapDto boardDetail = boardMapper.selectBoardDetail(boardId);
|
||||||
|
if (boardDetail != null) {
|
||||||
|
enrichBoardDetail(boardDetail);
|
||||||
|
}
|
||||||
|
return boardDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<MapDto> getAttachments(Long boardId) {
|
public List<MapDto> getAttachments(Long boardId) {
|
||||||
return boardMapper.selectAttachments(boardId);
|
return boardMapper.selectAttachments(boardId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteBoard(MapDto map) {
|
public void deleteBoard(MapDto map) {
|
||||||
boardMapper.deleteCommentsByBoardId(map);
|
boardMapper.deleteCommentsByBoardId(map);
|
||||||
boardMapper.deleteBoard(map);
|
boardMapper.deleteBoard(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,14 +81,11 @@ public class localbordService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void reactToBoard(MapDto map) {
|
public void reactToBoard(MapDto map) {
|
||||||
// 기존 반응 확인
|
|
||||||
MapDto existingReaction = boardMapper.findReaction(map);
|
MapDto existingReaction = boardMapper.findReaction(map);
|
||||||
|
|
||||||
if (existingReaction != null) {
|
if (existingReaction != null) {
|
||||||
// 기존 반응이 있는 경우 업데이트
|
|
||||||
boardMapper.updateReaction(map);
|
boardMapper.updateReaction(map);
|
||||||
} else {
|
} else {
|
||||||
// 기존 반응이 없는 경우 새로 삽입
|
|
||||||
boardMapper.insertReaction(map);
|
boardMapper.insertReaction(map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,8 +95,8 @@ public class localbordService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addCommentOrReply(MapDto map) {
|
public void addCommentOrReply(MapDto map) {
|
||||||
if (map.get("LOCCMTPNT") == null) {
|
if (map.get("LOCCMTPNT") == null) {
|
||||||
map.put("LOCCMTPNT", null);
|
map.put("LOCCMTPNT", null);
|
||||||
}
|
}
|
||||||
boardMapper.addCommentOrReply(map);
|
boardMapper.addCommentOrReply(map);
|
||||||
}
|
}
|
||||||
@ -98,22 +106,17 @@ public class localbordService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void deleteComment(MapDto map) {
|
public void deleteComment(MapDto map) {
|
||||||
// 댓글인지 대댓글인지 확인
|
|
||||||
boolean isReply = boardMapper.isReply(map);
|
boolean isReply = boardMapper.isReply(map);
|
||||||
|
|
||||||
if (isReply) {
|
if (isReply) {
|
||||||
// 대댓글 삭제
|
boardMapper.deleteReply(map);
|
||||||
boardMapper.deleteReply(map);
|
|
||||||
} else {
|
} else {
|
||||||
// 댓글인 경우
|
|
||||||
boolean hasReplies = boardMapper.hasReplies(map);
|
boolean hasReplies = boardMapper.hasReplies(map);
|
||||||
|
|
||||||
if (hasReplies) {
|
if (hasReplies) {
|
||||||
// 대댓글이 있는 경우 내용 업데이트
|
boardMapper.softDeleteComment(map);
|
||||||
boardMapper.softDeleteComment(map);
|
|
||||||
} else {
|
} else {
|
||||||
// 대댓글이 없는 경우 댓글 삭제
|
boardMapper.deleteComment(map);
|
||||||
boardMapper.deleteComment(map);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,24 +124,24 @@ public class localbordService {
|
|||||||
public String getCommentPassword(int commentId) {
|
public String getCommentPassword(int commentId) {
|
||||||
return boardMapper.selectCommentPassword(commentId);
|
return boardMapper.selectCommentPassword(commentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBoardPassword(int boardId) {
|
public String getBoardPassword(int boardId) {
|
||||||
return boardMapper.selectBoardPassword(boardId);
|
return boardMapper.selectBoardPassword(boardId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapDto getCommentById(int commentId) {
|
public MapDto getCommentById(int commentId) {
|
||||||
return boardMapper.getCommentById(commentId);
|
return boardMapper.getCommentById(commentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCommentCount(Long boardId) {
|
public int getCommentCount(Long boardId) {
|
||||||
return boardMapper.countComments(boardId);
|
return boardMapper.countComments(boardId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAttachments(Long boardId) {
|
public boolean hasAttachments(Long boardId) {
|
||||||
int count = boardMapper.countAttachments(boardId);
|
int count = boardMapper.countAttachments(boardId);
|
||||||
return count > 0;
|
return count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapDto getBoardReactions(Long boardId) {
|
public MapDto getBoardReactions(Long boardId) {
|
||||||
return boardMapper.getBoardReactions(boardId);
|
return boardMapper.getBoardReactions(boardId);
|
||||||
}
|
}
|
||||||
@ -147,6 +150,128 @@ public class localbordService {
|
|||||||
return boardMapper.getCommentReactions(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<MapDto> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user