325 lines
11 KiB
Java
325 lines
11 KiB
Java
/************************************************************
|
|
*
|
|
* @packageName : io.company.localhost.controller.api
|
|
* @fileName : BoardController.java
|
|
* @author : 서지희
|
|
* @date : 25.01.07
|
|
* @description : 게시판
|
|
*
|
|
* ===========================================================
|
|
* DATE AUTHOR NOTE
|
|
* -----------------------------------------------------------
|
|
* 24.01.02 서지희 최초 생성
|
|
*
|
|
*************************************************************/
|
|
|
|
package io.company.localhost.controller.api;
|
|
|
|
import java.math.BigInteger;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.sql.Blob;
|
|
import java.util.ArrayList;
|
|
import java.util.Date;
|
|
import java.util.HashMap;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import org.springframework.http.ResponseEntity;
|
|
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.RequestBody;
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
import org.springframework.web.bind.annotation.RequestParam;
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
import com.github.pagehelper.PageInfo;
|
|
import com.github.pagehelper.PageSerializable;
|
|
|
|
import io.company.localhost.common.annotation.ReqMap;
|
|
import io.company.localhost.common.dto.ApiResponse;
|
|
import io.company.localhost.common.dto.MapDto;
|
|
import io.company.localhost.service.localbordService;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
@RestController
|
|
@RequestMapping("/api/board")
|
|
@RequiredArgsConstructor
|
|
@Slf4j
|
|
public class BoardController {
|
|
private final localbordService boardService;
|
|
|
|
/**
|
|
* 공지사항 목록 조회
|
|
* @ReqMap map 요청 파라미터 (searchKeyword)
|
|
* @return 전체 공지사항 목록
|
|
*/
|
|
@GetMapping("/notices")
|
|
public ApiResponse<List<MapDto>> getNotices(@ReqMap MapDto map) {
|
|
List<MapDto> posts = 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));
|
|
}
|
|
}
|
|
|
|
return ApiResponse.ok(posts);
|
|
}
|
|
|
|
/**
|
|
* 자유/익명 게시판 목록 조회
|
|
* @ReqMap map 요청 파라미터 (page, searchKeyword)
|
|
* @return 페이징된 자유/익명 게시판 목록
|
|
*/
|
|
@GetMapping("/general")
|
|
public ApiResponse<PageInfo<MapDto>> getGeneralPosts(@ReqMap MapDto map) {
|
|
PageInfo<MapDto> posts = 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));
|
|
}
|
|
}
|
|
|
|
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,
|
|
* LOCBRDPWD(익명일떄에만), LOCBRDCAT(지식커뮤니티만))
|
|
* @return 작성된 게시물의 ID
|
|
*/
|
|
@PostMapping
|
|
public ApiResponse<?> createBoard(@ReqMap MapDto map) {
|
|
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 첨부파일 저장 결과 메시지
|
|
*/
|
|
@PostMapping("/{CMNBRDSEQ}/attachments")
|
|
public ApiResponse<String> uploadAttachment(@ReqMap MapDto map) {
|
|
// 파일 데이터 저장
|
|
boardService.addAttachment(map);
|
|
|
|
return ApiResponse.ok("첨부파일이 저장되었습니다.");
|
|
}
|
|
|
|
/**
|
|
* 게시물 상세보기
|
|
* @param boardId 게시물 ID
|
|
* @return 게시물 상세정보, 첨부파일 목록, 댓글 목록
|
|
*/
|
|
@GetMapping("/{boardId}")
|
|
public ApiResponse<MapDto> getBoardDetail(@PathVariable("boardId") Long boardId) {
|
|
log.info("Fetching details for board ID: {}", 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);
|
|
}
|
|
}
|
|
|
|
// 첨부파일 및 댓글 조회
|
|
List<MapDto> attachments = boardService.getAttachments(boardId);
|
|
List<MapDto> comments = boardService.getComments(boardId.intValue());
|
|
|
|
// 결과 조합
|
|
MapDto result = new MapDto();
|
|
result.put("boardDetail", boardDetail);
|
|
result.put("attachments", attachments);
|
|
result.put("comments", comments);
|
|
|
|
return ApiResponse.ok(result);
|
|
}
|
|
|
|
/**
|
|
* 게시물 삭제
|
|
* @param boardId 게시물 ID
|
|
* @return 삭제 결과 메시지
|
|
*/
|
|
@DeleteMapping("/{boardId}")
|
|
public ApiResponse<String> deleteBoard(@PathVariable("boardId") Long boardId, @ReqMap MapDto map) {
|
|
map.put("LOCBRDSEQ", boardId);
|
|
log.info("Deleting board with ID: {}", boardId);
|
|
boardService.deleteBoard(map);
|
|
return ApiResponse.ok("게시물이 삭제되었습니다.");
|
|
}
|
|
|
|
/**
|
|
* 게시물 수정
|
|
* @param boardId 게시물 ID
|
|
* @ReqMap map 수정 데이터 (LOCBRDTTL, LOCBRDCON)
|
|
* @return 수정 결과 메시지
|
|
*/
|
|
@PutMapping("/{boardId}")
|
|
public ApiResponse<String> updateBoard(@PathVariable("boardId") Long boardId,@ReqMap MapDto map) {
|
|
map.put("LOCBRDSEQ", boardId);
|
|
boardService.updateBoard(map);
|
|
return ApiResponse.ok("게시물이 수정되었습니다.");
|
|
}
|
|
|
|
/**
|
|
* 게시물,댓글 좋아요/싫어요 추가
|
|
* @ReqMap map 데이터 (LOCCMTSEQ, MEMBERSEQ, LOCGOBGOD, LOCGOBBAD, LOCBRDSEQ)
|
|
* @return 반응 추가 결과 메시지
|
|
*/
|
|
@PostMapping("/{LOCBRDSEQ}/{LOCCMTSEQ}/reaction")
|
|
public ApiResponse<String> reactToBoard(@ReqMap MapDto map) {
|
|
boardService.reactToBoard(map);
|
|
return ApiResponse.ok("반응이 추가되었습니다.");
|
|
}
|
|
|
|
/**
|
|
* 댓글/대댓글 조회
|
|
* @param boardId 게시물 ID
|
|
* @return 댓글과 대댓글의 계층 구조 데이터
|
|
*/
|
|
@GetMapping("/{boardId}/comments")
|
|
public ApiResponse<List<MapDto>> getComments(@PathVariable("boardId") int boardId) {
|
|
// 모든 댓글과 대댓글 조회
|
|
List<MapDto> comments = boardService.getComments(boardId);
|
|
|
|
return ApiResponse.ok(comments);
|
|
}
|
|
|
|
|
|
/**
|
|
* 댓글/대댓글 작성
|
|
* @param boardId 게시물 ID
|
|
* @ReqMap map 댓글 데이터 (LOCBRDSEQ, LOCCMTRPY, LOCCMTPNT, LOCCMTPWD, MEMBERSEQ 등)
|
|
* @return 작성 결과 메시지
|
|
*/
|
|
@PostMapping("/{LOCBRDSEQ}/comment")
|
|
public ApiResponse<String> addCommentOrReply(@ReqMap MapDto map) {
|
|
// 부모 댓글 확인
|
|
|
|
|
|
boardService.addCommentOrReply(map);
|
|
return ApiResponse.ok("댓글 또는 대댓글이 작성되었습니다.");
|
|
}
|
|
|
|
/**
|
|
* 댓글/대댓글 수정
|
|
* @param commentId 댓글 ID
|
|
* @ReqMap map 수정 데이터 (LOCCMTSEQ, LOCCMTRPY )
|
|
* @return 수정 결과 메시지
|
|
*/
|
|
@PutMapping("/comment/{commentId}")
|
|
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);
|
|
|
|
return ApiResponse.ok("댓글이 수정되었습니다.");
|
|
}
|
|
|
|
/**
|
|
* 댓글/대댓글 삭제
|
|
* @param commentId 댓글 ID
|
|
* @return 삭제 결과 메시지
|
|
*/
|
|
@DeleteMapping("/comment/{commentId}")
|
|
public ApiResponse<String> deleteComment(@PathVariable("commentId") int commentId, @ReqMap MapDto map) {
|
|
map.put("LOCCMTSEQ", commentId);
|
|
boardService.deleteComment(map);
|
|
|
|
return ApiResponse.ok("댓글이 삭제되었습니다.");
|
|
}
|
|
|
|
/**
|
|
* 댓글 비밀번호 확인
|
|
* @param commentId 댓글 ID
|
|
* @ReqMap map 비밀번호 데이터
|
|
* @return 비밀번호 확인 결과
|
|
*/
|
|
@PostMapping("/comment/{commentId}/password")
|
|
public ApiResponse<Boolean> checkCommentPassword(@PathVariable("commentId") int commentId, @ReqMap MapDto map) {
|
|
map.put("LOCCMTSEQ", commentId);
|
|
return ApiResponse.ok(boardService.checkCommentPassword(map));
|
|
}
|
|
|
|
/**
|
|
* 게시물 비밀번호 확인
|
|
* @param boardId 게시물 ID
|
|
* @ReqMap map 비밀번호 데이터
|
|
* @return 비밀번호 확인 결과
|
|
*/
|
|
@PostMapping("/{boardId}/password")
|
|
public ApiResponse<Boolean> checkBoardPassword(@PathVariable("boardId") int boardId, @ReqMap MapDto map) {
|
|
map.put("LOCBRDSEQ", boardId);
|
|
return ApiResponse.ok(boardService.checkBoardPassword(map));
|
|
}
|
|
|
|
// /**
|
|
// * 비밀게시판 여부 확인
|
|
// * @param boardId 게시물 ID
|
|
// * @return 비밀게시판 여부
|
|
// */
|
|
// @GetMapping("/{boardId}/isSecret")
|
|
// public ApiResponse<Boolean> isSecretBoard(@PathVariable("boardId") Long boardId) {
|
|
// log.info("Checking if board ID {} is secret", boardId);
|
|
// return ApiResponse.ok(boardService.isSecretBoard(boardId));
|
|
// }
|
|
|
|
}
|