diff --git a/app/kac-app/src/test/java/kr/co/palnet/kac/user/account/UserAccountControllerTest.java b/app/kac-app/src/test/java/kr/co/palnet/kac/user/account/UserAccountControllerTest.java index e5f72f1..b32550d 100644 --- a/app/kac-app/src/test/java/kr/co/palnet/kac/user/account/UserAccountControllerTest.java +++ b/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; diff --git a/data/com/src/main/java/kr/co/palnet/kac/data/com/domain/ComFileBas.java b/data/com/src/main/java/kr/co/palnet/kac/data/com/domain/ComFileBas.java index ef674a2..6e528a0 100644 --- a/data/com/src/main/java/kr/co/palnet/kac/data/com/domain/ComFileBas.java +++ b/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; } diff --git a/data/com/src/main/java/kr/co/palnet/kac/data/com/service/ComFileDomainService.java b/data/com/src/main/java/kr/co/palnet/kac/data/com/service/ComFileDomainService.java new file mode 100644 index 0000000..8ce729f --- /dev/null +++ b/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); + } +} diff --git a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanArcrft.java b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanArcrft.java index 66261ee..22e04ca 100644 --- a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanArcrft.java +++ b/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, diff --git a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/service/FltPlanDomainService.java b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/service/FltPlanDomainService.java index a6e120b..e735840 100644 --- a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/service/FltPlanDomainService.java +++ b/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); + } + + + diff --git a/data/other/src/main/java/kr/co/palnet/kac/data/other/service/OtherDomainService.java b/data/other/src/main/java/kr/co/palnet/kac/data/other/service/OtherDomainService.java new file mode 100644 index 0000000..2bff8f3 --- /dev/null +++ b/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); + } +} diff --git a/web/api-flight/build.gradle b/web/api-flight/build.gradle index 78f6131..9a6e25e 100644 --- a/web/api-flight/build.gradle +++ b/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") } diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/controller/FlightLaancController.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/controller/FlightLaancController.java index 93056c7..4e563d1 100644 --- a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/controller/FlightLaancController.java +++ b/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 createPlan(@RequestBody CreatePlanRQ rq) { + public ResponseEntity createPlan(@RequestBody CreateLaancPlanRQ rq) { flightLaancService.createPlan(rq); diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/AnctCstmrTermsModel.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/AnctCstmrTermsModel.java index a22d4b0..3bda7f1 100644 --- a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/AnctCstmrTermsModel.java +++ b/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; + } diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/BasLaancArcrftModel.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/BasLaancArcrftModel.java index 1b8e1c6..de7f12b 100644 --- a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/BasLaancArcrftModel.java +++ b/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; diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/ComFileBasDTO.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/ComFileBasDTO.java new file mode 100644 index 0000000..7f38918 --- /dev/null +++ b/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(); + } + +} diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/FltPlanArcrftDTO.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/FltPlanArcrftDTO.java new file mode 100644 index 0000000..5c61f62 --- /dev/null +++ b/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(); + + } +} diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/FltPlanBasDTO.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/FltPlanBasDTO.java index a7f8d5d..fcbf3eb 100644 --- a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/FltPlanBasDTO.java +++ b/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()); diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/FltPlanPilotDTO.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/FltPlanPilotDTO.java index f222055..f452cac 100644 --- a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/FltPlanPilotDTO.java +++ b/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; } diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/PtyTermsAgreeTxnDTO.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/PtyTermsAgreeTxnDTO.java new file mode 100644 index 0000000..0ce0a1c --- /dev/null +++ b/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(); + } + +} diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/SuredataEntityDTO.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/SuredataEntityDTO.java new file mode 100644 index 0000000..6f885fe --- /dev/null +++ b/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(); + } + +} diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CreatePlanRQ.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CreateLaancPlanRQ.java similarity index 98% rename from web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CreatePlanRQ.java rename to web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CreateLaancPlanRQ.java index 96fb7b0..7714719 100644 --- a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CreatePlanRQ.java +++ b/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; diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CreateLaancPlanRS.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CreateLaancPlanRS.java new file mode 100644 index 0000000..58e6117 --- /dev/null +++ b/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; +} diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/service/FlightLaancService.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/service/FlightLaancService.java index 7b6e859..6ff22b2 100644 --- a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/service/FlightLaancService.java +++ b/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(); } } diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/external/model/ComnSmsLaancAprovModel.java b/web/api-flight/src/main/java/kr/co/palnet/kac/external/model/ComnSmsLaancAprovModel.java new file mode 100644 index 0000000..aab6dfc --- /dev/null +++ b/web/api-flight/src/main/java/kr/co/palnet/kac/external/model/ComnSmsLaancAprovModel.java @@ -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; // 신청일자 + +} diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CtrTrnsLctnModel.java b/web/api-flight/src/main/java/kr/co/palnet/kac/external/model/CtrTrnsLctnModel.java similarity index 83% rename from web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CtrTrnsLctnModel.java rename to web/api-flight/src/main/java/kr/co/palnet/kac/external/model/CtrTrnsLctnModel.java index 2a17ce0..e25e7be 100644 --- a/web/api-flight/src/main/java/kr/co/palnet/kac/api/v1/flight/laanc/model/create/CtrTrnsLctnModel.java +++ b/web/api-flight/src/main/java/kr/co/palnet/kac/external/model/CtrTrnsLctnModel.java @@ -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; diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/external/service/ComnSmsService.java b/web/api-flight/src/main/java/kr/co/palnet/kac/external/service/ComnSmsService.java new file mode 100644 index 0000000..47e842b --- /dev/null +++ b/web/api-flight/src/main/java/kr/co/palnet/kac/external/service/ComnSmsService.java @@ -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; + } +} diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/external/CtrTrnsLctnService.java b/web/api-flight/src/main/java/kr/co/palnet/kac/external/service/CtrTrnsLctnService.java similarity index 97% rename from web/api-flight/src/main/java/kr/co/palnet/kac/external/CtrTrnsLctnService.java rename to web/api-flight/src/main/java/kr/co/palnet/kac/external/service/CtrTrnsLctnService.java index 01bb9ac..c35ce5b 100644 --- a/web/api-flight/src/main/java/kr/co/palnet/kac/external/CtrTrnsLctnService.java +++ b/web/api-flight/src/main/java/kr/co/palnet/kac/external/service/CtrTrnsLctnService.java @@ -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; diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/util/DateUtils.java b/web/api-flight/src/main/java/kr/co/palnet/kac/util/DateUtils.java new file mode 100644 index 0000000..2d0ac42 --- /dev/null +++ b/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)); + } + + +} diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/util/FileUtils.java b/web/api-flight/src/main/java/kr/co/palnet/kac/util/FileUtils.java new file mode 100644 index 0000000..efb02f1 --- /dev/null +++ b/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; + } +} + + diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/util/HttpUtils.java b/web/api-flight/src/main/java/kr/co/palnet/kac/util/HttpUtils.java new file mode 100644 index 0000000..96fa12d --- /dev/null +++ b/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(); + } +} diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/util/PdfUtils.java b/web/api-flight/src/main/java/kr/co/palnet/kac/util/PdfUtils.java new file mode 100644 index 0000000..755a779 --- /dev/null +++ b/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 + * @param pdfDto + * @return + */ + public String getHtmlToString(T pdfDto) { + + Map param = pdfDto.getParam(); + + // Thymeleaf 방식 html에 입힐 데이터 바인딩 + Context context = new Context(); + + for (Map.Entry 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; + } +} diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/util/constant/ExtensionConstant.java b/web/api-flight/src/main/java/kr/co/palnet/kac/util/constant/ExtensionConstant.java new file mode 100644 index 0000000..81bdfee --- /dev/null +++ b/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 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; + } +} diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/util/model/LaancPdfModel.java b/web/api-flight/src/main/java/kr/co/palnet/kac/util/model/LaancPdfModel.java new file mode 100644 index 0000000..2feee44 --- /dev/null +++ b/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 getParam(){ + + Field[] fields = getClass().getDeclaredFields(); + + HashMap 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"); + } + +} \ No newline at end of file diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/util/model/PdfBaseModel.java b/web/api-flight/src/main/java/kr/co/palnet/kac/util/model/PdfBaseModel.java new file mode 100644 index 0000000..b9b7c2e --- /dev/null +++ b/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 getParam(); + +} diff --git a/web/api-flight/src/main/resources/templates/fonts/H2GTRE.ttf b/web/api-flight/src/main/resources/templates/fonts/H2GTRE.ttf new file mode 100644 index 0000000..9cf3984 Binary files /dev/null and b/web/api-flight/src/main/resources/templates/fonts/H2GTRE.ttf differ diff --git a/web/api-flight/src/main/resources/templates/fonts/NanumGothic.ttf b/web/api-flight/src/main/resources/templates/fonts/NanumGothic.ttf new file mode 100644 index 0000000..009887a Binary files /dev/null and b/web/api-flight/src/main/resources/templates/fonts/NanumGothic.ttf differ diff --git a/web/api-flight/src/main/resources/templates/fonts/gulim003.ttf b/web/api-flight/src/main/resources/templates/fonts/gulim003.ttf new file mode 100644 index 0000000..3de8725 Binary files /dev/null and b/web/api-flight/src/main/resources/templates/fonts/gulim003.ttf differ diff --git a/web/api-flight/src/main/resources/templates/fonts/gulim004.ttf b/web/api-flight/src/main/resources/templates/fonts/gulim004.ttf new file mode 100644 index 0000000..f232899 Binary files /dev/null and b/web/api-flight/src/main/resources/templates/fonts/gulim004.ttf differ diff --git a/web/api-flight/src/main/resources/templates/imgs/od-expo2030.png b/web/api-flight/src/main/resources/templates/imgs/od-expo2030.png new file mode 100644 index 0000000..dd9f427 Binary files /dev/null and b/web/api-flight/src/main/resources/templates/imgs/od-expo2030.png differ diff --git a/web/api-flight/src/main/resources/templates/imgs/od-mlit.jpg b/web/api-flight/src/main/resources/templates/imgs/od-mlit.jpg new file mode 100644 index 0000000..eca1d24 Binary files /dev/null and b/web/api-flight/src/main/resources/templates/imgs/od-mlit.jpg differ diff --git a/web/api-flight/src/main/resources/templates/laanc/official_document.html b/web/api-flight/src/main/resources/templates/laanc/official_document.html new file mode 100644 index 0000000..23cee55 --- /dev/null +++ b/web/api-flight/src/main/resources/templates/laanc/official_document.html @@ -0,0 +1,273 @@ + + + + + + + + + +
+
+
+ logo +
+
+
"위대한 헌신, 영원히 가슴에"
+
김포항공관리사무소
+
+
+
+
수신 님(조종자 이름)
+
제목 비행승인 완료
+
+
+
+
+
<초경량비행장치 비행 승인(알림)>
+
+
+
1.
+
초경량비행장치 비행승인 신청 (신청일자) 관련입니다.
+
+
+
+
+
2.
+
귀하께서 신청한 초경량비행장치 비행을 「항공안전법」 제127조제3항 및 같은 법 시행규칙 제308조제3항에 따라 다음과 같이 승인하였음을 알려드립니다. +
+
+
+
+
+
가.
+
비행개요
+
+
+
+
+
1)
+
비행일시: (비행시작일시) ~ + (비행종료일시) [주간(일출 ~ 일몰)에 가시권내 비행에 한함] +
+
+
+
+
+
2)
+
비행목적: (비행목적)
+
+
+
※ 촬영금지시설 유무는 항공촬영 신청(국방부)을 통해 별도로 확인 필요
+
+
+
3)
+
비행장치 종류 및 조종자
+
+
+
+
+
가)
+
비행기체종류(신고번호): - ()
+
+
+
+
+ +
나)
+
조종자(생년월일): 님 ()
+
+
+
+
+
4)
+
비행경로/고도(반경)
+
+
+
- /m
+
+
+
나.
+
비행승인 조건
+
+
+
+
+
1)
+
위 가. 관련사항 반드시 준수 및 개인·법인·단체·인근 군부대 등과 별도 협의 등 필요시 해당사항 조치 후 비행할 것
+
+
+
+
+
2)
+
군부대의 경우 「군사기지 및 군사시설보호법」 제5조 및 제9조에 따라 보호구역에서의 금지 또는 제한사항이 엄격히 적용되오니 관할부대의 관련규정을 반드시 + 준수할 것. +
+
+
+
+
+
3)
+
국방부장관이 관할하는 공역(空域) 내에서는 「행정권한의 위임 및 위탁에 관한 규정」 제41조제6항에 따라 국방부장관으로부터 비행승인 등을 받아야 비행이 + 가능함 +
+
+
+
+
+
4)
+
「항공안전법 시행규칙」 제310조(초경량비행장치 조종자의 준수사항) 준수 철저
+
+
+
+
+
5)
+
주거지역, 상업지역 등 인구가 밀집된 지역이나 사람이 많이 모인 장소의 상공에서 인명 또는 재산에 위험을 초래할 우려가 있는 방법으로 비행하는 행위 금지 +
+
+
+
+
+
6)
+
사람 또는 건축물이 밀집된 지역의 상공에서 건축물과 충돌할 우려가 있는 방법으로 근접하여 비행하는 행위 금지
+
+
+
+
+
7)
+
인명이나 재산에 위험을 초래할 우려가 있는 낙하물 투하(投下) 금지
+
+
+
+
+
8)
+
시정(視程) 5km 이상에서만 비행할 것
+
+
+
+
+
9)
+
비행경로 주변에서 시계비행 항공기(헬리콥터 등) 운항시 비행을 일시 중단할 것
+
+
+
+
+
10)
+
자동비행기능의 정상작동 여부를 이륙시마다 확인할 것
+
+
+
+
+
11)
+
무인비행장치와 통제장치 간 신호차단시 승인받은 비행고도 이하를 유지하면서 이륙 위치로 복귀하여 착륙하도록 비행장치의 기능을 사전에 설정할 것
+
+
+
+
+
12)
+
무인비행장치 조종능력 상실 등 우발상황 발생시 관계기관(02-2660-2151)에 지체 없이 보고하고 비상연락체계를 항상 유지할 것
+
+
+
+
+
13)
+
김포국제공항 항공기 이륙·착륙 경로 및 시계비행 항공기 운항에 영향을 주지 않도록 비행경로 등에 대한 관리·감독을 철저히 할 것
+
+
+
+
+
14)
+
조종자에 대한 비행 및 안전 관련 교육 철저
+
+
+
+
+
15)
+
소음 등 민원 발생시 비행 금지
+
+
+
+
+
16)
+
사람 또는 건축물 밀집지역 회피비행 철저
+
+
+
+
+
17)
+
비행 전 비행지역에 대한 기상 및 항공고시보(NOTAM) 확인 철저
+
+
+
+
+
18)
+
비행승인 기간 중 조종자가 추가되는 경우 변경승인을 받은 후 비행할 것
+
+
+
+
+
19)
+
「항공사업법」 제70조 항공보험 등의 가입의무에 해당하는 신청자(영리 및 국가·지방자치단체 등)는 비행기간에 대한 보험 유효기간을 확인할 것
+
+
+
+
+
20)
+
사고 발생시 지체 없이 아래의 연락처로 통보할 것
+
+
+
- 일과 중 032-740-2169, 공휴일 및 야간 032-740-2107.
+
끝.
+
+ + \ No newline at end of file diff --git a/web/api-flight/src/main/resources/templates/sms/SmsLaancAprov.txt b/web/api-flight/src/main/resources/templates/sms/SmsLaancAprov.txt new file mode 100644 index 0000000..7f96067 --- /dev/null +++ b/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조 등 관련 법령에 따라 처벌받을 수 있습니다.