Browse Source

Merge pull request 'feature/dos/paging' (#19) from feature/dos/paging into develop

Reviewed-on: #19
feature/dos/statistics
lkd9125 3 weeks ago
parent
commit
af2e4bee10
  1. 32
      pav-server/src/main/java/com/palnet/biz/api/bas/dos/controller/BasDosController.java
  2. 4
      pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/BasDosPlanDroneRs.java
  3. 4
      pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/BasDosPlanPilotRs.java
  4. 13
      pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/Pagination.java
  5. 47
      pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/SearchBasDosPlanRQ.java
  6. 14
      pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/SearchBasDosPlanRS.java
  7. 374
      pav-server/src/main/java/com/palnet/biz/api/bas/dos/service/BasDosService.java
  8. 2
      pav-server/src/main/java/com/palnet/biz/jpa/repository/dos/DosFltPlanDroneRepository.java
  9. 2
      pav-server/src/main/java/com/palnet/biz/jpa/repository/dos/DosFltPlanPilotRepository.java
  10. 127
      pav-server/src/main/java/com/palnet/biz/jpa/repository/dos/DosFltPlanQueryRepository.java
  11. 2
      pav-server/src/main/java/com/palnet/comn/exception/CustomException.java

32
pav-server/src/main/java/com/palnet/biz/api/bas/dos/controller/BasDosController.java

@ -2,6 +2,7 @@ package com.palnet.biz.api.bas.dos.controller;
import com.palnet.biz.api.bas.dos.model.*; import com.palnet.biz.api.bas.dos.model.*;
import com.palnet.biz.api.bas.dos.service.BasDosService; import com.palnet.biz.api.bas.dos.service.BasDosService;
import com.palnet.biz.api.comn.response.SuccessResponse;
import com.palnet.comn.code.ErrorCode; import com.palnet.comn.code.ErrorCode;
import com.palnet.comn.exception.CustomException; import com.palnet.comn.exception.CustomException;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
@ -10,7 +11,9 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@ -25,7 +28,7 @@ public class BasDosController {
/** /**
* 비행계획 조회 * 비행계획 조회
* *
* @param rq * @param rq 비행승인 계획 요청 RQ, 승인날짜 범위, 지역이름 ..
* @return * @return
*/ */
@GetMapping("/plan") @GetMapping("/plan")
@ -34,6 +37,33 @@ public class BasDosController {
return ResponseEntity.ok(rs); return ResponseEntity.ok(rs);
} }
/**
* 비행계획 조회 [페이징]
*
* @param rq
* @return
*/
@GetMapping("/plan/paging")
public ResponseEntity<?> getPagingDosPlan(SearchBasDosPlanRQ rq) {
SearchBasDosPlanRS rs = null;
try {
rs = basDosService.getPagingDosPlan(rq, PlanSelectType.LIST);
} catch (CustomException e) {
ErrorCode errorCode = ErrorCode.fromCode(e.getSourceErrorCode());
String paramMessage = (String)e.getParamArray()[0];
Map<String, Object> resultMap = new HashMap<>();
log.error("IGNORE : ", e);
resultMap.put("result", false);
resultMap.put("errorCode", errorCode.code());
resultMap.put("errorMessage", errorCode.message());
resultMap.put("errorDesc", paramMessage);
return ResponseEntity.ok().body(new SuccessResponse<>(resultMap));
}
return ResponseEntity.ok(rs);
}
/** /**
* 비행계획 수정 * 비행계획 수정
* *

4
pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/BasDosPlanDroneRs.java

@ -1,5 +1,6 @@
package com.palnet.biz.api.bas.dos.model; package com.palnet.biz.api.bas.dos.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
@ -22,4 +23,7 @@ public class BasDosPlanDroneRs {
private String weightNm; private String weightNm;
// 가입여부 // 가입여부
private String insrncJoinYn; private String insrncJoinYn;
// planSno
@JsonIgnore
private Long planSno;
} }

4
pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/BasDosPlanPilotRs.java

@ -1,5 +1,6 @@
package com.palnet.biz.api.bas.dos.model; package com.palnet.biz.api.bas.dos.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
@ -18,4 +19,7 @@ public class BasDosPlanPilotRs {
private String birthDate; private String birthDate;
// 조종사 자격번호 // 조종사 자격번호
private String crtfctNo; private String crtfctNo;
@JsonIgnore
private Long planSno;
} }

13
pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/Pagination.java

@ -0,0 +1,13 @@
package com.palnet.biz.api.bas.dos.model;
import lombok.Data;
@Data
public class Pagination {
private Long totalDataCount; // 전체데이터
private Long totalPages; // 나올 수 있는 페이지 갯수
private Long currentPage; // 현재 페이지 [RQ로 수급]
private Long pageDataSize; // 페이지당 데이터 갯수 [RQ로 수급]
private Boolean isFirst; // 첫번째 페이지인지 여부
private Boolean isLast; // 마지막 페이지인지 여부
}

47
pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/SearchBasDosPlanRQ.java

@ -0,0 +1,47 @@
package com.palnet.biz.api.bas.dos.model;
import com.palnet.biz.jpa.entity.type.ReviewedProcType;
import com.palnet.biz.jpa.entity.type.ReviewedType;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDate;
@Data
public class SearchBasDosPlanRQ {
@Schema(description = "검색시작일자", example = "2024-06-01", implementation = LocalDate.class)
private LocalDate searchStDt;
@Schema(description = "검색끝일자", example = "2024-06-30", implementation = LocalDate.class)
private LocalDate searchEndDt;
@Schema(description = "문서번호", example = "201118-1010", implementation = String.class)
private String applyNo;
@Schema(description = "승인코드", example = "S", implementation = String.class)
private String approvalCd;
@Schema(description = "바운더리", example = "GIMPO", implementation = String.class)
private String selectZone;
@Schema(description = "시/구 주소", example = "인천광역시", implementation = String.class)
private String ctprvn;
@Schema(description = "시/군/구 주소", example = "남동구", implementation = String.class)
private String sig;
@Schema(description = "상세주소", example = "만수동", implementation = String.class)
private String address;
@Schema(description = "검토유형(운항과)", example = "W", implementation = ReviewedType.class)
private ReviewedType reviewedType;
@Schema(description = "검토유형(관제과)", example = "W", implementation = ReviewedProcType.class)
private ReviewedProcType reviewedProcType;
@Schema(description = "페이지번호 [Default : 1]", example = "1", implementation = Integer.class)
private Long page = 1L;
@Schema(description = "페이지당 데이터 갯수 [Default : 10]", example = "10", implementation = Integer.class)
private Long pageDataSize = 10L;
}

14
pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/SearchBasDosPlanRS.java

@ -0,0 +1,14 @@
package com.palnet.biz.api.bas.dos.model;
import lombok.Data;
import java.util.List;
@Data
public class SearchBasDosPlanRS {
private List<BasDosPlanRs> content;
private Pagination pagination;
}

374
pav-server/src/main/java/com/palnet/biz/api/bas/dos/service/BasDosService.java

@ -15,6 +15,7 @@ import com.palnet.biz.api.external.model.DosApprovalResult;
import com.palnet.biz.api.external.service.DronOneStopService; import com.palnet.biz.api.external.service.DronOneStopService;
import com.palnet.biz.jpa.entity.DosFltPlanArea; import com.palnet.biz.jpa.entity.DosFltPlanArea;
import com.palnet.biz.jpa.entity.DosFltPlanBas; import com.palnet.biz.jpa.entity.DosFltPlanBas;
import com.palnet.biz.jpa.entity.DosFltPlanDrone;
import com.palnet.biz.jpa.entity.DosFltPlanResult; import com.palnet.biz.jpa.entity.DosFltPlanResult;
import com.palnet.biz.jpa.entity.type.ReviewedProcType; import com.palnet.biz.jpa.entity.type.ReviewedProcType;
import com.palnet.biz.jpa.entity.type.ReviewedType; import com.palnet.biz.jpa.entity.type.ReviewedType;
@ -53,6 +54,7 @@ import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.*; import java.io.*;
import java.lang.reflect.Field;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.Instant; import java.time.Instant;
@ -129,9 +131,10 @@ public class BasDosService {
} }
// 비행지역
List<BasDosPlanAreaRs> areaRsList = new ArrayList<>(); List<BasDosPlanAreaRs> areaRsList = new ArrayList<>();
// area 객체를
for (DosFltPlanArea area : areaList) { for (DosFltPlanArea area : areaList) {
if (area.getPlanSno().equals(planSno)) { if (area.getPlanSno().equals(planSno)) {
Optional<DosFltPlanResult> first = resultList.stream().filter(result -> result.getPlanAreaSno().equals(area.getPlanAreaSno())).findFirst(); Optional<DosFltPlanResult> first = resultList.stream().filter(result -> result.getPlanAreaSno().equals(area.getPlanAreaSno())).findFirst();
@ -143,6 +146,11 @@ public class BasDosService {
fltElevMax = dosFltPlanResult.getFltElevMax(); fltElevMax = dosFltPlanResult.getFltElevMax();
} }
/**
* 1. 요청코드가 있을경우 [검색조건]
* 2. 조회할 area의 승인코드 있을경우
* 3. 요청코드와 조회한 area의 승인코드가 맞지 않을경우 continue
*/
if (rq.getApprovalCd() != null && approvalCd != null && !rq.getApprovalCd().equals(approvalCd.getCode())) { if (rq.getApprovalCd() != null && approvalCd != null && !rq.getApprovalCd().equals(approvalCd.getCode())) {
continue; continue;
} }
@ -175,6 +183,7 @@ public class BasDosService {
}); });
if (!isContain) continue; if (!isContain) continue;
} else if ("DF0002-1".equals(cptAuthCode)) { } else if ("DF0002-1".equals(cptAuthCode)) {
// 운항과는 전체건수 조회
/* /*
// TODO 운항과(김항소 관리 전역) // TODO 운항과(김항소 관리 전역)
if(boundary == null) { if(boundary == null) {
@ -204,12 +213,15 @@ public class BasDosService {
.geometry(rqGeometry) .geometry(rqGeometry)
.build(); .build();
boolean isDuplicatedAirspace = airspaceUtils.isDuplicatedAirspace(targetfeatureInfo, AirspaceUtils.AirspaceType.GIMPO); boolean isDuplicatedAirspace = airspaceUtils.isDuplicatedAirspace(targetfeatureInfo, AirspaceUtils.AirspaceType.GIMPO);
// 지역과 공역이 중복되지 않는다면 continue
if (!isDuplicatedAirspace) { if (!isDuplicatedAirspace) {
continue; continue;
} }
} }
bufferCoordList = coordBuffers.stream().map(coord -> Map.of("lat", coord.y, "lon", coord.x)).collect(Collectors.toList()); bufferCoordList = coordBuffers.stream().map(coord -> Map.of("lat", coord.y, "lon", coord.x)).collect(Collectors.toList());
if (area.getReqRadius() != null && area.getReqRadius() > 0) { if (area.getReqRadius() != null && area.getReqRadius() > 0) {
// 승인요청 지역 바운더리 좌표
List<Coordinate> reqCoordBuffers = areaUtils.createCircle(new Coordinate(area.getLon(), area.getLat()), area.getReqRadius()); List<Coordinate> reqCoordBuffers = areaUtils.createCircle(new Coordinate(area.getLon(), area.getLat()), area.getReqRadius());
reqBufferCoordList = reqCoordBuffers.stream().map(coord -> Map.of("lat", coord.y, "lon", coord.x)).collect(Collectors.toList()); reqBufferCoordList = reqCoordBuffers.stream().map(coord -> Map.of("lat", coord.y, "lon", coord.x)).collect(Collectors.toList());
} }
@ -959,4 +971,364 @@ public class BasDosService {
} }
} }
/**
* 페이징처리
* @param rq
* @param type
* @return
*/
@Transactional(readOnly = true)
public SearchBasDosPlanRS getPagingDosPlan(SearchBasDosPlanRQ rq, PlanSelectType type){
List<DosFltPlanBas> planBasList = dosFltPlanQueryRepository.findPlanByBasSearch(rq);
if (planBasList.isEmpty()) {
return null;
}
List<Long> planSnoList = planBasList.stream().map(DosFltPlanBas::getPlanSno).collect(Collectors.toList());
Long totalDataCount = dosFltPlanQueryRepository.countByPlanSnoInAndSearchOrderByZoneNoAsc(planSnoList, rq);
Long totalPages = totalDataCount / rq.getPageDataSize();
if(totalDataCount % rq.getPageDataSize() > 0) totalPages ++;
if(rq.getPage() > totalPages || rq.getPage() < 1) throw new CustomException(ErrorCode.NON_VALID_PARAMETER, String.format("페이지는 [ %s ] page 부터 [ %s ] page 까지입니다.", 1, totalPages));
Boolean isFirst = rq.getPage() == 1;
Boolean isLast = rq.getPage().equals(totalPages);
Pagination pagination = new Pagination();
pagination.setTotalDataCount(totalDataCount);
pagination.setTotalPages(totalPages);
pagination.setCurrentPage(rq.getPage());
pagination.setPageDataSize(rq.getPageDataSize());
pagination.setIsFirst(isFirst);
pagination.setIsLast(isLast);
Map<Long , DosFltPlanBas> fltPlanBasMap = this.getConvertMap(planBasList, "planSno", Long.class);
Map<Long , List<BasDosPlanDroneRs>> fltDroneBasMap = dosFltPlanDroneRepository.findByPlanSnoIn(planSnoList).stream()
.map(drone -> {
String weightCd = drone.getWeightCd();
WeightCdType weightCdType = WeightCdType.fromCode(weightCd);
return BasDosPlanDroneRs.builder()
.planDroneSno(drone.getPlanDroneSno())
.fbctnNo(drone.getFbctnNo())
.benefit(drone.getBenefit())
.weightCd(drone.getWeightCd())
.weightNm(weightCdType != null ? weightCdType.getMessage() : null)
.insrncJoinYn(drone.getInsrncJoinYn())
.planSno(drone.getPlanSno())
.build();
})
.collect(Collectors.groupingBy(BasDosPlanDroneRs::getPlanSno));;
Map<Long , List<BasDosPlanPilotRs>> fltPliotBasMap = dosFltPlanPilotRepository.findByPlanSnoIn(planSnoList).stream()
.map(pilot -> {
return BasDosPlanPilotRs.builder()
.planPilotSno(pilot.getPlanPilotSno())
.pilotNm(pilot.getPilotNm())
.birthDate(pilot.getBirthDate())
.crtfctNo(pilot.getCrtfctNo())
.planSno(pilot.getPlanPilotSno())
.build();
})
.collect(Collectors.groupingBy(BasDosPlanPilotRs::getPlanSno));
List<DosFltPlanArea> areaList = dosFltPlanQueryRepository.findByPlanSnoInAndSearchOrderByZoneNoAsc(planSnoList, rq);
List<DosFltPlanResult> resultList = dosFltPlanResultRepository.findByPlanSnoIn(planSnoList);
Set<Long> areaPlanSno = areaList.stream().map(DosFltPlanArea::getPlanSno).collect(Collectors.toSet());
Set<Long> removePlanSnoSet = new HashSet<>(planSnoList);
removePlanSnoSet.removeAll(areaPlanSno);
List<Long> removeList = new ArrayList<>(removePlanSnoSet);
for(Long removePlanSno : removeList){
fltPlanBasMap.remove(removePlanSno);
}
List<BasDosPlanRs> rs = new ArrayList<>();
List<Geometry> boundary = null;
Map<Long, DosFltPlanBas> sortedMap = fltPlanBasMap.entrySet().stream()
.sorted((e1, e2) -> {
int cmp = e2.getValue().getApplyDt().compareTo(e1.getValue().getApplyDt());
if (cmp == 0) {
return e2.getValue().getApplyNo().compareTo(e1.getValue().getApplyNo());
}
return cmp;
})
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
for(Map.Entry<Long, DosFltPlanBas> entry : sortedMap.entrySet()){
Long planSno = entry.getKey();
DosFltPlanBas bas = entry.getValue();
String applyNo = bas.getApplyNo();
// 신청일시 분할
LocalDate applyDt = bas.getApplyDt();
String applyDtMonth = String.valueOf(applyDt.getMonthValue());
String applyDtDay = String.valueOf(applyDt.getDayOfMonth());
// 비행목적 - 비행목적은 레저비행, 사진/영상촬영을 제외한 나머지 목적은 기타 로 표현
String purpose = "기타";
String[] purposeTexts = {"레저비행", "사진/영상촬영"};
if (StringUtils.hasText(bas.getPurpose())) {
purpose = Arrays.asList(purposeTexts).contains(bas.getPurpose()) ? bas.getPurpose() : "기타";
}
List<BasDosPlanAreaRs> areaRsList = new ArrayList<>();
for (int i = 0; i < areaList.size(); i ++) {
DosFltPlanArea area = areaList.get(i);
// TOOD :: 추후 리스트를 삭제하며 돌 수 있도록 수정 필요
// Boolean addResult = false;
if (area.getPlanSno().equals(planSno)) {
Optional<DosFltPlanResult> first = resultList.stream().filter(result -> result.getPlanAreaSno().equals(area.getPlanAreaSno())).findFirst();
ApprovalCd approvalCd = null;
Double fltElevMax = null;
if (first.isPresent()) {
DosFltPlanResult dosFltPlanResult = first.get();
approvalCd = ApprovalCd.fromCode(dosFltPlanResult.getApprovalCd());
fltElevMax = dosFltPlanResult.getFltElevMax();
}
/**
* 1. 요청코드가 있을경우 [검색조건]
* 2. 조회할 area의 승인코드 있을경우
* 3. 요청코드와 조회한 area의 승인코드가 맞지 않을경우 continue
*/
if (rq.getApprovalCd() != null && approvalCd != null && !rq.getApprovalCd().equals(approvalCd.getCode())) {
continue;
}
// ReviewedType이 UNNECESSARY(불필요)인 경우 ApprovalCd가 UNTARGETED_AREA(비대상)인 경우만 조회
if (rq.getReviewedType() == ReviewedType.UNNECESSARY) {
if (approvalCd != ApprovalCd.UNTARGETED_AREA) {
continue;
}
}
// 사용자 부서에 따른 필터 관제과(DF0002), 운항과(DF0002-1)
String cptAuthCode = jwtTokenUtil.getCptAuthCodeByToken();
if (cptAuthCode != null) {
Coordinate centerPoint = new Coordinate(area.getLon(), area.getLat());
if ("DF0002".equals(cptAuthCode)) {
// 관제과와 관련된 내용으로만 필터링 reviewedProcType이 null이 아니라면 표출
if (area.getReviewedProcType() == null) {
continue;
}
// 관제과(9.3km)
AirspaceUtils airspaceUtils = AirspaceUtils.getInstance();
List<AirspaceUtils.FeatureInfo> airspaces = airspaceUtils.getAirspaces(AirspaceUtils.AirspaceType.GIMPO);
GeometryFactory geometryFactory = new GeometryFactory();
Point point = geometryFactory.createPoint(centerPoint);
boolean isContain = airspaces.stream().anyMatch(airspace -> {
Geometry airspaceGeometry = airspace.getGeometry();
return airspaceGeometry.contains(point);
});
if (!isContain) continue;
} else if ("DF0002-1".equals(cptAuthCode)) {
// 운항과는 전체건수 조회
/*
// TODO 운항과(김항소 관리 전역)
if(boundary == null) {
boundary = comnCoordinateService.getDeptGeometry("F0002");
}
// log.info("boundary : {}", boundary);
GeometryFactory geometryFactory = new GeometryFactory();
Point point = geometryFactory.createPoint(centerPoint);
boolean isContain = boundary.stream().anyMatch(geometry -> geometry.contains(point));
if(!isContain) continue;
*/
}
}
List<Map<String, Double>> bufferCoordList = null;
List<Map<String, Double>> reqBufferCoordList = null;
if (type == PlanSelectType.LIST) {
List<Coordinate> coordBuffers = areaUtils.createCircle(new Coordinate(area.getLon(), area.getLat()), area.getBufferZone());
if ("GIMPO".equalsIgnoreCase(rq.getSelectZone())) {
AirspaceUtils airspaceUtils = AirspaceUtils.getInstance();
Geometry rqGeometry = airspaceUtils.createGeometryByCoordinate(coordBuffers);
AirspaceUtils.FeatureInfo targetfeatureInfo = AirspaceUtils.FeatureInfo.builder()
.lowElev(0D)
.highElev(area.getFltElev())
.geometry(rqGeometry)
.build();
boolean isDuplicatedAirspace = airspaceUtils.isDuplicatedAirspace(targetfeatureInfo, AirspaceUtils.AirspaceType.GIMPO);
// 지역과 공역이 중복되지 않는다면 continue
if (!isDuplicatedAirspace) {
continue;
}
}
bufferCoordList = coordBuffers.stream().map(coord -> Map.of("lat", coord.y, "lon", coord.x)).collect(Collectors.toList());
if (area.getReqRadius() != null && area.getReqRadius() > 0) {
// 승인요청 지역 바운더리 좌표
List<Coordinate> reqCoordBuffers = areaUtils.createCircle(new Coordinate(area.getLon(), area.getLat()), area.getReqRadius());
reqBufferCoordList = reqCoordBuffers.stream().map(coord -> Map.of("lat", coord.y, "lon", coord.x)).collect(Collectors.toList());
}
}
// TODO 추후 Utils 생성
// 주소 분할 - 임시 순서대로 split
String addr = area.getAddr() != null ? area.getAddr() : "";
String[] addrArr = addr.split(" ");
String addr1 = "";
String addr2 = "";
StringBuilder addrRest = new StringBuilder();
for (int j = 0; j < addrArr.length; j++) {
switch (j) {
case 0:
addr1 = addrArr[j];
break;
case 1:
addr2 = addrArr[j];
break;
case 2:
addrRest.append(addrArr[j]);
break;
default:
addrRest.append(" ").append(addrArr[j]);
break;
}
}
String addr3 = addrRest.toString();
String limitZone = area.getLimitZone();
LimitZoneType limitZoneType = LimitZoneType.fromCode(limitZone);
ReviewedType reviewedType = area.getReviewedType();
if (reviewedType == null) {
reviewedType = approvalCd == ApprovalCd.UNTARGETED_AREA ? ReviewedType.UNNECESSARY : ReviewedType.WAIT;
}
BasDosPlanAreaRs areaRs = BasDosPlanAreaRs.builder()
.planAreaSno(area.getPlanAreaSno())
.planSno(area.getPlanSno())
.applyNo(applyNo)
.applyDt(applyDt)
.applyDtMonth(applyDtMonth)
.applyDtDay(applyDtDay)
.zoneNo(area.getZoneNo())
.bufferZone(area.getBufferZone())
.fltElev(area.getFltElev())
.lat(area.getLat())
.lon(area.getLon())
.addr(addr)
.addr1(addr1)
.addr2(addr2)
.addr3(addr3)
.approvalCd(approvalCd != null ? approvalCd.getCode() : null)
.fltElevMax(fltElevMax)
.reqElev(area.getReqElev())
.dtl(area.getDtl())
.era(area.getEra())
.rm(area.getRm())
.reviewedType(reviewedType)
.reviewedReason(area.getReviewedReason())
.reviewedProcType(area.getReviewedProcType())
.reqRadius(area.getReqRadius())
.allowRadius(area.getAllowRadius())
.limitZoneCd(area.getLimitZone())
.limitZoneNm(limitZoneType != null ? limitZoneType.getMessage() : null)
.bufferCoordList(bufferCoordList)
.reqBufferCoordList(reqBufferCoordList)
.build();
// addResult =
areaRsList.add(areaRs);
}
// if(addResult) areaList.remove(i);
}
// TODO :: 속도이슈 걸리는 곳.. [paging 하면 완화됨]
List<BasDosPlanDroneRs> droneList = null;
List<BasDosPlanPilotRs> pilotList = null;
if (type == PlanSelectType.LIST) {
droneList = fltDroneBasMap.get(planSno);
pilotList = fltPliotBasMap.get(planSno);
}
BasDosPlanRs basRs = BasDosPlanRs.builder()
.planSno(bas.getPlanSno())
.applyNo(bas.getApplyNo())
.applyDt(applyDt)
.applyDtMonth(applyDtMonth)
.applyDtDay(applyDtDay)
.applyNm(bas.getApplyNm())
.schFltStDt(bas.getSchFltStDt())
.schFltEndDt(bas.getSchFltEndDt())
.purpose(purpose)
.updateDt(bas.getUpdateDt())
.createDt(bas.getCreateDt())
.areaList(areaRsList)
.droneList(droneList)
.pilotList(pilotList)
.build();
rs.add(basRs);
}
int count = 0;
for(int i = 0; i < rs.size(); i ++){
BasDosPlanRs rsNode = rs.get(i);
count += rsNode.getAreaList().size();
}
SearchBasDosPlanRS result = new SearchBasDosPlanRS();
result.setContent(rs);
result.setPagination(pagination);
return result;
}
/**
* List 노드객체의 컬럼중 하나를 Key값으로 잡아 Map을 만듬
* EX -> PlanBas의 planSno를 키값으로 잡아 Map<planSno, PlanBas> 형태로 변환
* @param list Map으로 바꿀 리스트
* @param fieldName Map의 key가 컬럼 이름
* @param keyType Map의 key가 클래스 타입
* @return
* @param <P>
* @param <B>
* @param <C>
*/
private <P, B extends List<C>, C> Map<P, C> getConvertMap(B list, String fieldName, Class<P> keyType) {
Map<P, C> result = new HashMap<>();
try {
for (C node : list) {
Field field = node.getClass().getDeclaredField(fieldName);
field.setAccessible(true); // private 필드 접근 허용
P key = keyType.cast(field.get(node));
result.put(key, node);
}
} catch (IllegalAccessException | NoSuchFieldException | SecurityException e) {
log.error("", e);
}
return result;
}
} }

2
pav-server/src/main/java/com/palnet/biz/jpa/repository/dos/DosFltPlanDroneRepository.java

@ -9,4 +9,6 @@ import java.util.List;
@Repository @Repository
public interface DosFltPlanDroneRepository extends JpaRepository<DosFltPlanDrone, Long> { public interface DosFltPlanDroneRepository extends JpaRepository<DosFltPlanDrone, Long> {
List<DosFltPlanDrone> findByPlanSno(Long planSno); List<DosFltPlanDrone> findByPlanSno(Long planSno);
List<DosFltPlanDrone> findByPlanSnoIn(List<Long> planSnot);
} }

2
pav-server/src/main/java/com/palnet/biz/jpa/repository/dos/DosFltPlanPilotRepository.java

@ -9,4 +9,6 @@ import java.util.List;
@Repository @Repository
public interface DosFltPlanPilotRepository extends JpaRepository<DosFltPlanPilot, Long> { public interface DosFltPlanPilotRepository extends JpaRepository<DosFltPlanPilot, Long> {
List<DosFltPlanPilot> findByPlanSno(Long planSno); List<DosFltPlanPilot> findByPlanSno(Long planSno);
List<DosFltPlanPilot> findByPlanSnoIn (List<Long> planSno);
} }

127
pav-server/src/main/java/com/palnet/biz/jpa/repository/dos/DosFltPlanQueryRepository.java

@ -1,6 +1,7 @@
package com.palnet.biz.jpa.repository.dos; package com.palnet.biz.jpa.repository.dos;
import com.palnet.biz.api.bas.dos.model.BasDosPlanRq; import com.palnet.biz.api.bas.dos.model.BasDosPlanRq;
import com.palnet.biz.api.bas.dos.model.SearchBasDosPlanRQ;
import com.palnet.biz.jpa.entity.DosFltPlanArea; import com.palnet.biz.jpa.entity.DosFltPlanArea;
import com.palnet.biz.jpa.entity.DosFltPlanBas; import com.palnet.biz.jpa.entity.DosFltPlanBas;
import com.palnet.biz.jpa.entity.QDosFltPlanArea; import com.palnet.biz.jpa.entity.QDosFltPlanArea;
@ -12,6 +13,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.util.LinkedList;
import java.util.List; import java.util.List;
@Slf4j @Slf4j
@ -105,4 +107,129 @@ public class DosFltPlanQueryRepository {
.fetch(); .fetch();
} }
public List<DosFltPlanArea> findByPlanSnoInAndSearchOrderByZoneNoAsc(List<Long> planSno, SearchBasDosPlanRQ rq) {
QDosFltPlanBas qDosFltPlanBas = QDosFltPlanBas.dosFltPlanBas;
QDosFltPlanArea qDosFltPlanArea = QDosFltPlanArea.dosFltPlanArea;
short idx = 0;
long offset = (rq.getPage() - 1) * rq.getPageDataSize();
long limit = rq.getPageDataSize();
StringBuilder districtAddr = new StringBuilder();
if (rq.getCtprvn() != null && !rq.getCtprvn().isBlank()) {
districtAddr.append(rq.getCtprvn());
idx++;
}
if (rq.getSig() != null && !rq.getSig().isBlank()) {
if (idx > 0) districtAddr.append(" ");
districtAddr.append(rq.getSig());
}
BooleanBuilder builder = new BooleanBuilder();
builder.and(qDosFltPlanArea.planSno.in(planSno));
if (!districtAddr.toString().isBlank()) {
builder.and(qDosFltPlanArea.addr.like("%" + districtAddr.toString() + "%"));
}
if (rq.getAddress() != null && !rq.getAddress().isEmpty()) {
builder.and(qDosFltPlanArea.addr.like("%" + rq.getAddress() + "%"));
}
// 검토 결과 - W일 경우 W, null 모두 조회(null == W)
if (rq.getReviewedType() != null) {
builder.and(qDosFltPlanArea.reviewedType.eq(rq.getReviewedType()).or(qDosFltPlanArea.reviewedType.isNull()));
}
return new LinkedList<>(query
.select(qDosFltPlanArea)
.from(qDosFltPlanArea)
.leftJoin(qDosFltPlanBas)
.on(qDosFltPlanBas.planSno.eq(qDosFltPlanArea.planSno))
.where(builder)
.orderBy(qDosFltPlanBas.applyDt.desc(), qDosFltPlanBas.applyNo.desc(), qDosFltPlanArea.zoneNo.asc())
.limit(limit)
.offset(offset)
.fetch());
}
public Long countByPlanSnoInAndSearchOrderByZoneNoAsc(List<Long> planSno, SearchBasDosPlanRQ rq) {
QDosFltPlanArea qDosFltPlanArea = QDosFltPlanArea.dosFltPlanArea;
short idx = 0;
StringBuilder districtAddr = new StringBuilder();
if (rq.getCtprvn() != null && !rq.getCtprvn().isBlank()) {
districtAddr.append(rq.getCtprvn());
idx++;
}
if (rq.getSig() != null && !rq.getSig().isBlank()) {
if (idx > 0) districtAddr.append(" ");
districtAddr.append(rq.getSig());
}
BooleanBuilder builder = new BooleanBuilder();
builder.and(qDosFltPlanArea.planSno.in(planSno));
if (!districtAddr.toString().isBlank()) {
builder.and(qDosFltPlanArea.addr.like("%" + districtAddr.toString() + "%"));
}
if (rq.getAddress() != null && !rq.getAddress().isEmpty()) {
builder.and(qDosFltPlanArea.addr.like("%" + rq.getAddress() + "%"));
}
// 검토 결과 - W일 경우 W, null 모두 조회(null == W)
if (rq.getReviewedType() != null) {
builder.and(qDosFltPlanArea.reviewedType.eq(rq.getReviewedType()).or(qDosFltPlanArea.reviewedType.isNull()));
}
return query
.select(qDosFltPlanArea.count())
.from(qDosFltPlanArea)
.where(builder)
.fetchOne();
}
public List<DosFltPlanBas> findPlanByBasSearch(SearchBasDosPlanRQ rq) {
QDosFltPlanBas bas = QDosFltPlanBas.dosFltPlanBas;
QDosFltPlanArea qDosFltPlanArea = QDosFltPlanArea.dosFltPlanArea;
short idx = 0;
StringBuilder districtAddr = new StringBuilder();
if (rq.getCtprvn() != null && !rq.getCtprvn().isBlank()) {
districtAddr.append(rq.getCtprvn());
idx++;
}
if (rq.getSig() != null && !rq.getSig().isBlank()) {
if (idx > 0) districtAddr.append(" ");
districtAddr.append(rq.getSig());
}
BooleanBuilder builder = new BooleanBuilder();
if (rq.getSearchStDt() != null) {
builder.and(bas.applyDt.goe(rq.getSearchStDt()));
}
if (rq.getSearchEndDt() != null) {
builder.and(bas.applyDt.loe(rq.getSearchEndDt()));
}
if (StringUtils.hasText(rq.getApplyNo())) {
builder.and(bas.applyNo.eq(rq.getApplyNo()));
}
if (!districtAddr.toString().isBlank()) {
builder.and(qDosFltPlanArea.addr.like("%" + districtAddr.toString() + "%"));
}
if (rq.getAddress() != null && !rq.getAddress().isEmpty()) {
builder.and(qDosFltPlanArea.addr.like("%" + rq.getAddress() + "%"));
}
return query.selectFrom(bas)
.leftJoin(qDosFltPlanArea)
.on(bas.planSno.eq(qDosFltPlanArea.planSno))
.where(builder)
.orderBy(bas.applyDt.desc(), bas.applyNo.desc())
.groupBy(bas.planSno)
.fetch();
}
} }

2
pav-server/src/main/java/com/palnet/comn/exception/CustomException.java

@ -70,7 +70,7 @@ public class CustomException extends RuntimeException {
// } // }
public CustomException(Throwable th, ErrorCode erorCode, String sourceErrorMessage) { public CustomException(Throwable th, ErrorCode erorCode, String sourceErrorMessage) {
this(th, Level.WARN, ErrorCode.INTERNAL_SERVER_ERROR, (Object[])null); this(th, Level.WARN, ErrorCode.INTERNAL_SERVER_ERROR,new Object[]{(Object) sourceErrorMessage});
this.sourceErrorCode = erorCode.code(); this.sourceErrorCode = erorCode.code();
this.sourceErrorMessage = errorCode.message(); this.sourceErrorMessage = errorCode.message();
} }

Loading…
Cancel
Save