feat: 전자고지 대상 엑셀 업로드 반영

테스트 페이지 추가
dev
gitea-관리자 1 year ago
parent cd883a6bf5
commit 5d89feee0c

@ -47,7 +47,7 @@ import lombok.RequiredArgsConstructor;
@Tag(name = "AuthApiController", description = "인증 관리")
@RequiredArgsConstructor
@RestController
@RequestMapping(value = "/api/core/auth")
@RequestMapping(value = "/api/auth")
public class AuthApiController {
@Value("${app.token.saveType:header}")
private String authSaveType;

@ -0,0 +1,40 @@
package kr.xit.core.biz.web;
import io.swagger.v3.oas.annotations.tags.Tag;
import kr.xit.biz.ens.model.cmm.CmmEnsFileDTO.FmcExcelUpload;
import kr.xit.core.model.ApiResponseDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <pre>
* description :
*
* packageName : kr.xit.core.biz.web
* fileName : CmmFileMgtController
* author : limju
* date : 2023-09-04
* ======================================================================
*
* ----------------------------------------------------------------------
* 2023-09-04 limju
*
* </pre>
*/
@Slf4j
@Tag(name = "CmmFileMgtController", description = "파일 관리")
@RestController
@RequestMapping(value = "/api/cmm")
public class CmmFileMgtController {
@PostMapping(value = "/fileUpload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ApiResponseDTO<?> saveFiles(@ModelAttribute FmcExcelUpload fileReq) {
//cmmFileMst, fileReq.getFiles()));
log.debug("{}", fileReq);
log.debug("{}", fileReq.getFiles()[0].getOriginalFilename());
return null;
}
}

@ -26,9 +26,10 @@ public class SpringDocsApiConfig {
@Bean
public GroupedOpenApi authentification() {
return GroupedOpenApi.builder()
.group("1. Core API")
.group("1. Common API")
.pathsToMatch(
"/api/core/**"
"/api/auth/**",
"/api/cmm/**"
)
.build();
}

@ -0,0 +1,113 @@
package kr.xit.ens.support.cmm.service;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import kr.xit.biz.ens.model.cmm.CmmEnsFileDTO.FmcExcel;
import kr.xit.biz.ens.model.cmm.CmmEnsFileDTO.FmcExcelUpload;
import kr.xit.core.exception.BizRuntimeException;
import kr.xit.core.spring.util.ApiWebClient;
import kr.xit.core.support.xlsx.StreamingReader;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
/**
* <pre>
* description :
*
* packageName : kr.xit.ens.support.cmm.service
* fileName : CmmEnsFileService
* author : limju
* date : 2023-09-05
* ======================================================================
*
* ----------------------------------------------------------------------
* 2023-09-05 limju
*
* </pre>
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class CmmEnsFileService extends EgovAbstractServiceImpl implements ICmmEnsFileService{
private final static int FMC_EXCEL_DATA_START_ROW = 3;
private final static int FMC_EXCEL_CELL_CNT = 7;
private final ApiWebClient webClient;
private static final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
@Override
public void fmcExcelUpload(FmcExcelUpload fileReq) {
Set<ConstraintViolation<FmcExcelUpload>> errors = validator.validate(fileReq);
if (errors.size() > 0) {
throw BizRuntimeException.create(errors.stream()
.map(row -> String.format("%s=%s", row.getPropertyPath(), row.getMessageTemplate()))
.collect(Collectors.toList()).toString());
}
List<FmcExcel> fmcExcels = parsingFmcExcel(fileReq.getFiles()[0]);
fileReq.setSndngCo(fmcExcels.size());
fileReq.setUnitySndngMastrId(UUID.randomUUID().toString().replaceAll("-", ""));
}
private List<FmcExcel> parsingFmcExcel(MultipartFile mf) {
List<FmcExcel> fmcExcels = new ArrayList<>();
try(
InputStream is = mf.getInputStream();
Workbook wb = StreamingReader.builder().open(is)) {
Sheet sheet = wb.getSheetAt(0);
if(sheet.getLastRowNum() <= FMC_EXCEL_DATA_START_ROW) throw BizRuntimeException.create("업로드할 데이타가 존재하지 않습니다.");;
Iterator<Row> it = sheet.iterator();
// 0 row
it.hasNext();
Row row = it.next();
if(row.getPhysicalNumberOfCells() != FMC_EXCEL_CELL_CNT) throw BizRuntimeException.create("엑셀파일의 셀정보가 부정확 합니다(Cell 갯수 오류)");
// 1 row
it.hasNext();
it.next();
while(it.hasNext()) {
Row r = it.next();
int i = 0;
fmcExcels.add( new FmcExcel(
r.getCell(i++).getStringCellValue(),
r.getCell(i++).getStringCellValue(),
r.getCell(i++).getStringCellValue(),
r.getCell(i++).getStringCellValue(),
r.getCell(i++).getStringCellValue(),
r.getCell(i++).getStringCellValue(),
r.getCell(i).getStringCellValue()
));
}
}catch (IOException ie){
}
return fmcExcels;
}
}

@ -0,0 +1,23 @@
package kr.xit.ens.support.cmm.service;
import kr.xit.biz.ens.model.cmm.CmmEnsFileDTO.FmcExcelUpload;
/**
* <pre>
* description :
*
* packageName : kr.xit.ens.support.cmm.service
* fileName : ICmmEnsFileService
* author : limju
* date : 2023-09-05
* ======================================================================
*
* ----------------------------------------------------------------------
* 2023-09-05 limju
*
* </pre>
*/
public interface ICmmEnsFileService {
void fmcExcelUpload(FmcExcelUpload fileReq);
}

@ -0,0 +1,52 @@
package kr.xit.ens.support.cmm.web;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import kr.xit.biz.ens.model.cmm.CmmEnsFileDTO.FmcExcelUpload;
import kr.xit.core.model.ApiResponseDTO;
import kr.xit.ens.support.cmm.service.ICmmEnsFileService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <pre>
* description :
*
* packageName : kr.xit.ens.support.cmm.web
* fileName : CmmFileMgtController
* author : limju
* date : 2023-09-04
* ======================================================================
*
* ----------------------------------------------------------------------
* 2023-09-04 limju
*
* </pre>
*/
@Slf4j
@Tag(name = "CmmEnsFileController", description = "전자고지 연계 파일 관련 처리")
@RequiredArgsConstructor
@RestController
@RequestMapping(value = "/api/cmm")
public class CmmEnsFileController {
private final ICmmEnsFileService service;
/**
* (Facility Management Corporation)
* @param fileReq
* @return
*/
@Operation(summary = "시설관리공단 전자고지 대상 엑셀업로드 처리", description = "시설관리공단 전자고지 대상 엑셀업로드 처리")
@PostMapping(value = "/fmcExcelUpload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ApiResponseDTO<?> fmcExcelUpload(@ModelAttribute FmcExcelUpload fileReq) {
service.fmcExcelUpload(fileReq);
//fileReq.setFiles(null);
return ApiResponseDTO.success(fileReq);
}
}

@ -0,0 +1,68 @@
<!DOCTYPE HTML>
<html lang="ko">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>excel upload</title>
</head>
<body>
<form action="http://localhost:8081/api/cmm/fmcExcelUpload" method="post"
enctype="multipart/form-data">
<fieldset>
<legend>선택</legend>
<label for="sysSeCode">시스템구분</label>
<select id="sysSeCode">
<option value="01">공영주차장</option>
<option value="02">장사시설</option>
</select><br/>
<label for="sndngSeCode">발송구분</label>
<select id="sndngSeCode">
<option value="KKO-MY-DOC">카카오</option>
<option value="KT-SMS">공공알림문자</option>
<option value="E-GREEN">e-그린</option>
</select><br/>
<label>전송일</label>
<input type="date" id="sndngDt" required/><br/>
<input type="file" accept="application/vnd.ms-excel" id="files" name="files" required/>
</fieldset>
<button>upload</button>
</form>
<script>
const handleSubmit = async (event) => {
event.preventDefault();
const form = event.currentTarget;
const fd = new FormData();
fd.append('sysSeCode', document.querySelector("#sysSeCode").value);
fd.append('sndngSeCode', document.querySelector("#sndngSeCode").value);
fd.append('sndngDt', document.querySelector("#sndngDt").value.replaceAll("-", ""));
fd.append('files', document.querySelector("#files").files[0]);
const url = form.action;
const res = await fetch(url,
{method: 'post', body: fd}
);
try {
const data = await res.json();
console.log(data);
alert(JSON.stringify(data.data))
alert(JSON.stringify(data))
} catch (e) {
console.log(res)
}
}
const form = document.querySelector('form');
form.addEventListener('submit', handleSubmit);
</script>
</body>
</html>

@ -0,0 +1,154 @@
package kr.xit.biz.ens.model.cmm;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.springframework.web.multipart.MultipartFile;
/**
* <pre>
* description : DTO
*
* packageName : kr.xit.biz.ens.model.cmm
* fileName : CmmEnsFileDTO
* author : limju
* date : 2023-09-04
* ======================================================================
*
* ----------------------------------------------------------------------
* 2023-09-04 limju
*
* </pre>
*/
public class CmmEnsFileDTO {
@Schema(name = "FmcExcelUpload", description = "시설관리공단 전자문서 발송대상 엑셀 파일 업로드 DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class FmcExcelUpload {
//-----------------------------------------------------------------------------------
// 시설관리공단 전자고지 대상 엑셀파일 업로드 필수 속성
//-----------------------------------------------------------------------------------
/**
* :
* |
*/
@Schema(requiredMode = RequiredMode.REQUIRED, title = "시스템구분코드", example = "???", description = "시스템구분코드")
@Size(min = 1, max = 5, message = "시스템 구분은 필수 입니다")
private String sysSeCode;
/**
* :
* KKO-MY-DOC|KT-SMS|E-GREEN
*/
@Schema(requiredMode = RequiredMode.REQUIRED, title = "발송구분코드", example = "KKO-MY-DOC", description = "KKO-MY-DOC|KT-SMS|E-GREEN")
@Size(min = 1, max = 10, message = "발송구분은 필수 입니다")
private String sndngSeCode;
/**
* :
* - yyyyMMdd
*/
@Schema(requiredMode = RequiredMode.REQUIRED, title = "발송일시", example = "20230905", description = "발송일시")
@Size(min = 8, max = 8, message = "발송일은 필수 입니다")
private String sndngDt;
/**
* excel file :
*/
@JsonIgnore
@Schema(requiredMode = RequiredMode.REQUIRED, title = "excel file", example = "null", description = "업로드 excel file")
@NotNull(message = "첨부파일은 필수 입니다")
private MultipartFile[] files;
//-----------------------------------------------------------------------------------
// 시설관리공단 전자고지 대상 엑셀파일 업로드 결과 속성
//-----------------------------------------------------------------------------------
/**
* : response
*
*/
@Schema(requiredMode = RequiredMode.AUTO, title = "발송 건수", example = "0", description = "발송건수")
private int sndngCo;
/**
* ID : response
* key -
*/
@Schema(requiredMode = RequiredMode.AUTO, title = "통합발송마스터ID", example = "0", description = "통합발송마스터ID")
private String unitySndngMastrId;
}
@Schema(name = "FmcExcel", description = "시설관리공단 전자문서 발송대상 엑셀 파일 DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class FmcExcel {
//-----------------------------------------------------------------------------------
// 시설관리공단 전자고지 대상 엑셀파일 업로드 필수 속성
//-----------------------------------------------------------------------------------
/**
* ID :
* key - unique key
*/
@Schema(requiredMode = RequiredMode.REQUIRED, title = "통합발송상세ID", example = " ", description = "통합발송상세ID")
private String unitySndngDetailId;
/**
* :
*/
@Schema(requiredMode = RequiredMode.REQUIRED, title = "이름", example = " ", description = "이름")
private String nm;
/**
* :
*/
@Schema(requiredMode = RequiredMode.REQUIRED, title = "주민번호", example = " ", description = "주민번호")
private String ihidnum;
//-----------------------------------------------------------------------------------
// 카카오 | KT-SMS 필수
//-----------------------------------------------------------------------------------
/**
* : |KT-SMS
*/
@Schema(requiredMode = RequiredMode.AUTO, title = "전화번호", example = " ", description = "전화번호-카카오|KT 필수")
private String moblphonNo;
//-----------------------------------------------------------------------------------
// e-GREEN 필수
//-----------------------------------------------------------------------------------
/**
* : e-GREEN
*/
@Schema(requiredMode = RequiredMode.AUTO, title = "주소", example = " ", description = "주소-e-GREEN필수")
private String adres;
/**
* : e-GREEN
*/
@Schema(requiredMode = RequiredMode.AUTO, title = "상세주소", example = " ", description = "상세주소-e-GREEN필수")
private String detailAdres;
/**
* : e-GREEN
*/
@Schema(requiredMode = RequiredMode.AUTO, title = "우편번호", example = " ", description = "우편번호-e-GREEN필수")
private String zip;
}
}

@ -1,5 +1,6 @@
package kr.xit.core.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
@ -68,6 +69,7 @@ public class ApiResponseDTO<T> implements Serializable {
@Schema(description = "API 실행 결과 데이타 수")
private int count;
@JsonIgnore
@Schema(description = "페이징 정보 - 결과값이 Collection type인 경우 사용됨", example = " ")
private PaginationInfo paginationInfo;

Loading…
Cancel
Save