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 0d8c765..2797975 100644 --- a/src/main/java/io/company/localhost/controller/api/BoardController.java +++ b/src/main/java/io/company/localhost/controller/api/BoardController.java @@ -131,6 +131,13 @@ public class BoardController { return ApiResponse.ok(board); } + /** + * 게시물 수정 조회(익명 게시글은 비밀번호 값 필수) + * + * @param boardId + * @param map + * @return + */ @Member @ParameterCheck @PostMapping("/{boardId}") @@ -176,8 +183,7 @@ public class BoardController { @ParameterCheck @DeleteMapping("/{boardId}") public ApiResponse deleteBoard(@ReqMap MapDto map) { - boardService.deleteBoard(map); - return ApiResponse.ok("게시물이 삭제되었습니다."); + return boardService.deleteBoard(map); } 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 b32d3bf..5066fb1 100644 --- a/src/main/java/io/company/localhost/controller/common/ImageUploadController.java +++ b/src/main/java/io/company/localhost/controller/common/ImageUploadController.java @@ -18,10 +18,12 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.List; import java.util.UUID; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -29,8 +31,11 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; 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.service.localbordService; +import io.company.localhost.utils.AuthUtil; +import io.company.localhost.vo.UploadFile; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -42,6 +47,8 @@ public class ImageUploadController { @Value("${filePath.boardfile}") private String boardFilePath; + + private final localbordService localbordService; /** * quilleditor 안에서 삽입된 이미지를 서버에 저장하는 메소드 @@ -50,7 +57,8 @@ public class ImageUploadController { */ @ParameterCheck @PostMapping("/upload") - public ApiResponse uploadImage(@RequestParam("file") MultipartFile file) throws IOException { + @Transactional + public ApiResponse uploadImage(@RequestParam("file") MultipartFile file) throws IOException { if (file.isEmpty()) { return ApiResponse.error(HttpStatus.BAD_REQUEST, "File is empty"); @@ -59,13 +67,47 @@ public class ImageUploadController { String fileExtension = originalFileName.substring(originalFileName.lastIndexOf(".")); String fileName = UUID.randomUUID().toString() + fileExtension; Path filePath = Paths.get(boardFilePath, fileName); + Long fileSize = file.getSize(); Files.createDirectories(filePath.getParent()); Files.write(filePath, file.getBytes()); String fileUrl = "upload/img/board/" + fileName; + long fileIndex = insertUploadEditorImageInfo(fileName, originalFileName, fileUrl, fileExtension, fileSize); + + MapDto map = new MapDto(); + if(fileIndex != 0) map.put("fileIndex", fileIndex); + map.put("fileUrl", fileUrl); - return ApiResponse.ok(fileUrl); - } + return ApiResponse.ok(map); + } + + + /** + * 업로드 된 파일정보를 DB 적재 + * + * @param fileName + * @param originalFileName + * @param filePath + * @param fileExtension + * @param fileSize + * @return success: DB 시퀀스 번호, fail: 0 + * + */ + public long insertUploadEditorImageInfo(String fileName, String originalFileName, String filePath, String fileExtension, Long fileSize) { + Long userId = AuthUtil.getUser().getId(); + + MapDto map = new MapDto(); + map.put("CMNFLENAM" , fileName ); + map.put("CMNFLEORG" , originalFileName ); + map.put("CMNFLEPAT" , filePath ); + map.put("CMNFLEEXT" , fileExtension ); + map.put("CMNFLESIZ" , fileSize ); + map.put("CMNFLEREG" , userId ); + + int result = localbordService.insertUploadEditorImageInfo(map); + + return result == 1 ? map.getLong("id") : 0; + } } diff --git a/src/main/java/io/company/localhost/mapper/localbordMapper.java b/src/main/java/io/company/localhost/mapper/localbordMapper.java index ff46cdc..715a243 100644 --- a/src/main/java/io/company/localhost/mapper/localbordMapper.java +++ b/src/main/java/io/company/localhost/mapper/localbordMapper.java @@ -15,8 +15,11 @@ package io.company.localhost.mapper; import java.util.List; + import org.apache.ibatis.annotations.Mapper; + import io.company.localhost.common.dto.MapDto; +import io.company.localhost.vo.FileVo; @Mapper public interface localbordMapper { @@ -110,6 +113,16 @@ public interface localbordMapper { String selectUserProfileImg(String userId); MapDto selectBoardDetail2(Long boardId); + + int insertUploadEditorImageInfo(MapDto map); + + int updateBoardIndexToFile(MapDto map); + + List selectFilesInfo(MapDto map); + + void deleteFiles(MapDto map); + + void deleteGoodOrBadByBoardId(MapDto map); } diff --git a/src/main/java/io/company/localhost/service/FileService.java b/src/main/java/io/company/localhost/service/FileService.java index d9d110d..2149779 100644 --- a/src/main/java/io/company/localhost/service/FileService.java +++ b/src/main/java/io/company/localhost/service/FileService.java @@ -139,4 +139,14 @@ public class FileService { public boolean removeFile(String path, String fileName) { return fileUtil.removeFile(path, fileName); } + + /** + * 게시글 파일 삭제 + * + * @param fileName + * @return + */ + public boolean removeBoardFile(String fileName) { + return fileUtil.removeFile(boardFilePath, fileName); + } } \ No newline at end of file diff --git a/src/main/java/io/company/localhost/service/localbordService.java b/src/main/java/io/company/localhost/service/localbordService.java index 398b6a2..488b2de 100644 --- a/src/main/java/io/company/localhost/service/localbordService.java +++ b/src/main/java/io/company/localhost/service/localbordService.java @@ -38,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.FileVo; import io.company.localhost.vo.MemberVo; import io.company.localhost.vo.UploadFile; import lombok.RequiredArgsConstructor; @@ -80,7 +81,8 @@ public class localbordService { boardMapper.updateIncrementViewCount(boardId); } - public BigInteger insertBoard(MapDto map) { + @SuppressWarnings("unchecked") + public BigInteger insertBoard(MapDto map) { // 익명게시판이면 회원 정보를 null로 설정 if ("300102".equals(String.valueOf(map.get("LOCBRDTYP")))) { map.put("MEMBERSEQ", null); @@ -89,6 +91,14 @@ public class localbordService { map.put("MEMBERSEQ", userId); } boardMapper.insertBoard(map); + + //에디터 첨부 이미지 게시글 번호 업데이트 + if(map.get("editorUploadedImgList") != null) { + ArrayList editorUploadedImgList = (ArrayList) map.get("editorUploadedImgList"); + map.put("editorImgList", editorUploadedImgList); + this.updateBoardIndexToFile(map); + } + return (BigInteger) map.get("LOCBRDSEQ"); } @@ -126,12 +136,50 @@ public class localbordService { return boardMapper.selectAttachments(boardId); } - public void deleteBoard(MapDto map) { - boardMapper.deleteCommentsByBoardId(map); - boardMapper.deleteBoard(map); + @Transactional + public ApiResponse deleteBoard(MapDto map) { + boardMapper.deleteCommentsByBoardId(map); // 댓글 대댓글 + boardMapper.deleteGoodOrBadByBoardId(map); // 좋아요 실어요 삭제 + this.deleteBoardFiles(map); // 파일 삭제 + boardMapper.deleteBoard(map); // 게시글 삭제 + + return ApiResponse.ok("게시물이 삭제되었습니다."); } - public int updateBoard(MapDto map) { + /** + * 게시글 첨부파일 및 에디터 이미지 파일 삭제 + * + * @param map + */ + private void deleteBoardFiles(MapDto map) { + List list = this.selectFilesInfo(map); // 삭제 파일 정보 조회 + for(FileVo vo : list) { + String fileName = vo.getCMNFLENAM(); + if(!fileName.contains(vo.getCMNFLEEXT())) fileName = fileName + vo.getCMNFLEEXT(); + fileService.removeBoardFile(fileName); // 파일 삭제 + } + this.deleteFiles(map); // 파일 데이터 삭제 + } + + /** + * 게시글 파일정보 삭제 + * @param map + */ + public void deleteFiles(MapDto map) { + boardMapper.deleteFiles(map); + } + + /** + * 게시글 파일 정보 조회 + * + * @param map + * @return + */ + public List selectFilesInfo(MapDto map) { + return boardMapper.selectFilesInfo(map); + } + + public int updateBoard(MapDto map) { return boardMapper.updateBoard(map); } @@ -345,18 +393,29 @@ public class localbordService { public ApiResponse updateBoardWithFiles(MapDto map, List files) throws IOException { int result = this.updateBoard(map); // 게시글 수정 Long userId = AuthUtil.getUser().getId(); + String[] editorUploadedImgList = null; + // 수정 성공 시 첨부파일 수정 변경 if(result == 1) { + //에디터 첨부 이미지 게시글 번호 업데이트 + if(map.get("editorUploadedImgList") != null) { + editorUploadedImgList = String.valueOf(map.get("editorUploadedImgList")).split(","); + map.put("editorImgList", editorUploadedImgList); + this.updateBoardIndexToFile(map); + } + + // 추가 첨부파일 업로드 if(files != null && !files.isEmpty()) { List list = fileService.boardUploadFiles(files); // 파일 업로드 map.put("CMNFLEREG", userId); map.put("list", list); - boardMapper.insertAttachments(map); + boardMapper.insertAttachments(map); // 파일 정보 DB 적재 } + // 제거 첨부파일 삭제 if(map.get("delFileIdx") != null) { String[] array = String.valueOf(map.get("delFileIdx")).split(","); - List delListInfo = this.selectDelFileInfo(array); // 삭제 정보 조회 + List delListInfo = this.selectDelFileInfo(array); // 삭제할 파일 정보 조회 for(String item : delListInfo) { fileService.removeFile(item); // 파일 삭제 } @@ -377,6 +436,10 @@ public class localbordService { private void deleteFileInfo(String[] array) { boardMapper.deleteFileInfo(array); } + + private int updateBoardIndexToFile(MapDto map) { + return boardMapper.updateBoardIndexToFile(map); + } /** * 삭제 첨부파일 정보 조회 @@ -427,12 +490,15 @@ public class localbordService { return ApiResponse.error(HttpStatus.NOT_FOUND, "해당 게시글이 없습니다"); } - this.enrichBoardDetail(resultMap); // 추가정보 - // 📌 첨부파일 목록 추가 - List attachments = this.selectAttachments(boardId); + this.enrichBoardDetail(resultMap); // 추가정보 세팅 + List attachments = this.selectAttachments(boardId); // 📌 첨부파일 목록 추가 resultMap.put("attachments", attachments != null ? attachments : new ArrayList<>()); return ApiResponse.ok(resultMap); } + public int insertUploadEditorImageInfo(MapDto map) { + return boardMapper.insertUploadEditorImageInfo(map); + } + } \ No newline at end of file diff --git a/src/main/java/io/company/localhost/vo/FileVo.java b/src/main/java/io/company/localhost/vo/FileVo.java new file mode 100644 index 0000000..05e14ae --- /dev/null +++ b/src/main/java/io/company/localhost/vo/FileVo.java @@ -0,0 +1,18 @@ + +package io.company.localhost.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class FileVo { + private String CMNFLESEQ; + private String CMNBRDSEQ; + private String CMNFLENAM; + private String CMNFLEORG; + private String CMNFLEPAT; + private String CMNFLEEXT; + private String CMNFLESIZ; + private String CMNFLETYP; +} diff --git a/src/main/resources/mapper/localbordMapper.xml b/src/main/resources/mapper/localbordMapper.xml index 1d5b215..84c3d1c 100644 --- a/src/main/resources/mapper/localbordMapper.xml +++ b/src/main/resources/mapper/localbordMapper.xml @@ -97,6 +97,32 @@ + + + + SELECT LAST_INSERT_ID() + + INSERT INTO commonfil ( + CMNFLENAM, + CMNFLEORG, + CMNFLEPAT, + CMNFLEEXT, + CMNFLESIZ, + CMNFLEREG, + CMNFLERDT, + CMNFLETYP + ) VALUES ( + #{CMNFLENAM}, + #{CMNFLEORG}, + #{CMNFLEPAT}, + #{CMNFLEEXT}, + #{CMNFLESIZ}, + #{CMNFLEREG}, + NOW(), + 2 + ) + + + + + + + + @@ -153,6 +204,12 @@ DELETE FROM localcomt WHERE LOCBRDSEQ = #{LOCBRDSEQ} + + + + DELETE FROM localgorb + WHERE LOCBRDSEQ = #{LOCBRDSEQ} + @@ -178,7 +235,19 @@ AND (LOCCMTSEQ = #{LOCCMTSEQ} OR (#{LOCCMTSEQ} IS NULL AND LOCCMTSEQ IS NULL)) AND MEMBERSEQ = #{MEMBERSEQ} - + + + UPDATE + COMMONFIL + SET + CMNBRDSEQ = #{LOCBRDSEQ} + WHERE + CMNFLESEQ IN + + #{item} + + + INSERT INTO localgorb (LOCBRDSEQ, LOCCMTSEQ, MEMBERSEQ, LOCGOBGOD, LOCGOBBAD) @@ -285,7 +354,7 @@