diff --git a/src/main/java/io/company/localhost/controller/api/BoardController.java b/src/main/java/io/company/localhost/controller/api/BoardController.java index 387bb23..99347f4 100644 --- a/src/main/java/io/company/localhost/controller/api/BoardController.java +++ b/src/main/java/io/company/localhost/controller/api/BoardController.java @@ -18,27 +18,26 @@ 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.List; import java.util.Map; +import java.util.UUID; -import org.springframework.http.ResponseEntity; +import org.springframework.security.crypto.password.PasswordEncoder; 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.fasterxml.jackson.databind.ObjectMapper; import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageSerializable; +import io.company.localhost.common.annotation.Member; +import io.company.localhost.common.annotation.ParameterCheck; import io.company.localhost.common.annotation.ReqMap; import io.company.localhost.common.dto.ApiResponse; import io.company.localhost.common.dto.MapDto; @@ -52,12 +51,15 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class BoardController { private final localbordService boardService; + private final PasswordEncoder passwordEncoder; /** * 공지사항 목록 조회 * @ReqMap map 요청 파라미터 (searchKeyword) - * @return 페이징된 공지사항 목록 + * @return 전체 공지사항 목록 */ + @Member + @ParameterCheck @GetMapping("/notices") public ApiResponse> getNotices(@ReqMap MapDto map) { List posts = boardService.getNotices(map); @@ -69,6 +71,12 @@ public class BoardController { 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); @@ -76,9 +84,11 @@ public class BoardController { /** * 자유/익명 게시판 목록 조회 - * @ReqMap map 요청 파라미터 (page, size, searchKeyword 포함) + * @ReqMap map 요청 파라미터 (page, searchKeyword, orderBy) * @return 페이징된 자유/익명 게시판 목록 */ + @Member + @ParameterCheck @GetMapping("/general") public ApiResponse> getGeneralPosts(@ReqMap MapDto map) { PageInfo posts = boardService.getGeneralPosts(map); @@ -90,6 +100,19 @@ public class BoardController { 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); @@ -121,56 +144,55 @@ public class BoardController { /** * 게시물 작성 - * @ReqMap map 요청 파라미터 (page, size, searchKeyword 포함) + * @ReqMap map 요청 파라미터 (LOCBRDTTL, LOCBRDCON, MEMBERSEQ, LOCBRDTYP, + * LOCBRDPWD(익명일떄에만), LOCBRDCAT(지식커뮤니티만)) * @return 작성된 게시물의 ID */ - @PostMapping - public ApiResponse createBoard(@ReqMap MapDto map) { - BigInteger createdIdx = boardService.createBoard(map); // 작성된 게시물의 idx를 반환 - Map responseData = new HashMap<>(); - responseData.put("boardId", createdIdx); - responseData.put("message", "게시물이 작성되었습니다."); - return ApiResponse.ok(responseData); - } + @Member + @ParameterCheck + @PostMapping + public ApiResponse createBoard(@ReqMap MapDto 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 responseData = new HashMap<>(); + responseData.put("CMNBRDSEQ", createdIdx); + responseData.put("message", "게시물이 작성되었습니다."); + return ApiResponse.ok(responseData); + } /** * 첨부파일 추가 - * @param boardId 게시물 ID - * @param file 업로드된 파일 - * @param filePath 파일 저장 경로 - * @param originalFileName 원본 파일명 - * @param fileExtension 파일 확장자 - * @param fileSize 파일 크기 - * @param registrantId 등록자 ID - * @param fileName 저장될 파일명 + * @ReqMap map 요청 파라미터 (CMNFLEREG, CMNFLESIZ, CMNFLEEXT, CMNFLEORG, CMNFLENAM, CMNFLEPAT, CMNBRDSEQ) * @return 첨부파일 저장 결과 메시지 */ - @PostMapping("/{boardId}/attachments") - public ApiResponse uploadAttachment( - @PathVariable("boardId") Long boardId, - @RequestParam("file") MultipartFile file, - @RequestParam("CMNFLEPAT") String filePath, - @RequestParam("CMNFLEORG") String originalFileName, - @RequestParam("CMNFLEEXT") String fileExtension, - @RequestParam("CMNFLESIZ") Long fileSize, - @RequestParam("CMNFLEREG") Long registrantId, - @RequestParam("CMNFLENAM") String fileName - ) { - // 데이터 준비 - MapDto fileData = new MapDto(); - fileData.put("CMNBRDSEQ", boardId); - fileData.put("CMNFLENAM", fileName); // 업로드된 파일 이름 - fileData.put("CMNFLEORG", originalFileName); - fileData.put("CMNFLEPAT", filePath); - fileData.put("CMNFLEEXT", fileExtension); - fileData.put("CMNFLESIZ", fileSize); - fileData.put("CMNFLEREG", registrantId); - fileData.put("CMNFLERDT", new Date()); // 등록일 현재 시간 - - log.info("Uploading attachment for board ID: {}", boardId); - + @Member + @ParameterCheck + @PostMapping("/{CMNBRDSEQ}/attachments") + public ApiResponse uploadAttachment(@ReqMap MapDto map) { + String filename = UUID.randomUUID().toString(); + map.put("CMNFLENAM", filename); + map.put("CMNFLEREG", 1); // 파일 데이터 저장 - boardService.addAttachment(fileData); + boardService.addAttachment(map); return ApiResponse.ok("첨부파일이 저장되었습니다."); } @@ -180,10 +202,15 @@ public class BoardController { * @param boardId 게시물 ID * @return 게시물 상세정보, 첨부파일 목록, 댓글 목록 */ + @Member + @ParameterCheck @GetMapping("/{boardId}") public ApiResponse getBoardDetail(@PathVariable("boardId") Long boardId) { log.info("Fetching details for board ID: {}", boardId); - + + // 조회수 증가 + boardService.incrementViewCount(boardId); + // 게시물 상세정보 조회 MapDto boardDetail = boardService.getBoardDetail(boardId); if (boardDetail == null) { @@ -200,16 +227,32 @@ public class BoardController { 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 attachments = boardService.getAttachments(boardId); List comments = boardService.getComments(boardId.intValue()); + List 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); } @@ -219,6 +262,8 @@ public class BoardController { * @param boardId 게시물 ID * @return 삭제 결과 메시지 */ + @Member + @ParameterCheck @DeleteMapping("/{boardId}") public ApiResponse deleteBoard(@PathVariable("boardId") Long boardId, @ReqMap MapDto map) { map.put("LOCBRDSEQ", boardId); @@ -230,9 +275,11 @@ public class BoardController { /** * 게시물 수정 * @param boardId 게시물 ID - * @ReqMap map 수정 데이터 (제목, 내용 등) + * @ReqMap map 수정 데이터 (LOCBRDTTL, LOCBRDCON) * @return 수정 결과 메시지 */ + @Member + @ParameterCheck @PutMapping("/{boardId}") public ApiResponse updateBoard(@PathVariable("boardId") Long boardId,@ReqMap MapDto map) { map.put("LOCBRDSEQ", boardId); @@ -241,72 +288,55 @@ public class BoardController { } /** - * 게시물 좋아요/싫어요 추가 - * @param boardId 게시물 ID - * @ReqMap map 좋아요/싫어요 데이터 + * 게시물,댓글 좋아요/싫어요 추가 + * @ReqMap map 데이터 (LOCCMTSEQ, MEMBERSEQ, LOCGOBGOD, LOCGOBBAD, LOCBRDSEQ) * @return 반응 추가 결과 메시지 */ - @PostMapping("/{boardId}/reaction") - public ApiResponse reactToBoard(@PathVariable("boardId") Long boardId, @ReqMap MapDto map) { - map.put("LOCBRDSEQ", boardId); + @Member + @ParameterCheck + @PostMapping("/{LOCBRDSEQ}/{LOCCMTSEQ}/reaction") + public ApiResponse reactToBoard(@ReqMap MapDto map) { + //로그인 미개발 ->임시 + map.put("MEMBERSEQ", 1); boardService.reactToBoard(map); - return ApiResponse.ok("반응이 추가되었습니다."); + return ApiResponse.ok("반응이 성공적으로 처리되었습니다."); } + - /** + /** * 댓글/대댓글 조회 * @param boardId 게시물 ID * @return 댓글과 대댓글의 계층 구조 데이터 */ + @Member + @ParameterCheck @GetMapping("/{boardId}/comments") - public ApiResponse>> getComments(@PathVariable("boardId") int boardId) { + public ApiResponse> getComments(@PathVariable("boardId") int boardId) { // 모든 댓글과 대댓글 조회 List comments = boardService.getComments(boardId); - // 댓글과 대댓글을 계층 구조로 정렬 - Map> commentMap = new HashMap<>(); - for (MapDto comment : comments) { - int commentId = (int) comment.get("LOCCMTSEQ"); - Integer parentId = (Integer) comment.get("LOCCMTRPY"); - - Map commentData = new HashMap<>(comment); - commentData.put("replies", new ArrayList<>()); // 대댓글 리스트 초기화 - - if (parentId == null) { - // 댓글인 경우 - commentMap.put(commentId, commentData); - } else { - // 대댓글인 경우, 부모 댓글의 "replies"에 추가 - Map parentComment = commentMap.get(parentId); - if (parentComment != null) { - List> replies = (List>) parentComment.get("replies"); - replies.add(commentData); - } - } - } - - // 최상위 댓글 리스트 반환 - List> result = new ArrayList<>(commentMap.values()); - return ApiResponse.ok(result); + return ApiResponse.ok(comments); } + /** * 댓글/대댓글 작성 * @param boardId 게시물 ID - * @ReqMap map 댓글 데이터 (내용, 부모 ID 등) + * @ReqMap map 댓글 데이터 (LOCBRDSEQ, LOCCMTRPY, LOCCMTPNT, LOCCMTPWD, MEMBERSEQ 등) * @return 작성 결과 메시지 */ - @PostMapping("/{boardId}/comment") - public ApiResponse addCommentOrReply(@PathVariable("boardId") int boardId, @ReqMap MapDto map) { - map.put("LOCBRDSEQ", boardId); - - // 부모 댓글 확인 - Integer parentCommentId = (Integer) map.get("LOCCMTRPY"); - if (parentCommentId != null) { - MapDto parentComment = boardService.getCommentById(parentCommentId); - if (parentComment == null) { - throw new IllegalArgumentException("Invalid parent comment ID: " + parentCommentId); - } + @Member + @ParameterCheck + @PostMapping("/{LOCBRDSEQ}/comment") + public ApiResponse 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); @@ -316,9 +346,11 @@ public class BoardController { /** * 댓글/대댓글 수정 * @param commentId 댓글 ID - * @ReqMap map 수정 데이터 (내용, 비밀번호 등) + * @ReqMap map 수정 데이터 (LOCCMTSEQ, LOCCMTRPY ) * @return 수정 결과 메시지 */ + @Member + @ParameterCheck @PutMapping("/comment/{commentId}") public ApiResponse updateComment(@PathVariable("commentId") int commentId, @ReqMap MapDto map) { // 기존 댓글 조회 @@ -327,9 +359,6 @@ public class BoardController { throw new IllegalArgumentException("Comment not found for ID: " + commentId); } - // 부모 댓글 ID는 수정 불가 - map.remove("LOCCMTRPY"); - map.put("LOCCMTSEQ", commentId); boardService.updateComment(map); @@ -339,9 +368,10 @@ public class BoardController { /** * 댓글/대댓글 삭제 * @param commentId 댓글 ID - * @ReqMap map 요청 데이터 (비밀번호 등) * @return 삭제 결과 메시지 */ + @Member + @ParameterCheck @DeleteMapping("/comment/{commentId}") public ApiResponse deleteComment(@PathVariable("commentId") int commentId, @ReqMap MapDto map) { map.put("LOCCMTSEQ", commentId); @@ -356,46 +386,36 @@ public class BoardController { * @ReqMap map 비밀번호 데이터 * @return 비밀번호 확인 결과 */ + @Member + @ParameterCheck @PostMapping("/comment/{commentId}/password") public ApiResponse checkCommentPassword(@PathVariable("commentId") int commentId, @ReqMap MapDto map) { - map.put("LOCCMTSEQ", commentId); - return ApiResponse.ok(boardService.checkCommentPassword(map)); + // DB에서 암호화된 비밀번호 조회 + String storedPassword = boardService.getCommentPassword(commentId); + String rawPassword = map.getString("LOCCMTPWD"); + + // 비밀번호 검증 + boolean isMatch = passwordEncoder.matches(rawPassword, storedPassword); + return ApiResponse.ok(isMatch); } - + /** * 게시물 비밀번호 확인 * @param boardId 게시물 ID * @ReqMap map 비밀번호 데이터 * @return 비밀번호 확인 결과 */ + @Member + @ParameterCheck @PostMapping("/{boardId}/password") public ApiResponse 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 isSecretBoard(@PathVariable("boardId") Long boardId) { - log.info("Checking if board ID {} is secret", boardId); - return ApiResponse.ok(boardService.isSecretBoard(boardId)); - } - - /** - * 댓글 좋아요/싫어요 추가 - * @param commentId 댓글 ID - * @ReqMap map 좋아요/싫어요 데이터 - * @return 반응 추가 결과 메시지 - */ - @PostMapping("/comment/{commentId}/reaction") - public ApiResponse reactToComment(@PathVariable("commentId") int commentId, @ReqMap MapDto map) { - map.put("LOCCMTSEQ", commentId); - boardService.reactToComment(map); - return ApiResponse.ok("Comment reaction added."); + // DB에서 암호화된 비밀번호 조회 + String storedPassword = boardService.getBoardPassword(boardId); + String rawPassword = map.getString("LOCBRDPWD"); + + // 비밀번호 검증 + boolean isMatch = passwordEncoder.matches(rawPassword, storedPassword); + return ApiResponse.ok(isMatch); } } diff --git a/src/main/java/io/company/localhost/controller/api/VacationController.java b/src/main/java/io/company/localhost/controller/api/VacationController.java index 4ae99f3..60dda49 100644 --- a/src/main/java/io/company/localhost/controller/api/VacationController.java +++ b/src/main/java/io/company/localhost/controller/api/VacationController.java @@ -1,6 +1,7 @@ package io.company.localhost.controller.api; import java.util.List; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -45,4 +46,16 @@ public class VacationController { // 성공적으로 저장된 경우 응답 반환 return ApiResponse.ok("모든 휴가가 성공적으로 저장되었습니다."); } + + /** + * 휴가 정보를 조회하여 프론트엔드로 전달 + */ + @GetMapping("/list") + public ApiResponse> getVacationList() { + + // 서비스 호출을 통해 데이터 조회 + List vacationList = localVacaService.getVacationList(); + + return ApiResponse.ok(vacationList); + } } diff --git a/src/main/java/io/company/localhost/controller/common/ImageUploadController.java b/src/main/java/io/company/localhost/controller/common/ImageUploadController.java index 2fa8a72..f722dce 100644 --- a/src/main/java/io/company/localhost/controller/common/ImageUploadController.java +++ b/src/main/java/io/company/localhost/controller/common/ImageUploadController.java @@ -21,11 +21,7 @@ import java.nio.file.Paths; import java.util.UUID; import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.io.FileSystemResource; -import org.springframework.core.io.Resource; import org.springframework.http.HttpStatus; -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.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -39,7 +35,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j @RestController -@RequestMapping("/api/img") +@RequestMapping("/api/quilleditor") @RequiredArgsConstructor public class ImageUploadController { @@ -47,9 +43,9 @@ public class ImageUploadController { private String boardFilePath; /** - * 에디터 내 이미지 업로드 - * @form-data file 업로드할 파일실제경로/파일이름 - * @return + * quilleditor 안에서 삽입된 이미지를 서버에 저장하는 메소드 + * @form-data 서버에 저장된 이미지 경로와 이름 + * @return */ @ParameterCheck @PostMapping("/upload") diff --git a/src/main/java/io/company/localhost/mapper/localbordMapper.java b/src/main/java/io/company/localhost/mapper/localbordMapper.java index eae03d2..7190ee7 100644 --- a/src/main/java/io/company/localhost/mapper/localbordMapper.java +++ b/src/main/java/io/company/localhost/mapper/localbordMapper.java @@ -15,7 +15,10 @@ public interface localbordMapper { // 자유/비밀 게시판 조회 List getGeneralPosts(MapDto map); - + + // 조회수 증가 + void incrementViewCount(Long boardId); + // 게시물 작성 void createBoard(MapDto map); @@ -24,12 +27,21 @@ public interface localbordMapper { // 게시물 삭제 void deleteBoard(MapDto map); + + // 게시물 삭제시 댓글/대댓글 삭제 + void deleteCommentsByBoardId(MapDto map); // 게시물 수정 void updateBoard(MapDto map); + + // 기존 반응 조회 + MapDto findReaction(MapDto map); - // 게시물 좋아요/싫어요 추가 - void reactToBoard(MapDto map); + // 새 반응 삽입 + void insertReaction(MapDto map); + + // 기존 반응 업데이트 + void updateReaction(MapDto map); // 댓글 조회 List getComments(int boardSeq); @@ -40,28 +52,47 @@ public interface localbordMapper { // 댓글/대댓글 수정 void updateComment(MapDto map); - // 댓글/대댓글 삭제 + // 대댓글인지 확인 + boolean isReply(MapDto map); + + // 댓글에 대댓글이 있는지 확인 + boolean hasReplies(MapDto map); + + // 댓글 내용만 삭제 처리 (대댓글 유지) + void softDeleteComment(MapDto map); + + // 댓글 삭제 (대댓글 없음) void deleteComment(MapDto map); - // 게시물 비밀번호 확인 - boolean checkBoardPassword(MapDto map); + // 대댓글 삭제 + void deleteReply(MapDto map); + + // 게시물 비밀번호 조회 + String selectCommentPassword(int commentId); - // 댓글 비밀번호 확인 - boolean checkCommentPassword(MapDto map); - - // 비밀 게시판 여부 확인 - boolean isSecretBoard(Long boardId); + // 댓글 비밀번호 조회 + String selectBoardPassword(int boardId); // 게시물 상세보기 MapDto selectBoardDetail(Long boardId); + // 댓글 갯수 + int countComments(Long boardId); + + // 첨부파일 유무 + int countAttachments(Long boardId); + + // 게시물 좋아요/싫어요 개수 + MapDto getBoardReactions(Long boardId); + + // 댓글 좋아요/싫어요 개수 + List getCommentReactions(Long boardId); + // 첨부파일 가져오기 List selectAttachments(Long boardId); - //댓글 좋아요/싫어요추가 - void reactToComment(MapDto map); - //댓글id 확인 MapDto getCommentById(int commentId); + } diff --git a/src/main/java/io/company/localhost/mapper/localvacaMapper.java b/src/main/java/io/company/localhost/mapper/localvacaMapper.java index f639c4b..b6bca47 100644 --- a/src/main/java/io/company/localhost/mapper/localvacaMapper.java +++ b/src/main/java/io/company/localhost/mapper/localvacaMapper.java @@ -1,13 +1,18 @@ package io.company.localhost.mapper; +import java.util.List; + import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; import io.company.localhost.common.dto.MapDto; @Mapper public interface localvacaMapper { - void insertVacation(MapDto vacationRequest); + void insertVacation(MapDto map); + + List findVacations(); } diff --git a/src/main/java/io/company/localhost/service/localbordService.java b/src/main/java/io/company/localhost/service/localbordService.java index b584c0d..b74afea 100644 --- a/src/main/java/io/company/localhost/service/localbordService.java +++ b/src/main/java/io/company/localhost/service/localbordService.java @@ -26,12 +26,25 @@ public class localbordService { 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); - return PageUtil.redefineNavigation(new PageInfo<>(boardMapper.getGeneralPosts(map), size)); + + List result = boardMapper.getGeneralPosts(map); + + return PageUtil.redefineNavigation(new PageInfo<>(result, size)); + } + + public void incrementViewCount(Long boardId) { + boardMapper.incrementViewCount(boardId); } public BigInteger createBoard(MapDto map) { - boardMapper.createBoard(map); // 게시물 작성 + boardMapper.createBoard(map); return (BigInteger) map.get("LOCBRDSEQ"); // Mapper에서 자동 생성된 key를 가져옴 } @@ -46,9 +59,9 @@ public class localbordService { public List getAttachments(Long boardId) { return boardMapper.selectAttachments(boardId); } - - + public void deleteBoard(MapDto map) { + boardMapper.deleteCommentsByBoardId(map); boardMapper.deleteBoard(map); } @@ -57,7 +70,16 @@ public class localbordService { } public void reactToBoard(MapDto map) { - boardMapper.reactToBoard(map); + // 기존 반응 확인 + MapDto existingReaction = boardMapper.findReaction(map); + + if (existingReaction != null) { + // 기존 반응이 있는 경우 업데이트 + boardMapper.updateReaction(map); + } else { + // 기존 반응이 없는 경우 새로 삽입 + boardMapper.insertReaction(map); + } } public List getComments(int boardSeq) { @@ -65,39 +87,65 @@ public class localbordService { } 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) { - boardMapper.deleteComment(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 boolean checkBoardPassword(MapDto map) { - return boardMapper.checkBoardPassword(map); - } - - public boolean checkCommentPassword(MapDto map) { - return boardMapper.checkCommentPassword(map); - } - - - public boolean isSecretBoard(Long boardId) { - return boardMapper.isSecretBoard(boardId); + public String getCommentPassword(int commentId) { + return boardMapper.selectCommentPassword(commentId); } - public void reactToComment(MapDto map) { - boardMapper.reactToComment(map); + 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); + } } diff --git a/src/main/java/io/company/localhost/service/localvacaService.java b/src/main/java/io/company/localhost/service/localvacaService.java index 0a65289..91086c3 100644 --- a/src/main/java/io/company/localhost/service/localvacaService.java +++ b/src/main/java/io/company/localhost/service/localvacaService.java @@ -18,4 +18,8 @@ public class localvacaService { localvacaMapper.insertVacation(vacationRequest); } + public List getVacationList() { + return localvacaMapper.findVacations(); + } + } diff --git a/src/main/java/io/company/localhost/utils/PageUtil.java b/src/main/java/io/company/localhost/utils/PageUtil.java index 8d92f10..cf7333a 100644 --- a/src/main/java/io/company/localhost/utils/PageUtil.java +++ b/src/main/java/io/company/localhost/utils/PageUtil.java @@ -57,6 +57,18 @@ public class PageUtil { list.setNavigateFirstPage(nav2[0]); list.setNavigateLastPage(nav2[nav2.length -1]); } + + // 페이지 그룹 크기 (예: 10개씩) + int groupSize = list.getNavigatePages(); + int totalPages = list.getPages(); + + // 현재 페이지 그룹 계산 + int currentGroup = (int) Math.ceil((double) currentPage / groupSize); + int totalGroups = (int) Math.ceil((double) totalPages / groupSize); + + // 이전/다음 그룹 존재 여부 설정 + list.setHasPreviousPage(currentGroup > 1); // 이전 그룹 존재 + list.setHasNextPage(currentGroup < totalGroups); // 다음 그룹 존재 return list; } diff --git a/src/main/resources/mapper/localbordMapper.xml b/src/main/resources/mapper/localbordMapper.xml index 3a50be3..7d451c4 100644 --- a/src/main/resources/mapper/localbordMapper.xml +++ b/src/main/resources/mapper/localbordMapper.xml @@ -8,13 +8,14 @@ LOCBRDSEQ AS id, LOCBRDTTL AS title, LOCBRDCON AS content, - LOCBRDRDT AS date + LOCBRDUDT AS date, + LOCBRDCNT AS cnt FROM localbord WHERE LOCBRDTYP = 'N' AND LOCBRDTTL LIKE CONCAT('%', #{searchKeyword}, '%') - ORDER BY LOCBRDRDT DESC + ORDER BY LOCBRDUDT DESC @@ -23,23 +24,31 @@ LOCBRDSEQ AS id, LOCBRDTTL AS title, LOCBRDCON AS content, - LOCBRDRDT AS date + LOCBRDUDT AS date, + LOCBRDCNT AS cnt FROM localbord WHERE LOCBRDTYP IN ('F', 'S') AND LOCBRDTTL LIKE CONCAT('%', #{searchKeyword}, '%') - ORDER BY LOCBRDRDT DESC + ORDER BY + + LOCBRDUDT DESC + LOCBRDCNT DESC + - - + + + + UPDATE localbord SET LOCBRDCNT = LOCBRDCNT + 1 WHERE LOCBRDSEQ = #{LOCBRDSEQ} + + INSERT INTO localbord (LOCBRDTTL, LOCBRDCON, LOCBRDCAT, MEMBERSEQ, LOCBRDCNT, LOCBRDRDT, LOCBRDUDT, LOCBRDPWD, LOCBRDTYP) VALUES (#{LOCBRDTTL}, #{LOCBRDCON}, #{LOCBRDCAT}, #{MEMBERSEQ}, 0, NOW(), NOW(), #{LOCBRDPWD}, #{LOCBRDTYP}) - - + INSERT INTO commonfil ( @@ -47,19 +56,17 @@ CMNFLEEXT,CMNFLESIZ,CMNFLEREG,CMNFLERDT ) VALUES ( #{CMNBRDSEQ},#{CMNFLENAM},#{CMNFLEORG},#{CMNFLEPAT}, - #{CMNFLEEXT},#{CMNFLESIZ},#{CMNFLEREG},#{CMNFLERDT} + #{CMNFLEEXT},#{CMNFLESIZ},#{CMNFLEREG},NOW() ) - - - + DELETE FROM localbord WHERE LOCBRDSEQ = #{LOCBRDSEQ} + + + + DELETE FROM localcomt + WHERE LOCBRDSEQ = #{LOCBRDSEQ} + @@ -81,14 +93,31 @@ SET LOCBRDTTL = #{LOCBRDTTL}, LOCBRDCON = #{LOCBRDCON}, LOCBRDUDT = NOW() WHERE LOCBRDSEQ = #{LOCBRDSEQ} + + + - - - INSERT INTO localgorb (LOCBRDSEQ, LOCCMTSEQ, MEMBERSEQ, LOCGOBGOD, LOCGOBBAD ) + + + UPDATE localgorb + SET LOCGOBGOD = #{LOCGOBGOD}, LOCGOBBAD = #{LOCGOBBAD} + WHERE (LOCBRDSEQ = #{LOCBRDSEQ} OR (#{LOCBRDSEQ} IS NULL AND LOCBRDSEQ IS NULL)) + AND (LOCCMTSEQ = #{LOCCMTSEQ} OR (#{LOCCMTSEQ} IS NULL AND LOCCMTSEQ IS NULL)) + AND MEMBERSEQ = #{MEMBERSEQ} + + + + + INSERT INTO localgorb (LOCBRDSEQ, LOCCMTSEQ, MEMBERSEQ, LOCGOBGOD, LOCGOBBAD) VALUES (#{LOCBRDSEQ}, #{LOCCMTSEQ}, #{MEMBERSEQ}, #{LOCGOBGOD}, #{LOCGOBBAD}) - ON DUPLICATE KEY UPDATE LOCGOBGOD = #{LOCGOBGOD}, LOCGOBBAD = #{LOCGOBBAD} - + - INSERT INTO localcomt (LOCBRDSEQ, LOCCMTRPY, LOCCMTPWD, LOCCMTRDT, LOCCMTPNT) - VALUES (#{LOCBRDSEQ}, #{LOCCMTRPY}, #{LOCCMTPWD}, NOW(), #{LOCCMTPNT}) + INSERT INTO localcomt (LOCBRDSEQ, LOCCMTRPY, LOCCMTPWD, LOCCMTRDT, LOCCMTUDT, LOCCMTPNT, MEMBERSEQ) + VALUES (#{LOCBRDSEQ}, #{LOCCMTRPY}, #{LOCCMTPWD}, NOW(), NOW() , #{LOCCMTPNT}, #{MEMBERSEQ}) UPDATE localcomt SET LOCCMTRPY = #{LOCCMTRPY}, LOCCMTUDT = NOW() - WHERE LOCCMTSEQ = #{LOCCMTSEQ} AND LOCCMTPWD = #{LOCCMTPWD} + WHERE LOCCMTSEQ = #{LOCCMTSEQ} - - - DELETE FROM localcomt - WHERE LOCCMTSEQ = #{LOCCMTSEQ} AND LOCCMTPWD = #{LOCCMTPWD} - - - - + SELECT COUNT(1) > 0 FROM localcomt + WHERE LOCCMTSEQ = #{LOCCMTSEQ} AND LOCCMTPNT IS NOT NULL + + + + + + + - - + SELECT LOCBRDPWD + FROM localbord + WHERE LOCBRDSEQ = #{boardId} - - - - INSERT INTO localcomt (LOCCMTSEQ, MEMBERSEQ, LOCGORGOD, LOCGORBAD) - VALUES (#{LOCCMTSEQ}, #{MEMBERSEQ}, #{LOCGORGOD}, #{LOCGORBAD}) - ON DUPLICATE KEY UPDATE LOCGORGOD = #{LOCGORGOD}, LOCGORBAD = #{LOCGORBAD} - + + + + + + + + + + + diff --git a/src/main/resources/mapper/localvacaMapper.xml b/src/main/resources/mapper/localvacaMapper.xml index 9b01418..a926273 100644 --- a/src/main/resources/mapper/localvacaMapper.xml +++ b/src/main/resources/mapper/localvacaMapper.xml @@ -8,4 +8,13 @@ VALUES (#{employeeId}, #{date}, #{type}, NOW()) + + \ No newline at end of file