feat: 공지사항 파일업로드 처리
parent
48999de67a
commit
d2469ee7ca
@ -0,0 +1,83 @@
|
|||||||
|
package com.xit.biz.ctgy.controller;
|
||||||
|
|
||||||
|
import com.xit.biz.cmm.dto.CmmFileDto;
|
||||||
|
import com.xit.biz.cmm.entity.CmmFileMst;
|
||||||
|
import com.xit.biz.ctgy.dto.MinInfoBoard680Dto;
|
||||||
|
|
||||||
|
import com.xit.biz.ctgy.entity.MinInfoBoard680;
|
||||||
|
import com.xit.biz.ctgy.service.ICtgyFileService;
|
||||||
|
import com.xit.core.api.IRestResponse;
|
||||||
|
import com.xit.core.api.RestResponse;
|
||||||
|
import com.xit.core.util.AssertUtils;
|
||||||
|
import com.xit.core.util.Checks;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Tag(name = "CtgyFileMgtController", description = "파일 관리")
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/api/v1/ctgy/file")
|
||||||
|
public class CtgyFileMgtController {
|
||||||
|
private final ICtgyFileService fileService;
|
||||||
|
|
||||||
|
@Operation(summary = "파일 조회" , description = "등록된 파일 조회")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ResponseEntity<? extends IRestResponse> findFiles(@PathVariable("inCode") @NonNull final Long inCode) {
|
||||||
|
AssertUtils.isTrue(!Checks.isEmpty(inCode), "대상 게시글[inCode]을 선택해 주세요.");
|
||||||
|
return RestResponse.of(fileService.findFiles(inCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Operation(summary = "파일 저장" , description = "파일 저장")
|
||||||
|
//@PostMapping()
|
||||||
|
// public ResponseEntity<? extends IRestResponse> saveFiles2(CmmFileMst cmmFileMst, @RequestParam("files") MultipartFile[] files) {
|
||||||
|
// AssertUtils.isTrue(!Checks.isEmpty(cmmFileMst), "파일 정보가 존재하지 않습니다.");
|
||||||
|
// AssertUtils.isTrue(!Checks.isEmpty(cmmFileMst.getFileCtgCd()), "파일 구분 코드[fileCtgCd] 정보가 존재하지 않습니다.");
|
||||||
|
// AssertUtils.isTrue(!Checks.isEmpty(cmmFileMst.getFileBizId()), "파일 업무 ID[fileBizId] 정보가 존재하지 않습니다.");
|
||||||
|
// AssertUtils.isTrue(!Checks.isEmpty(files), "대상 파일이 존재하지 않습니다.");
|
||||||
|
// return RestResponse.of(fileService.saveFiles(cmmFileMst, files));
|
||||||
|
//
|
||||||
|
// RedirectAttributes redirectAttributes
|
||||||
|
// redirectAttributes.addFlashAttribute("message",
|
||||||
|
// "You successfully uploaded " + file.getOriginalFilename() + "!");
|
||||||
|
//
|
||||||
|
// return "redirect:/";
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Operation(summary = "파일 저장" , description = "파일 저장")
|
||||||
|
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
|
public ResponseEntity<? extends IRestResponse> saveFiles(@Nonnull MinInfoBoard680Dto dto) {
|
||||||
|
AssertUtils.isTrue(!Checks.isEmpty(dto), "파일 정보가 존재하지 않습니다.");
|
||||||
|
// AssertUtils.isTrue(!Checks.isEmpty(cmmFileDto.getFileCtgCd()), "파일 구분 코드[fileCtgCd] 정보가 존재하지 않습니다.");
|
||||||
|
// AssertUtils.isTrue(!Checks.isEmpty(cmmFileDto.getFileBizId()), "파일 업무 ID[fileBizId] 정보가 존재하지 않습니다.");
|
||||||
|
// AssertUtils.isTrue(!Checks.isEmpty(cmmFileDto.getFiles()), "대상 파일이 존재하지 않습니다.");
|
||||||
|
// CmmFileMst cmmFileMst = CmmFileMst.builder()
|
||||||
|
// .fileMstId(cmmFileDto.getFileMstId())
|
||||||
|
// .fileCtgCd(cmmFileDto.getFileCtgCd())
|
||||||
|
// .fileBizId(cmmFileDto.getFileBizId())
|
||||||
|
// .build();
|
||||||
|
MinInfoBoard680 minInfoBoard680 = MinInfoBoard680.builder()
|
||||||
|
.inCode(dto.getInCode())
|
||||||
|
.inBgubun(dto.getInBgubun())
|
||||||
|
.inTitle(dto.getInTitle())
|
||||||
|
.inContents(dto.getInContents())
|
||||||
|
.build();
|
||||||
|
//fileService.saveFiles(minInfoBoard680, dto.getFiles());
|
||||||
|
return RestResponse.of(fileService.saveFiles(minInfoBoard680, dto.getFiles()));
|
||||||
|
|
||||||
|
// RedirectAttributes redirectAttributes
|
||||||
|
// redirectAttributes.addFlashAttribute("message",
|
||||||
|
// "You successfully uploaded " + file.getOriginalFilename() + "!");
|
||||||
|
//
|
||||||
|
// return "redirect:/";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.xit.biz.ctgy.service;
|
||||||
|
|
||||||
|
import com.xit.biz.cmm.entity.CmmFileMst;
|
||||||
|
import com.xit.biz.ctgy.entity.MinInfoBoard680;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Lim, Jong Uk (minuk926)
|
||||||
|
* @since 2021-07-16
|
||||||
|
*/
|
||||||
|
public interface ICtgyFileService {
|
||||||
|
MinInfoBoard680 findFiles(Long inCode);
|
||||||
|
|
||||||
|
List<MinInfoBoard680> saveFiles(@Nonnull MinInfoBoard680 minInfoBoard680, MultipartFile[] files);
|
||||||
|
}
|
@ -0,0 +1,145 @@
|
|||||||
|
package com.xit.biz.ctgy.service.impl;
|
||||||
|
|
||||||
|
import com.xit.biz.cmm.entity.CmmFileDtl;
|
||||||
|
import com.xit.biz.cmm.entity.CmmFileMst;
|
||||||
|
import com.xit.biz.cmm.entity.ids.CmmFileDtlIds;
|
||||||
|
import com.xit.biz.cmm.repository.ICmmFileDtlRepository;
|
||||||
|
import com.xit.biz.cmm.repository.ICmmFileMstRepository;
|
||||||
|
import com.xit.biz.cmm.service.ICmmFileService;
|
||||||
|
import com.xit.biz.ctgy.CtgyConstants;
|
||||||
|
import com.xit.biz.ctgy.entity.MinInfoBoard680;
|
||||||
|
import com.xit.biz.ctgy.entity.Tf680Recall;
|
||||||
|
import com.xit.biz.ctgy.repository.IPublicBoardRepository;
|
||||||
|
import com.xit.biz.ctgy.service.ICtgyFileService;
|
||||||
|
import com.xit.core.support.jpa.JpaUtil;
|
||||||
|
import com.xit.core.util.AssertUtils;
|
||||||
|
import com.xit.core.util.CommUtil;
|
||||||
|
import com.xit.core.util.DateUtil;
|
||||||
|
import io.jsonwebtoken.lang.Assert;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class CtgyFileService implements ICtgyFileService {
|
||||||
|
|
||||||
|
@Value("${file.cmm.upload.root:c:/data/file/upload}")
|
||||||
|
private String rootPath;
|
||||||
|
|
||||||
|
@Value("${file.cmm.upload.path:/kangnamSIM/simUpFile/}")
|
||||||
|
private String uploadPath;
|
||||||
|
|
||||||
|
@Value("${file.cmm.upload.url}")
|
||||||
|
private String serviceUrl;
|
||||||
|
|
||||||
|
@Value("${file.cmm.upload.allow.ext:}")
|
||||||
|
private String allowExt;
|
||||||
|
|
||||||
|
@Value("${file.cmm.upload.max.size:1024}")
|
||||||
|
private long maxSize;
|
||||||
|
|
||||||
|
private final IPublicBoardRepository repository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MinInfoBoard680 findFiles(Long inCode) {
|
||||||
|
Assert.notNull(inCode, "대상 게시글[inCode]을 선택해 주세요.");
|
||||||
|
|
||||||
|
return repository.findById(inCode).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 파일 등록
|
||||||
|
* 신규등록시는 CmmFileMst.fileMstId가 null, 변경시 not null
|
||||||
|
* 변경시 동일한 파일 이름이 존재하면 DB 및 해당 파일 삭제후 신규로 생성
|
||||||
|
*
|
||||||
|
* @param entity MinInfoBoard680
|
||||||
|
* @param files MultipartFile[]
|
||||||
|
* @return CmmFileMst
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public List<MinInfoBoard680> saveFiles(@Nonnull MinInfoBoard680 entity, MultipartFile[] files) {
|
||||||
|
String makePath = "";
|
||||||
|
|
||||||
|
makePath = File.separator + DateUtil.getToday("");
|
||||||
|
|
||||||
|
// 파일 경로 : upload root 제외
|
||||||
|
String urlPath = this.uploadPath + makePath;
|
||||||
|
// 물리적인 파일 저장 위치
|
||||||
|
String fileUploadPath = this.rootPath + urlPath;
|
||||||
|
File file = new File(fileUploadPath);
|
||||||
|
if(!file.exists()) file.mkdirs();
|
||||||
|
|
||||||
|
List<MinInfoBoard680> entityList = new ArrayList<>();
|
||||||
|
for(MultipartFile mf : files){
|
||||||
|
if(!mf.isEmpty()) {
|
||||||
|
String orgFileName = "";
|
||||||
|
try {
|
||||||
|
orgFileName = StringUtils.cleanPath(Objects.requireNonNull(mf.getOriginalFilename()));
|
||||||
|
|
||||||
|
// 파일 저장 && 전송
|
||||||
|
MinInfoBoard680 savedEntity = repository.findById(entity.getInCode()).orElseGet(MinInfoBoard680::new);
|
||||||
|
savedEntity.setInFilename(orgFileName);
|
||||||
|
savedEntity.setInFilesize(mf.getSize());
|
||||||
|
savedEntity.setInFileurl(serviceUrl+urlPath);
|
||||||
|
JpaUtil.saveIfNullId(savedEntity.getInCode(), repository, savedEntity);
|
||||||
|
|
||||||
|
entityList.add(savedEntity);
|
||||||
|
mf.transferTo(new File(fileUploadPath + File.separator + orgFileName));
|
||||||
|
|
||||||
|
// inputStream을 가져와서
|
||||||
|
// copyOfLocation (저장위치)로 파일을 쓴다.
|
||||||
|
// copy의 옵션은 기존에 존재하면 REPLACE(대체한다), 오버라이딩 한다
|
||||||
|
//Files.copy(multipartFile.getInputStream(), copyOfLocation, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
|
}catch(IOException e){
|
||||||
|
String errMsg = String.format("File Upload Error :: %s", orgFileName);
|
||||||
|
//TODO : 에러처리
|
||||||
|
//return RestError.of(String.format("File Upload Error :: %s", orgFileName));
|
||||||
|
AssertUtils.isTrue(false, String.format("File Upload Error :: %s", orgFileName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entityList;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Transactional
|
||||||
|
// public void removeExistsUploadFile(String fileMstId, String orgFileNm){
|
||||||
|
// CmmFileDtl cmmFileDtl = cmmFileDtlRepository.findByFileMstIdAndOrgFileNmIgnoreCase(fileMstId, orgFileNm);
|
||||||
|
// if(cmmFileDtl != null){
|
||||||
|
// CmmFileDtlIds cmmFileDtlIds = new CmmFileDtlIds();
|
||||||
|
// cmmFileDtlIds.setFileMstId(fileMstId);
|
||||||
|
// cmmFileDtlIds.setFileId(cmmFileDtl.getFileId());
|
||||||
|
// cmmFileDtlRepository.deleteById(cmmFileDtlIds);
|
||||||
|
// new File(this.uploadPath + cmmFileDtl.getFileUpldPath() + File.separator + cmmFileDtl.getFileId()).delete();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// File.seperator 는 OS종속적이다.
|
||||||
|
// Spring에서 제공하는 cleanPath()를 통해서 ../ 내부 점들에 대해서 사용을 억제한다
|
||||||
|
Path copyOfLocation = Paths.get(uploadDir + File.separator + StringUtils.cleanPath(multipartFile.getOriginalFilename()));
|
||||||
|
try {
|
||||||
|
// inputStream을 가져와서
|
||||||
|
// copyOfLocation (저장위치)로 파일을 쓴다.
|
||||||
|
// copy의 옵션은 기존에 존재하면 REPLACE(대체한다), 오버라이딩 한다
|
||||||
|
Files.copy(multipartFile.getInputStream(), copyOfLocation, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new FileStorageException("Could not store file : " + multipartFile.getOriginalFilename());
|
||||||
|
}
|
||||||
|
*/
|
Loading…
Reference in New Issue