feat: 거주자의견진술 등록 반영

dev
minuk926 3 years ago
parent 983b188343
commit 36555df311

@ -0,0 +1,96 @@
package com.xit.biz.cmm.controller;
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.constant.ErrorCode;
import com.xit.core.exception.CustomBaseException;
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.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Nonnull;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
@Tag(name = "CtgyFileMgtController", description = "공지사항 / 게시판 관리")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/ctgy/cmm")
public class CmmFileController {
private final Environment env;
@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;
private final ICtgyFileService service;
@GetMapping("/download/{inCode}")
public void download(@PathVariable Long inCode, HttpServletResponse response) {
MinInfoBoard680 entity = service.findFiles(inCode);
String absFile = "";
if (Arrays.asList(env.getActiveProfiles()).contains("prod"))
absFile = entity.getInFileurl() + File.separator + entity.getInFilename();
else
absFile = rootPath + entity.getInFileurl().split(serviceUrl)[1] + File.separator + entity.getInFilename();
Path path = Paths.get(absFile);
String contentType = null;
try {
contentType = Files.probeContentType(path);
} catch (IOException e) {
throw new CustomBaseException(ErrorCode.FILE_NOT_FOUND);
}
File file = new File(absFile);
byte[] fileByte = new byte[0];
try {
fileByte = FileUtils.readFileToByteArray(file);
} catch (IOException e) {
throw new CustomBaseException(ErrorCode.FILE_NOT_FOUND);
}
response.setContentType(contentType);
response.setHeader(HttpHeaders.CONTENT_TYPE, contentType);
response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + URLEncoder.encode(entity.getInFilename(), StandardCharsets.UTF_8) + "\";");
//response.setHeader(HttpHeaders.CONTENT_ENCODING, "binary");
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(entity.getInFilesize()));
try {
response.getOutputStream().write(fileByte);
response.getOutputStream().flush();
response.getOutputStream().close();
} catch (IOException e) {
throw new CustomBaseException(ErrorCode.FILE_NOT_FOUND);
}
}
}

@ -1,19 +1,12 @@
package com.xit.biz.cmm.service; package com.xit.biz.cmm.service;
import com.xit.biz.ctgy.entity.MinInfoBoard680;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Nonnull;
import java.util.List;
/** /**
* @author Lim, Jong Uk (minuk926) * @author Lim, Jong Uk (minuk926)
* @since 2021-07-16 * @since 2021-07-16
*/ */
public interface ICmmFileService { public interface ICmmFileService {
MinInfoBoard680 findFiles(Long inCode); String uploadFiles(MultipartFile[] files, String rootPath, String uploadPath);
List<MinInfoBoard680> saveFiles(@Nonnull MinInfoBoard680 minInfoBoard680, MultipartFile[] files);
void removePublicBoardFile(Long inCode);
} }

@ -1,16 +1,8 @@
package com.xit.biz.cmm.service.impl; package com.xit.biz.cmm.service.impl;
import com.xit.biz.cmm.service.ICmmFileService; 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.repository.IPublicBoardRepository;
import com.xit.core.constant.ErrorCode;
import com.xit.core.exception.CustomBaseException;
import com.xit.core.support.jpa.JpaUtil;
import com.xit.core.util.AssertUtils; import com.xit.core.util.AssertUtils;
import com.xit.core.util.Checks;
import com.xit.core.util.DateUtil; import com.xit.core.util.DateUtil;
import io.jsonwebtoken.lang.Assert;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -19,11 +11,8 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Nonnull;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects; import java.util.Objects;
@Slf4j @Slf4j
@ -31,12 +20,6 @@ import java.util.Objects;
@RequiredArgsConstructor @RequiredArgsConstructor
public class CmmFileService implements ICmmFileService { public class CmmFileService implements ICmmFileService {
@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}") @Value("${file.cmm.upload.url}")
private String serviceUrl; private String serviceUrl;
@ -46,36 +29,25 @@ public class CmmFileService implements ICmmFileService {
@Value("${file.cmm.upload.max.size:1024}") @Value("${file.cmm.upload.max.size:1024}")
private long maxSize; 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 * return(ex : 20220406)
* DB * -> rootPath + uploadPath + + fileName
*
* @param entity MinInfoBoard680
* @param files MultipartFile[] * @param files MultipartFile[]
* @return CmmFileMst * @return String makePath
*/ */
@Override @Override
@Transactional @Transactional
public List<MinInfoBoard680> saveFiles(@Nonnull MinInfoBoard680 entity, MultipartFile[] files) { public String uploadFiles(MultipartFile[] files, String rootPath, String uploadPath) {
List<MinInfoBoard680> entityList = new ArrayList<>(); String makePath = "";
if(files != null && files.length > 0){ if(files != null && files.length > 0){
String makePath = File.separator + DateUtil.getToday(""); makePath = File.separator + DateUtil.getToday("");
// 파일 경로 : upload root 제외 // 파일 경로 : upload root 제외
String urlPath = this.uploadPath + makePath; String urlPath = uploadPath + makePath;
// 물리적인 파일 저장 위치 // 물리적인 파일 저장 위치
String fileUploadPath = this.rootPath + urlPath; String fileUploadPath = rootPath + urlPath;
File file = new File(fileUploadPath); File file = new File(fileUploadPath);
if(!file.exists()) file.mkdirs(); if(!file.exists()) file.mkdirs();
@ -84,20 +56,6 @@ public class CmmFileService implements ICmmFileService {
String orgFileName = ""; String orgFileName = "";
try { try {
orgFileName = StringUtils.cleanPath(Objects.requireNonNull(mf.getOriginalFilename())); orgFileName = StringUtils.cleanPath(Objects.requireNonNull(mf.getOriginalFilename()));
MinInfoBoard680 savedEntity = null;
// 파일 저장 && 전송
if(Checks.isEmpty(entity.getInCode()))
savedEntity = new MinInfoBoard680();
else
savedEntity = repository.findById(entity.getInCode()).orElseGet(MinInfoBoard680::new);
savedEntity.setInFilename(orgFileName);
savedEntity.setInFilesize(mf.getSize());
savedEntity.setInFileurl(serviceUrl + urlPath);
setEntity(savedEntity, entity);
JpaUtil.saveIfNullId(entity.getInCode(), repository, savedEntity);
entityList.add(savedEntity);
mf.transferTo(new File(fileUploadPath + File.separator + orgFileName)); mf.transferTo(new File(fileUploadPath + File.separator + orgFileName));
// inputStream을 가져와 // inputStream을 가져와
@ -113,49 +71,8 @@ public class CmmFileService implements ICmmFileService {
} }
} }
} }
}else{
MinInfoBoard680 savedEntity = null;
if(Checks.isEmpty(entity.getInCode()))
savedEntity = new MinInfoBoard680();
else
savedEntity = repository.findById(entity.getInCode()).orElseGet(MinInfoBoard680::new);
setEntity(savedEntity, entity);
JpaUtil.saveIfNullId(entity.getInCode(), repository, savedEntity);
}
return entityList;
}
@Override
@Transactional
public void removePublicBoardFile(Long inCode) {
MinInfoBoard680 savedEntity = repository.findById(inCode).orElseThrow(() -> new CustomBaseException(ErrorCode.NOT_FOUND));
repository.delete(savedEntity);
// 정보 삭제후 파일 삭제 : 에러 발생시 skip
if(Checks.isNotEmpty(savedEntity.getInFilename())){
String absFile = rootPath + savedEntity.getInFileurl().split(serviceUrl)[1]+File.separator + savedEntity.getInFilename();
try {
File file = new File(absFile);
if (Checks.isNotEmpty(file) && file.exists()) file.delete();
}catch(Exception e){
//
}
}
}
private void setEntity(MinInfoBoard680 savedEntity, MinInfoBoard680 entity){
savedEntity.setInBgubun(CtgyConstants.PublicBoard.GUBUN.getCode());
savedEntity.setInDept(entity.getInDept());
savedEntity.setInTitle(entity.getInTitle());
savedEntity.setInContents(entity.getInContents());
if(Checks.isEmpty(entity.getInCode())) {
savedEntity.setInCode(repository.getInCodeByInBgubun());
savedEntity.setInContentno(savedEntity.getInCode());
} }
return makePath;
} }
} }

@ -52,7 +52,8 @@ public class ResidentController {
public ResponseEntity<? extends IRestResponse> saveResidentData(@Nonnull GnRecallScDto dto) { public ResponseEntity<? extends IRestResponse> saveResidentData(@Nonnull GnRecallScDto dto) {
AssertUtils.isTrue(!Checks.isEmpty(dto), "등록할 거주자 의견진술 자료가 존재하지 않습니다."); AssertUtils.isTrue(!Checks.isEmpty(dto), "등록할 거주자 의견진술 자료가 존재하지 않습니다.");
service.saveResidentData(mapstruct.toEntity(dto), dto.getPicadFiles(), dto.getFrecadFiles(), dto.getContadFiles()); service.saveResidentData(dto);
//service.saveResidentData(mapstruct.toEntity(dto), dto.getPicadFiles(), dto.getFrecadFiles(), dto.getContadFiles());
return RestResponse.of(HttpStatus.OK); return RestResponse.of(HttpStatus.OK);
// return RestResponse.of(HttpStatus.OK); // return RestResponse.of(HttpStatus.OK);
} }

@ -12,13 +12,19 @@ import java.util.Objects;
@Schema(name = "GnRecallSc", description = "") @Schema(name = "GnRecallSc", description = "")
@Table(name = "gn_recall_sc", schema = "traffic", catalog = "") @Table(name = "gn_recall_sc", schema = "traffic", catalog = "")
@Entity @Entity
@SequenceGenerator(
name = "RECALL_SC_SEQ_GEN",
sequenceName = "GN_RECALL_SC_SEQ",
allocationSize = 1 // default = 50 이므로 반드시 setting 필요
)
@Getter @Getter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Builder @Builder
public class GnRecallSc { public class GnRecallSc {
@Schema(required = true, title = " ", example = " ", description = " ")
@Id @Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "RECALL_SC_SEQ_GEN")
@Schema(required = true, title = " ", example = " ", description = " ")
@Column(name = "sc_code") @Column(name = "sc_code")
private Long scCode; private Long scCode;
@Schema(required = true, title = " ", example = " ", description = " ") @Schema(required = true, title = " ", example = " ", description = " ")
@ -124,6 +130,16 @@ public class GnRecallSc {
@Column(name = "sc_bunji") @Column(name = "sc_bunji")
private String scBunji; private String scBunji;
@PrePersist
public void onPrePersist(){
this.scDatagb = "1";
}
@PreUpdate
public void onPreUpdate(){
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;

@ -1,13 +1,9 @@
package com.xit.biz.ctgy.entity; package com.xit.biz.ctgy.entity;
import com.xit.biz.cmm.entity.CmmUser;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
import javax.persistence.*; import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
@Schema(name = "MinSimsa680", description = "민원심사") @Schema(name = "MinSimsa680", description = "민원심사")
@Table(name = "min_simsa680", schema = "", catalog = "") @Table(name = "min_simsa680", schema = "", catalog = "")

@ -1,13 +1,10 @@
package com.xit.biz.ctgy.entity; package com.xit.biz.ctgy.entity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
import javax.persistence.*; import javax.persistence.*;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
@Schema(name = "MinSimsaUser680", description = "민원심사사용자매핑") @Schema(name = "MinSimsaUser680", description = "민원심사사용자매핑")
@Table(name = "min_simsa_user680", schema = "", catalog = "") @Table(name = "min_simsa_user680", schema = "", catalog = "")

@ -2,7 +2,15 @@ package com.xit.biz.ctgy.repository;
import com.xit.biz.ctgy.entity.GnRecallSc; import com.xit.biz.ctgy.entity.GnRecallSc;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface IResidentRepository extends JpaRepository<GnRecallSc, Long>, IResidentRepositoryCustom { public interface IResidentRepository extends JpaRepository<GnRecallSc, Long>, IResidentRepositoryCustom {
// TODO : Ansi - sql 미사용
//@Query(value = "SELECT max(e.sc_code) + 1 FROM gn_recall_sc e, nativeQuery = true)
@Query(value = "SELECT rpad(nvl(max(e.sc_seq), :year), 10, '0') + 1 FROM gn_recall_sc e WHERE e.sc_datagb = '1' AND e.sc_seq LIKE :year||'%' ", nativeQuery = true)
Long getGnRecallScMaxScSeq(@Param("year") String year);
GnRecallSc findByScCode(final Long scCode); GnRecallSc findByScCode(final Long scCode);
} }

@ -17,5 +17,5 @@ public interface IResidentService {
Page<GnRecallSc> findAll(final GnRecallSc entity, Pageable pageable); Page<GnRecallSc> findAll(final GnRecallSc entity, Pageable pageable);
void saveResidentData(GnRecallSc entity, MultipartFile[] picadFiles, MultipartFile[] frecadFiles, MultipartFile[] contadFiles); void saveResidentData(GnRecallScDto entity);
} }

@ -1,23 +1,44 @@
package com.xit.biz.ctgy.service.impl; package com.xit.biz.ctgy.service.impl;
import com.xit.biz.cmm.service.ICmmFileService;
import com.xit.biz.ctgy.dto.GnRecallScDto; import com.xit.biz.ctgy.dto.GnRecallScDto;
import com.xit.biz.ctgy.dto.struct.GnRecallScMapstruct;
import com.xit.biz.ctgy.entity.*; import com.xit.biz.ctgy.entity.*;
import com.xit.biz.ctgy.repository.*; import com.xit.biz.ctgy.repository.*;
import com.xit.biz.ctgy.service.IResidentService; import com.xit.biz.ctgy.service.IResidentService;
import com.xit.core.support.jpa.JpaUtil; import com.xit.core.support.jpa.JpaUtil;
import com.xit.core.util.DateUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.mapstruct.factory.Mappers;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.*; import org.springframework.data.domain.*;
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.util.StringUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
public class ResidentService implements IResidentService { public class ResidentService implements IResidentService {
@Value("${file.cmm.upload.root:c:/data/file/upload}")
private String rootPath;
@Value("${file.cmm.upload.simsaPath:[simUpFile_sc1]}")
private String[] uploadPath;
private final IResidentRepository repository; private final IResidentRepository repository;
private final GnRecallScMapstruct mapstruct = Mappers.getMapper(GnRecallScMapstruct.class);
private final ICmmFileService fileService;
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
@ -54,7 +75,39 @@ public class ResidentService implements IResidentService {
} }
@Override @Override
public void saveResidentData(GnRecallSc entity, MultipartFile[] picadFiles, MultipartFile[] frecadFiles, MultipartFile[] contadFiles) { public void saveResidentData(GnRecallScDto dto) {
log.debug("{}{}{}{}", entity, picadFiles, frecadFiles, contadFiles);
if(dto.getPicadFiles() != null) {
setFileInfoAndFileUpload(dto, dto.getPicadFiles(), "setScPicad");
}
if(dto.getFrecadFiles() != null) {
setFileInfoAndFileUpload(dto, dto.getFrecadFiles(), "setScPicad");
}
if(dto.getContadFiles() != null) {
setFileInfoAndFileUpload(dto, dto.getContadFiles(), "setScContad");
}
// 접수번호 채번 : 년도 + seq 10자리
dto.setScSeq(repository.getGnRecallScMaxScSeq(String.valueOf(DateUtil.getCurrentYear())));
GnRecallSc entity = mapstruct.toEntity(dto);
repository.save(entity);
}
private void setFileInfoAndFileUpload(GnRecallScDto dto, MultipartFile[] mfs, String setMethodName) {
String makePath = fileService.uploadFiles(mfs, rootPath, uploadPath[0]);
makePath = makePath + File.separator;
for(int idx = 0; idx < mfs.length; idx++){
MultipartFile mf = mfs[idx];
try {
Method method = GnRecallScDto.class.getMethod(setMethodName + (idx+1), String.class);
method.invoke(dto, StringUtils.cleanPath(makePath + mf.getOriginalFilename()));
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
} }
} }

@ -21,6 +21,8 @@ file:
# root: /Users/minuk/data/file/upload # root: /Users/minuk/data/file/upload
# 공지사항 # 공지사항
path: /kangnamSIM/simUpFile path: /kangnamSIM/simUpFile
publicPath: simUpFile #/kangnamSIM/simUpFile
simsaPath: simUpFile_sc1, simUpFile_sc2 # 거주자 simUpFile_sc1, 장애인 simUpFile_sc2
url: http://traffic.gangnam.go.kr url: http://traffic.gangnam.go.kr
allow: allow:
ext: ext:

Loading…
Cancel
Save