From 31cad333d1fa3b476f2dafd177fdc2880806a0f7 Mon Sep 17 00:00:00 2001 From: nevermoregb Date: Mon, 17 Mar 2025 13:06:48 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=A0=91=EA=B7=BC=20?= =?UTF-8?q?=EC=8B=9C=20=EB=B9=84=EB=B0=80=EB=B2=88=ED=98=B8=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../company/localhost/common/dto/MapDto.java | 17 ++++++ .../controller/api/BoardController.java | 12 +++- .../localhost/mapper/localbordMapper.java | 2 + .../localhost/service/localbordService.java | 57 ++++++++++++++++++- src/main/resources/mapper/localbordMapper.xml | 18 ++++++ 5 files changed, 102 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/company/localhost/common/dto/MapDto.java b/src/main/java/io/company/localhost/common/dto/MapDto.java index 2b6e6d5..0c36484 100644 --- a/src/main/java/io/company/localhost/common/dto/MapDto.java +++ b/src/main/java/io/company/localhost/common/dto/MapDto.java @@ -79,6 +79,23 @@ public class MapDto extends ListOrderedMap { return null; } + /** + * 주어진 키에 해당하는 값을 Long 타입으로 반환합니다. + * 값이 BigInteger인 경우 자동으로 long으로 변환합니다. + * + * @param key Map에서 값을 검색할 키 + * @return 해당 키에 대한 값(Long 타입), 값이 없으면 null + */ + public Long getLong(String key) { + Object value = get(key); + if (value instanceof BigInteger) { + return ((BigInteger) value).longValue(); + } else if (value instanceof Long) { + return (Long) value; + } + return null; + } + public List getList(String key, Class clazz) { Object value = this.get(key); if (value == null) { 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 ffec70a..32d71c6 100644 --- a/src/main/java/io/company/localhost/controller/api/BoardController.java +++ b/src/main/java/io/company/localhost/controller/api/BoardController.java @@ -47,9 +47,7 @@ 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; -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; @@ -124,7 +122,7 @@ public class BoardController { if (board == null) { //throw new NotFoundHandler("게시물 ID " + boardId + "을(를) 찾을 수 없습니다."); String errMessage = "게시물 ID " + boardId + "을(를) 찾을 수 없습니다."; - ApiResponse.error(HttpStatus.NOT_FOUND, errMessage); + return ApiResponse.error(HttpStatus.NOT_FOUND, errMessage); } // 📌 첨부파일 목록 추가 List attachments = boardService.selectAttachments(boardId); @@ -132,6 +130,14 @@ public class BoardController { return ApiResponse.ok(board); } + + @Member + @ParameterCheck + @PostMapping("/{boardId}") + public ApiResponse getBoardDetail2(@PathVariable("boardId") Long boardId, @ReqMap MapDto map) { + map.put("boardId", boardId); + return boardService.selectBoardDetail2(map); + } /** * 파일 다운로드 API diff --git a/src/main/java/io/company/localhost/mapper/localbordMapper.java b/src/main/java/io/company/localhost/mapper/localbordMapper.java index 28ac22f..ff46cdc 100644 --- a/src/main/java/io/company/localhost/mapper/localbordMapper.java +++ b/src/main/java/io/company/localhost/mapper/localbordMapper.java @@ -108,6 +108,8 @@ public interface localbordMapper { void deleteFileInfo(String[] array); String selectUserProfileImg(String userId); + + MapDto selectBoardDetail2(Long boardId); } diff --git a/src/main/java/io/company/localhost/service/localbordService.java b/src/main/java/io/company/localhost/service/localbordService.java index c76db7c..323cf85 100644 --- a/src/main/java/io/company/localhost/service/localbordService.java +++ b/src/main/java/io/company/localhost/service/localbordService.java @@ -16,11 +16,15 @@ package io.company.localhost.service; import java.io.IOException; import java.math.BigInteger; +import java.util.ArrayList; import java.util.List; import java.util.UUID; +import org.springframework.http.HttpStatus; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import com.fasterxml.jackson.databind.JsonNode; @@ -34,6 +38,7 @@ import io.company.localhost.mapper.localbordMapper; import io.company.localhost.utils.AuthUtil; import io.company.localhost.utils.BlobUtil; import io.company.localhost.utils.PageUtil; +import io.company.localhost.vo.MemberVo; import io.company.localhost.vo.UploadFile; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -45,6 +50,7 @@ public class localbordService { private final localbordMapper boardMapper; private final FileService fileService; private static final long MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB + private final PasswordEncoder passwordEncoder; public List selectNotices(MapDto map) { List posts = boardMapper.selectNotices(map); @@ -297,6 +303,8 @@ public class localbordService { } private void enrichBoardDetail(MapDto boardDetail) { + if(boardDetail == null) return; + long boardId = ((Number) boardDetail.get("id")).longValue(); boardDetail.put("hasAttachment", selectIsAttachments(boardId)); boardDetail.put("commentCount", selectCountComments(boardId)); @@ -391,7 +399,7 @@ public class localbordService { this.deleteFileInfo(array); // db 데이터 삭제 } } else { - return ApiResponse.ok("게시물이 수정에 실패하였습니다."); + return ApiResponse.error(HttpStatus.INTERNAL_SERVER_ERROR, "게시물이 수정에 실패하였습니다."); } return ApiResponse.ok("게시물이 수정되었습니다."); @@ -416,4 +424,51 @@ public class localbordService { return boardMapper.selectDelFileInfo(array); } + /** + * 게시글 수정 조회 + * + * @param map + * @return + */ + public ApiResponse selectBoardDetail2(MapDto map) { + String password = map.getString("password"); // 입력한 비밀번호 + Long boardId = map.getLong("boardId"); // 조회한 게시글 번호 + MemberVo member = AuthUtil.getUser(); // 로그인 정보 조회 + MapDto resultMap = boardMapper.selectBoardDetail2(boardId); // 게시글 정보 조회 + if(resultMap == null) return ApiResponse.error(HttpStatus.NOT_FOUND, "해당 게시글이 없습니다"); + String boardType = resultMap.getString("type"); // 게시글 타입 + + // 익명 게시글 + if("300102".equals(boardType)) { + String hashedPassword = resultMap.getString("password"); + + if(StringUtils.hasText(password)) { + boolean isMatch = passwordEncoder.matches(password, hashedPassword); + if(!isMatch) return ApiResponse.error(HttpStatus.UNAUTHORIZED, "비밀번호가 일치하지 않습니다"); + } else { + return ApiResponse.error(HttpStatus.UNAUTHORIZED, "비밀번호를 입력하세요"); + } + + // 자유 게시글 + } else if("300101".equals(boardType)) { + Long writerId = Long.valueOf(resultMap.getInt("authorId")); + if(member.getId() != writerId) return ApiResponse.error(HttpStatus.UNAUTHORIZED, "권한이 없습니다"); + + // 공지글 + } else if("300103".equals(boardType)) { + if(!"ROLE_ADMIN".equals(member.getRole())) return ApiResponse.error(HttpStatus.UNAUTHORIZED, "권한이 없습니다"); + + } else { + log.error("게시글 카테고리 정보 없음"); + return ApiResponse.error(HttpStatus.NOT_FOUND, "해당 게시글이 없습니다"); + } + + this.enrichBoardDetail(resultMap); // 추가정보 + // 📌 첨부파일 목록 추가 + List attachments = this.selectAttachments(boardId); + resultMap.put("attachments", attachments != null ? attachments : new ArrayList<>()); + + return ApiResponse.ok(resultMap); + } + } \ No newline at end of file diff --git a/src/main/resources/mapper/localbordMapper.xml b/src/main/resources/mapper/localbordMapper.xml index 7683691..9e46d19 100644 --- a/src/main/resources/mapper/localbordMapper.xml +++ b/src/main/resources/mapper/localbordMapper.xml @@ -105,6 +105,24 @@ LEFT JOIN netmember m ON b.MEMBERSEQ = m.MEMBERSEQ WHERE b.LOCBRDSEQ = #{boardId} + + +