@ -10,19 +10,15 @@ import com.palnet.comn.code.ErrorCode;
import com.palnet.comn.exception.CustomException ;
import com.querydsl.core.BooleanBuilder ;
import com.querydsl.core.types.Projections ;
import com.querydsl.core.types.dsl.Expressions ;
import com.querydsl.core.types.dsl.NumberTemplate ;
import com.querydsl.core.types.dsl.StringTemplate ;
import com.querydsl.core.types.dsl.* ;
import com.querydsl.jpa.impl.JPAQueryFactory ;
import lombok.RequiredArgsConstructor ;
import lombok.extern.slf4j.Slf4j ;
import org.springframework.stereotype.Repository ;
import java.time.LocalDate ;
import java.util.ArrayList ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
import java.util.* ;
import java.util.concurrent.ConcurrentHashMap ;
import java.util.stream.Collectors ;
@Repository
@ -33,58 +29,73 @@ public class DosFltPlanAreaQueryRepository {
private final JPAQueryFactory query ;
public AllStatDataRS . GroupModel allApplyData ( ) {
/ * *
* 총 데이터 조회
* @return
* /
public List < AllStatDataRS . GroupModel > allApplyTopData ( ) {
QDosFltPlanArea qDosFltPlanArea = QDosFltPlanArea . dosFltPlanArea ;
QDosFltPlanBas qDosFltPlanBas = QDosFltPlanBas . dosFltPlanBas ;
Integer year = LocalDate . now ( ) . getYear ( ) ;
Integer month = LocalDate . now ( ) . getMonth ( ) . getValue ( ) ;
NumberTemplate < Long > yearTemplate = Expressions . numberTemplate ( Long . class , "COUNT(CASE WHEN YEAR({0}) = {1} THEN 1 END)" , qDosFltPlanBas . applyDt , year ) ;
NumberTemplate < Long > monthTemplate = Expressions . numberTemplate ( Long . class , "COUNT(CASE WHEN YEAR({0}) = {1} AND MONTH({2}) = {3} THEN 1 END)" , qDosFltPlanBas . applyDt , year , qDosFltPlanBas . applyDt , month ) ;
NumberTemplate < Long > todayTemplate = Expressions . numberTemplate ( Long . class , "COUNT(CASE WHEN DATE({0}) = CURDATE() THEN 1 END)" , qDosFltPlanBas . applyDt ) ;
// TODO :: CPT_CD의 데이터가 없음으로 임시 F0002처리
StringTemplate ifTemplate = Expressions . stringTemplate ( "CASE WHEN {0} IS NULL THEN 'F0002' ELSE {0} END" , qDosFltPlanArea . cptCd ) ;
BooleanBuilder builder = new BooleanBuilder ( ) ;
builder . and ( Expressions . boolean Template( "{0} IS NOT N ULL" , qDosFltPlanArea . cptCd ) ) ;
Map < String , Long > cptCountModels = query
Map < String , AllStatDataRS . GroupModel > groupModel = query
. select (
Projections . bean (
AllStatDataRS . CptCountModel . class ,
ifTemplate . as ( "cptName" ) ,
qDosFltPlanArea . count ( ) . as ( "count" )
AllStatDataRS . GroupModel . class ,
qDosFltPlanArea . cptCd . as ( "groupName" ) ,
qDosFltPlanArea . count ( ) . as ( "all" ) ,
yearTemplate . as ( "year" ) ,
monthTemplate . as ( "month" ) ,
todayTemplate . as ( "day" )
)
)
. from ( qDosFltPlanArea )
. leftJoin ( qDosFltPlanBas )
. on ( qDosFltPlanArea . planSno . eq ( qDosFltPlanBas . planSno ) )
. where ( builder )
. groupBy ( qDosFltPlanArea . cptCd )
. fetch ( )
. stream ( )
. collect ( Collectors . toMap (
AllStatDataRS . CptCountModel : : getCptName ,
AllStatDataRS . CptCountModel : : getCount
) ) ;
key - > {
for ( Map . Entry < String , Long > entry : cptCountModels . entrySet ( ) ) {
if ( key . getGroupName ( ) = = null ) return "" ;
String [ ] cptCdArray = entry . getKey ( ) . split ( "," ) ;
if ( cptCdArray . length > 1 ) continue ;
StringBuilder result = new StringBuilder ( ) ;
for ( String cptCd : cptCdArray ) {
Long newCount = cptCountModels . get ( cptCd ) + entry . getValue ( ) ;
cptCountModels . put ( cptCd , newCount ) ;
}
}
key . getGroupName ( ) . forEach ( node - > {
result . append ( node ) ;
result . append ( "," ) ;
} ) ;
// 정렬
Long max = - 1000L ;
String cptCd = "" ;
result . deleteCharAt ( result . length ( ) - 1 ) ;
for ( Map . Entry < String , Long > entry : cptCountModels . entrySet ( ) ) {
Long value = entry . getValue ( ) ;
return result . toString ( ) ;
} ,
value - > value
) ) ;
if ( value > max ) {
max = value ;
cptCd = entry . getKey ( ) ;
}
return this . topDataParsing ( groupModel ) ;
}
/ * *
* 관제 , 비관제 데이터 조회
* @param controlFlag TRUE : 관제권 조회 , FALSE : 비 관제권 조회
* @return
* /
public List < AllStatDataRS . GroupModel > controlApplyTopData ( Boolean controlFlag ) {
QDosFltPlanArea qDosFltPlanArea = QDosFltPlanArea . dosFltPlanArea ;
QDosFltPlanBas qDosFltPlanBas = QDosFltPlanBas . dosFltPlanBas ;
Integer year = LocalDate . now ( ) . getYear ( ) ;
Integer month = LocalDate . now ( ) . getMonth ( ) . getValue ( ) ;
@ -93,13 +104,23 @@ public class DosFltPlanAreaQueryRepository {
NumberTemplate < Long > monthTemplate = Expressions . numberTemplate ( Long . class , "COUNT(CASE WHEN YEAR({0}) = {1} AND MONTH({2}) = {3} THEN 1 END)" , qDosFltPlanBas . applyDt , year , qDosFltPlanBas . applyDt , month ) ;
NumberTemplate < Long > todayTemplate = Expressions . numberTemplate ( Long . class , "COUNT(CASE WHEN DATE({0}) = CURDATE() THEN 1 END)" , qDosFltPlanBas . applyDt ) ;
ListPath < String , StringPath > groupingColumn = null ;
BooleanBuilder builder = new BooleanBuilder ( ) ;
builder . and ( qDosFltPlanArea . cptCd . contains ( cptCd ) ) ;
builder . and ( Expressions . booleanTemplate ( "{0} IS NOT NULL" , qDosFltPlanArea . cptCd ) ) ;
if ( controlFlag ) {
builder . and ( Expressions . booleanTemplate ( "{0} IS NOT NULL" , qDosFltPlanArea . innerCptCd ) ) ;
groupingColumn = qDosFltPlanArea . innerCptCd ;
} else {
builder . and ( Expressions . booleanTemplate ( "{0} IS NULL" , qDosFltPlanArea . innerCptCd ) ) ;
groupingColumn = qDosFltPlanArea . cptCd ;
}
AllStatDataRS . GroupModel groupModel = query
Map < String , AllStatDataRS . GroupModel > groupModel = query
. select (
Projections . bean (
AllStatDataRS . GroupModel . class ,
groupingColumn . as ( "groupName" ) ,
qDosFltPlanArea . count ( ) . as ( "all" ) ,
yearTemplate . as ( "year" ) ,
monthTemplate . as ( "month" ) ,
@ -109,14 +130,37 @@ public class DosFltPlanAreaQueryRepository {
. from ( qDosFltPlanArea )
. leftJoin ( qDosFltPlanBas )
. on ( qDosFltPlanArea . planSno . eq ( qDosFltPlanBas . planSno ) )
. fetchOne ( ) ;
. where ( builder )
. groupBy ( groupingColumn )
. fetch ( )
. stream ( )
. collect ( Collectors . toMap (
key - > {
if ( key . getGroupName ( ) = = null ) return "" ;
StringBuilder result = new StringBuilder ( ) ;
groupModel . setGroupName ( cptCd ) ;
key . getGroupName ( ) . forEach ( node - > {
result . append ( node ) ;
result . append ( "," ) ;
} ) ;
return groupModel ;
result . deleteCharAt ( result . length ( ) - 1 ) ;
return result . toString ( ) ;
} ,
value - > value
) ) ;
return this . topDataParsing ( groupModel ) ;
}
/ * *
* 공항별 데이터 통계
* @param rq
* @return
* /
public List < CptStatRS . CptStat > cptStatData ( CptStatRQ rq ) {
QDosFltPlanArea qDosFltPlanArea = QDosFltPlanArea . dosFltPlanArea ;
@ -131,7 +175,10 @@ public class DosFltPlanAreaQueryRepository {
String format = this . getFormat ( rq . getCategory ( ) ) ;
StringTemplate formattedDate = Expressions . stringTemplate ( "DATE_FORMAT({0},{1})" , qDosFltPlanBas . applyDt , format ) ;
String cptCd = competnetAgency . name ( ) ;
BooleanBuilder builder = new BooleanBuilder ( ) ;
builder . and ( Expressions . booleanTemplate ( "{0} LIKE CONCAT('%', {1}, '%')" , qDosFltPlanArea . cptCd , cptCd ) ) ;
if ( ! rq . getCategory ( ) . equals ( "year" ) ) {
builder . and ( qDosFltPlanBas . applyDt . goe ( rq . getStartDt ( ) ) ) ;
@ -171,12 +218,8 @@ public class DosFltPlanAreaQueryRepository {
CptStatRS . CptStat cptStatModel = new CptStatRS . CptStat ( ) ;
cptStatModel . setCptName ( competnetAgency . getDesc ( ) ) ;
cptStatModel . setCptCd ( competnetAgency . name ( ) ) ;
// TODO :: CPT_CD 나오기전 임시 코드
if ( competnetAgency . name ( ) . equals ( "F0002" ) ) {
cptStatModel . setCountModel ( countModel ) ;
cptStatModel . setCoordinateModels ( coordinateModels ) ;
}
cptStatList . add ( cptStatModel ) ;
}
@ -184,6 +227,72 @@ public class DosFltPlanAreaQueryRepository {
return cptStatList ;
}
private List < AllStatDataRS . GroupModel > topDataParsing ( Map < String , AllStatDataRS . GroupModel > groupModel ) {
Map < String , AllStatDataRS . GroupModel > currentMap = new ConcurrentHashMap < > ( groupModel ) ;
// CptCd가 한 개가 아닌 값들에 대한 로직
for ( Map . Entry < String , AllStatDataRS . GroupModel > entry : currentMap . entrySet ( ) ) {
String [ ] cptCdArray = entry . getKey ( ) . split ( "," ) ;
// CptCd가 1개일 경우 continue
if ( cptCdArray . length < = 1 ) continue ;
for ( String cptCd : cptCdArray ) {
// 기존 Map에 없는 값일 경우 CptCd를 Key로 새로 만들어 put
if ( currentMap . get ( cptCd ) = = null ) {
AllStatDataRS . GroupModel node = new AllStatDataRS . GroupModel ( ) ;
node . setGroupName ( Collections . singletonList ( cptCd ) ) ;
node . setAll ( entry . getValue ( ) . getAll ( ) ) ;
node . setYear ( entry . getValue ( ) . getYear ( ) ) ;
node . setMonth ( entry . getValue ( ) . getMonth ( ) ) ;
node . setDay ( entry . getValue ( ) . getDay ( ) ) ;
currentMap . put ( cptCd , node ) ;
continue ;
}
// 기존 값이 있을 경우 객체를 새로운 메모리에 할당하여 put
AllStatDataRS . GroupModel node = new AllStatDataRS . GroupModel ( ) ;
node . setGroupName ( Collections . singletonList ( cptCd ) ) ;
node . setAll ( currentMap . get ( cptCd ) . getAll ( ) + entry . getValue ( ) . getAll ( ) ) ;
node . setYear ( currentMap . get ( cptCd ) . getYear ( ) + entry . getValue ( ) . getYear ( ) ) ;
node . setMonth ( currentMap . get ( cptCd ) . getMonth ( ) + entry . getValue ( ) . getMonth ( ) ) ;
node . setDay ( currentMap . get ( cptCd ) . getDay ( ) + entry . getValue ( ) . getDay ( ) ) ;
currentMap . put ( cptCd , node ) ;
}
currentMap . remove ( entry . getKey ( ) ) ;
}
// Key의 맞는 GroupName Set
currentMap . forEach ( ( key , value ) - > {
value . setGroupName ( Collections . singletonList ( key ) ) ;
} ) ;
// 총 카운트가 가장많은 값 추출
Long max = currentMap . values ( ) . stream ( )
. mapToLong ( AllStatDataRS . GroupModel : : getAll )
. max ( )
. orElse ( 0 ) ;
List < AllStatDataRS . GroupModel > result = new ArrayList < > ( ) ;
// 가장 많은 값만 반환 리스트에 ADD
for ( Map . Entry < String , AllStatDataRS . GroupModel > entry : currentMap . entrySet ( ) ) {
if ( entry . getValue ( ) . getAll ( ) . equals ( max ) ) {
result . add ( entry . getValue ( ) ) ;
}
}
if ( result . isEmpty ( ) ) result . add ( new AllStatDataRS . GroupModel ( ) ) ;
return result ;
}
private String getFormat ( String category ) {
String format = null ;
@ -204,4 +313,5 @@ public class DosFltPlanAreaQueryRepository {
return format ;
}
}