290 lines
12 KiB
Java
290 lines
12 KiB
Java
package sgis.board.controller;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Comparator;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.time.OffsetDateTime; // OffsetDateTime import 추가
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.util.Map;
|
|
import java.util.stream.Collectors;
|
|
|
|
import javax.servlet.http.HttpSession;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.ui.ModelMap;
|
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
|
import org.springframework.web.bind.annotation.GetMapping;
|
|
import org.springframework.web.bind.annotation.ModelAttribute; // ModelAttribute import는 다른 메서드를 위해 유지
|
|
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.ResponseBody;
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
|
|
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
|
|
|
import egovframework.com.cmm.util.EgovUserDetailsHelper;
|
|
import sgis.board.entity.Board;
|
|
import sgis.board.entity.Member;
|
|
import sgis.board.entity.Post; // Post entity import
|
|
import sgis.board.mapper.BoardMapper;
|
|
import sgis.board.mapper.MemberMapper;
|
|
import sgis.board.mapper.PostMapper;
|
|
import sgis.board.service.PostService;
|
|
import sgis.com.vo.SessionVO;
|
|
import sgis.com.web.BaseController;
|
|
|
|
@RestController // @ResponseBody(JSON)응답
|
|
public class BoardRestController extends BaseController {
|
|
|
|
@Autowired
|
|
BoardMapper boardMapper; // 기존 Board 관련 로직을 사용하지 않는다면 제거 고려
|
|
|
|
@Autowired
|
|
PostService postService;
|
|
|
|
@Autowired
|
|
MemberMapper memberMapper;
|
|
|
|
// ObjectMapper 인스턴스 생성
|
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
public BoardRestController() {
|
|
// OffsetDateTime을 ISO 8601 형식으로 직렬화하기 위한 설정
|
|
objectMapper.findAndRegisterModules(); // Java 8 date/time modules 등록
|
|
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
|
}
|
|
|
|
/**
|
|
* @Method_Name : getSessionInfo
|
|
* @Date : 2022. 5. 10.
|
|
* @Creator : ICTWAY KIM Yoon-Su
|
|
* @Method_Discription : 세션정보 가져오기
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public SessionVO getSessionInfo() throws Exception {
|
|
return (SessionVO) EgovUserDetailsHelper.getAuthenticatedUser();
|
|
}
|
|
|
|
// Post 객체를 Board 객체로 변환하는 헬퍼 메서드
|
|
private Board postToBoard(Post post) {
|
|
Board board = new Board();
|
|
if( post == null ) {
|
|
return board;
|
|
}
|
|
board.setIdx(post.getPostId() != null ? post.getPostId().intValue() : 0);
|
|
board.setUserId(post.getUserNo() != null ? String.valueOf(post.getUserNo()) : null);
|
|
// 답변글 제목 형식 변경 로직
|
|
if (post.getParentPostId() != null && post.getParentPostId() != 0) {
|
|
// 부모 게시글 정보 조회 (부모 게시글의 제목을 가져오기 위함)
|
|
Post parentPost = postService.getPostById(post.getParentPostId());
|
|
if (parentPost != null) {
|
|
board.setTitle("" + parentPost.getTitle()); // "<상위글 제목>" 형식으로 설정
|
|
} else {
|
|
board.setTitle(post.getTitle()); // 부모 게시글을 찾을 수 없으면 원본 제목 사용
|
|
}
|
|
} else {
|
|
board.setTitle(post.getTitle()); // 답변글이 아니면 원본 제목 사용
|
|
}
|
|
|
|
board.setBoardContent(post.getContent());
|
|
board.setWriter(post.getUserNo() != null ? "User " + post.getUserNo() : "Unknown"); // 실제 사용자 이름을 가져오는 로직 필요
|
|
|
|
// Handle dates: OffsetDateTime to String (assuming 'yyyy-MM-dd HH:mm:ss' format for indate)
|
|
if (post.getCreatedAt() != null) { // Checks if createdAt is not null
|
|
board.setIndate(post.getCreatedAt().toLocalDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); // Formats createdAt to String
|
|
} else {
|
|
board.setIndate(null); // Sets indate to null if createdAt is null
|
|
}
|
|
board.setCount(post.getViewCount() != null ? post.getViewCount() : 0); // Maps viewCount to count, handling potential null
|
|
|
|
// JSP의 Kendo Grid가 기대하는 project 관련 필드들 (Post 데이터에서 매핑 필요)
|
|
board.setProjectName(post.getTitle()); // 예시: Post의 title을 projectName으로 매핑
|
|
board.setProjectHarborName(""); // Post에 직접적인 매핑이 없다면 빈 문자열 또는 다른 로직으로 채움
|
|
board.setProjectOrderingName("");
|
|
board.setProjectAffiliatedName("");
|
|
board.setProjectInputId(post.getUserNo() != null ? String.valueOf(post.getUserNo()) : null); // 예시: Post의 userId를 projectInputId로 매핑
|
|
|
|
// projectStartDate, projectEndDate도 Post의 createdAt, updatedAt에서 매핑
|
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
if (post.getCreatedAt() != null) {
|
|
board.setProjectStartDate(post.getCreatedAt().format(formatter));
|
|
} else {
|
|
board.setProjectStartDate(null);
|
|
}
|
|
if (post.getUpdatedAt() != null) {
|
|
board.setProjectEndDate(post.getUpdatedAt().format(formatter));
|
|
} else {
|
|
board.setProjectEndDate(null);
|
|
}
|
|
board.setUserNm(post.getUserNo() != null ? "User" + post.getUserNo() : "Unknown"); // userNm 매핑 (예시)
|
|
board.setParentPostId(post.getParentPostId()); // parentPostId 매핑 추가
|
|
|
|
return board;
|
|
}
|
|
|
|
|
|
// @ResponseBody->jackson-databind(객체를->JSON 데이터포멧으로 변환)
|
|
@RequestMapping(value = "/sgis/portal/board/all.do", produces = "application/json;charset=UTF-8")
|
|
public String boardList(@RequestParam HashMap<String,Object> params, ModelMap model, Member m, HttpSession session) throws JsonProcessingException {
|
|
String boardCategoryIdParam = (String) params.get("boardCategoryId"); // Get the parameter as String
|
|
List<Post> posts;
|
|
|
|
// 게시글 조회
|
|
if ("all".equalsIgnoreCase(boardCategoryIdParam) || boardCategoryIdParam == null || boardCategoryIdParam.isEmpty()) {
|
|
posts = postService.getAllPosts(); // If "all" or null/empty, get all posts
|
|
} else {
|
|
try {
|
|
Integer boardCategoryId = Integer.valueOf(boardCategoryIdParam); // Try to convert to Integer
|
|
posts = postService.getPostsByBoardCategoryId(boardCategoryId); // Get posts by specific category
|
|
} catch (NumberFormatException e) {
|
|
System.err.println("Invalid boardCategoryId format: " + boardCategoryIdParam + ". Fetching all posts instead.");
|
|
posts = postService.getAllPosts(); // Fallback to all posts if conversion fails
|
|
}
|
|
}
|
|
|
|
// 게시글 정렬 로직 (부모-자식 관계에 따라 정렬)
|
|
List<Board> boardListForJsp = new ArrayList<>();
|
|
|
|
// 1. 부모 게시글과 답변 게시글을 분리
|
|
Map<Long, List<Post>> repliesMap = posts.stream()
|
|
.filter(post -> post.getParentPostId() != null)
|
|
.collect(Collectors.groupingBy(Post::getParentPostId, Collectors.toCollection(ArrayList::new)));
|
|
|
|
List<Post> topLevelPosts = posts.stream()
|
|
.filter(post -> post.getParentPostId() == null)
|
|
.sorted(Comparator.comparing(Post::getCreatedAt).reversed()) // 최신글이 위로 오도록 정렬
|
|
.collect(Collectors.toList());
|
|
|
|
// 2. 부모 게시글 아래에 답변 게시글을 삽입하여 최종 정렬된 리스트 생성
|
|
for (Post topPost : topLevelPosts) {
|
|
boardListForJsp.add(postToBoard(topPost)); // 부모 게시글 추가
|
|
|
|
// 해당 부모 게시글의 답변들을 가져와서 정렬 (예: 오래된 답변이 먼저 오도록)
|
|
List<Post> currentReplies = repliesMap.get(topPost.getPostId());
|
|
if (currentReplies != null && !currentReplies.isEmpty()) {
|
|
currentReplies.sort(Comparator.comparing(Post::getCreatedAt)); // 답변은 오래된 순서로
|
|
for (Post reply : currentReplies) {
|
|
boardListForJsp.add(postToBoard(reply)); // 답변 게시글 추가
|
|
}
|
|
}
|
|
}
|
|
|
|
HashMap<String, Object> responseMap = new HashMap<>();
|
|
responseMap.put("dataList1", boardListForJsp);
|
|
|
|
return objectMapper.writeValueAsString(responseMap); // Returns the list of Board objects as JSON data
|
|
}
|
|
|
|
@PostMapping("/sgis/portal/board/new.do")
|
|
@ResponseBody
|
|
public Post createNewPost(
|
|
@RequestParam("boardCategoryId") Integer boardCategoryId,
|
|
@RequestParam("title") String title,
|
|
@RequestParam("boardContent") String content,
|
|
// Using @RequestParam(value = "parentPostId", required = false) for optionality.
|
|
// If it comes as an empty string, it will be null.
|
|
@RequestParam(value = "parentPostId", required = false) Long parentPostId // This is good
|
|
) {
|
|
Post newPost = new Post();
|
|
newPost.setBoardCategoryId(boardCategoryId);
|
|
newPost.setTitle(title);
|
|
newPost.setContent(content);
|
|
// parentPostId를 Post 객체에 설정합니다. (null일 수도 있음)
|
|
newPost.setParentPostId(parentPostId);
|
|
|
|
|
|
// userId를 세션에서 직접 가져와 Post 객체에 설정합니다.
|
|
try {
|
|
SessionVO sessionVO = getSessionInfo();
|
|
|
|
String userId = sessionVO.getsUserId();
|
|
|
|
if (sessionVO != null && sessionVO.getsUserId() != null) {
|
|
Member m = memberMapper.registerCheck(userId);
|
|
if( m!=null ) {
|
|
newPost.setUserNo(m.getUserNo()); // userId는 String 타입으로 직접 설정
|
|
}
|
|
|
|
} else {
|
|
System.err.println("User ID not found in session for Post creation or session is null.");
|
|
throw new IllegalStateException("User ID is required for post creation.");
|
|
}
|
|
} catch (Exception e) {
|
|
System.err.println("Error getting session info for Post creation: " + e.getMessage());
|
|
throw new RuntimeException("Failed to get session user info.", e);
|
|
}
|
|
|
|
|
|
// 그 외 필드 (기본값 설정)
|
|
newPost.setViewCount(0); // 새 글이므로 0
|
|
newPost.setStatus("active"); // 기본 상태
|
|
newPost.setCreatedAt(OffsetDateTime.now()); // 현재 시간으로 설정
|
|
newPost.setUpdatedAt(OffsetDateTime.now()); // 현재 시간으로 설정
|
|
|
|
// PostService를 통해 게시글 생성
|
|
Post createdPost = postService.createPost(newPost);
|
|
|
|
// 생성된 Post 객체 반환 (클라이언트에게 성공 여부 및 생성된 게시글 정보 전달)
|
|
return createdPost;
|
|
}
|
|
|
|
|
|
@DeleteMapping("/sgis/portal/board/delete{idx}.do")
|
|
public void boardDelete(@PathVariable("idx") int idx) {
|
|
postService.deletePost(Long.valueOf(idx)); // PostService의 deletePost 호출
|
|
}
|
|
|
|
@PutMapping("/sgis/portal/board/update.do")
|
|
public void boardUpdate(@RequestBody Board vo) {
|
|
// 1. Get the postId from the incoming Board object
|
|
Long postId = Long.valueOf(vo.getIdx());
|
|
|
|
// 2. Fetch the existing Post from the database
|
|
Post existingPost = postService.getPostById(postId);
|
|
|
|
if (existingPost == null) {
|
|
// Handle case where the post to update is not found.
|
|
// You might want to throw a specific exception or return an error response.
|
|
System.err.println("Post with ID " + postId + " not found for update.");
|
|
// Example: throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Post not found");
|
|
return; // Or return an appropriate ResponseEntity
|
|
}
|
|
|
|
// 3. Update only the fields that are provided in the request body
|
|
// The JSP sends title and boardContent, which map to title and content in Post.
|
|
existingPost.setTitle(vo.getTitle());
|
|
existingPost.setContent(vo.getBoardContent());
|
|
existingPost.setUpdatedAt(OffsetDateTime.now()); // Update the modification timestamp
|
|
|
|
// Other fields like boardCategoryId, parentPostId, userNo, viewCount, status
|
|
// will retain their original values from 'existingPost' as they are not
|
|
// explicitly updated from the 'Board vo' in this method.
|
|
|
|
// 4. Call PostService to update the post with the modified existingPost object
|
|
postService.updatePost(existingPost);
|
|
}
|
|
|
|
@GetMapping("/sgis/portal/board/{idx}.do")
|
|
public Board boardContent(@RequestParam HashMap<String,Object> params, @PathVariable("idx") int idx) {
|
|
Post post = postService.getPostById(Long.valueOf(idx) ); // PostService를 통해 Post 조회
|
|
Board vo = postToBoard(post); // Post 객체를 Board 객체로 변환
|
|
return vo;
|
|
}
|
|
|
|
@PutMapping("/sgis/portal/board/count/{idx}.do")
|
|
public Board boardCount(@PathVariable("idx") int idx) {
|
|
Post post = postService.getPostById(Long.valueOf(idx)); // getPostById 호출 시 조회수 자동 증가
|
|
Board vo = postToBoard(post);
|
|
return vo;
|
|
}
|
|
}
|