Browse Source

feat: Flt모듈 - laanc코드 이동완료

pull/9/head
lkd9125(이경도) 7 months ago
parent
commit
523717ed47
  1. 4
      app/kac-app/src/test/java/kr/co/palnet/kac/user/account/UserAccountControllerTest.java
  2. 6
      data/com/src/main/java/kr/co/palnet/kac/data/com/domain/ComFileBas.java
  3. 19
      data/com/src/main/java/kr/co/palnet/kac/data/com/service/ComFileDomainService.java
  4. 6
      data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanArcrft.java
  5. 18
      data/flt/src/main/java/kr/co/palnet/kac/data/flt/service/FltPlanDomainService.java
  6. 19
      data/other/src/main/java/kr/co/palnet/kac/data/other/service/OtherDomainService.java
  7. 6
      web/api-flight/build.gradle
  8. 4
      web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/controller/FlightLaancController.java
  9. 6
      web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/AnctCstmrTermsModel.java
  10. 9
      web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/BasLaancArcrftModel.java
  11. 45
      web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/ComFileBasDTO.java
  12. 110
      web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/FltPlanArcrftDTO.java
  13. 4
      web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/FltPlanBasDTO.java
  14. 1
      web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/FltPlanPilotDTO.java
  15. 38
      web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/PtyTermsAgreeTxnDTO.java
  16. 127
      web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/SuredataEntityDTO.java
  17. 2
      web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CreateLaancPlanRQ.java
  18. 17
      web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CreateLaancPlanRS.java
  19. 126
      web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/service/FlightLaancService.java
  20. 27
      web/api-flight/src/main/java/kr/co/palnet/kac/external/model/ComnSmsLaancAprovModel.java
  21. 2
      web/api-flight/src/main/java/kr/co/palnet/kac/external/model/CtrTrnsLctnModel.java
  22. 94
      web/api-flight/src/main/java/kr/co/palnet/kac/external/service/ComnSmsService.java
  23. 4
      web/api-flight/src/main/java/kr/co/palnet/kac/external/service/CtrTrnsLctnService.java
  24. 35
      web/api-flight/src/main/java/kr/co/palnet/kac/util/DateUtils.java
  25. 108
      web/api-flight/src/main/java/kr/co/palnet/kac/util/FileUtils.java
  26. 35
      web/api-flight/src/main/java/kr/co/palnet/kac/util/HttpUtils.java
  27. 165
      web/api-flight/src/main/java/kr/co/palnet/kac/util/PdfUtils.java
  28. 40
      web/api-flight/src/main/java/kr/co/palnet/kac/util/constant/ExtensionConstant.java
  29. 61
      web/api-flight/src/main/java/kr/co/palnet/kac/util/model/LaancPdfModel.java
  30. 16
      web/api-flight/src/main/java/kr/co/palnet/kac/util/model/PdfBaseModel.java
  31. BIN
      web/api-flight/src/main/resources/templates/fonts/H2GTRE.ttf
  32. BIN
      web/api-flight/src/main/resources/templates/fonts/NanumGothic.ttf
  33. BIN
      web/api-flight/src/main/resources/templates/fonts/gulim003.ttf
  34. BIN
      web/api-flight/src/main/resources/templates/fonts/gulim004.ttf
  35. BIN
      web/api-flight/src/main/resources/templates/imgs/od-expo2030.png
  36. BIN
      web/api-flight/src/main/resources/templates/imgs/od-mlit.jpg
  37. 273
      web/api-flight/src/main/resources/templates/laanc/official_document.html
  38. 16
      web/api-flight/src/main/resources/templates/sms/SmsLaancAprov.txt

4
app/kac-app/src/test/java/kr/co/palnet/kac/user/account/UserAccountControllerTest.java

@ -12,6 +12,10 @@ import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
import org.springframework.restdocs.payload.JsonFieldType;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;

6
data/com/src/main/java/kr/co/palnet/kac/data/com/domain/ComFileBas.java

@ -6,7 +6,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.Instant;
import java.time.LocalDateTime;
@Data
@ -62,7 +62,7 @@ public class ComFileBas {
// 삭제일시
@Column(name = "DEL_DT", columnDefinition = "datetime")
private Instant delDt;
private LocalDateTime delDt;
// 생성사용자ID
@Column(name = "CREATE_USER_ID", length = 30, updatable = false, nullable = false)
@ -70,7 +70,7 @@ public class ComFileBas {
// 생성일시
@Column(name = "CREATE_DT", columnDefinition = "datetime", updatable = false, nullable = false)
private Instant createDt;
private LocalDateTime createDt;
}

19
data/com/src/main/java/kr/co/palnet/kac/data/com/service/ComFileDomainService.java

@ -0,0 +1,19 @@
package kr.co.palnet.kac.data.com.service;
import kr.co.palnet.kac.data.com.domain.ComFileBas;
import kr.co.palnet.kac.data.com.repository.ComFileBasRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
@RequiredArgsConstructor
public class ComFileDomainService {
private final ComFileBasRepository comFileBasRepository;
public ComFileBas saveComFileBas(ComFileBas entity){
return comFileBasRepository.save(entity);
}
}

6
data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanArcrft.java

@ -4,7 +4,7 @@ import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.UpdateTimestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalDate;
@Data
@ -130,7 +130,7 @@ public class FltPlanArcrft {
// 생성일시
@Column(name = "CREATE_DT", columnDefinition = "datetime", updatable = false, nullable = false)
private Instant createDt;
private LocalDateTime createDt;
// 수정사용자ID
@Column(name = "UPDATE_USER_ID", length = 30, nullable = false)
@ -139,7 +139,7 @@ public class FltPlanArcrft {
// 수정일시
@UpdateTimestamp
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false)
private Instant updateDt;
private LocalDateTime updateDt;
@JoinColumn(
name = "PLAN_SNO", insertable = false, updatable = false,

18
data/flt/src/main/java/kr/co/palnet/kac/data/flt/service/FltPlanDomainService.java

@ -1,13 +1,7 @@
package kr.co.palnet.kac.data.flt.service;
import kr.co.palnet.kac.data.flt.model.FltPlanArea;
import kr.co.palnet.kac.data.flt.model.FltPlanAreaCoord;
import kr.co.palnet.kac.data.flt.model.FltPlanBas;
import kr.co.palnet.kac.data.flt.model.FltPlanPilot;
import kr.co.palnet.kac.data.flt.repository.FltPlanAreaCoordRepository;
import kr.co.palnet.kac.data.flt.repository.FltPlanAreaRepository;
import kr.co.palnet.kac.data.flt.repository.FltPlanBasRepository;
import kr.co.palnet.kac.data.flt.repository.FltPlanPilotRepository;
import kr.co.palnet.kac.data.flt.model.*;
import kr.co.palnet.kac.data.flt.repository.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@ -25,6 +19,8 @@ public class FltPlanDomainService {
private final FltPlanPilotRepository fltPlanPilotRepository;
private final FltPlanArcrftRepository fltPlanArcrftRepository;
public FltPlanBas saveFltPlanBas(FltPlanBas entity){
return fltPlanBasRepository.save(entity);
@ -42,6 +38,12 @@ public class FltPlanDomainService {
return fltPlanPilotRepository.save(entity);
}
public FltPlanArcrft saveFltPlanArcrft(FltPlanArcrft entity){
return fltPlanArcrftRepository.save(entity);
}

19
data/other/src/main/java/kr/co/palnet/kac/data/other/service/OtherDomainService.java

@ -0,0 +1,19 @@
package kr.co.palnet.kac.data.other.service;
import kr.co.palnet.kac.data.other.model.SuredataEntity;
import kr.co.palnet.kac.data.other.repository.SuredataRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
@RequiredArgsConstructor
public class OtherDomainService {
private final SuredataRepository suredataRepository;
public SuredataEntity saveSuredate(SuredataEntity entity){
return suredataRepository.save(entity);
}
}

6
web/api-flight/build.gradle

@ -4,6 +4,11 @@ dependencies {
implementation "$boot:spring-boot-starter-web"
implementation "$boot:spring-boot-starter-data-jpa"
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.apache.commons:commons-io:1.3.2'
implementation 'com.itextpdf:html2pdf:5.0.3'
compileOnly 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
implementation project(":common:core")
implementation project(":common:util")
@ -11,6 +16,7 @@ dependencies {
implementation project(":data:ctr")
implementation project(":data:com")
implementation project(":data:pty")
implementation project(":data:other")
compileOnly project(":web:security")
}

4
web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/controller/FlightLaancController.java

@ -1,6 +1,6 @@
package kr.co.palnet.kac.api.v1.flight.laanc.controller;
import kr.co.palnet.kac.api.v1.flight.laanc.model.create.CreatePlanRQ;
import kr.co.palnet.kac.api.v1.flight.laanc.model.create.CreateLaancPlanRQ;
import kr.co.palnet.kac.api.v1.flight.laanc.service.FlightLaancService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -20,7 +20,7 @@ public class FlightLaancController {
private final FlightLaancService flightLaancService;
@PostMapping("/plan/create")
public ResponseEntity<Object> createPlan(@RequestBody CreatePlanRQ rq) {
public ResponseEntity<Object> createPlan(@RequestBody CreateLaancPlanRQ rq) {
flightLaancService.createPlan(rq);

6
web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/AnctCstmrTermsModel.java

@ -1,7 +1,13 @@
package kr.co.palnet.kac.api.v1.flight.laanc.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class AnctCstmrTermsModel {
@Schema(description = "약관 일련번호", example = "1")
private Long termsSno;
@Schema(description = "동의여부", example = "Y")
private String agreeYn;
}

9
web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/BasLaancArcrftModel.java

@ -6,19 +6,20 @@ import kr.co.palnet.kac.api.v1.flight.laanc.model.constant.ArcrftTypeCd;
import kr.co.palnet.kac.api.v1.flight.laanc.model.constant.ArcrftWghtCd;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
public class BasLaancArcrftModel {
@Schema(description = "계획서 기체 일련번호", example = "1", hidden = true)
private Integer planArcrftSno;
private Long planArcrftSno;
@Schema(description = "비행계획서 일련번호", example = "1", hidden = true)
private Integer planSno;
private Long planSno;
@Schema(description = "기체 일련번호", example = "1", hidden = true)
private Integer arcrftSno;
private Long arcrftSno;
@Schema(description = "식별번호(기체번호)", example = "PA0001")
private String idntfNum;
@ -39,7 +40,7 @@ public class BasLaancArcrftModel {
private String prdctCmpnNm;
@Schema(description = "제작일자", example = "2022-01-01", hidden = true)
private LocalDateTime prdctDate;
private LocalDate prdctDate;
@Schema(description = "기체길이", example = "1.0", hidden = true)
private double arcrftLngth;

45
web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/ComFileBasDTO.java

@ -0,0 +1,45 @@
package kr.co.palnet.kac.api.v1.flight.laanc.model;
import jakarta.persistence.Column;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import kr.co.palnet.kac.data.com.domain.ComFileBas;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class ComFileBasDTO {
private Long fileSno; // 파일일련번호
private Long fileGroupNo; // 파일그룹번호
private String fileSaveNm; // 저장된파일명
private String fileOriNm; // 실제파일명
private String filePath; // 파일저장경로
private String fileExt; // 파일확장명
private String fileSize; // 파일크기
private String delYn; // 삭제여부
private String delUserId; // 삭제사용자ID
private LocalDateTime delDt; // 삭제일시
private String createUserId; // 생성사용자ID
private LocalDateTime createDt; // 생성일시
public static ComFileBas toEntity(ComFileBasDTO dto){
return ComFileBas.builder()
.fileSno(dto.getFileSno())
.fileGroupNo(dto.getFileGroupNo())
.fileSaveNm(dto.getFileSaveNm())
.fileOriNm(dto.getFileOriNm())
.filePath(dto.getFilePath())
.fileExt(dto.getFileExt())
.fileSize(dto.getFileSize())
.delYn(dto.getDelYn())
.delUserId(dto.getDelUserId())
.delDt(dto.getDelDt())
.createUserId(dto.getCreateUserId())
.createDt(dto.getCreateDt())
.build();
}
}

110
web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/FltPlanArcrftDTO.java

@ -0,0 +1,110 @@
package kr.co.palnet.kac.api.v1.flight.laanc.model;
import kr.co.palnet.kac.data.flt.model.FltPlanArcrft;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
public class FltPlanArcrftDTO {
private Long planArcrftSno;
private Long planSno; // 비행계획서일련번호
private Long arcrftSno; // 기체일련번호
private String idntfNum; // 식별번호
private String groupNm; // 그룹명
private String prdctNum; // 제작번호
private String arcrftTypeCd; // 기체종류코드
private String arcrftModelNm; // 기체모델명
private String prdctCmpnNm; // 제작자
private LocalDate prdctDate; // 제작일자
private Double arcrftLngth; // 기체길이
private Double arcrftWdth; // 기체폭
private Double arcrftHght; // 기체높이
private Double arcrftWght; // 자체중량
private String arcrftWghtCd; // 자체중량코드
private String wghtTypeCd; // 중량구분코드
private String imageUrl; // 이미지URL
private Double takeoffWght; // 최대이륙중량
private String useYn; // 사용여부
private String cameraYn; // 카메라탑재여부
private String insrncYn; // 보험가입여부
private String acrftInsuranceYn; // 기체보험유무
private String insuranceExperiod; // 보험유효기간
private String corporationNm; // 법인명
private String ownerNm; // 소유자명
private String createUserId; // 생성사용자ID
private LocalDateTime createDt; // 생성일시
private String updateUserId; // 수정사용자ID
private LocalDateTime updateDt; // 수정일시
public static FltPlanArcrftDTO toDto(BasLaancArcrftModel model){
FltPlanArcrftDTO dto = new FltPlanArcrftDTO();
dto.setPlanArcrftSno(model.getPlanArcrftSno());
dto.setPlanSno(model.getPlanSno());
dto.setArcrftSno(model.getArcrftSno());
dto.setIdntfNum(model.getIdntfNum());
dto.setGroupNm(model.getGroupNm());
dto.setPrdctNum(model.getPrdctNum());
dto.setArcrftTypeCd(model.getArcrftTypeCd().getCode());
dto.setArcrftModelNm(model.getArcrftModelNm());
dto.setPrdctCmpnNm(model.getPrdctCmpnNm());
dto.setPrdctDate(model.getPrdctDate());
dto.setArcrftLngth(model.getArcrftLngth());
dto.setArcrftWdth(model.getArcrftWdth());
dto.setArcrftHght(model.getArcrftHght());
dto.setArcrftWght(model.getArcrftWght());
dto.setArcrftWghtCd(model.getWghtTypeCd());
dto.setWghtTypeCd(model.getWghtTypeCd());
dto.setImageUrl(model.getImageUrl());
dto.setTakeoffWght(model.getTakeoffWght());
dto.setUseYn(model.getUseYn());
dto.setCameraYn(model.getCameraYn());
dto.setInsrncYn(model.getInsrncYn());
dto.setAcrftInsuranceYn(model.getAcrftInsuranceYn());
dto.setInsuranceExperiod(model.getAcrftInsuranceYn());
dto.setCorporationNm(model.getCorporationNm());
dto.setOwnerNm(model.getOwnerNm());
dto.setCreateUserId(model.getCreateUserId());
dto.setCreateDt(model.getCreateDt());
dto.setUpdateUserId(model.getUpdateUserId());
dto.setUpdateDt(model.getUpdateDt());
return dto;
}
public static FltPlanArcrft toEntity(FltPlanArcrftDTO dto){
return FltPlanArcrft.builder()
.planArcrftSno(dto.getPlanArcrftSno())
.planSno(dto.getPlanSno())
.arcrftSno(dto.getArcrftSno())
.idntfNum(dto.getIdntfNum())
.prdctNum(dto.getPrdctNum())
.arcrftTypeCd(dto.getArcrftTypeCd())
.arcrftModelNm(dto.getArcrftModelNm())
.prdctCmpnNm(dto.getPrdctCmpnNm())
.prdctDate(dto.getPrdctDate())
.arcrftLngth(dto.getArcrftLngth())
.arcrftWdth(dto.getArcrftWdth())
.arcrftHght(dto.getArcrftHght())
.arcrftWght(dto.getArcrftWght())
.arcrftWghtCd(dto.getArcrftWghtCd())
.wghtTypeCd(dto.getWghtTypeCd())
.imageUrl(dto.getImageUrl())
.takeoffWght(dto.getTakeoffWght())
.useYn(dto.getUseYn())
.cameraYn(dto.getCameraYn())
.insrncYn(dto.getInsrncYn())
.acrftInsuranceYn(dto.getAcrftInsuranceYn())
.insuranceExperiod(dto.getInsuranceExperiod())
.corporationNm(dto.getCorporationNm())
.ownerNm(dto.getOwnerNm())
.createUserId(dto.getCreateUserId())
.createDt(dto.getCreateDt())
.updateUserId(dto.getUpdateUserId())
.updateDt(dto.getUpdateDt())
.build();
}
}

4
web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/FltPlanBasDTO.java

@ -2,7 +2,7 @@ package kr.co.palnet.kac.api.v1.flight.laanc.model;
import kr.co.palnet.kac.api.v1.flight.laanc.model.constant.FltPurpose;
import kr.co.palnet.kac.api.v1.flight.laanc.model.constant.FltType;
import kr.co.palnet.kac.api.v1.flight.laanc.model.create.CreatePlanRQ;
import kr.co.palnet.kac.api.v1.flight.laanc.model.create.CreateLaancPlanRQ;
import kr.co.palnet.kac.data.flt.model.FltPlanBas;
import lombok.Data;
@ -37,7 +37,7 @@ public class FltPlanBasDTO {
private LocalDateTime updateDt; // 수정일시
public static FltPlanBasDTO toFltPlanBasDto(CstmrModel model, CreatePlanRQ rq){
public static FltPlanBasDTO toFltPlanBasDto(CstmrModel model, CreateLaancPlanRQ rq){
FltPlanBasDTO dto = new FltPlanBasDTO();
dto.setCstmrSno(model.getCstmrSno());
dto.setMemberName(model.getMemberName());

1
web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/FltPlanPilotDTO.java

@ -43,7 +43,6 @@ public class FltPlanPilotDTO {
dto.setAddrDtlCn(model.getAddrDtlCn());
dto.setZip(model.getZip());
return dto;
}

38
web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/PtyTermsAgreeTxnDTO.java

@ -0,0 +1,38 @@
package kr.co.palnet.kac.api.v1.flight.laanc.model;
import jakarta.persistence.Column;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import kr.co.palnet.kac.data.pty.model.PtyTermsAgreeTxn;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class PtyTermsAgreeTxnDTO {
private Long agreeSno; // 동의일련번호
private Long termsSno; // 약관일련번호
private Long cstmrSno; // 고객일련번호
private String agreeYn; // 동의여부
private LocalDateTime agreeDt; // 동의일시
private String procIp; // 처리IP주소
private LocalDateTime updateDt; // 수정일시
private String updateUserId; // 수정사용자ID
public static PtyTermsAgreeTxn toEntity(PtyTermsAgreeTxnDTO dto){
return PtyTermsAgreeTxn.builder()
.agreeSno(dto.getAgreeSno())
.termsSno(dto.getTermsSno())
.cstmrSno(dto.getCstmrSno())
.agreeYn(dto.getAgreeYn())
.agreeDt(dto.getAgreeDt())
.procIp(dto.getProcIp())
.updateDt(dto.getUpdateDt())
.updateUserId(dto.getUpdateUserId())
.build();
}
}

127
web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/SuredataEntityDTO.java

@ -0,0 +1,127 @@
package kr.co.palnet.kac.api.v1.flight.laanc.model;
import jakarta.persistence.*;
import kr.co.palnet.kac.data.other.model.SuredataEntity;
import lombok.Data;
import org.hibernate.annotations.ColumnDefault;
@Data
public class SuredataEntityDTO {
private Long seqno;
private String intime; // date_format(now(), '%y%m%d%H%i%s')
private String usercode;
private String deptcode;
private String biztype;
private String yellowidKey;
private String reqname;
private String reqphone;
private String callname;
private String country;
private String callphone;
private String subject;
private String msg;
private String reqtime;
private String senttime;
private String recvtime;
private String result;
private Integer errcode;
private String kind;
private Integer fkcontent;
private String imageUrl;
private Integer batchflag;
private Integer retry;
private String resend;
private String templatecode;
private String retext;
private String resentflag;
private String sentmedia;
private String mediatype;
private String btnType01;
private String btnNm01;
private String btn01Url01;
private String btn01Url02;
private String btnType02;
private String btnNm02;
private String btn02Url01;
private String btn02Url02;
private String btnType03;
private String btnNm03;
private String btn03Url01;
private String btn03Url02;
private String btnType04;
private String btnNm04;
private String btn04Url01;
private String btn04Url02;
private String btnType05;
private String btnNm05;
private String btn05Url01;
private String btn05Url02;
private String kakaoerrcode;
private String etc1;
private String etc2;
private String etc3;
private String etc4;
private String etc5;
public static SuredataEntity toEntity(SuredataEntityDTO dto){
return SuredataEntity.builder()
.seqno(dto.getSeqno())
.intime(dto.getIntime())
.usercode(dto.getUsercode())
.deptcode(dto.getDeptcode())
.biztype(dto.getBiztype())
.yellowidKey(dto.getYellowidKey())
.reqname(dto.getReqname())
.reqphone(dto.getReqphone())
.callname(dto.getCallname())
.country(dto.getCountry())
.callphone(dto.getCallphone())
.subject(dto.getSubject())
.msg(dto.getMsg())
.reqtime(dto.getReqtime())
.senttime(dto.getSenttime())
.recvtime(dto.getRecvtime())
.result(dto.getResult())
.errcode(dto.getErrcode())
.kind(dto.getKind())
.fkcontent(dto.getFkcontent())
.imageUrl(dto.getImageUrl())
.batchflag(dto.getBatchflag())
.retry(dto.getRetry())
.resend(dto.getResend())
.templatecode(dto.getTemplatecode())
.retext(dto.getRetext())
.resentflag(dto.getResentflag())
.sentmedia(dto.getSentmedia())
.mediatype(dto.getMediatype())
.btnType01(dto.getBtnType01())
.btnNm01(dto.getBtnNm01())
.btn02Url01(dto.getBtn02Url01())
.btn02Url02(dto.getBtn02Url02())
.btnType02(dto.getBtnType02())
.btnNm02(dto.getBtnNm02())
.btn02Url01(dto.getBtn01Url01())
.btn02Url02(dto.getBtn01Url02())
.btnType03(dto.getBtnType03())
.btnNm03(dto.getBtnNm03())
.btn03Url01(dto.getBtn03Url01())
.btn03Url02(dto.getBtn03Url02())
.btnType04(dto.getBtnType04())
.btnNm04(dto.getBtnNm04())
.btn04Url01(dto.getBtn04Url01())
.btn04Url02(dto.getBtn04Url02())
.btnType05(dto.getBtnType05())
.btnNm05(dto.getBtnNm05())
.btn05Url01(dto.getBtn05Url01())
.btn05Url02(dto.getBtn05Url02())
.kakaoerrcode(dto.getKakaoerrcode())
.etc1(dto.getEtc1())
.etc2(dto.getEtc2())
.etc3(dto.getEtc3())
.etc4(dto.getEtc4())
.etc5(dto.getEtc5())
.build();
}
}

2
web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CreatePlanRQ.java → web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CreateLaancPlanRQ.java

@ -13,7 +13,7 @@ import java.time.LocalDateTime;
import java.util.List;
@Data
public class CreatePlanRQ {
public class CreateLaancPlanRQ {
@Schema(description = "비행계획서 일련번호", example = "1", hidden = true)
private Integer planSno;

17
web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CreateLaancPlanRS.java

@ -0,0 +1,17 @@
package kr.co.palnet.kac.api.v1.flight.laanc.model.create;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CreateLaancPlanRS {
private String pdfUrl;
private String address;
}

126
web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/service/FlightLaancService.java

@ -2,11 +2,16 @@ package kr.co.palnet.kac.api.v1.flight.laanc.service;
import kr.co.palnet.kac.api.v1.flight.laanc.model.CstmrModel;
import kr.co.palnet.kac.api.v1.flight.laanc.model.*;
import kr.co.palnet.kac.api.v1.flight.laanc.model.create.CreatePlanRQ;
import kr.co.palnet.kac.api.v1.flight.laanc.model.create.CtrTrnsLctnModel;
import kr.co.palnet.kac.api.v1.flight.laanc.model.create.CreateLaancPlanRQ;
import kr.co.palnet.kac.api.v1.flight.laanc.model.create.CreateLaancPlanRS;
import kr.co.palnet.kac.data.other.service.OtherDomainService;
import kr.co.palnet.kac.external.model.ComnSmsLaancAprovModel;
import kr.co.palnet.kac.external.model.CtrTrnsLctnModel;
import kr.co.palnet.kac.api.v1.flight.laanc.model.pliotvalid.PilotValidRs;
import kr.co.palnet.kac.config.security.util.SessionHelper;
import kr.co.palnet.kac.core.exception.BaseErrorCode;
import kr.co.palnet.kac.core.exception.BaseException;
import kr.co.palnet.kac.data.com.service.ComFileDomainService;
import kr.co.palnet.kac.data.flt.model.FltPlanArea;
import kr.co.palnet.kac.data.flt.model.FltPlanBas;
import kr.co.palnet.kac.data.flt.service.FltPlanDomainService;
@ -15,11 +20,18 @@ import kr.co.palnet.kac.data.pty.model.PtyCstmrDtl;
import kr.co.palnet.kac.data.pty.model.PtyGroupBas;
import kr.co.palnet.kac.data.pty.service.PtyCstmrDomainService;
import kr.co.palnet.kac.data.pty.service.PtyGroupDomainService;
import kr.co.palnet.kac.external.CtrTrnsLctnService;
import kr.co.palnet.kac.data.pty.service.PtyTermsDomainService;
import kr.co.palnet.kac.external.service.ComnSmsService;
import kr.co.palnet.kac.external.service.CtrTrnsLctnService;
import kr.co.palnet.kac.util.DateUtils;
import kr.co.palnet.kac.util.FileUtils;
import kr.co.palnet.kac.util.HttpUtils;
import kr.co.palnet.kac.util.model.LaancPdfModel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
@ -32,14 +44,24 @@ public class FlightLaancService {
private final PtyCstmrDomainService ptyCstmrDomainService;
private final PtyTermsDomainService ptyTermsDomainService;
private final PtyGroupDomainService ptyGroupDomainService;
private final FltPlanDomainService fltPlanDomainService;
private final ComFileDomainService comFileDomainService;
private final OtherDomainService otherDomainService;
private final CtrTrnsLctnService ctrTrnsLctnService;
private final ComnSmsService comnSmsService;
private final FileUtils fileUtils;
@Transactional
public void createPlan(CreatePlanRQ rq) {
public CreateLaancPlanRS createPlan(CreateLaancPlanRQ rq) {
Long cstmrnSno = SessionHelper.getCstmrSno();
String userId = SessionHelper.getUserId();
@ -143,10 +165,106 @@ public class FlightLaancService {
if (basLaancArcrftModelList != null && !basLaancArcrftModelList.isEmpty()) {
for (BasLaancArcrftModel basLaancArcrftModel : basLaancArcrftModelList) {
FltPlanArcrftDTO arcrftEntityDto = FltPlanArcrftDTO.toDto(basLaancArcrftModel);
arcrftEntityDto.setPlanSno(planSno);
arcrftEntityDto.setCreateUserId(userId);
arcrftEntityDto.setCreateDt(LocalDateTime.now());
arcrftEntityDto.setUpdateUserId(userId);
arcrftEntityDto.setUpdateDt(LocalDateTime.now());
String arcrftInsuranceYn = "N";
// 추가 필드
if (rq.getPilotValidRsList() != null && !rq.getPilotValidRsList().isEmpty() && basLaancArcrftModel.getIdntfNum() != null) {
PilotValidRs pilotValidRs = rq.getPilotValidRsList().stream().filter(pilotValid -> pilotValid.getRq().getDeclarationnum().equals(arcrftEntityDto.getIdntfNum())).findFirst().orElse(null);
if (pilotValidRs != null) {
String arcrftinsuranceyn = pilotValidRs.getArcrftinsuranceyn();
arcrftInsuranceYn = "Y".equals(arcrftinsuranceyn) ? "Y" : "N";
}
}
arcrftEntityDto.setAcrftInsuranceYn(arcrftInsuranceYn); // 보험여부
// arcrftEntity.setInsuranceExperiod(null); // 보헌 유효기간
// arcrftEntity.setCorporationNm(null); // 법인명
fltPlanDomainService.saveFltPlanArcrft(FltPlanArcrftDTO.toEntity(arcrftEntityDto));
}
}
if (rq.getTerms() != null && !rq.getTerms().isEmpty()) {
for (AnctCstmrTermsModel agree : rq.getTerms()) {
PtyTermsAgreeTxnDTO agreeEntityDto = new PtyTermsAgreeTxnDTO();
agreeEntityDto.setCstmrSno(fltPlanBas.getCstmrSno());
agreeEntityDto.setProcIp(HttpUtils.getRequestIp()); // TODO :: 현시점에는 HttpUtil Util이 없으므로 임시로 FLT 모듈 자체에서 Util을 만들어서 사용, 추후 모든 모듈 완성 되었을 시 Common모듈 코드 사용
agreeEntityDto.setTermsSno(agree.getTermsSno());
agreeEntityDto.setUpdateDt(LocalDateTime.now());
agreeEntityDto.setUpdateUserId(userId);
agreeEntityDto.setAgreeYn(agree.getAgreeYn());
if (agree.getAgreeYn().equals("Y")) {
agreeEntityDto.setAgreeDt(LocalDateTime.now());
}
ptyTermsDomainService.savePtyTermsAgreeTxn(PtyTermsAgreeTxnDTO.toEntity(agreeEntityDto));
}
} else {
throw new BaseException(BaseErrorCode.FAILED, "약관등록 실패");
}
String address = "";
// PDF 생성 후 URL 가져오기
LaancPdfModel laancPdfModel = new LaancPdfModel();
laancPdfModel.setPilotName(cstmrInfo.getMemberName());
if (rq.getAreaList() != null && !rq.getAreaList().isEmpty()) {
address = rq.getAreaList().get(0).getFltAreaAddr();
laancPdfModel.setAddress(address);
laancPdfModel.setElev(rq.getAreaList().get(0).getFltElev());
}
if (rq.getArcrftList() != null && !rq.getArcrftList().isEmpty()) {
if (rq.getArcrftList().get(0).getArcrftTypeCd() != null) {
laancPdfModel.setArcrftType(rq.getArcrftList().get(0).getArcrftTypeCd().getValue());
}
if (StringUtils.hasText(rq.getArcrftList().get(0).getIdntfNum())) {
laancPdfModel.setIdntfNum(rq.getArcrftList().get(0).getIdntfNum());
}
}
laancPdfModel.setBirthDate(cstmrInfo.getBrthdyDate().toString());
laancPdfModel.setSchFltStDt(DateUtils.toDateTimeStringByFormat(rq.getSchFltStDt(), "yyyy.MM.dd HH:mm"));
laancPdfModel.setSchFltEndDt(DateUtils.toDateTimeStringByFormat(rq.getSchFltEndDt(), "yyyy.MM.dd HH:mm"));
laancPdfModel.setCreateDt(DateUtils.toDateTimeStringByFormat(LocalDateTime.now(), "yyyy.MM.dd HH:mm"));
laancPdfModel.setFltPurpose(rq.getFltPurpose().getValue());
// TODO :: 현시점에는 파일 Util이 없으므로 임시로 FLT 모듈 자체에서 Util을 만들어서 사용, 추후 모든 모듈 완성 되었을 시 Common모듈 코드 사용
ComFileBasDTO comFileBasDto = fileUtils.makePdf(laancPdfModel);
comFileDomainService.saveComFileBas(ComFileBasDTO.toEntity(comFileBasDto));
fltPlanBas.setFileGroupNo(comFileBasDto.getFileGroupNo());
fltPlanDomainService.saveFltPlanBas(fltPlanBas);
String downloadUrl = fileUtils.getDownloadUrl(comFileBasDto.getFileSno());
// SMS 전송
try {
ComnSmsLaancAprovModel comnSmsLaancAprovModel = new ComnSmsLaancAprovModel();
comnSmsLaancAprovModel.setPilotName(cstmrInfo.getMemberName());
comnSmsLaancAprovModel.setCallphone(cstmrInfo.getHpno());
comnSmsLaancAprovModel.setSchFltStDt(DateUtils.toDateTimeStringByFormat(rq.getSchFltStDt(), "yyyy년 MM월 dd일 HH시 mm분"));
comnSmsLaancAprovModel.setSchFltEndDt(DateUtils.toDateTimeStringByFormat(rq.getSchFltEndDt(), "yyyy년 MM월 dd일 HH시 mm분"));
comnSmsLaancAprovModel.setFltPurpose(rq.getFltPurpose().getValue());
comnSmsLaancAprovModel.setAddress(address);
if (rq.getAreaList() != null && !rq.getAreaList().isEmpty()) {
comnSmsLaancAprovModel.setElev(rq.getAreaList().get(0).getFltElev());
}
SuredataEntityDTO sureDateEntityDto = comnSmsService.sendLaancAprovSms(comnSmsLaancAprovModel);
otherDomainService.saveSuredate(SuredataEntityDTO.toEntity(sureDateEntityDto));
} catch (Exception e) {
log.error("ERROR: ", e);
}
return CreateLaancPlanRS.builder()
.pdfUrl(downloadUrl)
.address(address)
.build();
}
}

27
web/api-flight/src/main/java/kr/co/palnet/kac/external/model/ComnSmsLaancAprovModel.java vendored

@ -0,0 +1,27 @@
package kr.co.palnet.kac.external.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ComnSmsLaancAprovModel {
private String callphone; // 수신번호
private String pilotName; // 조종사 이름
// private String birthDate; // 조종사 생년월일
private String schFltStDt; // 비행시작일시
private String schFltEndDt; // 비행종료일시
private String fltPurpose; // 비행목적
// private String arcrftType; // 등록 종류
// private String idntfNum; // 신고번호
private String address; // 주소
private String elev; // 고도
// private String createDt; // 신청일자
}

2
web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CtrTrnsLctnModel.java → web/api-flight/src/main/java/kr/co/palnet/kac/external/model/CtrTrnsLctnModel.java vendored

@ -1,4 +1,4 @@
package kr.co.palnet.kac.api.v1.flight.laanc.model.create;
package kr.co.palnet.kac.external.model;
import lombok.Data;

94
web/api-flight/src/main/java/kr/co/palnet/kac/external/service/ComnSmsService.java vendored

@ -0,0 +1,94 @@
package kr.co.palnet.kac.external.service;
import kr.co.palnet.kac.api.v1.flight.laanc.model.SuredataEntityDTO;
import kr.co.palnet.kac.external.model.ComnSmsLaancAprovModel;
import kr.co.palnet.kac.util.DateUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.LocalDateTime;
@Slf4j
@RequiredArgsConstructor
@Service
public class ComnSmsService {
/**
* 비행승인시 SMS를 보내는 기능.
* @param model
*/
public SuredataEntityDTO sendLaancAprovSms(ComnSmsLaancAprovModel model) {
log.info("sendSms : {}", model);
ClassPathResource resource = new ClassPathResource("templates/sms/SmsLaancAprov.txt");
String template = "";
try(BufferedReader br = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))){
StringBuilder stringBuilder = new StringBuilder();
String line;
boolean firstLine = true; // 첫 번째 줄은 개행 문자를 추가하지 않음
while ((line = br.readLine()) != null) {
if (firstLine) {
firstLine = false;
} else {
stringBuilder.append("\n"); // 개행 문자 추가
}
stringBuilder.append(line);
}
template = stringBuilder.toString();
} catch (IOException e) {
throw new RuntimeException(e);
}
template = template.replace("${pilotName}", model.getPilotName());
template = template.replace("${schFltStDt}", model.getSchFltStDt());
template = template.replace("${schFltEndDt}", model.getSchFltEndDt());
template = template.replace("${fltPurpose}", model.getFltPurpose());
template = template.replace("${address}", model.getAddress());
template = template.replace("${elev}", model.getElev());
SuredataEntityDTO entity = getInitialEntity();
entity.setSubject("[비행승인 완료]");
entity.setMsg(template);
entity.setCallname(model.getPilotName());
entity.setCallphone(model.getCallphone());
entity.setKind("M");
log.info("entity : {}", entity);
log.info("========================================");
log.info("message : {}", template);
log.info("========================================");
log.info("message : {}", entity.getMsg());
// suredataRepository.save(entity);
return entity;
}
/**
* 데이터베이스에 추가할 메세지 발송이력 데이터를 셋팅함.
* @return
*/
public SuredataEntityDTO getInitialEntity() {
String nowStr = DateUtils.toDateTimeStringByFormat(LocalDateTime.now(), "yyyyMMddHHmmss");
SuredataEntityDTO entity = new SuredataEntityDTO();
entity.setUsercode("palnet");
entity.setIntime(nowStr);
entity.setReqname("한국공항공사");
entity.setReqphone("0262003912"); // 1661-2626
// entity.setCallname("지대한");
// entity.setCallphone("010-0000-0000");
// entity.setSubject("주제");
// entity.setMsg("");
entity.setReqtime("00000000000000");
entity.setResult("0");
entity.setKind("S");
return entity;
}
}

4
web/api-flight/src/main/java/kr/co/palnet/kac/external/CtrTrnsLctnService.java → web/api-flight/src/main/java/kr/co/palnet/kac/external/service/CtrTrnsLctnService.java vendored

@ -1,6 +1,6 @@
package kr.co.palnet.kac.external;
package kr.co.palnet.kac.external.service;
import kr.co.palnet.kac.api.v1.flight.laanc.model.create.CtrTrnsLctnModel;
import kr.co.palnet.kac.external.model.CtrTrnsLctnModel;
import kr.co.palnet.kac.core.exception.BaseErrorCode;
import kr.co.palnet.kac.util.ObjectMapperUtils;
import org.slf4j.Logger;

35
web/api-flight/src/main/java/kr/co/palnet/kac/util/DateUtils.java

@ -0,0 +1,35 @@
package kr.co.palnet.kac.util;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class DateUtils {
private static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
public static String toDateString(LocalDate date){
return date.toString();
}
public static String toDateStringByFormat(LocalDate date, String format){
return date.format(DateTimeFormatter.ofPattern(format));
}
public static String toDateTimeString(LocalDateTime dateTime){
return dateTime.format(DateTimeFormatter.ofPattern(DateUtils.DEFAULT_DATETIME_FORMAT));
}
public static String toDateTimeStringByFormat(LocalDateTime dateTime, String format){
return dateTime.format(DateTimeFormatter.ofPattern(format));
}
}

108
web/api-flight/src/main/java/kr/co/palnet/kac/util/FileUtils.java

@ -0,0 +1,108 @@
package kr.co.palnet.kac.util;
import kr.co.palnet.kac.api.v1.flight.laanc.model.ComFileBasDTO;
import kr.co.palnet.kac.config.security.util.SessionHelper;
import kr.co.palnet.kac.util.constant.ExtensionConstant;
import kr.co.palnet.kac.util.model.LaancPdfModel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.InputStream;
import java.time.Instant;
import java.time.LocalDateTime;
@Component
@RequiredArgsConstructor
@Slf4j
public class FileUtils {
private final PdfUtils pdfUtils;
private final String DOWNLOAD_URL = "/api/comn/file/download";
/**
* PDF 생성
*
* @param model
* @return
*/
public ComFileBasDTO makePdf(LaancPdfModel model) {
String airUser = model.getPilotName();
String etc = String.valueOf(System.currentTimeMillis()); // 동명이인 방지
String fileName = getLaancSaveName(ExtensionConstant.PDF, airUser, etc);
// TODO 추후 img tag의 src로 들어가는 이미지들을 base64로 변환하여 html에 넣어줘야함
// images 넣기(임시)
log.debug(">>> {}", model.getTemplate());
if ("laanc/official_document".equals(model.getTemplate())) {
System.out.println("!!!!! official_document.html");
String imgMlit = imagesToBase64ForSrc("templates/imgs/od-mlit.jpg");
model.setImgMlit(imgMlit);
String imgExpo = imagesToBase64ForSrc("templates/imgs/od-expo2030.png");
model.setImgExpo(imgExpo);
}
String htmlContent = pdfUtils.getHtmlToString(model);
// System.out.println(">>>" + htmlContent);
ComFileBasDTO comFileBasDto = pdfUtils.generatePDF(htmlContent, fileName);
String userId = SessionHelper.getUserId();
if (userId == null) userId = "NONE";
comFileBasDto.setCreateUserId(userId);
return comFileBasDto;
}
private String getLaancSaveName(ExtensionConstant extension, String... etcName) {
String date = DateUtils.toDateTimeStringByFormat(LocalDateTime.now(), "yyyyMMddHHmmss");
StringBuilder result = new StringBuilder();
result.append(date);
for (String name : etcName) {
result.append("-")
.append(name);
}
result.append(extension.extension);
return result.toString();
}
public String imagesToBase64ForSrc(String path) {
StringBuilder str = new StringBuilder();
ClassPathResource resource = new ClassPathResource(path);
String ext = "";
int lastIndex = path.lastIndexOf(".");
if (lastIndex >= 0) {
ext = path.substring(lastIndex + 1);
}
try (InputStream is = resource.getInputStream();) {
byte[] imageBytes = IOUtils.toByteArray(is);
String encodedString = java.util.Base64.getEncoder().encodeToString(imageBytes);
str
.append("data:image/")
.append(ext)
.append(";base64,")
.append(encodedString);
} catch (IOException e) {
throw new RuntimeException(e);
}
return str.toString();
}
public String getDownloadUrl(Long fileSno) {
if(fileSno == null) return null;
return this.DOWNLOAD_URL + "/" + fileSno;
}
}

35
web/api-flight/src/main/java/kr/co/palnet/kac/util/HttpUtils.java

@ -0,0 +1,35 @@
package kr.co.palnet.kac.util;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Slf4j
public class HttpUtils {
/**
* 클라이언트 IP 가져온다
* @return 클라이언트 IP
*/
public static String getRequestIp() {
HttpServletRequest req = getCurrentRequest();
String[] HEADER_CLIENT_IP = { "NS-CLIENT-IP", "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};
for (String name : HEADER_CLIENT_IP) {
String clientIp = req.getHeader(name);
if(!StringUtils.isEmpty(clientIp) && !"unknown".equalsIgnoreCase(clientIp)) {
log.debug("{}={}", name, clientIp);
return clientIp;
}
}
return req.getRemoteAddr();
}
public static HttpServletRequest getCurrentRequest() {
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return sra.getRequest();
}
}

165
web/api-flight/src/main/java/kr/co/palnet/kac/util/PdfUtils.java

@ -0,0 +1,165 @@
package kr.co.palnet.kac.util;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.font.FontProvider;
import kr.co.palnet.kac.api.v1.flight.laanc.model.ComFileBasDTO;
import kr.co.palnet.kac.util.constant.ExtensionConstant;
import kr.co.palnet.kac.util.model.PdfBaseModel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Map;
@Slf4j
@RequiredArgsConstructor
@Component
public class PdfUtils {
private final TemplateEngine templateEngine;
@Value("${url.base.file}")
private String BASE_PATH;
private final String PDF_FORDER_PATH = "od/";
/**
* Thymeleaf HTML 파일을 데이터 바인딩하여 String으로 변환
*
* @param <T>
* @param pdfDto
* @return
*/
public <T extends PdfBaseModel> String getHtmlToString(T pdfDto) {
Map<String, Object> param = pdfDto.getParam();
// Thymeleaf 방식 html에 입힐 데이터 바인딩
Context context = new Context();
for (Map.Entry<String, Object> entry : param.entrySet()) {
String key = entry.getKey();
context.setVariable(key, param.get(key));
}
// 앞 뒤 prefix, suffix는 yml에 정의해놓음
// html에 바인딩할 데이터 넣고 파싱이후 String형식으로 뽑아옴
String htmlContent = templateEngine.process(pdfDto.getTemplate(), context);
return htmlContent;
}
/**
* HTML 태그로 이루어진 String값을 PDF로 변환
*
* @param htmlContent
* @param fileName
* @return
*/
public ComFileBasDTO generatePDF(String htmlContent, String fileName) {
ComFileBasDTO result = new ComFileBasDTO();
String pdfPath = new StringBuilder()
.append(this.BASE_PATH)
.append(this.PDF_FORDER_PATH)
.append(LocalDate.now().toString())
.append("/")
.toString();
String pdfFilePath = pdfPath + fileName;
File path = new File(pdfPath);
boolean mkdirs = path.mkdirs();
log.debug(">>> 폴더 생성여부 : {}", mkdirs);
// PDF 생성
try (FileOutputStream fileOutputStream = new FileOutputStream(pdfFilePath)) {
PdfWriter pdfWriter = new PdfWriter(fileOutputStream);
PdfDocument pdfDoc = new PdfDocument(pdfWriter);
ConverterProperties converterProperties = new ConverterProperties();
// FontProvider를 사용하여 한글 폰트 지정
FontProvider fontProvider = new FontProvider();
// NanumGothic은 한글 폰트
// fontProvider.addFont("templates/fonts/NanumGothic.ttf", PdfEncodings.IDENTITY_H);
// fontProvider.addFont("templates/fonts/NanumGothic-Bold.ttf", PdfEncodings.IDENTITY_H);
// fontProvider.addFont("templates/fonts/NanumGothic-ExtraBold.ttf", PdfEncodings.IDENTITY_H);
// fontProvider.addFont("templates/fonts/NanumGothic-Regular.ttf", PdfEncodings.IDENTITY_H);
// fontProvider.addFont("templates/fonts/hy-gothic.ttf", PdfEncodings.IDENTITY_H);
/*
fontName = "Dotum"
fullNameLowerCase = "dotum"
fontNameLowerCase = "dotum"
familyNameLowerCase = "dotum"
*/
fontProvider.addFont("templates/fonts/gulim003.ttf", PdfEncodings.IDENTITY_H);
// fontProvider.addFont("templates/fonts/gulim003.otf", PdfEncodings.IDENTITY_H);
// fontProvider.addFont("templates/fonts/gulim003.woff", PdfEncodings.IDENTITY_H);
/*
fontName = "DotumChe"
fullNameLowerCase = "dotumche"
fontNameLowerCase = "dotumche"
familyNameLowerCase = "dotumche"
*/
fontProvider.addFont("templates/fonts/gulim004.ttf", PdfEncodings.IDENTITY_H);
// fontProvider.addFont("templates/fonts/gulim004.otf", PdfEncodings.IDENTITY_H);
/*
fontName = "H2gtrE"
fullNameLowerCase = "hygothic-extra"
fontNameLowerCase = "h2gtre"
familyNameLowerCase = "hygothic-extra"
*/
fontProvider.addFont("templates/fonts/H2GTRE.ttf", PdfEncodings.IDENTITY_H);
// fontProvider.addFont("templates/fonts/H2GTRE.otf", PdfEncodings.IDENTITY_H);
/*
fontName = "MalgunGothic"
fullNameLowerCase = "malgun gothic"
fontNameLowerCase = "malgungothic"
familyNameLowerCase = "malgun gothic"
*/
// fontProvider.addFont("templates/fonts/malgun.ttf", PdfEncodings.IDENTITY_H);
String defaultFontFamily = fontProvider.getDefaultFontFamily();
log.debug(">>> defaultFontFamily : {}", defaultFontFamily);
converterProperties.setFontProvider(fontProvider);
HtmlConverter.convertToPdf(htmlContent, pdfDoc, converterProperties);
} catch (IOException e) {
throw new RuntimeException(e);
}
result.setFileGroupNo(0L);
result.setFilePath(pdfPath);
result.setFileExt(ExtensionConstant.PDF.extension);
result.setCreateDt(Instant.now());
result.setFileSaveNm(fileName);
result.setFileOriNm(fileName);
try {
String filePath = result.getFileOriNm();
long fileSize = Files.size(Paths.get(pdfPath + filePath)) / 1024;
if (fileSize >= 0) result.setFileSize(String.valueOf(fileSize));
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}

40
web/api-flight/src/main/java/kr/co/palnet/kac/util/constant/ExtensionConstant.java

@ -0,0 +1,40 @@
package kr.co.palnet.kac.util.constant;
import java.util.HashSet;
public enum ExtensionConstant {
JPG(".jpg"),
PNG(".png"),
JPEG(".jpeg"),
PDF(".pdf"),
XLSX(".xlsx"),
XLS(".xls"),
HWPX(".hwpx"),
HWP(".hwp"),
;
public final String extension;
public HashSet<ExtensionConstant> hashExtension;
private ExtensionConstant(String extension) {
this.extension = extension;
}
public static ExtensionConstant fromExtension(String extension) {
try {
for (ExtensionConstant constant : ExtensionConstant.values()) {
if (constant.extension.equals(extension)) {
return constant;
}
}
} catch (Exception e) {
return null;
}
return null;
}
}

61
web/api-flight/src/main/java/kr/co/palnet/kac/util/model/LaancPdfModel.java

@ -0,0 +1,61 @@
package kr.co.palnet.kac.util.model;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.lang.reflect.Field;
import java.util.HashMap;
@Data
@EqualsAndHashCode(callSuper = true)
public class LaancPdfModel extends PdfBaseModel {
private String pilotName; // 조종사 이름
private String birthDate; // 조종사 생년월일
private String schFltStDt; // 비행시작일시
private String schFltEndDt; // 비행종료일시
private String fltPurpose; // 비행목적
private String arcrftType; // 등록 종류
private String idntfNum; // 신고번호
private String address; // 주소
private String elev; // 고도
private String createDt; // 신청일자
// 정적 이미지
private String imgMlit;
private String imgExpo;
public LaancPdfModel(){
init();
}
public HashMap<String, Object> getParam(){
Field[] fields = getClass().getDeclaredFields();
HashMap<String, Object> result = new HashMap<>();
try {
for(Field field : fields){
Object value = field.get(this);
String key = field.getName();
result.put(key, value);
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e){
e.printStackTrace();
}
return result;
}
@Override
public void init() {
super.setTemplate("laanc/official_document");
}
}

16
web/api-flight/src/main/java/kr/co/palnet/kac/util/model/PdfBaseModel.java

@ -0,0 +1,16 @@
package kr.co.palnet.kac.util.model;
import lombok.Data;
import java.util.Map;
@Data
public abstract class PdfBaseModel {
private String template;
public abstract void init();
public abstract Map<String, Object> getParam();
}

BIN
web/api-flight/src/main/resources/templates/fonts/H2GTRE.ttf

Binary file not shown.

BIN
web/api-flight/src/main/resources/templates/fonts/NanumGothic.ttf

Binary file not shown.

BIN
web/api-flight/src/main/resources/templates/fonts/gulim003.ttf

Binary file not shown.

BIN
web/api-flight/src/main/resources/templates/fonts/gulim004.ttf

Binary file not shown.

BIN
web/api-flight/src/main/resources/templates/imgs/od-expo2030.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
web/api-flight/src/main/resources/templates/imgs/od-mlit.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

273
web/api-flight/src/main/resources/templates/laanc/official_document.html

@ -0,0 +1,273 @@
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
body {
margin: 36px 36px 36px 36px;
}
.font-dotum {
font-family: 'dotum';
font-size: 15px;
}
.font-dotumche {
font-family: 'dotumche';
font-size: 15px;
}
.font-hygothic {
font-family: 'hygothic-extra';
}
.line {
/*margin: 8px 0 8px 0;*/
line-height: 26px;
}
.wrap {
display: flex;
}
.wrap .content {
flex: auto;
}
.tab1 {
padding-left: 18px;
}
.tab2 {
padding-left: 36px;
}
.tab3 {
padding-left: 54px;
}
.tab4 {
padding-left: 72px;
}
.tab5 {
padding-left: 90px;
}
</style>
</head>
<body>
<div class="font-dotum">
<div>
<div style="width: 100px; position: absolute; margin-top: 18px">
<img th:src="@{${imgMlit}}" alt="logo"/>
</div>
<div style="text-align: center">
<div style="font-size: 12px;">"위대한 헌신, 영원히 가슴에"</div>
<div class="font-hygothic" style="font-size: 24px; margin: 28px 0 28px 0">김포항공관리사무소</div>
</div>
</div>
<div style="margin-top: 40px">
<div class="line" style="font-weight: 700">수신 <span th:text="${pilotName}"></span>님(조종자 이름)</div>
<div class="line" style="margin-bottom: 2px">제목 비행승인 완료</div>
</div>
</div>
<hr style="margin: 0; padding: 0;"/>
<div class="font-dotumche">
<div class="line" style="margin-top: 0">&lt;초경량비행장치 비행 승인(알림)&gt;</div>
<div class="line">
<div class="wrap">
<div>1.</div>
<div class="content">초경량비행장치 비행승인 신청 <span th:text="${createDt}"></span>(신청일자) 관련입니다.</div>
</div>
</div>
<div class="line">
<div class="wrap">
<div>2.</div>
<div class="content">귀하께서 신청한 초경량비행장치 비행을 「항공안전법」 제127조제3항 및 같은 법 시행규칙 제308조제3항에 따라 다음과 같이 승인하였음을 알려드립니다.
</div>
</div>
</div>
<div class="line tab1">
<div class="wrap">
<div>가.</div>
<div class="content">비행개요</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>1)</div>
<div class="content">비행일시: <span th:text="${schFltStDt}"/> (비행시작일시) ~ <span th:text="${schFltEndDt}"/>
(비행종료일시) [주간(일출 ~ 일몰)에 가시권내 비행에 한함]
</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>2)</div>
<div class="content">비행목적: <span th:text="${fltPurpose}"/>(비행목적)</div>
</div>
</div>
<div class="line tab3">※ 촬영금지시설 유무는 항공촬영 신청(국방부)을 통해 별도로 확인 필요</div>
<div class="line tab2">
<div class="wrap">
<div>3)</div>
<div class="content">비행장치 종류 및 조종자</div>
</div>
</div>
<div class="line tab3" th:if="${arcrftType} or ${idntfNum}">
<div class="wrap">
<div>가)</div>
<div class="content">비행기체종류(신고번호): <span th:if="${arcrftType}" th:text="${arcrftType}"/><span th:unless="${arcrftType}">- </span><span th:if="${idntfNum}">(<span th:text="${idntfNum}"/>)<span></span></div>
</div>
</div>
<div class="line tab3">
<div class="wrap">
<!-- th:text="'Execution mode is ' + ( (${execMode} == 'dev')? 'Development' : 'Production')"-->
<div th:text="(${arcrftType} or ${idntfNum}) ? '나)' : '가)'">나)</div>
<div class="content">조종자(생년월일): <span th:text="${pilotName}"/>님 (<span th:text="${birthDate}"/>)</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>4)</div>
<div class="content">비행경로/고도(반경)</div>
</div>
</div>
<div class="line tab3">- <span th:text="${address}"/>/<span th:text="${elev}"/>m</div>
<div class="line tab1">
<div class="wrap">
<div>나.</div>
<div class="content">비행승인 조건</div>
</div>
</div>
<div class="line tab2">
<div class="wrap" style="font-weight: bold">
<div>1)</div>
<div class="content">위 가. 관련사항 반드시 준수 및 개인·법인·단체·인근 군부대 등과 별도 협의 등 필요시 해당사항 조치 후 비행할 것</div>
</div>
</div>
<div class="line tab2">
<div class="wrap" style="font-weight: bold">
<div>2)</div>
<div class="content">군부대의 경우 「군사기지 및 군사시설보호법」 제5조 및 제9조에 따라 보호구역에서의 금지 또는 제한사항이 엄격히 적용되오니 관할부대의 관련규정을 반드시
준수할 것.
</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>3)</div>
<div class="content">국방부장관이 관할하는 공역(空域) 내에서는 「행정권한의 위임 및 위탁에 관한 규정」 제41조제6항에 따라 국방부장관으로부터 비행승인 등을 받아야 비행이
가능함
</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>4)</div>
<div class="content">「항공안전법 시행규칙」 제310조(초경량비행장치 조종자의 준수사항) 준수 철저</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>5)</div>
<div class="content">주거지역, 상업지역 등 인구가 밀집된 지역이나 사람이 많이 모인 장소의 상공에서 인명 또는 재산에 위험을 초래할 우려가 있는 방법으로 비행하는 행위 금지
</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>6)</div>
<div class="content">사람 또는 건축물이 밀집된 지역의 상공에서 건축물과 충돌할 우려가 있는 방법으로 근접하여 비행하는 행위 금지</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>7)</div>
<div class="content">인명이나 재산에 위험을 초래할 우려가 있는 낙하물 투하(投下) 금지</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>8)</div>
<div class="content">시정(視程) 5km 이상에서만 비행할 것</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>9)</div>
<div class="content">비행경로 주변에서 시계비행 항공기(헬리콥터 등) 운항시 비행을 일시 중단할 것</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>10)</div>
<div class="content">자동비행기능의 정상작동 여부를 이륙시마다 확인할 것</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>11)</div>
<div class="content">무인비행장치와 통제장치 간 신호차단시 승인받은 비행고도 이하를 유지하면서 이륙 위치로 복귀하여 착륙하도록 비행장치의 기능을 사전에 설정할 것</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>12)</div>
<div class="content">무인비행장치 조종능력 상실 등 우발상황 발생시 관계기관(02-2660-2151)에 지체 없이 보고하고 비상연락체계를 항상 유지할 것</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>13)</div>
<div class="content">김포국제공항 항공기 이륙·착륙 경로 및 시계비행 항공기 운항에 영향을 주지 않도록 비행경로 등에 대한 관리·감독을 철저히 할 것</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>14)</div>
<div class="content">조종자에 대한 비행 및 안전 관련 교육 철저</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>15)</div>
<div class="content">소음 등 민원 발생시 비행 금지</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>16)</div>
<div class="content">사람 또는 건축물 밀집지역 회피비행 철저</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>17)</div>
<div class="content">비행 전 비행지역에 대한 기상 및 항공고시보(NOTAM) 확인 철저</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>18)</div>
<div class="content">비행승인 기간 중 조종자가 추가되는 경우 변경승인을 받은 후 비행할 것</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>19)</div>
<div class="content">「항공사업법」 제70조 항공보험 등의 가입의무에 해당하는 신청자(영리 및 국가·지방자치단체 등)는 비행기간에 대한 보험 유효기간을 확인할 것</div>
</div>
</div>
<div class="line tab2">
<div class="wrap">
<div>20)</div>
<div class="content">사고 발생시 지체 없이 아래의 연락처로 통보할 것</div>
</div>
</div>
<div class="line tab3">- 일과 중 032-740-2169, 공휴일 및 야간 032-740-2107.</div>
<div class="line " style="margin-top: 32px">끝.</div>
</div>
</body>
</html>

16
web/api-flight/src/main/resources/templates/sms/SmsLaancAprov.txt

@ -0,0 +1,16 @@
[비행승인 완료]
${pilotName}님비행승인이 완료되었습니다.
가. 비행개요
1. 비행일시 : ${schFltStDt} ~ ${schFltEndDt}까지
2. 비행목적 : ${fltPurpose}
3. 비행경로 / 고도 : ${address} / ${elev}m
나. 비행 준수사항
1. 승인된 시간, 장소 및 고도를 반드시 준수해 주십시오.
2. 군작전, 경호 관련 안전위해요소과위규사항(지정된 장소, 고도, 시간 미준수)발생 시 비행이 취소 될 수 있습니다.
3. 비행에 관련된 모든 책임은 해당 업체(개인)에 있으니 유의 하시기 바랍니다.
4. 비행전/ 군 수방사로 반드시 연락 후 비행하시기 바랍니다.
* 조종자 준수사항 미 준수시 항공안전법 제 161조, 같은 법 제 166조 등 관련 법령에 따라 처벌받을 수 있습니다.
Loading…
Cancel
Save