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 e07cf66..ffec70a 100644 --- a/src/main/java/io/company/localhost/controller/api/BoardController.java +++ b/src/main/java/io/company/localhost/controller/api/BoardController.java @@ -49,6 +49,7 @@ import io.company.localhost.common.dto.ApiResponse; import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.exception.InvalidPasswordException; import io.company.localhost.common.exception.NotFoundHandler; +import io.company.localhost.common.exception.code.UserErrorCode; import io.company.localhost.service.commoncodService; import io.company.localhost.service.localbordService; import io.company.localhost.utils.AuthUtil; @@ -121,7 +122,9 @@ public class BoardController { public ApiResponse getBoardDetail(@PathVariable("boardId") Long boardId) { MapDto board = boardService.selectBoardDetail(boardId); if (board == null) { - throw new NotFoundHandler("게시물 ID " + boardId + "을(를) 찾을 수 없습니다."); + //throw new NotFoundHandler("게시물 ID " + boardId + "을(를) 찾을 수 없습니다."); + String errMessage = "게시물 ID " + boardId + "을(를) 찾을 수 없습니다."; + ApiResponse.error(HttpStatus.NOT_FOUND, errMessage); } // 📌 첨부파일 목록 추가 List attachments = boardService.selectAttachments(boardId); @@ -296,9 +299,10 @@ public class BoardController { @Member @ParameterCheck @DeleteMapping("/comment/{commentId}") - public ApiResponse deleteComment(@PathVariable("commentId") Long commentId) { + public ApiResponse deleteComment(@PathVariable("commentId") Long commentId, @RequestParam(value = "LOCCMTPNT") Long parentId) { MapDto map = new MapDto(); map.put("LOCCMTSEQ", commentId); + map.put("LOCCMTPNT", parentId); boardService.deleteComment(map); return ApiResponse.ok("댓글이 삭제되었습니다."); @@ -328,11 +332,13 @@ public class BoardController { String storedHashedPassword = boardService.selectBoardPassword(boardId); if (storedHashedPassword == null) { throw new NotFoundHandler("해당 게시물이 존재하지 않습니다."); + } boolean isMatch = passwordEncoder.matches(rawPassword, storedHashedPassword); if (!isMatch) { - throw new InvalidPasswordException("비밀번호가 일치하지 않습니다."); + //throw new InvalidPasswordException("비밀번호가 일치하지 않습니다."); + return ApiResponse.error(HttpStatus.UNAUTHORIZED, "비밀번호가 일치하지 않습니다."); } return ApiResponse.ok(true); @@ -365,7 +371,8 @@ public class BoardController { boolean isMatch = passwordEncoder.matches(rawPassword, storedHashedPassword); if (!isMatch) { - throw new InvalidPasswordException("비밀번호가 일치하지 않습니다."); + //throw new InvalidPasswordException("비밀번호가 일치하지 않습니다."); + return ApiResponse.error(HttpStatus.UNAUTHORIZED, "비밀번호가 일치하지 않습니다."); } return ApiResponse.ok(true); 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 001fdec..c1eb988 100644 --- a/src/main/java/io/company/localhost/controller/api/VacationController.java +++ b/src/main/java/io/company/localhost/controller/api/VacationController.java @@ -13,6 +13,7 @@ * *************************************************************/ package io.company.localhost.controller.api; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -54,25 +55,36 @@ public class VacationController { @PostMapping public ApiResponse insertVacations(@RequestBody List list) { Long user = AuthUtil.getUser().getId(); + List savedVacations = new ArrayList<>(); + for (MapDto request : list) { String date = request.getString("date"); String type = request.getString("type"); Object receiverId = request.get("receiverId"); - request.put("employeeId", user); - + if (date == null || type == null) { throw new IllegalArgumentException("요청 데이터에 누락된 값이 있습니다: " + request); } - + Integer count = request.getInt("count"); if (count == null || count < 1) { count = 1; } + for (int i = 0; i < count; i++) { - localVacaService.insertVacation(request); + MapDto vacationRequest = new MapDto(); + vacationRequest.put("date", date); + vacationRequest.put("type", type); + vacationRequest.put("receiverId", receiverId); + vacationRequest.put("employeeId", user); + + // 실제 저장 + localVacaService.insertVacation(vacationRequest); + savedVacations.add(vacationRequest); } } - return ApiResponse.ok("모든 휴가가 성공적으로 저장되었습니다."); + + return ApiResponse.ok(savedVacations); } /** diff --git a/src/main/java/io/company/localhost/mapper/localbordMapper.java b/src/main/java/io/company/localhost/mapper/localbordMapper.java index b74911c..28ac22f 100644 --- a/src/main/java/io/company/localhost/mapper/localbordMapper.java +++ b/src/main/java/io/company/localhost/mapper/localbordMapper.java @@ -66,13 +66,13 @@ public interface localbordMapper { void updateComment(MapDto map); // 댓글에 대댓글이 있는지 확인 - int selectHasReplies(MapDto map); + int selectReplyCount(Long parentId); // 댓글 내용만 삭제 처리 (대댓글 유지) - void updateSoftDeleteComment(MapDto map); + void updateSoftDeleteComment(Long commentId); // 댓글 삭제 (대댓글 없음) - void deleteComment(MapDto map); + void deleteComment(Long commentId); // 댓글 비밀번호 조회 String selectCommentPassword(int commentId); @@ -106,6 +106,8 @@ public interface localbordMapper { List selectDelFileInfo(String[] array); void deleteFileInfo(String[] array); + + String selectUserProfileImg(String userId); } diff --git a/src/main/java/io/company/localhost/service/localbordService.java b/src/main/java/io/company/localhost/service/localbordService.java index cb5b4c8..c76db7c 100644 --- a/src/main/java/io/company/localhost/service/localbordService.java +++ b/src/main/java/io/company/localhost/service/localbordService.java @@ -36,9 +36,11 @@ import io.company.localhost.utils.BlobUtil; import io.company.localhost.utils.PageUtil; import io.company.localhost.vo.UploadFile; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; @Service @RequiredArgsConstructor +@Slf4j public class localbordService { private final localbordMapper boardMapper; private final FileService fileService; @@ -148,8 +150,7 @@ public class localbordService { } public List selectReply(MapDto map) { - - return boardMapper.selectReply(map); + return boardMapper.selectReply(map); } public void insertCommentOrReply(MapDto map) { @@ -173,20 +174,33 @@ public class localbordService { } public void deleteComment(MapDto map) { + Long commentId = (Long) map.get("LOCCMTSEQ"); // 댓글이 대댓글이 있는지 확인 - boolean hasReplies = boardMapper.selectHasReplies(map) > 0; - + boolean hasReplies = boardMapper.selectReplyCount(commentId) > 0; if (hasReplies) { // 대댓글이 있는 경우, '삭제된 댓글입니다.'로 변경 (소프트 삭제) - boardMapper.updateSoftDeleteComment(map); + boardMapper.updateSoftDeleteComment(commentId); } else { // 대댓글이 없는 경우, 완전 삭제 - boardMapper.deleteComment(map); + boardMapper.deleteComment(commentId); } - + checkAndDeleteParentComment(map); } - public String selectCommentPassword(int commentId) { + private void checkAndDeleteParentComment(MapDto map) { + Long parentId = (Long) map.get("LOCCMTPNT"); + if (parentId == null) return; // 부모가 없으면 종료 + + // 부모 댓글의 남아있는 대댓글 개수 확인 + int remainingReplies = boardMapper.selectReplyCount(parentId); + + if (remainingReplies == 0) { + // 남은 대댓글이 없으면 부모 댓글도 삭제 + boardMapper.deleteComment(parentId); + } + } + + public String selectCommentPassword(int commentId) { return boardMapper.selectCommentPassword(commentId); } @@ -325,6 +339,16 @@ public class localbordService { private void enrichCommentsWithAdditionalData(List comments) { for (MapDto comment : comments) { Object idObject = comment.get("LOCCMTSEQ"); + String userId = ""; + + // 프로필 이미지 추가 + if(comment.containsKey("authorId")) { + userId = String.valueOf(comment.get("authorId")); + String profileImg = boardMapper.selectUserProfileImg(userId); + comment.put("profileImg", profileImg); + } + + if (idObject instanceof Number) { long commentId = ((Number) idObject).longValue(); diff --git a/src/main/resources/mapper/localbordMapper.xml b/src/main/resources/mapper/localbordMapper.xml index 60e93d0..7683691 100644 --- a/src/main/resources/mapper/localbordMapper.xml +++ b/src/main/resources/mapper/localbordMapper.xml @@ -99,7 +99,8 @@ b.LOCBRDTYP AS type, b.LOCBRDCNT AS cnt, m.MEMBERNAM AS author, - m.MEMBERSEQ AS authorId + m.MEMBERSEQ AS authorId, + m.MEMBERPRF AS profileImg FROM localbord b LEFT JOIN netmember m ON b.MEMBERSEQ = m.MEMBERSEQ WHERE b.LOCBRDSEQ = #{boardId} @@ -122,7 +123,7 @@ - DELETE FROM localcomt + DELETE FROM localcomt WHERE LOCBRDSEQ = #{LOCBRDSEQ} @@ -176,7 +177,8 @@ c.LOCCMTSEQ,c.LOCBRDSEQ,c.LOCCMTPNT,c.LOCCMTRPY, c.LOCCMTUDT,c.LOCCMTPWD,c.LOCCMTRDT,c.LOCCMTPNT, m.MEMBERNAM AS author, - m.MEMBERSEQ AS authorId + m.MEMBERSEQ AS authorId, + m.MEMBERPRF as profileImg FROM localcomt c LEFT JOIN netmember m ON c.MEMBERSEQ = m.MEMBERSEQ WHERE LOCCMTPNT = #{LOCCMTPNT} and LOCCMTPNT != 1 @@ -207,7 +209,6 @@ ) - DELETE FROM localcomt @@ -216,10 +217,13 @@ SELECT 1 FROM localcomt WHERE LOCCMTPNT = #{LOCCMTSEQ} ) - - - + SELECT COUNT(*) + FROM localcomt + WHERE LOCCMTPNT = #{LOCCMTSEQ} + AND LOCCMTPNT IS NOT NULL @@ -247,7 +251,7 @@ @@ -302,4 +306,14 @@ + + + diff --git a/src/main/resources/mapper/localvacaMapper.xml b/src/main/resources/mapper/localvacaMapper.xml index b8dde0c..a39eb4b 100644 --- a/src/main/resources/mapper/localvacaMapper.xml +++ b/src/main/resources/mapper/localvacaMapper.xml @@ -33,23 +33,31 @@ FROM localvaca WHERE MEMBERSEQ = #{userId} AND YEAR(LOCVACUDT) = #{year} - AND DATE_FORMAT(LOCVACUDT, '%Y') = DATE_FORMAT(CURDATE(), '%Y') GROUP BY LOCVACUDT, LOCVACTYP, LOCVACRMM ORDER BY LOCVACUDT DESC -