This commit is contained in:
parent
b7435d82f4
commit
4490655eab
@ -15,14 +15,12 @@
|
|||||||
|
|
||||||
package io.company.localhost.controller.api;
|
package io.company.localhost.controller.api;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
@ -31,7 +29,15 @@ import org.springframework.http.HttpHeaders;
|
|||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RequestPart;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
@ -165,18 +171,21 @@ public class BoardController {
|
|||||||
return ApiResponse.ok("게시물이 삭제되었습니다.");
|
return ApiResponse.ok("게시물이 삭제되었습니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 게시물 수정
|
* 게시물 수정
|
||||||
* @ReqMap map 수정 데이터 (LOCBRDTTL, LOCBRDCON, LOCBRDSEQ)
|
*
|
||||||
* @return 수정 결과 메시지
|
* @param map 수정 데이터 (LOCBRDTTL, LOCBRDCON, LOCBRDSEQ, delListInfo)
|
||||||
|
* @param files 첨부파일 정보
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@Member
|
@Member
|
||||||
@ParameterCheck
|
|
||||||
@PutMapping("/{boardId}")
|
@PutMapping("/{boardId}")
|
||||||
public ApiResponse<String> updateBoard(@ReqMap MapDto map) {
|
public ApiResponse<String> updateBoard(@ReqMap MapDto map, @RequestPart(value = "files", required = false) List<MultipartFile> files) throws IOException {
|
||||||
boardService.updateBoard(map);
|
return boardService.updateBoardWithFiles(map, files);
|
||||||
return ApiResponse.ok("게시물이 수정되었습니다.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 첨부파일 추가
|
* 첨부파일 추가
|
||||||
|
|||||||
@ -42,7 +42,7 @@ public interface localbordMapper {
|
|||||||
void deleteCommentsByBoardId(MapDto map);
|
void deleteCommentsByBoardId(MapDto map);
|
||||||
|
|
||||||
// 게시물 수정
|
// 게시물 수정
|
||||||
void updateBoard(MapDto map);
|
int updateBoard(MapDto map);
|
||||||
|
|
||||||
// 기존 반응 조회
|
// 기존 반응 조회
|
||||||
MapDto selectReaction(MapDto map);
|
MapDto selectReaction(MapDto map);
|
||||||
@ -100,6 +100,12 @@ public interface localbordMapper {
|
|||||||
|
|
||||||
//댓글id 확인
|
//댓글id 확인
|
||||||
MapDto selectCommentById(int commentId);
|
MapDto selectCommentById(int commentId);
|
||||||
|
|
||||||
|
void insertAttachments(MapDto map);
|
||||||
|
|
||||||
|
List<String> selectDelFileInfo(String[] array);
|
||||||
|
|
||||||
|
void deleteFileInfo(String[] array);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,11 +19,15 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import io.company.localhost.utils.FileUtil;
|
||||||
|
import io.company.localhost.vo.UploadFile;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@ -37,6 +41,8 @@ public class FileService {
|
|||||||
@Value("${filePath.boardfile}")
|
@Value("${filePath.boardfile}")
|
||||||
private String boardFilePath;
|
private String boardFilePath;
|
||||||
|
|
||||||
|
private final FileUtil fileUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 파일 업로드
|
* 파일 업로드
|
||||||
*
|
*
|
||||||
@ -101,4 +107,36 @@ public class FileService {
|
|||||||
throw new RuntimeException("파일 업로드 실패: " + e.getMessage());
|
throw new RuntimeException("파일 업로드 실패: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 게시판 다중파일 업로드
|
||||||
|
*
|
||||||
|
* @param files
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public List<UploadFile> boardUploadFiles(List<MultipartFile> files) throws IOException {
|
||||||
|
return fileUtil.uploadFiles(boardFilePath, files);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 파일 삭제
|
||||||
|
*
|
||||||
|
* @param path 경로+파일명
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean removeFile(String path) {
|
||||||
|
return fileUtil.removeFile(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 파일 삭제
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* @param fileName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean removeFile(String path, String fileName) {
|
||||||
|
return fileUtil.removeFile(path, fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -14,14 +14,11 @@
|
|||||||
*************************************************************/
|
*************************************************************/
|
||||||
package io.company.localhost.service;
|
package io.company.localhost.service;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import io.company.localhost.utils.BlobUtil;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@ -31,10 +28,13 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
|
|
||||||
|
import io.company.localhost.common.dto.ApiResponse;
|
||||||
import io.company.localhost.common.dto.MapDto;
|
import io.company.localhost.common.dto.MapDto;
|
||||||
import io.company.localhost.mapper.localbordMapper;
|
import io.company.localhost.mapper.localbordMapper;
|
||||||
import io.company.localhost.utils.AuthUtil;
|
import io.company.localhost.utils.AuthUtil;
|
||||||
|
import io.company.localhost.utils.BlobUtil;
|
||||||
import io.company.localhost.utils.PageUtil;
|
import io.company.localhost.utils.PageUtil;
|
||||||
|
import io.company.localhost.vo.UploadFile;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@ -123,8 +123,8 @@ public class localbordService {
|
|||||||
boardMapper.deleteBoard(map);
|
boardMapper.deleteBoard(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateBoard(MapDto map) {
|
public int updateBoard(MapDto map) {
|
||||||
boardMapper.updateBoard(map);
|
return boardMapper.updateBoard(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void procReactToBoard(MapDto map) {
|
public void procReactToBoard(MapDto map) {
|
||||||
@ -338,4 +338,58 @@ public class localbordService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 게시판 수정
|
||||||
|
*
|
||||||
|
* @param map
|
||||||
|
* @param files
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Transactional
|
||||||
|
public ApiResponse<String> updateBoardWithFiles(MapDto map, List<MultipartFile> files) throws IOException {
|
||||||
|
int result = this.updateBoard(map); // 게시글 수정
|
||||||
|
Long userId = AuthUtil.getUser().getId();
|
||||||
|
|
||||||
|
if(result == 1) {
|
||||||
|
if(files != null && !files.isEmpty()) {
|
||||||
|
List<UploadFile> list = fileService.boardUploadFiles(files); // 파일 업로드
|
||||||
|
map.put("CMNFLEREG", userId);
|
||||||
|
map.put("list", list);
|
||||||
|
boardMapper.insertAttachments(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(map.get("delFileIdx") != null) {
|
||||||
|
String[] array = String.valueOf(map.get("delFileIdx")).split(",");
|
||||||
|
List<String> delListInfo = this.selectDelFileInfo(array); // 삭제 정보 조회
|
||||||
|
for(String item : delListInfo) {
|
||||||
|
fileService.removeFile(item); // 파일 삭제
|
||||||
|
}
|
||||||
|
this.deleteFileInfo(array); // db 데이터 삭제
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ApiResponse.ok("게시물이 수정에 실패하였습니다.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApiResponse.ok("게시물이 수정되었습니다.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 첨부파일 데이터 삭제
|
||||||
|
*
|
||||||
|
* @param array
|
||||||
|
*/
|
||||||
|
private void deleteFileInfo(String[] array) {
|
||||||
|
boardMapper.deleteFileInfo(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 삭제 첨부파일 정보 조회
|
||||||
|
*
|
||||||
|
* @param array
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private List<String> selectDelFileInfo(String[] array) {
|
||||||
|
return boardMapper.selectDelFileInfo(array);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
147
src/main/java/io/company/localhost/utils/FileUtil.java
Normal file
147
src/main/java/io/company/localhost/utils/FileUtil.java
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
package io.company.localhost.utils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import io.company.localhost.vo.UploadFile;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class FileUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 파일 저장 경로/파일명
|
||||||
|
* @param savePath
|
||||||
|
* @param fileName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getFullPath(String savePath, String fileName) {
|
||||||
|
return Paths.get(savePath, fileName).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DB에 저장될 파일명
|
||||||
|
* @param originalFilename
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String createSaveFileName(String originalFilename) {
|
||||||
|
String uuid = UUID.randomUUID().toString();
|
||||||
|
String extension = getFileExtension(originalFilename);
|
||||||
|
|
||||||
|
return uuid + "." + extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 파일 확장자
|
||||||
|
* @param originalFileName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getFileExtension(String originalFileName) {
|
||||||
|
int pos = originalFileName.lastIndexOf(".");
|
||||||
|
|
||||||
|
return originalFileName.substring(pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 파일 확장자 제외
|
||||||
|
* @param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String excludeFileExtension(String withExt) {
|
||||||
|
int pos = withExt.lastIndexOf(".");
|
||||||
|
|
||||||
|
return withExt.substring(0, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 단일 파일 업로드
|
||||||
|
* @param savePath
|
||||||
|
* @param multipartFile
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public UploadFile uploadFile(String savePath, MultipartFile multipartFile) throws IOException{
|
||||||
|
File saveDirectory = new File(savePath);
|
||||||
|
|
||||||
|
if(!saveDirectory.exists()) saveDirectory.mkdirs();
|
||||||
|
if(multipartFile.isEmpty()) return null;
|
||||||
|
|
||||||
|
String originalFileName = multipartFile.getOriginalFilename(); //원본파일명
|
||||||
|
String saveFileName = createSaveFileName(originalFileName); //난수명
|
||||||
|
String ext = getFileExtension(originalFileName); //확장자
|
||||||
|
Long size = multipartFile.getSize(); //사이즈
|
||||||
|
String filePath = getFullPath(savePath, saveFileName);
|
||||||
|
|
||||||
|
multipartFile.transferTo(new File(filePath));
|
||||||
|
|
||||||
|
String orgFileName = this.excludeFileExtension(originalFileName);
|
||||||
|
String savFileName = this.excludeFileExtension(saveFileName);
|
||||||
|
|
||||||
|
return new UploadFile(orgFileName, savFileName, ext, size, filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 다중 파일 업로드
|
||||||
|
* @param savePath
|
||||||
|
* @param multipartFiles
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public List<UploadFile> uploadFiles(String savePath, List<MultipartFile> multipartFiles) throws IOException{
|
||||||
|
List<UploadFile> uploadFiles = new ArrayList<>();
|
||||||
|
|
||||||
|
for(MultipartFile multipartFile : multipartFiles) {
|
||||||
|
if(!multipartFile.isEmpty()) {
|
||||||
|
uploadFiles.add(uploadFile(savePath, multipartFile));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uploadFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 업로드된 파일 삭제
|
||||||
|
* @param path
|
||||||
|
* @param originalProfile
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Boolean removeFile(String path, String saveFileName) {
|
||||||
|
log.debug("========================================");
|
||||||
|
log.debug("FileUtil.removeFile()");
|
||||||
|
log.debug("path : {}", path);
|
||||||
|
log.debug("saveFileName : {}", saveFileName);
|
||||||
|
|
||||||
|
File file = new File(path, saveFileName);
|
||||||
|
System.gc();
|
||||||
|
boolean result = file.delete();
|
||||||
|
|
||||||
|
log.debug("result : {}", result);
|
||||||
|
log.debug("========================================");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean removeFile(String path) {
|
||||||
|
log.debug("========================================");
|
||||||
|
log.debug("FileUtil.removeFile()");
|
||||||
|
log.debug("path : {}", path);
|
||||||
|
|
||||||
|
File file = new File(path);
|
||||||
|
System.gc();
|
||||||
|
boolean result = file.delete();
|
||||||
|
|
||||||
|
log.debug("result : {}", result);
|
||||||
|
log.debug("========================================");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/main/java/io/company/localhost/vo/UploadFile.java
Normal file
15
src/main/java/io/company/localhost/vo/UploadFile.java
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
package io.company.localhost.vo;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class UploadFile {
|
||||||
|
private String originalFileName;
|
||||||
|
private String saveFileName;
|
||||||
|
private String extension;
|
||||||
|
private long fileSize;
|
||||||
|
private String filePath;
|
||||||
|
}
|
||||||
@ -65,6 +65,30 @@
|
|||||||
)
|
)
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
|
<!-- 멀티 첨부파일 저장 -->
|
||||||
|
<insert id="insertAttachments" parameterType="map">
|
||||||
|
INSERT INTO commonfil (
|
||||||
|
CMNBRDSEQ,
|
||||||
|
CMNFLENAM,
|
||||||
|
CMNFLEORG,
|
||||||
|
CMNFLEPAT,
|
||||||
|
CMNFLEEXT,
|
||||||
|
CMNFLESIZ,
|
||||||
|
CMNFLEREG,
|
||||||
|
CMNFLERDT
|
||||||
|
) VALUES
|
||||||
|
<foreach collection="list" item="item" index="index" open="(" separator="),(" close=")">
|
||||||
|
#{LOCBRDSEQ},
|
||||||
|
#{item.saveFileName},
|
||||||
|
#{item.originalFileName},
|
||||||
|
#{item.filePath},
|
||||||
|
#{item.extension},
|
||||||
|
#{item.fileSize},
|
||||||
|
#{CMNFLEREG},
|
||||||
|
NOW()
|
||||||
|
</foreach>
|
||||||
|
</insert>
|
||||||
|
|
||||||
<!-- 게시물 상세정보 조회 -->
|
<!-- 게시물 상세정보 조회 -->
|
||||||
<select id="selectBoardDetail" resultType="io.company.localhost.common.dto.MapDto">
|
<select id="selectBoardDetail" resultType="io.company.localhost.common.dto.MapDto">
|
||||||
SELECT
|
SELECT
|
||||||
@ -253,6 +277,29 @@
|
|||||||
WHERE LOCCMTSEQ = #{commentId}
|
WHERE LOCCMTSEQ = #{commentId}
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 삭제 파일 정보 조회 -->
|
||||||
|
<select id="selectDelFileInfo" >
|
||||||
|
SELECT
|
||||||
|
CMNFLEPAT
|
||||||
|
FROM
|
||||||
|
commonfil
|
||||||
|
WHERE
|
||||||
|
CMNFLESEQ in
|
||||||
|
<foreach collection="array" item="item" separator="," open="(" close=")">
|
||||||
|
#{item}
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 파일 정보 삭제 -->
|
||||||
|
<delete id="deleteFileInfo" >
|
||||||
|
DELETE FROM
|
||||||
|
commonfil
|
||||||
|
WHERE
|
||||||
|
CMNFLESEQ in
|
||||||
|
<foreach collection="array" item="item" separator="," open="(" close=")">
|
||||||
|
#{item}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user