+
+
+
+
+
+
+
POST /v1/flight/plan/area/buffer HTTP/1.1
+Content-Type: application/json;charset=UTF-8
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJBVVRIIiwiYXVkIjoia2FjIiwiaXNzIjoicGFsbmV0IiwiaWF0IjoxNzA4OTM3NjMzLCJleHAiOjE3MDg5NzM2MzMsInVzZXJJZCI6IlRFU1RfMTcwODkzNzYzMzg4MSIsInNubyI6IkF0QWUzU0dIL3FHZjE4ak9uV0hZNXc9PSIsInJvbGUiOiJNRU1CRVIifQ.gBkKq41JXPoooVbLa3DEQZy-URTWirFpA4Ft6YxyuboBDRfTqwDTC8w6eqr7HzrOjAoS71sPDNd9nWDTkeh3gQ
+Content-Length: 584
+Host: localhost:8080
+
+[ {
+ "planAreaSno" : 0,
+ "planSno" : 0,
+ "areaType" : "LINE",
+ "fltMethod" : "",
+ "fltMothoeRm" : "",
+ "bufferZone" : 100,
+ "fltElev" : 0,
+ "createUserId" : "",
+ "createDt" : "",
+ "updateUserId" : "",
+ "updateDt" : "",
+ "coordList" : [ {
+ "planAreaCoordSno" : 0,
+ "planAreaSno" : 0,
+ "lat" : 37.53540376761919,
+ "lon" : 126.70505084176824,
+ "createUserId" : "",
+ "createDt" : ""
+ }, {
+ "planAreaCoordSno" : 0,
+ "planAreaSno" : 0,
+ "lat" : 37.53254793498979,
+ "lon" : 126.71167265598018,
+ "createUserId" : "",
+ "createDt" : ""
+ } ]
+} ]
+
+
+
+
+
+
+
+
+
+
+파라미터 |
+설명 |
+필수 |
+
+
+
+
+Authorization
|
+Access토큰 [로그인 발급] |
+true |
+
+
+
+
+
+
+
+
+
+
+
+
+파라미터 |
+타입 |
+설명 |
+필수 |
+
+
+
+
+[].planAreaSno
|
+Number
|
+비행구역 일련번호 |
+false |
+
+
+[].planSno
|
+Number
|
+비행계획서 일련번호 |
+false |
+
+
+[].areaType
|
+String
|
+비행구역 생성타입 |
+true |
+
+
+[].fltMethod
|
+String
|
+비행방식 |
+false |
+
+
+[].fltMothoeRm
|
+String
|
+비행방식(기타) |
+false |
+
+
+[].bufferZone
|
+Number
|
+버퍼존 |
+true |
+
+
+[].fltElev
|
+Number
|
+비행고도 |
+false |
+
+
+[].createUserId
|
+String
|
+생성자ID |
+false |
+
+
+[].createDt
|
+String
|
+생성일시 |
+false |
+
+
+[].updateUserId
|
+String
|
+수정자ID |
+false |
+
+
+[].updateDt
|
+String
|
+수정일시 |
+false |
+
+
+[].coordList
|
+Array
|
+좌표리스트 |
+true |
+
+
+[].coordList[].planAreaCoordSno
|
+Number
|
+비행구역좌표 일련번호 |
+false |
+
+
+[].coordList[].planAreaSno
|
+Number
|
+비행계획비행구역 일련번호 |
+false |
+
+
+[].coordList[].lat
|
+Number
|
+위도 [ ex → 37.53540376761919 ] |
+true |
+
+
+[].coordList[].lon
|
+Number
|
+경도 [ ex → 126.70505084176824 ] |
+true |
+
+
+[].coordList[].createUserId
|
+String
|
+생성자ID |
+false |
+
+
+[].coordList[].createDt
|
+String
|
+생성일시 |
+false |
+
+
+
+
+
+
+
+
+
HTTP/1.1 200 OK
+Vary: Origin
+Vary: Access-Control-Request-Method
+Vary: Access-Control-Request-Headers
+Content-Type: application/json;charset=UTF-8
+X-Content-Type-Options: nosniff
+X-XSS-Protection: 0
+Cache-Control: no-cache, no-store, max-age=0, must-revalidate
+Pragma: no-cache
+Expires: 0
+X-Frame-Options: DENY
+Content-Length: 2093
+
+[ {
+ "planAreaSno" : 0,
+ "planSno" : 0,
+ "areaType" : "LINE",
+ "fltMethod" : null,
+ "fltAreaAddr" : null,
+ "bufferZone" : 100,
+ "fltElev" : "0",
+ "createUserId" : "",
+ "createDt" : null,
+ "updateUserId" : "",
+ "updateDt" : null,
+ "docState" : "R",
+ "coordList" : [ {
+ "planAreaCoordSno" : 0,
+ "planAreaSno" : 0,
+ "lat" : 37.53540376761919,
+ "lon" : 126.70505084176824,
+ "createUserId" : "",
+ "createDt" : null,
+ "docState" : "R"
+ }, {
+ "planAreaCoordSno" : 0,
+ "planAreaSno" : 0,
+ "lat" : 37.53254793498979,
+ "lon" : 126.71167265598018,
+ "createUserId" : "",
+ "createDt" : null,
+ "docState" : "R"
+ } ],
+ "bufferCoordList" : [ {
+ "planAreaCoordSno" : null,
+ "planAreaSno" : null,
+ "lat" : 37.53334018922286,
+ "lon" : 126.71221147466153,
+ "createUserId" : null,
+ "createDt" : null,
+ "docState" : "R"
+ }, {
+ "planAreaCoordSno" : null,
+ "planAreaSno" : null,
+ "lat" : 37.53291108693739,
+ "lon" : 126.7132063119948,
+ "createUserId" : null,
+ "createDt" : null,
+ "docState" : "R"
+ }, {
+ "planAreaCoordSno" : null,
+ "planAreaSno" : null,
+ "lat" : 37.5313265848548,
+ "lon" : 126.7121286710013,
+ "createUserId" : null,
+ "createDt" : null,
+ "docState" : "R"
+ }, {
+ "planAreaCoordSno" : null,
+ "planAreaSno" : null,
+ "lat" : 37.53461148124986,
+ "lon" : 126.70451208435273,
+ "createUserId" : null,
+ "createDt" : null,
+ "docState" : "R"
+ }, {
+ "planAreaCoordSno" : null,
+ "planAreaSno" : null,
+ "lat" : 37.53504050986325,
+ "lon" : 126.70351717504246,
+ "createUserId" : null,
+ "createDt" : null,
+ "docState" : "R"
+ }, {
+ "planAreaCoordSno" : null,
+ "planAreaSno" : null,
+ "lat" : 37.53662508898539,
+ "lon" : 126.70459468623305,
+ "createUserId" : null,
+ "createDt" : null,
+ "docState" : "R"
+ }, {
+ "planAreaCoordSno" : null,
+ "planAreaSno" : null,
+ "lat" : 37.53334018922286,
+ "lon" : 126.71221147466153,
+ "createUserId" : null,
+ "createDt" : null,
+ "docState" : "R"
+ } ],
+ "fltMothoeRm" : ""
+} ]
+
+
+
+
+
+
+
+
+
+
+
+파라미터 |
+타입 |
+설명 |
+필수 |
+
+
+
+
+[].planAreaSno
|
+Number
|
+비행구역 일련번호 |
+false |
+
+
+[].planSno
|
+Number
|
+비행계획서 일련번호 |
+false |
+
+
+[].areaType
|
+String
|
+비행구역 생성타입 |
+true |
+
+
+[].fltMethod
|
+String
|
+비행방식 |
+false |
+
+
+[].fltAreaAddr
|
+String
|
+비행지역주소 |
+false |
+
+
+[].fltMothoeRm
|
+String
|
+비행방식(기타) |
+false |
+
+
+[].bufferZone
|
+Number
|
+버퍼존 |
+true |
+
+
+[].fltElev
|
+String
|
+비행고도 |
+false |
+
+
+[].createUserId
|
+String
|
+생성자ID |
+false |
+
+
+[].createDt
|
+String
|
+생성일시 |
+false |
+
+
+[].updateUserId
|
+String
|
+수정자ID |
+false |
+
+
+[].updateDt
|
+String
|
+수정일시 |
+false |
+
+
+[].docState
|
+String
|
+코드 |
+false |
+
+
+[].bufferCoordList
|
+Array
|
+좌표리스트 |
+true |
+
+
+[].bufferCoordList[].planAreaCoordSno
|
+Number
|
+비행구역좌표 일련번호 |
+false |
+
+
+[].bufferCoordList[].planAreaSno
|
+Number
|
+비행계획비행구역 일련번호 |
+false |
+
+
+[].bufferCoordList[].lat
|
+Number
|
+위도 [ ex → 37.53540376761919 ] |
+true |
+
+
+[].bufferCoordList[].lon
|
+Number
|
+경도 [ ex → 126.70505084176824 ] |
+true |
+
+
+[].bufferCoordList[].createUserId
|
+String
|
+생성자ID |
+false |
+
+
+[].bufferCoordList[].createDt
|
+String
|
+생성자ID |
+false |
+
+
+[].bufferCoordList[].docState
|
+String
|
+코드 |
+false |
+
+
+[].coordList
|
+Array
|
+좌표리스트 |
+true |
+
+
+[].coordList[].planAreaCoordSno
|
+Number
|
+비행구역좌표 일련번호 |
+false |
+
+
+[].coordList[].planAreaSno
|
+Number
|
+비행계획비행구역 일련번호 |
+false |
+
+
+[].coordList[].lat
|
+Number
|
+위도 [ ex → 37.53540376761919 ] |
+true |
+
+
+[].coordList[].lon
|
+Number
|
+경도 [ ex → 126.70505084176824 ] |
+true |
+
+
+[].coordList[].createUserId
|
+String
|
+생성자ID |
+false |
+
+
+[].coordList[].createDt
|
+String
|
+생성자ID |
+false |
+
+
+[].coordList[].docState
|
+String
|
+코드 |
+false |
+
+
+
+
+
+
+
+
+
+
+
+
+
GET /v1/flight/plan/schedule?searchDate=2024-02-28 HTTP/1.1
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJBVVRIIiwiYXVkIjoia2FjIiwiaXNzIjoicGFsbmV0IiwiaWF0IjoxNzA4OTM3NjMzLCJleHAiOjE3MDg5NzM2MzMsInVzZXJJZCI6IlRFU1RfMTcwODkzNzYzMzIwOSIsInNubyI6InVYUWRsb29leFpiSnZKRVM0UjdrV3c9PSIsInJvbGUiOiJNRU1CRVIifQ.IEF1KfC-71Br02Hc1m5kxoOHDHJJ_j1GjqFzWwUwzKf3hQoc4qMZ0bLN5OH0HPrJKLiNALPjrGkbhxsFMjPKvA
+Host: localhost:8080
+
+
+
+
+
+
+
+
+
+
+파라미터 |
+설명 |
+필수 |
+
+
+
+
+Authorization
|
+Access토큰 [로그인 발급] |
+true |
+
+
+
+
+
+
+
+
+
+
+
+파라미터 |
+설명 |
+필수 |
+
+
+
+
+searchDate
|
+검색일자 |
+true |
+
+
+
+
+
+
+
+
+
HTTP/1.1 200 OK
+Vary: Origin
+Vary: Access-Control-Request-Method
+Vary: Access-Control-Request-Headers
+Content-Type: application/json;charset=UTF-8
+X-Content-Type-Options: nosniff
+X-XSS-Protection: 0
+Cache-Control: no-cache, no-store, max-age=0, must-revalidate
+Pragma: no-cache
+Expires: 0
+X-Frame-Options: DENY
+Content-Length: 381
+
+[ {
+ "groupId" : "",
+ "groupNm" : "",
+ "ownerNm" : "",
+ "idntfNum" : "PA0001",
+ "startAddress" : null,
+ "endAddress" : null,
+ "schFltStDt" : "2024-02-27T17:53:53.234721",
+ "schFltEndDt" : "2024-02-29T17:53:53.234725",
+ "cntrlId" : "00121354-7c41-4637-8283-c34c508625ac",
+ "cntrlStDt" : "2024-02-28T00:00:00",
+ "cntrlEndDt" : "2024-02-28T02:00:00",
+ "statusCd" : "S"
+} ]
+
+
+
+
+
+
+
+
+
+
+
+파라미터 |
+타입 |
+설명 |
+필수 |
+
+
+
+
+[].groupId
|
+String
|
+그룹아이디 |
+false |
+
+
+[].groupNm
|
+String
|
+그룹 명 |
+false |
+
+
+[].ownerNm
|
+String
|
+기체 소유자 이름 |
+false |
+
+
+[].idntfNum
|
+String
|
+기체 식별번호 |
+true |
+
+
+[].startAddress
|
+String
|
+비행시작 주소 |
+false |
+
+
+[].endAddress
|
+String
|
+비행종료 주소 |
+false |
+
+
+[].schFltStDt
|
+String
|
+비행계획서 시작일 |
+false |
+
+
+[].schFltEndDt
|
+String
|
+비행계획서 종료일 |
+false |
+
+
+[].cntrlId
|
+String
|
+관제ID |
+true |
+
+
+[].cntrlStDt
|
+String
|
+비행 시작시간 |
+true |
+
+
+[].cntrlEndDt
|
+String
|
+비행 종료시간 |
+true |
+
+
+[].statusCd
|
+String
|
+스테이터스 |
+false |
+
+
+
@@ -2234,7 +5774,7 @@ X-Frame-Options: DENY
diff --git a/app/kac-app/src/test/java/kr/co/palnet/kac/BaseTest.java b/app/kac-app/src/test/java/kr/co/palnet/kac/BaseTest.java
index b96ab51..ffea74b 100644
--- a/app/kac-app/src/test/java/kr/co/palnet/kac/BaseTest.java
+++ b/app/kac-app/src/test/java/kr/co/palnet/kac/BaseTest.java
@@ -1,15 +1,12 @@
package kr.co.palnet.kac;
-import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletException;
-import kr.co.palnet.kac.api.v1.user.account.model.detail.SearchUserRS;
import kr.co.palnet.kac.api.v1.user.account.model.register.FormRegisterRQ;
import kr.co.palnet.kac.api.v1.user.account.service.UserAccountService;
import kr.co.palnet.kac.app.KacAppApplication;
import kr.co.palnet.kac.config.security.model.BaseUserDetails;
import kr.co.palnet.kac.config.security.service.BaseUserDetailsService;
import kr.co.palnet.kac.config.security.util.JwtUtil;
-import kr.co.palnet.kac.util.ObjectMapperUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -18,8 +15,9 @@ import org.springframework.mock.web.MockFilterConfig;
import org.springframework.restdocs.RestDocumentationContextProvider;
import org.springframework.restdocs.RestDocumentationExtension;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.BeanIds;
-import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@@ -27,7 +25,6 @@ import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.DelegatingFilterProxy;
import java.time.LocalDate;
-import java.time.LocalDateTime;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.modifyUris;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
@@ -47,6 +44,8 @@ public class BaseTest {
public MockMvc mockMvc;
+ protected String CREATE_USERNAME;
+
protected final String CREATE_PASSWORD = "palnet!234";
@BeforeEach
@@ -73,6 +72,7 @@ public class BaseTest {
protected String getUserToken(){
String username = "TEST_" + System.currentTimeMillis();
+ this.CREATE_USERNAME = username;
String jsonRQ = """
{
@@ -113,6 +113,12 @@ public class BaseTest {
BaseUserDetails userDetails = (BaseUserDetails) baseUserDetailsService.loadUserByUsername(username);
+ UsernamePasswordAuthenticationToken userToken = new UsernamePasswordAuthenticationToken(
+ userDetails, null, userDetails.getAuthorities()
+ );
+
+ SecurityContextHolder.getContext().setAuthentication(userToken);
+
return JwtUtil.makeAuthToken(userDetails);
}
diff --git a/app/kac-app/src/test/java/kr/co/palnet/kac/flt/laanc/FlightLaancControllerTest.java b/app/kac-app/src/test/java/kr/co/palnet/kac/flt/laanc/FlightLaancControllerTest.java
new file mode 100644
index 0000000..a4ca93b
--- /dev/null
+++ b/app/kac-app/src/test/java/kr/co/palnet/kac/flt/laanc/FlightLaancControllerTest.java
@@ -0,0 +1,653 @@
+package kr.co.palnet.kac.flt.laanc;
+
+import kr.co.palnet.kac.BaseTest;
+import kr.co.palnet.kac.api.v1.flight.laanc.model.FltPlanBasDTO;
+import kr.co.palnet.kac.api.v1.flight.laanc.model.create.CreateLaancPlanRQ;
+import kr.co.palnet.kac.api.v1.flight.laanc.service.FlightLaancService;
+import kr.co.palnet.kac.config.security.util.SessionHelper;
+import kr.co.palnet.kac.util.ObjectMapperUtils;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.restdocs.headers.HeaderDocumentation;
+import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
+import org.springframework.restdocs.payload.JsonFieldType;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.UUID;
+
+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;
+import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
+import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
+import static org.springframework.restdocs.request.RequestDocumentation.queryParameters;
+import static org.springframework.restdocs.payload.PayloadDocumentation.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+public class FlightLaancControllerTest extends BaseTest {
+
+ @Autowired
+ private FlightLaancService flightLaancService;
+
+ private final String BASE_URL = "/v1/flight/laanc";
+
+ private final String GRANT_TYPE = "Bearer";
+
+ @DisplayName("LAANC 승인 상세 조회")
+ @Test
+ @Transactional
+ public void getLaancAprvDetail() throws Exception{
+ String token = this.getUserToken();
+
+ String planSno = this.testCreatePlan().getPlanSno().toString();
+
+ this.mockMvc.perform(
+ RestDocumentationRequestBuilders.get(this.BASE_URL + "/detail/{planSno}", planSno)
+ .accept(MediaType.APPLICATION_JSON_VALUE)
+ .header("Authorization", GRANT_TYPE + " " + token)
+ )
+ .andDo(print())
+ .andDo(
+ document(
+ "flight/laanc/detail",
+ preprocessResponse(prettyPrint()),
+ HeaderDocumentation.requestHeaders(
+ HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]")
+ ),
+ pathParameters(
+ parameterWithName("planSno").description("비행계획서 일련번호")
+ ),
+ responseFields(
+ fieldWithPath("planSno").type(JsonFieldType.NUMBER).description("비행계획서 일련번호"),
+ fieldWithPath("groupId").type(JsonFieldType.STRING).description("그룹 아이디"),
+ fieldWithPath("cstmrSno").type(JsonFieldType.NUMBER).description("작성자 일련번호"),
+ fieldWithPath("memberName").type(JsonFieldType.STRING).description("작성자 이름"),
+ fieldWithPath("email").type(JsonFieldType.STRING).description("이메일"),
+ fieldWithPath("hpno").type(JsonFieldType.STRING).description("연락처"),
+ fieldWithPath("clncd").type(JsonFieldType.STRING).description("국가번호(연락처)"),
+ fieldWithPath("addr").type(JsonFieldType.STRING).description("주소").optional(),
+ fieldWithPath("addrDtlCn").type(JsonFieldType.STRING).description("상세주소").optional(),
+ fieldWithPath("zip").type(JsonFieldType.STRING).description("우편번호").optional(),
+ fieldWithPath("schFltStDt").type(JsonFieldType.STRING).description("비행시작일시"),
+ fieldWithPath("schFltEndDt").type(JsonFieldType.STRING).description("비행종료일시"),
+ fieldWithPath("fltPurpose").type(JsonFieldType.STRING).description("비행목적"),
+ fieldWithPath("fltType").type(JsonFieldType.STRING).description("상업/비사업 구분"),
+ fieldWithPath("fltTypeNm").type(JsonFieldType.STRING).description("상업/비사업 구분 코드"),
+ fieldWithPath("aprvlYn").type(JsonFieldType.STRING).description("승인여부"),
+ fieldWithPath("aprvlDt").type(JsonFieldType.STRING).description("승인일자"),
+ fieldWithPath("fileGroupNo").type(JsonFieldType.NUMBER).description("파일그룹번호"),
+ fieldWithPath("createUserId").type(JsonFieldType.STRING).description("등록자ID"),
+ fieldWithPath("createDt").type(JsonFieldType.STRING).description("등록일시"),
+ fieldWithPath("updateUserId").type(JsonFieldType.STRING).description("수정자ID"),
+ fieldWithPath("updateDt").type(JsonFieldType.STRING).description("수정일시"),
+ fieldWithPath("serviceType").type(JsonFieldType.STRING).description("각 항별 코드"),
+ fieldWithPath("corpRegYn").type(JsonFieldType.STRING).description("기업여부"),
+ fieldWithPath("pdfUrl").type(JsonFieldType.STRING).description("공문URL"),
+
+ fieldWithPath("areaList").type(JsonFieldType.ARRAY).description("비행구역 리스트"),
+ fieldWithPath("areaList[].planAreaSno").type(JsonFieldType.NUMBER).description("비행구역 일련번호"),
+ fieldWithPath("areaList[].planSno").type(JsonFieldType.NUMBER).description("비행계획서 일련번호"),
+ fieldWithPath("areaList[].areaType").type(JsonFieldType.STRING).description("비행구역 생성타입"),
+ fieldWithPath("areaList[].fltMethod").type(JsonFieldType.STRING).description("비행방식"),
+ fieldWithPath("areaList[].fltAreaAddr").type(JsonFieldType.STRING).description("비행구역주소"),
+ fieldWithPath("areaList[].bufferZone").type(JsonFieldType.NUMBER).description("버퍼존"),
+ fieldWithPath("areaList[].fltElev").type(JsonFieldType.STRING).description("고도"),
+ fieldWithPath("areaList[].createUserId").type(JsonFieldType.STRING).description("생성자ID"),
+ fieldWithPath("areaList[].createDt").type(JsonFieldType.STRING).description("생성일시"),
+ fieldWithPath("areaList[].updateUserId").type(JsonFieldType.STRING).description("수정자ID"),
+ fieldWithPath("areaList[].updateDt").type(JsonFieldType.STRING).description("수정일시"),
+ fieldWithPath("areaList[].docState").type(JsonFieldType.STRING).description("코드"),
+ fieldWithPath("areaList[].bufferCoordList").type(JsonFieldType.ARRAY).description("비행 버퍼 좌표리스트").optional(),
+ fieldWithPath("areaList[].fltMothoeRm").type(JsonFieldType.STRING).description("비행방식(기타)"),
+ fieldWithPath("areaList[].coordList").type(JsonFieldType.ARRAY).description("비행구역 좌표리스트").optional(),
+
+ fieldWithPath("areaList[].coordList[].planAreaCoordSno").type(JsonFieldType.NUMBER).description("비행구역좌표 일련번호"),
+ fieldWithPath("areaList[].coordList[].planAreaSno").type(JsonFieldType.NUMBER).description("비행계획비행구역 일련번호"),
+ fieldWithPath("areaList[].coordList[].lat").type(JsonFieldType.NUMBER).description("위도"),
+ fieldWithPath("areaList[].coordList[].lon").type(JsonFieldType.NUMBER).description("경"),
+ fieldWithPath("areaList[].coordList[].createUserId").type(JsonFieldType.STRING).description("생성자ID"),
+ fieldWithPath("areaList[].coordList[].createDt").type(JsonFieldType.STRING).description("생성일시"),
+ fieldWithPath("areaList[].coordList[].docState").type(JsonFieldType.STRING).description("코드"),
+
+
+ fieldWithPath("arcrftList").type(JsonFieldType.ARRAY).description("비행기체 리스트"),
+ fieldWithPath("arcrftList[].planArcrftSno").type(JsonFieldType.NUMBER).description("계획서 기체 일련번호"),
+ fieldWithPath("arcrftList[].planSno").type(JsonFieldType.NUMBER).description("비행계획서 일련번호"),
+ fieldWithPath("arcrftList[].arcrftSno").type(JsonFieldType.NUMBER).description("기체 일련번호").optional(),
+ fieldWithPath("arcrftList[].idntfNum").type(JsonFieldType.STRING).description("식별번호(기체번호)"),
+ fieldWithPath("arcrftList[].groupNm").type(JsonFieldType.STRING).description("그룹명"),
+ fieldWithPath("arcrftList[].prdctNum").type(JsonFieldType.STRING).description("제작번호"),
+ fieldWithPath("arcrftList[].arcrftTypeCd").type(JsonFieldType.STRING).description("기체종류코드"),
+ fieldWithPath("arcrftList[].arcrftModelNm").type(JsonFieldType.STRING).description("기체모델명"),
+ fieldWithPath("arcrftList[].prdctCmpnNm").type(JsonFieldType.STRING).description("제작자"),
+ fieldWithPath("arcrftList[].prdctDate").type(JsonFieldType.STRING).description("제작일자").optional(),
+ fieldWithPath("arcrftList[].arcrftLngth").type(JsonFieldType.NUMBER).description("기체길이"),
+ fieldWithPath("arcrftList[].arcrftWdth").type(JsonFieldType.NUMBER).description("길체폭"),
+ fieldWithPath("arcrftList[].arcrftHght").type(JsonFieldType.NUMBER).description("기체높이"),
+ fieldWithPath("arcrftList[].arcrftWght").type(JsonFieldType.NUMBER).description("기체중량"),
+ fieldWithPath("arcrftList[].wghtTypeCd").type(JsonFieldType.STRING).description("중량구분코드"),
+ fieldWithPath("arcrftList[].imageUrl").type(JsonFieldType.STRING).description("이미지URL"),
+ fieldWithPath("arcrftList[].takeoffWght").type(JsonFieldType.NUMBER).description("최대이륙중량"),
+ fieldWithPath("arcrftList[].useYn").type(JsonFieldType.STRING).description("사용여부"),
+ fieldWithPath("arcrftList[].cameraYn").type(JsonFieldType.STRING).description("카메라탑재여부"),
+ fieldWithPath("arcrftList[].insrncYn").type(JsonFieldType.STRING).description("보험가입여부"),
+ fieldWithPath("arcrftList[].ownerNm").type(JsonFieldType.STRING).description("소유자명(법인명)"),
+ fieldWithPath("arcrftList[].createUserId").type(JsonFieldType.STRING).description("생성자ID"),
+ fieldWithPath("arcrftList[].createDt").type(JsonFieldType.STRING).description("생성일시"),
+ fieldWithPath("arcrftList[].updateUserId").type(JsonFieldType.STRING).description("수정자ID"),
+ fieldWithPath("arcrftList[].updateDt").type(JsonFieldType.STRING).description("수정일시"),
+ fieldWithPath("arcrftList[].docState").type(JsonFieldType.STRING).description("코드"),
+ fieldWithPath("arcrftList[].idntfTypeCd").type(JsonFieldType.STRING).description("식별장치종류코드").optional(),
+ fieldWithPath("arcrftList[].acrftInsuranceYn").type(JsonFieldType.STRING).description("기체보험유무"),
+ fieldWithPath("arcrftList[].insuranceExperiod").type(JsonFieldType.STRING).description("보험유효기간").optional(),
+ fieldWithPath("arcrftList[].corporationNm").type(JsonFieldType.STRING).description("법인명").optional(),
+ fieldWithPath("arcrftList[].arcrftWghtCd").type(JsonFieldType.STRING).description("자체중량코드"),
+
+ fieldWithPath("pilotList").type(JsonFieldType.ARRAY).description("조종자 정보 리스트").optional(),
+ fieldWithPath("pilotList[].planPilotSno").type(JsonFieldType.NUMBER).description("조종자 일련번호"),
+ fieldWithPath("pilotList[].planSno").type(JsonFieldType.NUMBER).description("비행계획서일련번호"),
+ fieldWithPath("pilotList[].cstmrSno").type(JsonFieldType.NUMBER).description("고객일련번호"),
+ fieldWithPath("pilotList[].groupNm").type(JsonFieldType.STRING).description("그룹명"),
+ fieldWithPath("pilotList[].memberName").type(JsonFieldType.STRING).description("회원이름"),
+ fieldWithPath("pilotList[].email").type(JsonFieldType.STRING).description("이메일"),
+ fieldWithPath("pilotList[].hpno").type(JsonFieldType.STRING).description("휴대폰번"),
+ fieldWithPath("pilotList[].clncd").type(JsonFieldType.STRING).description("국가전화번호"),
+ fieldWithPath("pilotList[].addr").type(JsonFieldType.STRING).description("주소").optional(),
+ fieldWithPath("pilotList[].addrDtlCn").type(JsonFieldType.STRING).description("주소 상세내용").optional(),
+ fieldWithPath("pilotList[].zip").type(JsonFieldType.STRING).description("우편번호").optional(),
+ fieldWithPath("pilotList[].qlfcNo").type(JsonFieldType.STRING).description("자격번호").optional(),
+ fieldWithPath("pilotList[].carrer").type(JsonFieldType.STRING).description("경력").optional(),
+ fieldWithPath("pilotList[].createUserId").type(JsonFieldType.STRING).description("생성자ID"),
+ fieldWithPath("pilotList[].createDt").type(JsonFieldType.STRING).description("생성일시"),
+ fieldWithPath("pilotList[].updateUserId").type(JsonFieldType.STRING).description("수정자ID"),
+ fieldWithPath("pilotList[].updateDt").type(JsonFieldType.STRING).description("수정일시"),
+
+
+ fieldWithPath("arcrftWght").type(JsonFieldType.STRING).description("기체 중량설명"),
+ fieldWithPath("elev").type(JsonFieldType.STRING).description("비행고도")
+ )
+ )
+ )
+ .andExpect(status().isOk());
+ }
+
+ @DisplayName("LAANC 승인 목록")
+ @Test
+ @Transactional
+ public void getLaancAprvList() throws Exception{
+ // TODO::TEST로 만들 비행계획서 필요함
+ String token = this.getUserToken();
+
+ FltPlanBasDTO fltPlanBasDto = this.testCreatePlan();
+
+ String createStDate = fltPlanBasDto.getCreateDt().toLocalDate().minusDays(1).toString();
+ String createEndDate = fltPlanBasDto.getCreateDt().toLocalDate().plusDays(1).toString();
+
+ this.mockMvc.perform(
+ get(this.BASE_URL + "/list")
+ .param("createStDate",createStDate)
+ .param("createEndDate",createEndDate)
+ .accept(MediaType.APPLICATION_JSON_VALUE)
+ .header("Authorization", GRANT_TYPE + " " + token)
+ )
+ .andDo(print())
+ .andDo(
+ document(
+ "flight/laanc/list",
+ preprocessResponse(prettyPrint()),
+ HeaderDocumentation.requestHeaders(
+ HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]")
+ ),
+ queryParameters(
+ parameterWithName("createStDate").description("검색 시작일").optional(),
+ parameterWithName("createEndDate").description("검색 끝일").optional(),
+ parameterWithName("memberName").description("이름").optional()
+ ),
+ responseFields(
+ fieldWithPath("[].planSno").type(JsonFieldType.NUMBER).description("비행계획서 일련번호").optional(),
+ fieldWithPath("[].groupId").type(JsonFieldType.STRING).description("그룹 아이디").optional(),
+ fieldWithPath("[].cstmrSno").type(JsonFieldType.NUMBER).description("작성자 일련번호").optional(),
+ fieldWithPath("[].memberName").type(JsonFieldType.STRING).description("작성자 이름").optional(),
+ fieldWithPath("[].email").type(JsonFieldType.STRING).description("이메일").optional(),
+ fieldWithPath("[].hpno").type(JsonFieldType.STRING).description("연락처").optional(),
+ fieldWithPath("[].clncd").type(JsonFieldType.STRING).description("국가번호(연락처)").optional(),
+ fieldWithPath("[].addr").type(JsonFieldType.STRING).description("주소").optional(),
+ fieldWithPath("[].addrDtlCn").type(JsonFieldType.STRING).description("상세주소").optional(),
+ fieldWithPath("[].zip").type(JsonFieldType.STRING).description("우편번호").optional(),
+ fieldWithPath("[].schFltStDt").type(JsonFieldType.STRING).description("비행시작일시").optional(),
+ fieldWithPath("[].schFltEndDt").type(JsonFieldType.STRING).description("비행종료일시").optional(),
+ fieldWithPath("[].fltPurpose").type(JsonFieldType.STRING).description("비행목적").optional(),
+ fieldWithPath("[].fltType").type(JsonFieldType.STRING).description("상업/비사업 구분").optional(),
+ fieldWithPath("[].fltTypeNm").type(JsonFieldType.STRING).description("상업/비사업 구분 코드").optional(),
+ fieldWithPath("[].aprvlYn").type(JsonFieldType.STRING).description("승인여부").optional(),
+ fieldWithPath("[].aprvlDt").type(JsonFieldType.STRING).description("승인일자").optional(),
+ fieldWithPath("[].fileGroupNo").type(JsonFieldType.NUMBER).description("파일그룹번호").optional(),
+ fieldWithPath("[].createUserId").type(JsonFieldType.STRING).description("등록자ID").optional(),
+ fieldWithPath("[].createDt").type(JsonFieldType.STRING).description("등록일시").optional(),
+ fieldWithPath("[].updateUserId").type(JsonFieldType.STRING).description("수정자ID").optional(),
+ fieldWithPath("[].updateDt").type(JsonFieldType.STRING).description("수정일시").optional(),
+ fieldWithPath("[].serviceType").type(JsonFieldType.STRING).description("각 항별 코드").optional(),
+ fieldWithPath("[].corpRegYn").type(JsonFieldType.STRING).description("기업여부").optional(),
+ fieldWithPath("[].pdfUrl").type(JsonFieldType.STRING).description("공문URL").optional(),
+
+ fieldWithPath("[].areaList").type(JsonFieldType.ARRAY).description("비행구역 리스트").optional(),
+ fieldWithPath("[].areaList[].planAreaSno").type(JsonFieldType.NUMBER).description("비행구역 일련번호"),
+ fieldWithPath("[].areaList[].planSno").type(JsonFieldType.NUMBER).description("비행계획서 일련번호"),
+ fieldWithPath("[].areaList[].areaType").type(JsonFieldType.STRING).description("비행구역 생성타입"),
+ fieldWithPath("[].areaList[].fltMethod").type(JsonFieldType.STRING).description("비행방식"),
+ fieldWithPath("[].areaList[].fltAreaAddr").type(JsonFieldType.STRING).description("비행구역주소"),
+ fieldWithPath("[].areaList[].bufferZone").type(JsonFieldType.NUMBER).description("버퍼존"),
+ fieldWithPath("[].areaList[].fltElev").type(JsonFieldType.STRING).description("고도"),
+ fieldWithPath("[].areaList[].createUserId").type(JsonFieldType.STRING).description("생성자ID"),
+ fieldWithPath("[].areaList[].createDt").type(JsonFieldType.STRING).description("생성일시"),
+ fieldWithPath("[].areaList[].updateUserId").type(JsonFieldType.STRING).description("수정자ID"),
+ fieldWithPath("[].areaList[].updateDt").type(JsonFieldType.STRING).description("수정일시"),
+ fieldWithPath("[].areaList[].docState").type(JsonFieldType.STRING).description("코드"),
+ fieldWithPath("[].areaList[].coordList").type(JsonFieldType.ARRAY).description("비행구역 좌표리스트").optional(),
+ fieldWithPath("[].areaList[].bufferCoordList").type(JsonFieldType.ARRAY).description("비행 버퍼 좌표리스트").optional(),
+ fieldWithPath("[].areaList[].fltMothoeRm").type(JsonFieldType.STRING).description("비행방식(기타)"),
+
+ fieldWithPath("[].arcrftList").type(JsonFieldType.ARRAY).description("비행기체 리스트").optional(),
+ fieldWithPath("[].arcrftList[].planArcrftSno").type(JsonFieldType.NUMBER).description("계획서 기체 일련번호"),
+ fieldWithPath("[].arcrftList[].planSno").type(JsonFieldType.NUMBER).description("비행계획서 일련번호"),
+ fieldWithPath("[].arcrftList[].arcrftSno").type(JsonFieldType.NUMBER).description("기체 일련번호").optional(),
+ fieldWithPath("[].arcrftList[].idntfNum").type(JsonFieldType.STRING).description("식별번호(기체번호)"),
+ fieldWithPath("[].arcrftList[].groupNm").type(JsonFieldType.STRING).description("그룹명"),
+ fieldWithPath("[].arcrftList[].prdctNum").type(JsonFieldType.STRING).description("제작번호"),
+ fieldWithPath("[].arcrftList[].arcrftTypeCd").type(JsonFieldType.STRING).description("기체종류코드"),
+ fieldWithPath("[].arcrftList[].arcrftModelNm").type(JsonFieldType.STRING).description("기체모델명"),
+ fieldWithPath("[].arcrftList[].prdctCmpnNm").type(JsonFieldType.STRING).description("제작자"),
+ fieldWithPath("[].arcrftList[].prdctDate").type(JsonFieldType.STRING).description("제작일자").optional(),
+ fieldWithPath("[].arcrftList[].arcrftLngth").type(JsonFieldType.NUMBER).description("기체길이"),
+ fieldWithPath("[].arcrftList[].arcrftWdth").type(JsonFieldType.NUMBER).description("길체폭"),
+ fieldWithPath("[].arcrftList[].arcrftHght").type(JsonFieldType.NUMBER).description("기체높이"),
+ fieldWithPath("[].arcrftList[].arcrftWght").type(JsonFieldType.NUMBER).description("기체중량"),
+ fieldWithPath("[].arcrftList[].wghtTypeCd").type(JsonFieldType.STRING).description("중량구분코드"),
+ fieldWithPath("[].arcrftList[].imageUrl").type(JsonFieldType.STRING).description("이미지URL"),
+ fieldWithPath("[].arcrftList[].takeoffWght").type(JsonFieldType.NUMBER).description("최대이륙중량"),
+ fieldWithPath("[].arcrftList[].useYn").type(JsonFieldType.STRING).description("사용여부"),
+ fieldWithPath("[].arcrftList[].cameraYn").type(JsonFieldType.STRING).description("카메라탑재여부"),
+ fieldWithPath("[].arcrftList[].insrncYn").type(JsonFieldType.STRING).description("보험가입여부"),
+ fieldWithPath("[].arcrftList[].ownerNm").type(JsonFieldType.STRING).description("소유자명(법인명)"),
+ fieldWithPath("[].arcrftList[].createUserId").type(JsonFieldType.STRING).description("생성자ID"),
+ fieldWithPath("[].arcrftList[].createDt").type(JsonFieldType.STRING).description("생성일시"),
+ fieldWithPath("[].arcrftList[].updateUserId").type(JsonFieldType.STRING).description("수정자ID"),
+ fieldWithPath("[].arcrftList[].updateDt").type(JsonFieldType.STRING).description("수정일시"),
+ fieldWithPath("[].arcrftList[].docState").type(JsonFieldType.STRING).description("코드"),
+ fieldWithPath("[].arcrftList[].idntfTypeCd").type(JsonFieldType.STRING).description("식별장치종류코드").optional(),
+ fieldWithPath("[].arcrftList[].acrftInsuranceYn").type(JsonFieldType.STRING).description("기체보험유무"),
+ fieldWithPath("[].arcrftList[].insuranceExperiod").type(JsonFieldType.STRING).description("보험유효기간").optional(),
+ fieldWithPath("[].arcrftList[].corporationNm").type(JsonFieldType.STRING).description("법인명").optional(),
+ fieldWithPath("[].arcrftList[].arcrftWghtCd").type(JsonFieldType.STRING).description("자체중량코드"),
+
+ fieldWithPath("[].pilotList").type(JsonFieldType.ARRAY).description("공문URL").optional(),
+ fieldWithPath("[].arcrftWght").type(JsonFieldType.STRING).description("기체 중량설명").optional(),
+ fieldWithPath("[].elev").type(JsonFieldType.STRING).description("비행고도").optional()
+ )
+ )
+ )
+ .andExpect(status().isOk());
+ }
+
+ @DisplayName("허용고도 조회")
+ @Test
+ @Transactional
+ public void getAllowableElevation() throws Exception{
+ String jsonRQ = """
+ [
+ {
+ "areaType" : "LINE",
+ "bufferZone" : 100,
+ "coordList" : [
+ {
+ "lat" : 127.277715,
+ "lon" : 37.406649
+ },
+ {
+ "lat" : 127.158070,
+ "lon" : 37.409050
+ }
+ ]
+ }
+ ]
+ """;
+
+ String token = this.getUserToken();
+
+ this.mockMvc.perform(
+ post(this.BASE_URL + "/valid/elev")
+ .contentType(MediaType.APPLICATION_JSON_VALUE)
+ .content(jsonRQ)
+ .accept(MediaType.APPLICATION_JSON_VALUE)
+ .header("Authorization", GRANT_TYPE + " " + token)
+ )
+ .andDo(print())
+ .andDo(
+ document(
+ "flight/laanc/valid/elev",
+ preprocessResponse(prettyPrint()),
+ HeaderDocumentation.requestHeaders(
+ HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]")
+ ),
+ requestFields(
+ fieldWithPath("[].areaType").type(JsonFieldType.STRING).description("비행구역 생성타입"),
+ fieldWithPath("[].bufferZone").type(JsonFieldType.NUMBER).description("버퍼존 크기"),
+
+ fieldWithPath("[].coordList").type(JsonFieldType.ARRAY).description("비행구역 좌표리스트"),
+ fieldWithPath("[].coordList[].lat").type(JsonFieldType.NUMBER).description("경도 [ex -> 126.706806]"),
+ fieldWithPath("[].coordList[].lon").type(JsonFieldType.NUMBER).description("위도 [ex -> 37.50854]")
+ ),
+ responseFields(
+ fieldWithPath("allowableElevation").description("비행고도 허용값")
+ )
+ )
+ )
+ .andExpect(status().isOk());
+ }
+
+ @DisplayName("공역(금지구역) 체크")
+ @Test
+ @Transactional
+ public void getDuplicatedAirspace() throws Exception{
+ String jsonRQ = """
+ [
+ {
+ "areaType" : "LINE",
+ "bufferZone" : 100,
+ "fltElev" : 130,
+ "coordList" : [
+ {
+ "lat" : 126.706806,
+ "lon" : 37.50854
+ },
+ {
+ "lat" : 126.7108901,
+ "lon" : 37.5094849
+ },
+ {
+ "lat" : 126.7091884,
+ "lon" : 37.5068526
+ }
+ ]
+ }
+ ]
+ """;
+
+ String token = this.getUserToken();
+
+ this.mockMvc.perform(
+ post(this.BASE_URL + "/valid/duplicated/airspace")
+ .contentType(MediaType.APPLICATION_JSON_VALUE)
+ .content(jsonRQ)
+ .accept(MediaType.APPLICATION_JSON_VALUE)
+ .header("Authorization", GRANT_TYPE + " " + token)
+ )
+ .andDo(print())
+ .andDo(
+ document(
+ "flight/laanc/valid/duplicated/airspace",
+ preprocessResponse(prettyPrint()),
+ HeaderDocumentation.requestHeaders(
+ HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]")
+ ),
+ requestFields(
+ fieldWithPath("[].areaType").type(JsonFieldType.STRING).description("비행구역 생성타입"),
+ fieldWithPath("[].bufferZone").type(JsonFieldType.NUMBER).description("버퍼존 크기"),
+ fieldWithPath("[].fltElev").type(JsonFieldType.NUMBER).description("비행 고도"),
+
+ fieldWithPath("[].coordList").type(JsonFieldType.ARRAY).description("비행구역 좌표리스트"),
+ fieldWithPath("[].coordList[].lat").type(JsonFieldType.NUMBER).description("경도 [ex -> 126.706806]"),
+ fieldWithPath("[].coordList[].lon").type(JsonFieldType.NUMBER).description("위도 [ex -> 37.50854]")
+ ),
+ responseFields(
+ fieldWithPath("[].rq.areaType").type(JsonFieldType.STRING).description("비행구역 생성타입"),
+ fieldWithPath("[].rq.bufferZone").type(JsonFieldType.NUMBER).description("버퍼존 크기"),
+ fieldWithPath("[].rq.fltElev").type(JsonFieldType.STRING).description("비행 고도"),
+
+ fieldWithPath("[].rq.coordList").type(JsonFieldType.ARRAY).description("비행구역 좌표리스트"),
+ fieldWithPath("[].rq.coordList[].lat").type(JsonFieldType.NUMBER).description("경도 [ex -> 126.706806]"),
+ fieldWithPath("[].rq.coordList[].lon").type(JsonFieldType.NUMBER).description("위도 [ex -> 37.50854]"),
+
+ fieldWithPath("[].duplicated").type(JsonFieldType.BOOLEAN).description("공역 체크값")
+ )
+ )
+ )
+ .andExpect(status().isOk());
+
+ }
+
+ @DisplayName("TS QR 코드 확인")
+ @Test
+ @Transactional
+ public void checkQrcode() throws Exception{
+
+ String token = this.getUserToken();
+
+ String confirmKey = UUID.randomUUID().toString();
+ flightLaancService.testCreateQRCode(confirmKey, this.CREATE_USERNAME);
+
+ this.mockMvc.perform(
+ RestDocumentationRequestBuilders.get(this.BASE_URL + "/ts/qr/{confirmKey}", confirmKey)
+ .accept(MediaType.APPLICATION_JSON_VALUE)
+ .header("Authorization", GRANT_TYPE + " " + token)
+ )
+ .andDo(print())
+ .andDo(
+ document(
+ "flight/laanc/ts/qr/confirm",
+ preprocessResponse(prettyPrint()),
+ HeaderDocumentation.requestHeaders(
+ HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]")
+ ),
+ pathParameters(
+ parameterWithName("confirmKey").description("컨펌키")
+ ),
+ responseFields(
+ fieldWithPath("rspCode").type(JsonFieldType.STRING).description("결과코드"),
+ fieldWithPath("rspMessage").type(JsonFieldType.STRING).description("결과메시지"),
+ fieldWithPath("pilotcredentialyn").type(JsonFieldType.STRING).description("조종사자격증명여부"),
+ fieldWithPath("arcrftinsuranceyn").type(JsonFieldType.STRING).description("기체보험가입여부"),
+ fieldWithPath("arcrftdeclaration").type(JsonFieldType.STRING).description("기체신고여부"),
+ fieldWithPath("corpregyn").type(JsonFieldType.STRING).description("사업자유무"),
+ fieldWithPath("rq").type(JsonFieldType.OBJECT).description("QR코드 데이터").optional()
+ )
+ )
+ )
+ .andExpect(status().isOk());
+
+
+ }
+
+ @DisplayName("TS QR 코드 생성")
+ @Test
+ @Transactional
+ public void createQRcode() throws Exception{
+ String jsonRQ = """
+ {
+ "idntfNum" : "C1CM0231251"
+ }
+ """;
+
+ String token = this.getUserToken();
+
+ this.mockMvc.perform(
+ post(this.BASE_URL + "/ts/qr")
+ .contentType(MediaType.APPLICATION_JSON_VALUE)
+ .content(jsonRQ)
+ .accept(MediaType.APPLICATION_JSON_VALUE)
+ .header("Authorization", GRANT_TYPE + " " + token)
+ )
+ .andDo(print())
+ .andDo(
+ document(
+ "flight/laanc/ts/qr",
+ preprocessResponse(prettyPrint()),
+ HeaderDocumentation.requestHeaders(
+ HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]")
+ ),
+ requestFields(
+ fieldWithPath("idntfNum").type(JsonFieldType.STRING).description("기체 식별번호")
+ ),
+ responseFields(
+ fieldWithPath("qrcode").type(JsonFieldType.STRING).description("QR코드 데이터"),
+ fieldWithPath("confirmKey").type(JsonFieldType.STRING).description("컨펌 키")
+ )
+ )
+ )
+ .andExpect(status().isCreated());
+
+ }
+
+ @DisplayName("비행계획서 생성")
+ @Test
+ @Transactional
+ public void createPlan() throws Exception{
+
+ String jsonRQ = """
+ {
+ "cstmrSno": 3,
+ "fltType": "COMMERCIAL",
+ "schFltStDt": "2024-02-25T11:43:00",
+ "schFltEndDt": "2024-02-28T15:46:00",
+ "fltPurpose": "06",
+ "serviceType": "KAC",
+ "areaList" : [
+ {
+ "areaType": "LINE",
+ "fltMethod": "02",
+ "fltMothoeRm": "",
+ "bufferZone": "100",
+ "fltElev": "100",
+ "coordList": [
+ {
+ "lat": 37.51625845252909,
+ "lon": 126.72340194011286
+ },
+ {
+ "lat": 37.512215014051776,
+ "lon": 126.72058946300956
+ },
+ {
+ "lat": 37.51123897883966,
+ "lon": 126.72463239884405
+ }
+ ]
+ }
+ ],
+ "arcrftList" : [
+ {
+ "idntfNum": "PA0001",
+ "groupNm": "",
+ "prdctNum": "",
+ "arcrftTypeCd": "11",
+ "arcrftModelNm": "",
+ "prdctCmpnNm": "",
+ "prdctDate": "",
+ "arcrftLngth": 0,
+ "arcrftWghtCd": "8",
+ "arcrftHght": 0,
+ "arcrftWght": 0,
+ "wghtTypeCd": "",
+ "imageUrl": "",
+ "takeoffWght": 0,
+ "useYn": "",
+ "cameraYn": "",
+ "insrncYn": "",
+ "ownerNm": ""
+ }
+ ],
+ "terms": [
+
+ ]
+ }
+ """;
+
+ String token = this.getUserToken();
+
+ this.mockMvc.perform(
+ post(this.BASE_URL + "/create/plan")
+ .contentType(MediaType.APPLICATION_JSON_VALUE)
+ .content(jsonRQ)
+ .accept(MediaType.APPLICATION_JSON_VALUE)
+ .header("Authorization", GRANT_TYPE + " " + token)
+ )
+ .andDo(print())
+ .andDo(
+ document(
+ "flight/laanc/create/plan",
+ preprocessResponse(prettyPrint()),
+ HeaderDocumentation.requestHeaders(
+ HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]")
+ ),
+ requestFields(
+ fieldWithPath("cstmrSno").type(JsonFieldType.NUMBER).description("회원 고유번호").optional(),
+ fieldWithPath("fltType").type(JsonFieldType.STRING).description("비행유형 - 상업/비상업"),
+ fieldWithPath("schFltStDt").type(JsonFieldType.STRING).description("비행시작일시"),
+ fieldWithPath("schFltEndDt").type(JsonFieldType.STRING).description("비행종료일시"),
+ fieldWithPath("fltPurpose").type(JsonFieldType.STRING).description("비행목적"),
+ fieldWithPath("serviceType").type(JsonFieldType.STRING).description("각 청들 코드"),
+
+ fieldWithPath("areaList").type(JsonFieldType.ARRAY).description("비행구역 리스트"),
+ fieldWithPath("areaList[].areaType").type(JsonFieldType.STRING).description("비행구역 생성타입"),
+ fieldWithPath("areaList[].fltMethod").type(JsonFieldType.STRING).description("비행방식"),
+ fieldWithPath("areaList[].fltMothoeRm").type(JsonFieldType.STRING).description("비행방식(기타)").optional(),
+ fieldWithPath("areaList[].bufferZone").type(JsonFieldType.STRING).description("버퍼존"),
+ fieldWithPath("areaList[].fltElev").type(JsonFieldType.STRING).description("비행고도"),
+ fieldWithPath("areaList[].coordList").type(JsonFieldType.ARRAY).description("비행 좌표 리스트"),
+ fieldWithPath("areaList[].coordList[].lat").type(JsonFieldType.NUMBER).description("위도"),
+ fieldWithPath("areaList[].coordList[].lon").type(JsonFieldType.NUMBER).description("경도"),
+
+ fieldWithPath("arcrftList").type(JsonFieldType.ARRAY).description("비행기체 정보리스트"),
+ fieldWithPath("arcrftList[].idntfNum").type(JsonFieldType.STRING).description("식별번호(기체번호)"),
+ fieldWithPath("arcrftList[].groupNm").type(JsonFieldType.STRING).description("그룹명").optional(),
+ fieldWithPath("arcrftList[].prdctNum").type(JsonFieldType.STRING).description("제작번호").optional(),
+ fieldWithPath("arcrftList[].arcrftTypeCd").type(JsonFieldType.STRING).description("기체종류코드"),
+ fieldWithPath("arcrftList[].arcrftModelNm").type(JsonFieldType.STRING).description("기체모델명").optional(),
+ fieldWithPath("arcrftList[].prdctCmpnNm").type(JsonFieldType.STRING).description("제작자").optional(),
+ fieldWithPath("arcrftList[].prdctDate").type(JsonFieldType.STRING).description("제작일자").optional(),
+ fieldWithPath("arcrftList[].arcrftLngth").type(JsonFieldType.NUMBER).description("기체길이").optional(),
+ fieldWithPath("arcrftList[].arcrftWghtCd").type(JsonFieldType.STRING).description("자체중량코드"),
+ fieldWithPath("arcrftList[].arcrftHght").type(JsonFieldType.NUMBER).description("기체높이").optional(),
+ fieldWithPath("arcrftList[].arcrftWght").type(JsonFieldType.NUMBER).description("기체중량").optional(),
+ fieldWithPath("arcrftList[].wghtTypeCd").type(JsonFieldType.STRING).description("중량구분코드").optional(),
+ fieldWithPath("arcrftList[].imageUrl").type(JsonFieldType.STRING).description("이미지URL").optional(),
+ fieldWithPath("arcrftList[].takeoffWght").type(JsonFieldType.NUMBER).description("최대이륙중량").optional(),
+ fieldWithPath("arcrftList[].useYn").type(JsonFieldType.STRING).description("사용여부").optional(),
+ fieldWithPath("arcrftList[].cameraYn").type(JsonFieldType.STRING).description("카메라탑재여부").optional(),
+ fieldWithPath("arcrftList[].insrncYn").type(JsonFieldType.STRING).description("보험가입여부").optional(),
+ fieldWithPath("arcrftList[].ownerNm").type(JsonFieldType.STRING).description("소유자명(법인명)").optional(),
+
+ fieldWithPath("terms").type(JsonFieldType.ARRAY).description("약관동의리스트").optional(),
+ fieldWithPath("terms[].termsSno").type(JsonFieldType.NUMBER).description("약관 일련번호").optional(),
+ fieldWithPath("terms[].agressYn").type(JsonFieldType.STRING).description("동의 여부").optional()
+
+
+ ),
+ responseFields(
+ fieldWithPath("pdfUrl").type(JsonFieldType.STRING).description("PDF 다운로드 URL").optional(),
+ fieldWithPath("address").type(JsonFieldType.STRING).description("주소").optional()
+ )
+ )
+ )
+ .andExpect(status().isCreated());
+
+ }
+
+ private FltPlanBasDTO testCreatePlan(){
+ String jsonRQ = "{\"cstmrSno\": 3,\"fltType\": \"COMMERCIAL\",\"schFltStDt\": \"2024-02-21T11:43:00\",\"schFltEndDt\": \"2024-02-22T15:46:00\",\"fltPurpose\": \"06\",\"serviceType\": \"KAC\",\"areaList\" : [{\"areaType\": \"LINE\",\"fltMethod\": \"02\",\"fltMothoeRm\": \"\",\"bufferZone\": \"100\",\"fltElev\": \"100\",\"coordList\": [{\"lat\": 37.51625845252909,\"lon\": 126.72340194011286},{\"lat\": 37.512215014051776,\"lon\": 126.72058946300956},{\"lat\": 37.51123897883966,\"lon\": 126.72463239884405}]}],\"arcrftList\" : [{\"idntfNum\": \"PA0001\",\"groupNm\": \"\",\"prdctNum\": \"\",\"arcrftTypeCd\": \"11\",\"arcrftModelNm\": \"\",\"prdctCmpnNm\": \"\",\"prdctDate\": \"\",\"arcrftLngth\": 0,\"arcrftWghtCd\": \"8\",\"arcrftHght\": 0,\"arcrftWght\": 0,\"wghtTypeCd\": \"\",\"imageUrl\": \"\",\"takeoffWght\": 0,\"useYn\": \"\",\"cameraYn\": \"\",\"insrncYn\": \"\",\"ownerNm\": \"\"}],\"terms\": []}".trim();
+
+ CreateLaancPlanRQ rq;
+ try{
+ rq = ObjectMapperUtils.getObjectMapper().readValue(jsonRQ, CreateLaancPlanRQ.class);
+ flightLaancService.createPlan(rq);
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+
+ return flightLaancService.testDescPlanSno();
+ }
+}
diff --git a/app/kac-app/src/test/java/kr/co/palnet/kac/flt/plan/FlightPlanControllerTest.java b/app/kac-app/src/test/java/kr/co/palnet/kac/flt/plan/FlightPlanControllerTest.java
new file mode 100644
index 0000000..329113f
--- /dev/null
+++ b/app/kac-app/src/test/java/kr/co/palnet/kac/flt/plan/FlightPlanControllerTest.java
@@ -0,0 +1,255 @@
+package kr.co.palnet.kac.flt.plan;
+
+import kr.co.palnet.kac.BaseTest;
+import kr.co.palnet.kac.api.v1.flight.laanc.model.FltPlanBasDTO;
+import kr.co.palnet.kac.api.v1.flight.laanc.model.create.CreateLaancPlanRQ;
+import kr.co.palnet.kac.api.v1.flight.laanc.service.FlightLaancService;
+import kr.co.palnet.kac.api.v1.flight.plan.model.CtrCntrlBasDTO;
+import kr.co.palnet.kac.api.v1.flight.plan.service.FlightPlanService;
+import kr.co.palnet.kac.util.ObjectMapperUtils;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.restdocs.headers.HeaderDocumentation;
+import org.springframework.restdocs.payload.JsonFieldType;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+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;
+import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
+import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
+import static org.springframework.restdocs.request.RequestDocumentation.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static org.springframework.restdocs.payload.PayloadDocumentation.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+
+public class FlightPlanControllerTest extends BaseTest {
+
+ @Autowired
+ private FlightLaancService flightLaancService;
+
+ @Autowired
+ private FlightPlanService flightPlanService;
+
+ private final String BASE_URL = "/v1/flight/plan";
+
+ private final String GRANT_TYPE = "Bearer";
+
+ @DisplayName("비행 운항 스케줄 조회")
+ @Test
+ @Transactional
+ public void getPlanSchedule() throws Exception{
+ String token = this.getUserToken();
+
+ LocalDate searchDate = LocalDate.now().plusDays(2);
+
+ this.testCreateData(searchDate);
+
+ this.mockMvc.perform(
+ get(this.BASE_URL + "/schedule")
+ .param("searchDate", searchDate.toString())
+ .accept(MediaType.APPLICATION_JSON_VALUE)
+ .header("Authorization", GRANT_TYPE + " " + token)
+ )
+ .andDo(print())
+ .andDo(
+ document(
+ "flight/plan/schedule",
+ preprocessResponse(prettyPrint()),
+ HeaderDocumentation.requestHeaders(
+ HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]")
+ ),
+ queryParameters(
+ parameterWithName("searchDate").description("검색일자")
+ ),
+ responseFields(
+ fieldWithPath("[].groupId").type(JsonFieldType.STRING).description("그룹아이디").optional(),
+ fieldWithPath("[].groupNm").type(JsonFieldType.STRING).description("그룹 명").optional(),
+ fieldWithPath("[].ownerNm").type(JsonFieldType.STRING).description("기체 소유자 이름").optional(),
+ fieldWithPath("[].idntfNum").type(JsonFieldType.STRING).description("기체 식별번호"),
+ fieldWithPath("[].startAddress").type(JsonFieldType.STRING).description("비행시작 주소").optional(),
+ fieldWithPath("[].endAddress").type(JsonFieldType.STRING).description("비행종료 주소").optional(),
+ fieldWithPath("[].schFltStDt").type(JsonFieldType.STRING).description("비행계획서 시작일").optional(),
+ fieldWithPath("[].schFltEndDt").type(JsonFieldType.STRING).description("비행계획서 종료일").optional(),
+ fieldWithPath("[].cntrlId").type(JsonFieldType.STRING).description("관제ID"),
+ fieldWithPath("[].cntrlStDt").type(JsonFieldType.STRING).description("비행 시작시간"),
+ fieldWithPath("[].cntrlEndDt").type(JsonFieldType.STRING).description("비행 종료시간"),
+ fieldWithPath("[].statusCd").type(JsonFieldType.STRING).description("스테이터스").optional()
+ )
+ )
+ )
+ .andExpect(status().isOk());
+
+ }
+
+ @DisplayName("비행 계획서 작성 - 버퍼존 생성")
+ @Test
+ @Transactional
+ public void createBuffer() throws Exception{
+ String token = this.getUserToken();
+
+ String jsonRQ = """
+ [
+ {
+ "planAreaSno": 0,
+ "planSno": 0,
+ "areaType": "LINE",
+ "fltMethod": "",
+ "fltMothoeRm": "",
+ "bufferZone": 100,
+ "fltElev": 0,
+ "createUserId": "",
+ "createDt": "",
+ "updateUserId": "",
+ "updateDt": "",
+ "coordList": [
+ {
+ "planAreaCoordSno": 0,
+ "planAreaSno": 0,
+ "lat": 37.53540376761919,
+ "lon": 126.70505084176824,
+ "createUserId": "",
+ "createDt": ""
+ },
+ {
+ "planAreaCoordSno": 0,
+ "planAreaSno": 0,
+ "lat": 37.53254793498979,
+ "lon": 126.71167265598018,
+ "createUserId": "",
+ "createDt": ""
+ }
+ ]
+ }
+ ]
+ """;
+
+ this.mockMvc.perform(
+ post(this.BASE_URL + "/area/buffer")
+ .contentType(MediaType.APPLICATION_JSON_VALUE)
+ .content(jsonRQ)
+ .accept(MediaType.APPLICATION_JSON_VALUE)
+ .header("Authorization", GRANT_TYPE + " " + token)
+ )
+ .andDo(print())
+ .andDo(
+ document(
+ "flight/plan/area/buffer",
+ preprocessResponse(prettyPrint()),
+ HeaderDocumentation.requestHeaders(
+ HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]")
+ ),
+ requestFields(
+ fieldWithPath("[].planAreaSno").type(JsonFieldType.NUMBER).description("비행구역 일련번호").optional(),
+ fieldWithPath("[].planSno").type(JsonFieldType.NUMBER).description("비행계획서 일련번호").optional(),
+ fieldWithPath("[].areaType").type(JsonFieldType.STRING).description("비행구역 생성타입"),
+ fieldWithPath("[].fltMethod").type(JsonFieldType.STRING).description("비행방식").optional(),
+ fieldWithPath("[].fltMothoeRm").type(JsonFieldType.STRING).description("비행방식(기타)").optional(),
+ fieldWithPath("[].bufferZone").type(JsonFieldType.NUMBER).description("버퍼존"),
+ fieldWithPath("[].fltElev").type(JsonFieldType.NUMBER).description("비행고도").optional(),
+ fieldWithPath("[].createUserId").type(JsonFieldType.STRING).description("생성자ID").optional(),
+ fieldWithPath("[].createDt").type(JsonFieldType.STRING).description("생성일시").optional(),
+ fieldWithPath("[].updateUserId").type(JsonFieldType.STRING).description("수정자ID").optional(),
+ fieldWithPath("[].updateDt").type(JsonFieldType.STRING).description("수정일시").optional(),
+
+ fieldWithPath("[].coordList").type(JsonFieldType.ARRAY).description("좌표리스트"),
+ fieldWithPath("[].coordList[].planAreaCoordSno").type(JsonFieldType.NUMBER).description("비행구역좌표 일련번호").optional(),
+ fieldWithPath("[].coordList[].planAreaSno").type(JsonFieldType.NUMBER).description("비행계획비행구역 일련번호").optional(),
+ fieldWithPath("[].coordList[].lat").type(JsonFieldType.NUMBER).description("위도 [ ex -> 37.53540376761919 ] "),
+ fieldWithPath("[].coordList[].lon").type(JsonFieldType.NUMBER).description("경도 [ ex -> 126.70505084176824 ]"),
+ fieldWithPath("[].coordList[].createUserId").type(JsonFieldType.STRING).description("생성자ID").optional(),
+ fieldWithPath("[].coordList[].createDt").type(JsonFieldType.STRING).description("생성일시").optional()
+ ),
+ responseFields(
+ fieldWithPath("[].planAreaSno").type(JsonFieldType.NUMBER).description("비행구역 일련번호").optional(),
+ fieldWithPath("[].planSno").type(JsonFieldType.NUMBER).description("비행계획서 일련번호").optional(),
+ fieldWithPath("[].areaType").type(JsonFieldType.STRING).description("비행구역 생성타입"),
+ fieldWithPath("[].fltMethod").type(JsonFieldType.STRING).description("비행방식").optional(),
+ fieldWithPath("[].fltAreaAddr").type(JsonFieldType.STRING).description("비행지역주소").optional(),
+ fieldWithPath("[].fltMothoeRm").type(JsonFieldType.STRING).description("비행방식(기타)").optional(),
+ fieldWithPath("[].bufferZone").type(JsonFieldType.NUMBER).description("버퍼존"),
+ fieldWithPath("[].fltElev").type(JsonFieldType.STRING).description("비행고도").optional(),
+ fieldWithPath("[].createUserId").type(JsonFieldType.STRING).description("생성자ID").optional(),
+ fieldWithPath("[].createDt").type(JsonFieldType.STRING).description("생성일시").optional(),
+ fieldWithPath("[].updateUserId").type(JsonFieldType.STRING).description("수정자ID").optional(),
+ fieldWithPath("[].updateDt").type(JsonFieldType.STRING).description("수정일시").optional(),
+ fieldWithPath("[].docState").type(JsonFieldType.STRING).description("코드").optional(),
+
+ fieldWithPath("[].bufferCoordList").type(JsonFieldType.ARRAY).description("좌표리스트"),
+ fieldWithPath("[].bufferCoordList[].planAreaCoordSno").type(JsonFieldType.NUMBER).description("비행구역좌표 일련번호").optional(),
+ fieldWithPath("[].bufferCoordList[].planAreaSno").type(JsonFieldType.NUMBER).description("비행계획비행구역 일련번호").optional(),
+ fieldWithPath("[].bufferCoordList[].lat").type(JsonFieldType.NUMBER).description("위도 [ ex -> 37.53540376761919 ] "),
+ fieldWithPath("[].bufferCoordList[].lon").type(JsonFieldType.NUMBER).description("경도 [ ex -> 126.70505084176824 ]"),
+ fieldWithPath("[].bufferCoordList[].createUserId").type(JsonFieldType.STRING).description("생성자ID").optional(),
+ fieldWithPath("[].bufferCoordList[].createDt").type(JsonFieldType.STRING).description("생성자ID").optional(),
+ fieldWithPath("[].bufferCoordList[].docState").type(JsonFieldType.STRING).description("코드").optional(),
+
+ fieldWithPath("[].coordList").type(JsonFieldType.ARRAY).description("좌표리스트"),
+ fieldWithPath("[].coordList[].planAreaCoordSno").type(JsonFieldType.NUMBER).description("비행구역좌표 일련번호").optional(),
+ fieldWithPath("[].coordList[].planAreaSno").type(JsonFieldType.NUMBER).description("비행계획비행구역 일련번호").optional(),
+ fieldWithPath("[].coordList[].lat").type(JsonFieldType.NUMBER).description("위도 [ ex -> 37.53540376761919 ] "),
+ fieldWithPath("[].coordList[].lon").type(JsonFieldType.NUMBER).description("경도 [ ex -> 126.70505084176824 ]"),
+ fieldWithPath("[].coordList[].createUserId").type(JsonFieldType.STRING).description("생성자ID").optional(),
+ fieldWithPath("[].coordList[].createDt").type(JsonFieldType.STRING).description("생성자ID").optional(),
+ fieldWithPath("[].coordList[].docState").type(JsonFieldType.STRING).description("코드").optional()
+ )
+ )
+ )
+ .andExpect(status().isOk());
+ }
+
+
+ private FltPlanBasDTO testCreateData(LocalDate searchData){
+
+ LocalDateTime plusOneDay = LocalDateTime.now().plusDays(1);
+ LocalDateTime plusThreeDay = LocalDateTime.now().plusDays(3);
+
+ String jsonRQ = "{\"cstmrSno\": 3,\"fltType\": \"COMMERCIAL\",\"schFltStDt\": \"%s\",\"schFltEndDt\": \"%s\",\"fltPurpose\": \"06\",\"serviceType\": \"KAC\",\"areaList\" : [{\"areaType\": \"LINE\",\"fltMethod\": \"02\",\"fltMothoeRm\": \"\",\"bufferZone\": \"100\",\"fltElev\": \"100\",\"coordList\": [{\"lat\": 37.51625845252909,\"lon\": 126.72340194011286},{\"lat\": 37.512215014051776,\"lon\": 126.72058946300956},{\"lat\": 37.51123897883966,\"lon\": 126.72463239884405}]}],\"arcrftList\" : [{\"idntfNum\": \"PA0001\",\"groupNm\": \"\",\"prdctNum\": \"\",\"arcrftTypeCd\": \"11\",\"arcrftModelNm\": \"\",\"prdctCmpnNm\": \"\",\"prdctDate\": \"\",\"arcrftLngth\": 0,\"arcrftWghtCd\": \"8\",\"arcrftHght\": 0,\"arcrftWght\": 0,\"wghtTypeCd\": \"\",\"imageUrl\": \"\",\"takeoffWght\": 0,\"useYn\": \"\",\"cameraYn\": \"\",\"insrncYn\": \"\",\"ownerNm\": \"\"}],\"terms\": []}"
+ .trim()
+ .formatted(plusOneDay.toString(), plusThreeDay.toString());
+
+ CreateLaancPlanRQ rq;
+
+ FltPlanBasDTO result = new FltPlanBasDTO();
+ try{
+ rq = ObjectMapperUtils.getObjectMapper().readValue(jsonRQ, CreateLaancPlanRQ.class);
+ flightLaancService.createPlan(rq);
+ result = flightLaancService.testDescPlanSno();
+
+ LocalDateTime ctEndDt = searchData.atStartOfDay().plusHours(2);
+ LocalDateTime ctStDt = searchData.atStartOfDay();
+
+ CtrCntrlBasDTO ctrCntrlBasDTO = new CtrCntrlBasDTO();
+ ctrCntrlBasDTO.setAvrgSpeed(0.0);
+ ctrCntrlBasDTO.setBttrCnsmptn(null);
+ ctrCntrlBasDTO.setTtlDstnc(33.30811254417446);
+ ctrCntrlBasDTO.setTtlTime(0.0);
+ ctrCntrlBasDTO.setCntrlEndDt(ctEndDt);
+ ctrCntrlBasDTO.setCntrlStDt(ctStDt);
+ ctrCntrlBasDTO.setCreateDt(LocalDateTime.now());
+ ctrCntrlBasDTO.setFlghtEndDt(null);
+ ctrCntrlBasDTO.setFlghtStDt(null);
+ ctrCntrlBasDTO.setUpdateDt(LocalDateTime.now());
+ ctrCntrlBasDTO.setEndTypeCd("01");
+ ctrCntrlBasDTO.setObjectTypeCd("DRON");
+ ctrCntrlBasDTO.setStatusCd("99");
+ ctrCntrlBasDTO.setTtlDstncType("M");
+ ctrCntrlBasDTO.setTtlTimeType(null);
+ ctrCntrlBasDTO.setIdntfNum("PA0001");
+ ctrCntrlBasDTO.setCntrlId("00121354-7c41-4637-8283-c34c508625ac");
+ ctrCntrlBasDTO.setProcStatusYn("N");
+
+ flightPlanService.testCreateCtrCntrlBas(ctrCntrlBasDTO);
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+}
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..87960c5 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
@@ -11,7 +11,6 @@ import org.springframework.restdocs.headers.HeaderDocumentation;
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
import org.springframework.restdocs.payload.JsonFieldType;
import org.springframework.transaction.annotation.Transactional;
-
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/build.gradle b/build.gradle
index e8bebf4..fcc30ca 100644
--- a/build.gradle
+++ b/build.gradle
@@ -32,7 +32,13 @@ allprojects {
plugins.apply("idea")
repositories {
- mavenCentral()
+ mavenCentral {
+ content {
+ excludeModule("javax.media", "jai_core")
+ }
+ }
+ maven { url "https://repo.osgeo.org/repository/release" }
+
}
configurations {
diff --git a/common/core/src/main/java/kr/co/palnet/kac/core/exception/BaseErrorCode.java b/common/core/src/main/java/kr/co/palnet/kac/core/exception/BaseErrorCode.java
index 125e550..f4b37fa 100644
--- a/common/core/src/main/java/kr/co/palnet/kac/core/exception/BaseErrorCode.java
+++ b/common/core/src/main/java/kr/co/palnet/kac/core/exception/BaseErrorCode.java
@@ -25,7 +25,13 @@ public enum BaseErrorCode {
WEB_NOT_FOUND("WB404", HttpStatus.INTERNAL_SERVER_ERROR, "찾을수 없는 페이지"),
WEB_API_ERROR("WB500", HttpStatus.INTERNAL_SERVER_ERROR, "외부 연동 에러"),
DATA_ALREADY_EXISTS("DT001", HttpStatus.INTERNAL_SERVER_ERROR, "이미 등록된 데이터"),
- DATA_EMPTY("DT002", HttpStatus.INTERNAL_SERVER_ERROR, "데이터 없음");
+ DATA_EMPTY("DT002", HttpStatus.INTERNAL_SERVER_ERROR, "데이터 없음"),
+
+ QR_EXPIRED("QR001", HttpStatus.BAD_REQUEST ,"QR코드 유효기간이 만료되었습니다")
+
+ ;
+
+
private final String code;
diff --git a/data/com/src/main/java/kr/co/palnet/kac/data/com/domain/ComConfirmBas.java b/data/com/src/main/java/kr/co/palnet/kac/data/com/domain/ComConfirmBas.java
index 1899853..6eb5fc8 100644
--- a/data/com/src/main/java/kr/co/palnet/kac/data/com/domain/ComConfirmBas.java
+++ b/data/com/src/main/java/kr/co/palnet/kac/data/com/domain/ComConfirmBas.java
@@ -6,7 +6,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
-import java.time.Instant;
+import java.time.LocalDateTime;
@Data
@Builder
@@ -61,7 +61,7 @@ public class ComConfirmBas {
// 생성일시
@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)
@@ -69,6 +69,6 @@ public class ComConfirmBas {
// 수정일시
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false)
- private Instant updateDt;
+ private LocalDateTime updateDt;
}
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/repository/ComConfirmBasRepository.java b/data/com/src/main/java/kr/co/palnet/kac/data/com/repository/ComConfirmBasRepository.java
index 16dfcd1..b5fdff1 100644
--- a/data/com/src/main/java/kr/co/palnet/kac/data/com/repository/ComConfirmBasRepository.java
+++ b/data/com/src/main/java/kr/co/palnet/kac/data/com/repository/ComConfirmBasRepository.java
@@ -3,6 +3,10 @@ package kr.co.palnet.kac.data.com.repository;
import kr.co.palnet.kac.data.com.domain.ComConfirmBas;
import org.springframework.data.jpa.repository.JpaRepository;
+import java.util.Optional;
+
public interface ComConfirmBasRepository extends JpaRepository
{
+ Optional findFirstByConfirmKeyOrderByCreateDtDesc(String confirmKey);
+
}
diff --git a/data/com/src/main/java/kr/co/palnet/kac/data/com/repository/ComFileBasRepository.java b/data/com/src/main/java/kr/co/palnet/kac/data/com/repository/ComFileBasRepository.java
index 5fa21ef..23c8b6b 100644
--- a/data/com/src/main/java/kr/co/palnet/kac/data/com/repository/ComFileBasRepository.java
+++ b/data/com/src/main/java/kr/co/palnet/kac/data/com/repository/ComFileBasRepository.java
@@ -3,6 +3,15 @@ package kr.co.palnet.kac.data.com.repository;
import kr.co.palnet.kac.data.com.domain.ComFileBas;
import org.springframework.data.jpa.repository.JpaRepository;
-public interface ComFileBasRepository extends JpaRepository {
+import java.util.List;
+import java.util.Optional;
+
+public interface ComFileBasRepository extends JpaRepository {
+
+ Optional findFirstByOrderByFileGroupNoDesc();
+
+ Optional> findByFileGroupNoInAndDelYnOrderByCreateDtDesc(List fileGroupNos, String delYn);
+
+ Optional findFirstByFileGroupNoAndDelYnOrderByCreateDtDesc(Long fileGroupNo, String delYn);
}
diff --git a/data/com/src/main/java/kr/co/palnet/kac/data/com/service/ComConfirmDomainService.java b/data/com/src/main/java/kr/co/palnet/kac/data/com/service/ComConfirmDomainService.java
new file mode 100644
index 0000000..af6f5d1
--- /dev/null
+++ b/data/com/src/main/java/kr/co/palnet/kac/data/com/service/ComConfirmDomainService.java
@@ -0,0 +1,30 @@
+package kr.co.palnet.kac.data.com.service;
+
+import kr.co.palnet.kac.data.com.domain.ComConfirmBas;
+import kr.co.palnet.kac.data.com.repository.ComConfirmBasRepository;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class ComConfirmDomainService {
+
+ private final ComConfirmBasRepository comConfirmBasRepository;
+
+ public ComConfirmBas saveComConfirmBas(ComConfirmBas entity){
+ return comConfirmBasRepository.save(entity);
+ }
+
+ public Optional findFirstByConfirmKeyOrderByCreateDtDesc(String confirmKey){
+ return comConfirmBasRepository.findFirstByConfirmKeyOrderByCreateDtDesc(confirmKey);
+ }
+
+ public void flush(){
+ comConfirmBasRepository.flush();
+ }
+
+}
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..7a81165
--- /dev/null
+++ b/data/com/src/main/java/kr/co/palnet/kac/data/com/service/ComFileDomainService.java
@@ -0,0 +1,42 @@
+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;
+
+import java.util.List;
+import java.util.Optional;
+
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class ComFileDomainService {
+
+ private final ComFileBasRepository comFileBasRepository;
+
+ public ComFileBas saveComFileBas(ComFileBas entity){
+ return comFileBasRepository.save(entity);
+ }
+
+ public Long findFirstByOrderByFileGroupNoDesc(){
+ Optional entityData = comFileBasRepository.findFirstByOrderByFileGroupNoDesc();
+
+ if(entityData.isPresent()){
+ ComFileBas lastComFileBas = entityData.get();
+
+ return lastComFileBas.getFileGroupNo() + 1;
+ } else {
+ return 1L;
+ }
+ }
+
+ public Optional> findByFileGroupNoInAndDelYnOrderByCreateDtDesc(List fileGroupNos, String delYn){
+ return comFileBasRepository.findByFileGroupNoInAndDelYnOrderByCreateDtDesc(fileGroupNos, delYn);
+ }
+
+ public Optional findFirstByFileGroupNoAndDelYnOrderByCreateDtDesc(Long fileGroupNo){
+ return comFileBasRepository.findFirstByFileGroupNoAndDelYnOrderByCreateDtDesc(fileGroupNo, "N");
+ }
+}
diff --git a/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/model/CtrCntrlBas.java b/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/model/CtrCntrlBas.java
index bf2ec2f..882e42f 100644
--- a/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/model/CtrCntrlBas.java
+++ b/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/model/CtrCntrlBas.java
@@ -3,7 +3,7 @@ package kr.co.palnet.kac.data.ctr.model;
import jakarta.persistence.*;
import lombok.*;
-import java.time.Instant;
+import java.time.LocalDateTime;
import java.util.List;
@@ -39,19 +39,19 @@ public class CtrCntrlBas {
// 비행시작일시
@Column(name = "FLGHT_ST_DT", columnDefinition = "datetime(6)")
- private Instant flghtStDt;
+ private LocalDateTime flghtStDt;
// 비행종료일시
@Column(name = "FLGHT_END_DT", columnDefinition = "datetime(6)")
- private Instant flghtEndDt;
+ private LocalDateTime flghtEndDt;
// 관제시작일시
@Column(name = "CNTRL_ST_DT", columnDefinition = "datetime(6)", nullable = false)
- private Instant cntrlStDt;
+ private LocalDateTime cntrlStDt;
// 관제종료일시
@Column(name = "CNTRL_END_DT", columnDefinition = "datetime(6)")
- private Instant cntrlEndDt;
+ private LocalDateTime cntrlEndDt;
// 총비행시간
@Column(name = "TTL_TIME", columnDefinition = "double default 0.0")
@@ -87,11 +87,11 @@ public class CtrCntrlBas {
// 생성일시
@Column(name = "CREATE_DT", columnDefinition = "datetime", updatable = false, nullable = false)
- private Instant createDt;
+ private LocalDateTime createDt;
// 수정일시
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false)
- private Instant updateDt;
+ private LocalDateTime updateDt;
@OneToMany(mappedBy = "ctrCntrlBas", fetch = FetchType.LAZY)
private List ctrCntrlHstryList;
diff --git a/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/model/CtrCntrlHstryArea.java b/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/model/CtrCntrlHstryArea.java
index 9e9013d..8948999 100644
--- a/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/model/CtrCntrlHstryArea.java
+++ b/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/model/CtrCntrlHstryArea.java
@@ -29,7 +29,7 @@ public class CtrCntrlHstryArea {
// 이력일련번호
@Column(name = "HSTRY_SNO", nullable = false) // mysql :: "int unsigned"
- private int hstrySno;
+ private Long hstrySno;
// 관제ID
@Column(name = "CNTRL_ID", length = 60, nullable = false)
diff --git a/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/model/join/CntrlJoinHstryAreaModel.java b/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/model/join/CntrlJoinHstryAreaModel.java
new file mode 100644
index 0000000..47d9021
--- /dev/null
+++ b/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/model/join/CntrlJoinHstryAreaModel.java
@@ -0,0 +1,20 @@
+package kr.co.palnet.kac.data.ctr.model.join;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class CntrlJoinHstryAreaModel {
+ private String startAddress;
+
+ private String endAddress;
+
+ private String cntrlId;
+
+ private LocalDateTime cntrlStDt;
+
+ private LocalDateTime cntrlEndDt;
+
+ private String statusCd;
+}
diff --git a/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/repository/CtrCntrlBasQueryRepository.java b/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/repository/CtrCntrlBasQueryRepository.java
new file mode 100644
index 0000000..a9362fc
--- /dev/null
+++ b/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/repository/CtrCntrlBasQueryRepository.java
@@ -0,0 +1,83 @@
+package kr.co.palnet.kac.data.ctr.repository;
+
+import com.querydsl.core.BooleanBuilder;
+import com.querydsl.core.types.ExpressionUtils;
+import com.querydsl.core.types.Projections;
+import com.querydsl.core.types.dsl.CaseBuilder;
+import com.querydsl.jpa.JPAExpressions;
+import com.querydsl.jpa.impl.JPAQueryFactory;
+import kr.co.palnet.kac.data.ctr.model.QCtrCntrlBas;
+import kr.co.palnet.kac.data.ctr.model.QCtrCntrlHstryArea;
+import kr.co.palnet.kac.data.ctr.model.join.CntrlJoinHstryAreaModel;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Repository;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+@Repository
+@Slf4j
+@RequiredArgsConstructor
+public class CtrCntrlBasQueryRepository {
+
+ private final JPAQueryFactory query;
+
+ public Optional> findByIdntfNumAndSearchDate(String idntfNum, LocalDateTime schFltStDt, LocalDateTime schFltEndDt){
+
+ QCtrCntrlBas cntrlBas = QCtrCntrlBas.ctrCntrlBas;
+ QCtrCntrlHstryArea cntrlHstryArea = QCtrCntrlHstryArea.ctrCntrlHstryArea;
+
+ BooleanBuilder builder = new BooleanBuilder();
+ builder.and(cntrlBas.cntrlStDt.loe(schFltEndDt))
+ .and(cntrlBas.cntrlStDt.goe(schFltStDt))
+ .and(cntrlBas.idntfNum.eq(idntfNum));
+
+ return Optional.ofNullable(query.select(Projections.bean(
+ CntrlJoinHstryAreaModel.class,
+ ExpressionUtils.as(
+ JPAExpressions.select(
+ cntrlHstryArea.area1.concat(" ")
+ .concat(cntrlHstryArea.area2).concat(" ")
+ .concat(cntrlHstryArea.area3).concat(" ")
+ .concat(cntrlHstryArea.landNm).concat(" ")
+ .concat(cntrlHstryArea.landNum)
+ )
+ .from(cntrlHstryArea)
+ .where(cntrlHstryArea.cntrlId.eq(cntrlBas.cntrlId)
+ .and(cntrlHstryArea.actnType.eq("01"))),
+ "startAddress"
+ ),
+ ExpressionUtils.as(
+ JPAExpressions.select(
+ cntrlHstryArea.area1.concat(" ")
+ .concat(cntrlHstryArea.area2).concat(" ")
+ .concat(cntrlHstryArea.area3).concat(" ")
+ .concat(cntrlHstryArea.landNm).concat(" ")
+ .concat(cntrlHstryArea.landNum)
+ )
+ .from(cntrlHstryArea)
+ .where(cntrlHstryArea.cntrlId.eq(cntrlBas.cntrlId)
+ .and(cntrlHstryArea.actnType.eq("99"))),
+ "endAddress"
+ ),
+ cntrlBas.cntrlId,
+ cntrlBas.cntrlStDt,
+ cntrlBas.cntrlEndDt,
+ new CaseBuilder()
+ .when(cntrlBas.statusCd.eq("01")).then("F")
+ .when(cntrlBas.statusCd.eq("99")).then("S")
+ .otherwise("B").as("statusCd")
+ ))
+ .from(cntrlBas)
+ .where(builder)
+ .orderBy(cntrlBas.cntrlStDt.asc())
+ .fetch());
+ }
+
+
+
+}
diff --git a/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/service/CtrCntrlDomainService.java b/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/service/CtrCntrlDomainService.java
new file mode 100644
index 0000000..bc236c0
--- /dev/null
+++ b/data/ctr/src/main/java/kr/co/palnet/kac/data/ctr/service/CtrCntrlDomainService.java
@@ -0,0 +1,35 @@
+package kr.co.palnet.kac.data.ctr.service;
+
+import kr.co.palnet.kac.data.ctr.model.CtrCntrlBas;
+import kr.co.palnet.kac.data.ctr.model.join.CntrlJoinHstryAreaModel;
+import kr.co.palnet.kac.data.ctr.repository.CtrCntrlBasQueryRepository;
+import kr.co.palnet.kac.data.ctr.repository.CtrCntrlBasRepository;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Optional;
+
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class CtrCntrlDomainService {
+
+ private final CtrCntrlBasRepository ctrCntrlBasRepository;
+
+ private final CtrCntrlBasQueryRepository ctrCntrlBasQueryRepository;
+
+ public Optional> findCntrlJoinHstryAreaByIdntfNumAndSearchDate(String idntfNum, LocalDateTime schFltStDt, LocalDateTime schFltEndDt){
+ return ctrCntrlBasQueryRepository.findByIdntfNumAndSearchDate(idntfNum, schFltStDt, schFltEndDt);
+ }
+
+ public CtrCntrlBas saveCtrCntrlBas(CtrCntrlBas entity){
+ return ctrCntrlBasRepository.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..02efee1 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
@@ -114,7 +114,7 @@ public class FltPlanArcrft {
// 보험유효기간
@Column(name = "INSURANCE_EXPERIOD", columnDefinition = "datetime")
- private String insuranceExperiod;
+ private LocalDateTime insuranceExperiod;
// 법인명
@Column(name = "CORPORATION_NM", length = 100)
@@ -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/model/FltPlanArea.java b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanArea.java
index 852c102..9dc8fb0 100644
--- a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanArea.java
+++ b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanArea.java
@@ -5,7 +5,7 @@ import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
-import java.time.Instant;
+import java.time.LocalDateTime;
import java.util.List;
@Data
@@ -64,7 +64,7 @@ public class FltPlanArea {
// 생성일시
@CreationTimestamp
@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)
@@ -73,7 +73,7 @@ public class FltPlanArea {
// 수정일시
@UpdateTimestamp
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false)
- private Instant updateDt;
+ private LocalDateTime updateDt;
@JoinColumn(
name = "PLAN_SNO", insertable = false, updatable = false,
@@ -82,7 +82,7 @@ public class FltPlanArea {
@ManyToOne(fetch = FetchType.LAZY)
private FltPlanBas fltPlanBas;
- @OneToMany(mappedBy = "fltPlanArea", fetch = FetchType.LAZY)
+ @OneToMany(mappedBy = "fltPlanArea", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List fltPlanAreaCoordList;
}
diff --git a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanAreaCoord.java b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanAreaCoord.java
index 7f48ebb..adb1db8 100644
--- a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanAreaCoord.java
+++ b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanAreaCoord.java
@@ -4,7 +4,7 @@ import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
-import java.time.Instant;
+import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@@ -46,7 +46,7 @@ public class FltPlanAreaCoord {
// 생성일시
@CreationTimestamp
@Column(name = "CREATE_DT", columnDefinition = "datetime", updatable = false, nullable = false)
- private Instant createDt;
+ private LocalDateTime createDt;
@JoinColumn(
name = "PLAN_AREA_SNO", insertable = false, updatable = false,
diff --git a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanBas.java b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanBas.java
index 1837583..d418109 100644
--- a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanBas.java
+++ b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanBas.java
@@ -3,7 +3,7 @@ package kr.co.palnet.kac.data.flt.model;
import jakarta.persistence.*;
import lombok.*;
-import java.time.Instant;
+import java.time.LocalDateTime;
import java.util.List;
@Data
@@ -69,11 +69,11 @@ public class FltPlanBas {
// 예정비행시작시간
@Column(name = "SCH_FLT_ST_DT", columnDefinition = "datetime(6)", nullable = false)
- private Instant schFltStDt;
+ private LocalDateTime schFltStDt;
// 예정비행종료시간
@Column(name = "SCH_FLT_END_DT", columnDefinition = "datetime(6)", nullable = false)
- private Instant schFltEndDt;
+ private LocalDateTime schFltEndDt;
// 비행목적
@Column(name = "FLT_PURPOSE", length = 200, nullable = false)
@@ -93,7 +93,7 @@ public class FltPlanBas {
// 승인일시
@Column(name = "APRVL_DT", columnDefinition = "datetime")
- private Instant aprvlDt;
+ private LocalDateTime aprvlDt;
// 삭제여부
@Column(name = "DEL_YN", columnDefinition = "char(1) default 'N'", nullable = false)
@@ -109,7 +109,7 @@ public class FltPlanBas {
// 생성일시
@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)
@@ -117,18 +117,18 @@ public class FltPlanBas {
// 수정일시
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false)
- private Instant updateDt;
+ private LocalDateTime updateDt;
- @OneToMany(mappedBy = "fltPlanBas", fetch = FetchType.LAZY)
+ @OneToMany(mappedBy = "fltPlanBas", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
private List fltPlanAreaList;
- @OneToMany(mappedBy = "fltPlanBas", fetch = FetchType.LAZY)
+ @OneToMany(mappedBy = "fltPlanBas", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
private List fltPlanArcrftList;
- @OneToMany(mappedBy = "fltPlanBas", fetch = FetchType.LAZY)
+ @OneToMany(mappedBy = "fltPlanBas", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
private List fltPlanPilotList;
- @OneToMany(mappedBy = "fltPlanBas", fetch = FetchType.LAZY)
+ @OneToMany(mappedBy = "fltPlanBas", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
private List fltPlanCtrCntrlRelList;
}
diff --git a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanCtrCntrlRel.java b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanCtrCntrlRel.java
index a8f7e8d..0775f67 100644
--- a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanCtrCntrlRel.java
+++ b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanCtrCntrlRel.java
@@ -21,7 +21,7 @@ public class FltPlanCtrCntrlRel {
@Builder
public static class FltPlanCtrCntrlRelId implements Serializable {
private String cntrlId;
- private Integer planSno;
+ private Long planSno;
}
// 관제ID
@@ -32,7 +32,7 @@ public class FltPlanCtrCntrlRel {
// 비행계획서일련번호
@Id
@Column(name = "PLAN_SNO") // mysql :: "int unsigned"
- private Integer planSno;
+ private Long planSno;
// 식별번호
@Column(name = "IDNTF_NUM", length = 30, nullable = false)
diff --git a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanPilot.java b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanPilot.java
index 21f174f..8618a10 100644
--- a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanPilot.java
+++ b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/FltPlanPilot.java
@@ -5,7 +5,7 @@ import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
-import java.time.Instant;
+import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@@ -83,7 +83,7 @@ public class FltPlanPilot {
// 생성일시
@CreationTimestamp
@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)
@@ -92,7 +92,7 @@ public class FltPlanPilot {
// 수정일시
@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/model/join/FltPlanBasJoinAreaModel.java b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/join/FltPlanBasJoinAreaModel.java
new file mode 100644
index 0000000..4c42e1c
--- /dev/null
+++ b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/model/join/FltPlanBasJoinAreaModel.java
@@ -0,0 +1,21 @@
+package kr.co.palnet.kac.data.flt.model.join;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class FltPlanBasJoinAreaModel {
+
+ private Long planSno;
+
+ private String groupId;
+
+ private LocalDateTime schFltStDt;
+
+ private LocalDateTime schFltEndDt;
+
+ private String ownerNm;
+
+ private String idntfNum;
+}
diff --git a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanArcrftRepository.java b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanArcrftRepository.java
index ac567d1..519a4cb 100644
--- a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanArcrftRepository.java
+++ b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanArcrftRepository.java
@@ -3,6 +3,11 @@ package kr.co.palnet.kac.data.flt.repository;
import kr.co.palnet.kac.data.flt.model.FltPlanArcrft;
import org.springframework.data.jpa.repository.JpaRepository;
-public interface FltPlanArcrftRepository extends JpaRepository {
+import java.util.List;
+import java.util.Optional;
+
+public interface FltPlanArcrftRepository extends JpaRepository {
+
+ public Optional> findByPlanSno(Long planSno);
}
diff --git a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanAreaRepository.java b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanAreaRepository.java
index 2e18c7f..ef81511 100644
--- a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanAreaRepository.java
+++ b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanAreaRepository.java
@@ -3,5 +3,12 @@ package kr.co.palnet.kac.data.flt.repository;
import kr.co.palnet.kac.data.flt.model.FltPlanArea;
import org.springframework.data.jpa.repository.JpaRepository;
-public interface FltPlanAreaRepository extends JpaRepository {
+import java.util.List;
+import java.util.Optional;
+
+public interface FltPlanAreaRepository extends JpaRepository {
+
+ public Optional> findByPlanSno(Long planSno);
+
+
}
diff --git a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanBasRepository.java b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanBasRepository.java
index c467230..c79e880 100644
--- a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanBasRepository.java
+++ b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanBasRepository.java
@@ -3,6 +3,10 @@ package kr.co.palnet.kac.data.flt.repository;
import kr.co.palnet.kac.data.flt.model.FltPlanBas;
import org.springframework.data.jpa.repository.JpaRepository;
-public interface FltPlanBasRepository extends JpaRepository {
+import java.util.Optional;
+public interface FltPlanBasRepository extends JpaRepository {
+
+
+ public Optional findTopByOrderByPlanSnoDesc();
}
diff --git a/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanQueryRepository.java b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanQueryRepository.java
new file mode 100644
index 0000000..6586a1e
--- /dev/null
+++ b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/repository/FltPlanQueryRepository.java
@@ -0,0 +1,81 @@
+package kr.co.palnet.kac.data.flt.repository;
+
+import com.querydsl.core.BooleanBuilder;
+import com.querydsl.core.types.Projections;
+import com.querydsl.jpa.impl.JPAQueryFactory;
+import kr.co.palnet.kac.data.flt.model.FltPlanBas;
+import kr.co.palnet.kac.data.flt.model.QFltPlanArcrft;
+import kr.co.palnet.kac.data.flt.model.QFltPlanBas;
+import kr.co.palnet.kac.data.flt.model.join.FltPlanBasJoinAreaModel;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Repository;
+import org.springframework.util.StringUtils;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Optional;
+
+@Repository
+@Slf4j
+@RequiredArgsConstructor
+public class FltPlanQueryRepository {
+
+ private final JPAQueryFactory query;
+
+ public Optional> findAllBySearch(String memberName, LocalDateTime createStDate, LocalDateTime createEndDate){
+
+ QFltPlanBas bas = QFltPlanBas.fltPlanBas;
+
+ BooleanBuilder builder = new BooleanBuilder();
+ if(StringUtils.hasText(memberName)){
+ builder.and(bas.memberName.contains(memberName));
+ }
+
+ if(createStDate != null) {
+ builder.and(bas.createDt.goe(createStDate));
+ }
+ if(createEndDate != null){
+ builder.and(bas.createDt.lt(createEndDate));
+ }
+
+ return Optional.ofNullable(query
+ .select(bas)
+ .from(bas)
+ .where(builder)
+ .orderBy(bas.createDt.desc())
+ .fetch());
+ }
+
+ public Optional> findAllBySearch(String searchDate){
+
+ QFltPlanBas fltPlanBas = QFltPlanBas.fltPlanBas;
+ QFltPlanArcrft fltPlanArcrft = QFltPlanArcrft.fltPlanArcrft;
+
+ LocalDateTime searchDateParam = LocalDate.parse(searchDate).atStartOfDay();
+
+ BooleanBuilder builder = new BooleanBuilder();
+ builder.and(fltPlanBas.schFltStDt.loe(searchDateParam))
+ .and(fltPlanBas.schFltEndDt.goe(searchDateParam))
+ .and(fltPlanBas.aprvlYn.eq("Y"));
+
+ return Optional.ofNullable(query.
+ select(Projections.bean(
+ FltPlanBasJoinAreaModel.class,
+ fltPlanBas.planSno,
+ fltPlanBas.groupId,
+ fltPlanBas.schFltStDt,
+ fltPlanBas.schFltEndDt,
+ fltPlanArcrft.ownerNm,
+ fltPlanArcrft.idntfNum
+ ))
+ .from(fltPlanBas)
+ .leftJoin(fltPlanArcrft)
+ .on(fltPlanBas.planSno.eq(fltPlanArcrft.planSno))
+ .where(builder)
+ .orderBy(fltPlanBas.schFltStDt.asc())
+ .fetch());
+ }
+
+}
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
new file mode 100644
index 0000000..2c37f15
--- /dev/null
+++ b/data/flt/src/main/java/kr/co/palnet/kac/data/flt/service/FltPlanDomainService.java
@@ -0,0 +1,84 @@
+package kr.co.palnet.kac.data.flt.service;
+
+import kr.co.palnet.kac.data.flt.model.*;
+import kr.co.palnet.kac.data.flt.model.join.FltPlanBasJoinAreaModel;
+import kr.co.palnet.kac.data.flt.repository.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Optional;
+
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class FltPlanDomainService {
+
+ private final FltPlanBasRepository fltPlanBasRepository;
+
+ private final FltPlanQueryRepository fltPlanQueryRepository;
+
+ private final FltPlanAreaRepository fltPlanAreaRepository;
+
+ private final FltPlanAreaCoordRepository fltPlanAreaCoordRepository;
+
+ private final FltPlanPilotRepository fltPlanPilotRepository;
+
+ private final FltPlanArcrftRepository fltPlanArcrftRepository;
+
+ public Optional> findAllFltPlanBasBySearch(String memberName, LocalDateTime createStDate, LocalDateTime createEndDate){
+
+ return fltPlanQueryRepository.findAllBySearch(memberName, createStDate, createEndDate);
+ }
+
+ public FltPlanBas findByOrderByPlanSnoDesc(){
+
+ Optional fltPlanBasData = fltPlanBasRepository.findTopByOrderByPlanSnoDesc();
+
+ return fltPlanBasData.orElse(null);
+ }
+
+ public Optional> findAllFltPlanBasBySearch(String searchDate){
+ return fltPlanQueryRepository.findAllBySearch(searchDate);
+ }
+
+ public Optional findById(Long planSno){
+ return fltPlanBasRepository.findById(planSno);
+ }
+
+ public FltPlanBas saveFltPlanBas(FltPlanBas entity){
+ return fltPlanBasRepository.save(entity);
+ }
+
+ public Optional> findFltPlanAreaByPlanSno(Long planSno){
+ return fltPlanAreaRepository.findByPlanSno(planSno);
+ }
+
+ public FltPlanArea saveFltPlanArea(FltPlanArea entity){
+ return fltPlanAreaRepository.save(entity);
+ }
+
+ public FltPlanAreaCoord saveFltPlanAreaCoord(FltPlanAreaCoord entity){
+ return fltPlanAreaCoordRepository.save(entity);
+ }
+
+ public FltPlanPilot saveFltPlanPilot(FltPlanPilot entity){
+ return fltPlanPilotRepository.save(entity);
+ }
+
+ public Optional> findFltPlanArcrftByPlanSno(Long planSno){
+ return fltPlanArcrftRepository.findByPlanSno(planSno);
+ }
+
+ 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/data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyGroupBasRepository.java b/data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyGroupBasRepository.java
index d21ed3f..4b5a46c 100644
--- a/data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyGroupBasRepository.java
+++ b/data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyGroupBasRepository.java
@@ -4,7 +4,11 @@ import kr.co.palnet.kac.data.pty.model.PtyGroupBas;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
+import java.util.List;
+import java.util.Optional;
+
@Repository
public interface PtyGroupBasRepository extends JpaRepository {
+ public Optional> findByGroupNm(String groupNm);
}
diff --git a/data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyGroupDomainService.java b/data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyGroupDomainService.java
index 6beada4..5e8983e 100644
--- a/data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyGroupDomainService.java
+++ b/data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyGroupDomainService.java
@@ -20,19 +20,23 @@ public class PtyGroupDomainService {
private final PtyCstmrGroupRepository ptyCstmrGroupRepository;
- public Optional> findJoinGroupByCstmrSno(Long cstmrSno){
+ public Optional> findPtyCstmrGroupJoinGroupByCstmrSno(Long cstmrSno){
return ptyCstmrGroupRepository.findByCstmrSnoAndJoinYn(cstmrSno, "Y");
}
- public Optional> findByGroupId(String groupId){
+ public Optional> findPtyCstmrGroupByGroupId(String groupId){
return ptyCstmrGroupRepository.findByGroupId(groupId);
}
- public Optional> findByCstmrSno(Long cstmrSno){
+ public Optional> findPtyGroupBasByGroupNm(String groupNm){
+ return ptyGroupBasRepository.findByGroupNm(groupNm);
+ }
+
+ public Optional> findPtyCstmrGroupByCstmrSno(Long cstmrSno){
return ptyCstmrGroupRepository.findByCstmrSno(cstmrSno);
}
- public Optional findByGroupIdAndCstmrSno(String groupId, Long cstmrSno){
+ public Optional findPtyCstmrGroupByGroupIdAndCstmrSno(String groupId, Long cstmrSno){
return ptyCstmrGroupRepository.findByGroupIdAndCstmrSno(groupId, cstmrSno);
}
@@ -40,7 +44,7 @@ public class PtyGroupDomainService {
return ptyCstmrGroupRepository.save(entity);
}
- public PtyGroupBas findById(String id){
+ public PtyGroupBas findPtyGroupBasById(String id){
return ptyGroupBasRepository.findById(id).orElse(null);
}
diff --git a/data/user/build.gradle b/data/user/build.gradle
new file mode 100644
index 0000000..6875d3b
--- /dev/null
+++ b/data/user/build.gradle
@@ -0,0 +1,6 @@
+
+
+dependencies {
+
+}
+
diff --git a/web/api-flight/build.gradle b/web/api-flight/build.gradle
new file mode 100644
index 0000000..c643e3b
--- /dev/null
+++ b/web/api-flight/build.gradle
@@ -0,0 +1,44 @@
+
+dependencies {
+ implementation "$boot:spring-boot-starter-web"
+ implementation "$boot:spring-boot-starter-data-jpa"
+
+ implementation 'javax.media:jai_core:1.1.3'
+
+ // thymeleaf
+ implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
+
+ // pdf create
+ implementation 'com.itextpdf:html2pdf:5.0.3'
+
+ // other
+ implementation 'org.apache.httpcomponents.client5:httpclient5:5.3'
+ implementation 'org.apache.commons:commons-io:1.3.2'
+ implementation 'com.googlecode.json-simple:json-simple:1.1.1'
+
+ // geometry
+ implementation 'com.esri.geometry:esri-geometry-api:2.2.4'
+ implementation 'org.locationtech.proj4j:proj4j:1.3.0'
+ implementation 'org.locationtech.proj4j:proj4j-epsg:1.3.0'
+ implementation 'org.locationtech.jts:jts-core:1.19.0'
+ implementation 'org.geotools:gt-geojson:29.2'
+ implementation 'org.geotools:gt-coverage:29.2'
+ implementation 'org.geotools:gt-geotiff:29.2'
+ implementation 'org.geotools:gt-epsg-hsql:29.2'
+
+ // QR Code
+ implementation 'com.google.zxing:core:3.5.2'
+ implementation 'com.google.zxing:javase:3.5.2'
+
+ compileOnly 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
+ implementation project(":common:core")
+ implementation project(":common:util")
+ implementation project(":data:flt")
+ 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/external/model/ComnSmsLaancAprovModel.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/external/model/ComnSmsLaancAprovModel.java
new file mode 100644
index 0000000..92ea0a3
--- /dev/null
+++ b/web/api-flight/src/main/java/kr/co/palnet/kac/api/external/model/ComnSmsLaancAprovModel.java
@@ -0,0 +1,27 @@
+package kr.co.palnet.kac.api.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/external/model/CtrTrnsLctnModel.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/external/model/CtrTrnsLctnModel.java
new file mode 100644
index 0000000..f9457cd
--- /dev/null
+++ b/web/api-flight/src/main/java/kr/co/palnet/kac/api/external/model/CtrTrnsLctnModel.java
@@ -0,0 +1,16 @@
+package kr.co.palnet.kac.api.external.model;
+
+import lombok.Data;
+
+@Data
+public class CtrTrnsLctnModel {
+ private Long hstryAreaSno;
+ private String area1;
+ private String area2;
+ private String area3;
+ private String zipCd;
+ private String landNm;
+ private String landNum;
+ private String areaType;
+ private String areaNm;
+}
diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/external/model/TsQRcodeRQ.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/external/model/TsQRcodeRQ.java
new file mode 100644
index 0000000..c6575f9
--- /dev/null
+++ b/web/api-flight/src/main/java/kr/co/palnet/kac/api/external/model/TsQRcodeRQ.java
@@ -0,0 +1,28 @@
+package kr.co.palnet.kac.api.external.model;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+public class TsQRcodeRQ {
+ private String type; // 5 (한국공항공사) - 고정
+ private String rtnUrl; // 리턴 url - 고정
+ private String reqId; // 추적 코드
+ private String submittype; // 기체신고번호
+ private String applyUser; // 사용자 인증 코드 ci
+
+ public TsQRcodeRQ() {
+ this.type = "5";
+ this.rtnUrl = "";
+ }
+
+ @Builder
+ public TsQRcodeRQ(String rtnUrl, String reqId, String submittype, String applyUser) {
+ this.type = "5";
+ this.rtnUrl = rtnUrl;
+ this.reqId = reqId;
+ this.submittype = submittype;
+ this.applyUser = applyUser;
+ }
+
+}
diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/external/service/ComnSmsService.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/external/service/ComnSmsService.java
new file mode 100644
index 0000000..f92ab79
--- /dev/null
+++ b/web/api-flight/src/main/java/kr/co/palnet/kac/api/external/service/ComnSmsService.java
@@ -0,0 +1,92 @@
+package kr.co.palnet.kac.api.external.service;
+
+import kr.co.palnet.kac.api.external.model.ComnSmsLaancAprovModel;
+import kr.co.palnet.kac.api.v1.flight.laanc.model.SuredataEntityDTO;
+import kr.co.palnet.kac.api.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.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 dto = getInitialEntity();
+ dto.setSubject("[비행승인 완료]");
+ dto.setMsg(template);
+ dto.setCallname(model.getPilotName());
+ dto.setCallphone(model.getCallphone());
+ dto.setKind("M");
+
+ log.info("entity : {}", dto);
+ log.info("========================================");
+ log.info("message : {}", template);
+ log.info("========================================");
+ log.info("message : {}", dto.getMsg());
+
+ if(dto.getBatchflag() == null) dto.setBatchflag(0);
+ return dto;
+ }
+
+ /**
+ * 데이터베이스에 추가할 메세지 발송이력 데이터를 셋팅함.
+ * @return
+ */
+ public SuredataEntityDTO getInitialEntity() {
+ String nowStr = DateUtils.toDateTimeStringByFormat(LocalDateTime.now(), "yyyyMMddHHmmss");
+ SuredataEntityDTO dto = new SuredataEntityDTO();
+ dto.setUsercode("palnet");
+ dto.setIntime(nowStr);
+ dto.setReqname("한국공항공사");
+ dto.setReqphone("0262003912"); // 1661-2626
+// entity.setCallname("지대한");
+// entity.setCallphone("010-0000-0000");
+// entity.setSubject("주제");
+// entity.setMsg("");
+ dto.setReqtime("00000000000000");
+ dto.setResult("0");
+ dto.setKind("S");
+ return dto;
+ }
+}
diff --git a/web/api-flight/src/main/java/kr/co/palnet/kac/api/external/service/CtrTrnsLctnService.java b/web/api-flight/src/main/java/kr/co/palnet/kac/api/external/service/CtrTrnsLctnService.java
new file mode 100644
index 0000000..98208f5
--- /dev/null
+++ b/web/api-flight/src/main/java/kr/co/palnet/kac/api/external/service/CtrTrnsLctnService.java
@@ -0,0 +1,134 @@
+package kr.co.palnet.kac.api.external.service;
+
+import kr.co.palnet.kac.api.external.model.CtrTrnsLctnModel;
+import kr.co.palnet.kac.core.exception.BaseErrorCode;
+import kr.co.palnet.kac.util.ObjectMapperUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.*;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class CtrTrnsLctnService {
+ @Value("${naver.api.url}")
+ private String NAVER_API_URL;
+
+ @Value("${naver.api.id}")
+ private String NAVER_API_ID;
+
+ @Value("${naver.api.key}")
+ private String NAVER_API_KEY;
+
+ private Logger logger = LoggerFactory.getLogger(getClass());
+
+ /**
+ * 위치에 맞는 값에 대한 주소로 변환하는 기능.
+ * @param lat
+ * @param lon
+ * @return
+ */
+ public CtrTrnsLctnModel convertLatlonToAddress(double lat , double lon) {
+ HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
+
+ factory.setConnectTimeout(5000); //타임아웃 설정 5초
+ factory.setConnectionRequestTimeout(5000);//타임아웃 설정 5초
+ RestTemplate restTemplate = new RestTemplate(factory);
+
+ HttpHeaders header = new HttpHeaders();
+ header.add("X-NCP-APIGW-API-KEY-ID", NAVER_API_ID);
+ header.add("X-NCP-APIGW-API-KEY", NAVER_API_KEY);
+ HttpEntity> entity = new HttpEntity<>(header);
+
+ UriComponents uri = UriComponentsBuilder.fromHttpUrl(NAVER_API_URL)
+ .queryParam("request", "coordsToaddr")
+ .queryParam("coords", lon + "," + lat)
+ .queryParam("sourcecrs", "epsg:4326")
+ .queryParam("output", "json")
+// .queryParam("orders", "roadaddr")
+ .queryParam("orders", "addr,roadaddr")
+ .build();
+
+ ResponseEntity