에디터 첨부 이미지 게시글 번호 업데이트 로직 추가

This commit is contained in:
nevermoregb 2025-03-20 16:16:52 +09:00
parent f37a281f6c
commit 302efa298c
7 changed files with 243 additions and 19 deletions

View File

@ -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<String> deleteBoard(@ReqMap MapDto map) {
boardService.deleteBoard(map);
return ApiResponse.ok("게시물이 삭제되었습니다.");
return boardService.deleteBoard(map);
}

View File

@ -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;
@ -43,6 +48,8 @@ public class ImageUploadController {
@Value("${filePath.boardfile}")
private String boardFilePath;
private final localbordService localbordService;
/**
* quilleditor 안에서 삽입된 이미지를 서버에 저장하는 메소드
* @form-data 서버에 저장된 이미지 경로와 이름
@ -50,7 +57,8 @@ public class ImageUploadController {
*/
@ParameterCheck
@PostMapping("/upload")
public ApiResponse<String> uploadImage(@RequestParam("file") MultipartFile file) throws IOException {
@Transactional
public ApiResponse<MapDto> 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);
return ApiResponse.ok(fileUrl);
MapDto map = new MapDto();
if(fileIndex != 0) map.put("fileIndex", fileIndex);
map.put("fileUrl", 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;
}
}

View File

@ -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 {
@ -111,6 +114,16 @@ public interface localbordMapper {
MapDto selectBoardDetail2(Long boardId);
int insertUploadEditorImageInfo(MapDto map);
int updateBoardIndexToFile(MapDto map);
List<FileVo> selectFilesInfo(MapDto map);
void deleteFiles(MapDto map);
void deleteGoodOrBadByBoardId(MapDto map);
}

View File

@ -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);
}
}

View File

@ -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<String> editorUploadedImgList = (ArrayList<String>) 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<String> 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<FileVo> 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<FileVo> 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<String> updateBoardWithFiles(MapDto map, List<MultipartFile> 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<UploadFile> 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<String> delListInfo = this.selectDelFileInfo(array); // 삭제 정보 조회
List<String> delListInfo = this.selectDelFileInfo(array); // 삭제 파일 정보 조회
for(String item : delListInfo) {
fileService.removeFile(item); // 파일 삭제
}
@ -378,6 +437,10 @@ public class localbordService {
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<MapDto> attachments = this.selectAttachments(boardId);
this.enrichBoardDetail(resultMap); // 추가정보 세팅
List<MapDto> 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);
}
}

View File

@ -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;
}

View File

@ -97,6 +97,32 @@
</foreach>
</insert>
<!-- 에디터 첨부 이미지 저장 -->
<insert id="insertUploadEditorImageInfo" parameterType="map">
<selectKey keyProperty="id" order="AFTER" resultType="long">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO commonfil (
CMNFLENAM,
CMNFLEORG,
CMNFLEPAT,
CMNFLEEXT,
CMNFLESIZ,
CMNFLEREG,
CMNFLERDT,
CMNFLETYP
) VALUES (
#{CMNFLENAM},
#{CMNFLEORG},
#{CMNFLEPAT},
#{CMNFLEEXT},
#{CMNFLESIZ},
#{CMNFLEREG},
NOW(),
2
)
</insert>
<!-- 게시물 상세정보 조회 -->
<select id="selectBoardDetail" resultType="io.company.localhost.common.dto.MapDto">
@ -139,10 +165,35 @@
SELECT CMNFLESEQ AS id, CMNFLEORG AS originalName, CMNFLENAM AS fileName, CMNFLEPAT AS path,
CMNFLEEXT AS extension, CMNFLESIZ AS size, CMNFLERDT AS uploadDate
FROM commonfil
WHERE CMNBRDSEQ = #{boardId}
WHERE CMNBRDSEQ = #{boardId} and CMNFLETYP = 1
ORDER BY CMNFLERDT DESC
</select>
<!-- 파일 목록 조회 -->
<select id="selectFilesInfo" resultType="io.company.localhost.vo.FileVo">
SELECT
CMNFLESEQ,
CMNBRDSEQ,
CMNFLENAM,
CMNFLEORG,
CMNFLEPAT,
CMNFLEEXT,
CMNFLESIZ,
CMNFLETYP
FROM
COMMONFIL
WHERE
CMNBRDSEQ = #{LOCBRDSEQ}
</select>
<!-- 파일 목록 조회 -->
<select id="deleteFiles">
DELETE FROM
COMMONFIL
WHERE
CMNBRDSEQ = #{LOCBRDSEQ}
</select>
<!-- 게시물 삭제 -->
<delete id="deleteBoard">
DELETE FROM localbord WHERE LOCBRDSEQ = #{LOCBRDSEQ}
@ -154,6 +205,12 @@
WHERE LOCBRDSEQ = #{LOCBRDSEQ}
</delete>
<!-- 게시물 삭제 시 좋아요/싫어요 삭제 -->
<delete id="deleteGoodOrBadByBoardId">
DELETE FROM localgorb
WHERE LOCBRDSEQ = #{LOCBRDSEQ}
</delete>
<!-- 게시물 수정 -->
<update id="updateBoard">
UPDATE localbord
@ -179,6 +236,18 @@
AND MEMBERSEQ = #{MEMBERSEQ}
</update>
<update id="updateBoardIndexToFile">
UPDATE
COMMONFIL
SET
CMNBRDSEQ = #{LOCBRDSEQ}
WHERE
CMNFLESEQ IN
<foreach collection="editorImgList" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</update>
<!-- 새 반응 삽입 -->
<insert id="insertReaction">
INSERT INTO localgorb (LOCBRDSEQ, LOCCMTSEQ, MEMBERSEQ, LOCGOBGOD, LOCGOBBAD)
@ -285,7 +354,7 @@
<select id="selectIsAttachments" resultType="int">
SELECT COUNT(*)
FROM commonfil
WHERE CMNBRDSEQ = #{boardId}
WHERE CMNBRDSEQ = #{boardId} and CMNFLETYP = 1
</select>
<!-- 게시물 좋아요/싫어요 개수 조회 -->