게시글 수정 페이지 접근 시 비밀번호 확인

This commit is contained in:
nevermoregb 2025-03-17 13:06:48 +09:00
parent d34fdf1fda
commit 31cad333d1
5 changed files with 102 additions and 4 deletions

View File

@ -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 <T> List<T> getList(String key, Class<T> clazz) {
Object value = this.get(key);
if (value == null) {

View File

@ -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<MapDto> attachments = boardService.selectAttachments(boardId);
@ -133,6 +131,14 @@ public class BoardController {
return ApiResponse.ok(board);
}
@Member
@ParameterCheck
@PostMapping("/{boardId}")
public ApiResponse<MapDto> getBoardDetail2(@PathVariable("boardId") Long boardId, @ReqMap MapDto map) {
map.put("boardId", boardId);
return boardService.selectBoardDetail2(map);
}
/**
* 파일 다운로드 API
* @param path 파일 경로

View File

@ -109,6 +109,8 @@ public interface localbordMapper {
String selectUserProfileImg(String userId);
MapDto selectBoardDetail2(Long boardId);
}

View File

@ -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<MapDto> selectNotices(MapDto map) {
List<MapDto> 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<MapDto> 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<MapDto> attachments = this.selectAttachments(boardId);
resultMap.put("attachments", attachments != null ? attachments : new ArrayList<>());
return ApiResponse.ok(resultMap);
}
}

View File

@ -106,6 +106,24 @@
WHERE b.LOCBRDSEQ = #{boardId}
</select>
<!-- 게시물 상세정보 조회2 -->
<select id="selectBoardDetail2" resultType="io.company.localhost.common.dto.MapDto">
SELECT
b.LOCBRDSEQ AS id,
b.LOCBRDTTL AS title,
b.LOCBRDCON AS content,
b.LOCBRDUDT AS date,
b.LOCBRDTYP AS type,
b.LOCBRDCNT AS cnt,
b.LOCBRDPWD AS password,
m.MEMBERNAM AS author,
m.MEMBERSEQ AS authorId,
m.MEMBERPRF AS profileImg
FROM localbord b
LEFT JOIN netmember m ON b.MEMBERSEQ = m.MEMBERSEQ
WHERE b.LOCBRDSEQ = #{boardId}
</select>
<!-- 첨부파일 목록 조회 -->
<select id="selectAttachments" resultType="io.company.localhost.common.dto.MapDto">