62 Commits

Author SHA1 Message Date
646e7afe2e 진행률 모델 개수 4개로 수정 2026-07-16 15:11:06 +09:00
522d0d02fa G4 모델 관련 내용 추가 2026-07-14 23:03:44 +09:00
d240e4349c 영상관리 스케줄러 true로 변경, 영상삭제 시 year도 업데이트 되게 추가 2026-05-18 15:29:44 +09:00
4801ae8b7d 라벨링 툴 영문명칭 수정 추가 2026-05-15 16:41:20 +09:00
8c33439bcd 작업현황 > 작업자목록 RoleType 영문명 추가 2026-05-15 11:13:25 +09:00
ec4fb46cea 적합여부 상태명 영문 추가 2026-05-15 10:57:06 +09:00
63b3b3c09d 변화지도 년도 목록 id desc 로 수정 2026-05-15 09:58:46 +09:00
cfd5963a15 추론 삭제여부 로직 추가 2026-05-15 09:55:31 +09:00
9116bf7b89 선택 모델목록 생성완료일 desc 로 수정 2026-05-12 16:58:29 +09:00
2d7413c8e1 영문버전 변환 누락된 부분 추가 2026-05-12 11:16:19 +09:00
df7a67ed41 추론 목록,class-count, geom-list 에 한글로 나오는 코드 영문버전 로직 추가 2026-05-12 10:49:39 +09:00
176d27c229 로그인 시, 접속 IP 대역 확인 2026-05-12 09:50:26 +09:00
8c70ec345c 추론 상세 geom-list 오래 걸리는 현상 수정 2026-05-11 17:52:37 +09:00
8fd92f5691 lang check 로직 수정 2026-05-11 16:24:11 +09:00
b69d09176e lang check 2026-05-11 16:14:25 +09:00
04af23b814 영문 Enum 항목값 내릴 수 있도록 수정 Accept-Language: en 으로 추가하여 호출해야 함. 2026-05-11 15:58:03 +09:00
a1fc62b3eb 메뉴 목록, 영상관리 목록 API 영문 헤더 추가, 추론 삭제기능 추가 2026-05-11 14:15:45 +09:00
ed3c901143 메뉴 API 영문명 로직 추가 2026-05-11 10:36:45 +09:00
b58b859470 주석 추가 2026-05-11 10:08:18 +09:00
b78fda151a 영상관리 삭제 API 추가, shp 생성 기존로직으로 수정 2026-05-11 10:02:48 +09:00
435a48afb9 test 2026-05-07 12:53:01 +09:00
af0866ff5b Merge branch 'develop' of https://kamco.git.gs.dabeeo.com/MVPTeam/kamco-cd-api into develop 2026-05-06 17:46:56 +09:00
d0132ac697 local 에서도 redis 포트 수정 2026-05-06 17:46:32 +09:00
dean
4272558f32 add log 2026-04-22 09:41:23 +09:00
d83fb01cbe 학습데이터 목록 쿼리 수정 2026-04-20 16:37:22 +09:00
0425a6486d Merge pull request 'shp 테스트' (#160) from feat/infer_dev_260211 into develop
Reviewed-on: #160
2026-03-25 14:07:21 +09:00
241c7222d1 shp 테스트 2026-03-25 14:07:06 +09:00
71e4ab14bd Merge pull request 'shp 테스트' (#159) from feat/infer_dev_260211 into develop
Reviewed-on: #159
2026-03-25 14:01:26 +09:00
52da4dafc3 shp 테스트 2026-03-25 14:01:02 +09:00
24d615174d Merge pull request '토근 정보 변경' (#158) from feat/infer_dev_260211 into develop
Reviewed-on: #158
2026-03-19 13:48:56 +09:00
12b0f0867d 토근 정보 변경 2026-03-19 13:48:14 +09:00
283d906da6 Merge pull request '토큰시간 변경' (#157) from feat/infer_dev_260211 into develop
Reviewed-on: #157
2026-03-19 10:31:05 +09:00
360b451c38 토큰시간 변경 2026-03-19 10:30:42 +09:00
80e281cb99 Merge pull request '개발서버 토큰 시간 변경' (#156) from feat/infer_dev_260211 into develop
Reviewed-on: #156
2026-03-18 14:02:29 +09:00
b07bc38ee8 개발서버 토큰 시간 변경 2026-03-18 14:01:56 +09:00
e4c1c76b2b Merge pull request '재할당 transactional 추가' (#155) from feat/infer_dev_260211 into develop
Reviewed-on: #155
2026-03-17 17:47:43 +09:00
01b64eeca7 재할당 transactional 추가 2026-03-17 17:47:15 +09:00
516f949a37 Merge pull request 'spotless 적용' (#154) from feat/infer_dev_260211 into develop
Reviewed-on: #154
2026-03-17 14:00:22 +09:00
b6ed3b57ef spotless 적용 2026-03-17 14:00:04 +09:00
9eebf23774 Merge pull request 'dev 토큰 유효시간 변경, 인증 Log 추가한거 삭제' (#153) from feat/infer_dev_260211 into develop
Reviewed-on: #153
2026-03-17 13:55:53 +09:00
4f742edf8b dev 토큰 유효시간 변경, 인증 Log 추가한거 삭제 2026-03-17 13:55:30 +09:00
0aa415cf3a Merge pull request '토큰 생성 로그 추가' (#152) from feat/infer_dev_260211 into develop
Reviewed-on: #152
2026-03-17 13:33:34 +09:00
884b635585 토큰 생성 로그 추가 2026-03-17 13:33:17 +09:00
6861f6b8b6 Merge pull request '메뉴 권한 Log 추가' (#151) from feat/infer_dev_260211 into develop
Reviewed-on: #151
2026-03-17 13:22:06 +09:00
a97af0d4dd 메뉴 권한 Log 추가 2026-03-17 13:21:46 +09:00
9297d19e24 Merge pull request 'refresh 토큰 인증 로그 추가' (#150) from feat/infer_dev_260211 into develop
Reviewed-on: #150
2026-03-17 12:46:12 +09:00
65c38b3083 refresh 토큰 인증 로그 추가 2026-03-17 12:45:56 +09:00
24dca652f0 Merge pull request 'refresh 토큰 재발급 로그 추가' (#149) from feat/infer_dev_260211 into develop
Reviewed-on: #149
2026-03-17 12:26:31 +09:00
193cd449a8 refresh 토큰 재발급 로그 추가 2026-03-17 12:23:45 +09:00
dean
0efde4e5bb access-token 2026-03-17 07:49:13 +09:00
dean
548d82da12 access-token 2026-03-17 07:20:08 +09:00
536ff8fc65 추론 종료 async 수정 2026-03-13 15:52:20 +09:00
1dc1ce741e 추론 종료 비동기 호출 2026-03-13 15:38:11 +09:00
d21ed61666 hello 2026-03-12 08:22:39 +09:00
c9a1007c21 hello 2026-03-12 08:08:59 +09:00
413afb0b7c shp파일 바꾸는로직정리 2026-03-12 08:08:11 +09:00
e69eccc82b shp파일 바꾸는로직정리 2026-03-12 07:57:14 +09:00
828a4c5dca shp파일 바꾸는로직정리 2026-03-12 07:31:54 +09:00
5d417d85ff Merge pull request '국유인연동 알럿 문구 변경' (#148) from feat/infer_dev_260211 into develop
Reviewed-on: #148
2026-03-09 10:52:25 +09:00
614d6da695 국유인연동 알럿 문구 변경 2026-03-09 10:51:57 +09:00
8d45e91982 Merge pull request '국유인연동 : 라벨링 진행중 회차 uuid 추가' (#147) from feat/infer_dev_260211 into develop
Reviewed-on: #147
2026-03-09 10:10:52 +09:00
e1febf5863 국유인연동 : 라벨링 진행중 회차 uuid 추가 2026-03-09 10:10:08 +09:00
76 changed files with 1197 additions and 294 deletions

View File

@@ -37,7 +37,6 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
// JWT 토큰을 검증하고, 인증된 사용자로 SecurityContext에 등록 // JWT 토큰을 검증하고, 인증된 사용자로 SecurityContext에 등록
if (token != null && jwtTokenProvider.isValidToken(token)) { if (token != null && jwtTokenProvider.isValidToken(token)) {
String username = jwtTokenProvider.getSubject(token); String username = jwtTokenProvider.getSubject(token);
UserDetails userDetails = userDetailsService.loadUserByUsername(username); UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authentication = UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());

View File

@@ -8,11 +8,13 @@ import jakarta.annotation.PostConstruct;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Date; import java.util.Date;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** 토큰 생성 */ /** 토큰 생성 */
@Component @Component
@Log4j2
public class JwtTokenProvider { public class JwtTokenProvider {
@Value("${jwt.secret}") @Value("${jwt.secret}")
@@ -34,11 +36,13 @@ public class JwtTokenProvider {
// Access Token 생성 // Access Token 생성
public String createAccessToken(String subject) { public String createAccessToken(String subject) {
log.info("TOKEN VALIDITY = {}", accessTokenValidityInMs);
return createToken(subject, accessTokenValidityInMs); return createToken(subject, accessTokenValidityInMs);
} }
// Refresh Token 생성 // Refresh Token 생성
public String createRefreshToken(String subject) { public String createRefreshToken(String subject) {
log.info("REFRESH TOKEN VALIDITY = {}", refreshTokenValidityInMs);
return createToken(subject, refreshTokenValidityInMs); return createToken(subject, refreshTokenValidityInMs);
} }

View File

@@ -58,6 +58,7 @@ public class MenuAuthorizationManager implements AuthorizationManager<RequestAut
for (MenuEntity menu : allowedMenus) { for (MenuEntity menu : allowedMenus) {
String baseUri = menu.getMenuUrl(); String baseUri = menu.getMenuUrl();
if (baseUri == null || baseUri.isBlank()) { if (baseUri == null || baseUri.isBlank()) {
continue; continue;
} }

View File

@@ -35,6 +35,11 @@ public class ChangeDetectionDto {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return name();
}
} }
@CodeExpose @CodeExpose
@@ -55,6 +60,11 @@ public class ChangeDetectionDto {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return desc;
}
} }
@Schema(name = "TestDto", description = "테스트용") @Schema(name = "TestDto", description = "테스트용")

View File

@@ -2,6 +2,7 @@ package com.kamco.cd.kamcoback.code.dto;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
import com.kamco.cd.kamcoback.common.utils.html.HtmlEscapeDeserializer; import com.kamco.cd.kamcoback.common.utils.html.HtmlEscapeDeserializer;
import com.kamco.cd.kamcoback.common.utils.html.HtmlUnescapeSerializer; import com.kamco.cd.kamcoback.common.utils.html.HtmlUnescapeSerializer;
import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
@@ -119,10 +120,11 @@ public class CommonCodeDto {
String props2, String props2,
String props3, String props3,
ZonedDateTime deletedDttm) { ZonedDateTime deletedDttm) {
boolean english = HeaderUtil.isEnglishRequest();
this.id = id; this.id = id;
this.code = code; this.code = code;
this.description = description; this.description = description;
this.name = name; this.name = english ? code : name;
this.order = order; this.order = order;
this.used = used; this.used = used;
this.deleted = deleted; this.deleted = deleted;

View File

@@ -45,4 +45,9 @@ public enum CommonUseStatus implements EnumType {
public EnumDto<CommonUseStatus> getEnumDto() { public EnumDto<CommonUseStatus> getEnumDto() {
return new EnumDto<>(this, this.id, this.text); return new EnumDto<>(this, this.id, this.text);
} }
@Override
public String getTextEn() {
return id;
}
} }

View File

@@ -9,12 +9,13 @@ import lombok.Getter;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public enum CrsType implements EnumType { public enum CrsType implements EnumType {
EPSG_3857("Web Mercator, 웹지도 미터(EPSG:900913 동일)"), EPSG_3857("Web Mercator, 웹지도 미터(EPSG:900913 동일)", "Web Mercator"),
EPSG_4326("WGS84 위경도, GeoJSON/OSM 기본"), EPSG_4326("WGS84 위경도, GeoJSON/OSM 기본", "GeoJSON/OSM"),
EPSG_5186("5186::Korea 2000 중부 TM, 한국 SHP"), EPSG_5186("5186::Korea 2000 중부 TM, 한국 SHP", "5186::Korea 2000"),
EPSG_5179("5179::Korea 2000 중부 TM, 한국 SHP"); EPSG_5179("5179::Korea 2000 중부 TM, 한국 SHP", "5179::Korea 2000");
private final String desc; private final String desc;
private final String descEn;
@Override @Override
public String getId() { public String getId() {
@@ -25,4 +26,9 @@ public enum CrsType implements EnumType {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return descEn;
}
} }

View File

@@ -1,5 +1,6 @@
package com.kamco.cd.kamcoback.common.enums; package com.kamco.cd.kamcoback.common.enums;
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@@ -51,6 +52,6 @@ public enum DetectionClassification {
*/ */
public static String fromStrDesc(String text) { public static String fromStrDesc(String text) {
DetectionClassification dtf = fromString(text); DetectionClassification dtf = fromString(text);
return dtf.getDesc(); return HeaderUtil.isEnglishRequest() ? dtf.getId() : dtf.getDesc();
} }
} }

View File

@@ -9,13 +9,14 @@ import lombok.Getter;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public enum FileUploadStatus implements EnumType { public enum FileUploadStatus implements EnumType {
INIT("초기화"), INIT("초기화", "Init"),
UPLOADING("업로드중"), UPLOADING("업로드중", "Uploading"),
DONE("업로드완료"), DONE("업로드완료", "Upload Done"),
MERGED("병합완료"), MERGED("병합완료", "Merged Done"),
MERGE_FAIL("병합 실패"); MERGE_FAIL("병합 실패", "Merge Failed");
private final String desc; private final String desc;
private final String descEn;
@Override @Override
public String getId() { public String getId() {
@@ -26,4 +27,9 @@ public enum FileUploadStatus implements EnumType {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return descEn;
}
} }

View File

@@ -1,5 +1,6 @@
package com.kamco.cd.kamcoback.common.enums; package com.kamco.cd.kamcoback.common.enums;
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
import com.kamco.cd.kamcoback.common.utils.enums.CodeExpose; import com.kamco.cd.kamcoback.common.utils.enums.CodeExpose;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType; import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import java.util.Arrays; import java.util.Arrays;
@@ -25,6 +26,11 @@ public enum ImageryFitStatus implements EnumType {
return desc; return desc;
} }
@Override
public String getTextEn() {
return name();
}
public static ImageryFitStatus fromCode(String code) { public static ImageryFitStatus fromCode(String code) {
if (code == null) { if (code == null) {
return null; return null;
@@ -38,6 +44,8 @@ public enum ImageryFitStatus implements EnumType {
public static String getDescByCode(String code) { public static String getDescByCode(String code) {
ImageryFitStatus status = fromCode(code); ImageryFitStatus status = fromCode(code);
return status != null ? status.getDesc() : null; return status != null
? (HeaderUtil.isEnglishRequest() ? status.getTextEn() : status.getDesc())
: null;
} }
} }

View File

@@ -10,14 +10,15 @@ import lombok.Getter;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public enum LayerType implements EnumType { public enum LayerType implements EnumType {
TILE("배경지도"), TILE("배경지도", "Tile"),
GEOJSON("객체데이터"), GEOJSON("객체데이터", "GeoJSON"),
WMTS("타일레이어"), WMTS("타일레이어", "WMTS"),
WMS("지적도"), WMS("지적도", "WMS"),
KAMCO_WMS("국유인WMS"), KAMCO_WMS("국유인WMS", "KAMCO_WMS"),
KAMCO_WMTS("국유인WMTS"); KAMCO_WMTS("국유인WMTS", "KAMCO_WMTS");
private final String desc; private final String desc;
private final String descEn;
@Override @Override
public String getId() { public String getId() {
@@ -29,6 +30,11 @@ public enum LayerType implements EnumType {
return desc; return desc;
} }
@Override
public String getTextEn() {
return descEn;
}
public static Optional<LayerType> from(String type) { public static Optional<LayerType> from(String type) {
try { try {
return Optional.of(LayerType.valueOf(type)); return Optional.of(LayerType.valueOf(type));

View File

@@ -9,12 +9,13 @@ import lombok.Getter;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public enum MngStateType implements EnumType { public enum MngStateType implements EnumType {
NOTYET("동기화 시작"), NOTYET("동기화 시작", "Sync Started"),
PROCESSING("데이터 체크"), PROCESSING("데이터 체크", "Data Check"),
DONE("동기화 작업 종료"), DONE("동기화 작업 종료", "Sync Completed"),
TAKINGERROR("오류 데이터 처리중"); TAKINGERROR("오류 데이터 처리중", "Processing Error Data");
private final String desc; private final String desc;
private final String descEn;
@Override @Override
public String getId() { public String getId() {
@@ -25,4 +26,8 @@ public enum MngStateType implements EnumType {
public String getText() { public String getText() {
return desc; return desc;
} }
public String getTextEn() {
return descEn;
}
} }

View File

@@ -24,4 +24,9 @@ public enum RoleType implements EnumType {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return name();
}
} }

View File

@@ -24,4 +24,9 @@ public enum StatusType implements EnumType {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return name();
}
} }

View File

@@ -23,4 +23,9 @@ public enum SyncCheckStateType implements EnumType {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return name();
}
} }

View File

@@ -30,4 +30,9 @@ public enum SyncStateType implements EnumType {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return name();
}
} }

View File

@@ -1,23 +1,45 @@
package com.kamco.cd.kamcoback.common.service; package com.kamco.cd.kamcoback.common.service;
import com.kamco.cd.kamcoback.config.InferenceProperties;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Log4j2 @Log4j2
// 0312
@RequiredArgsConstructor
@Component @Component
public class ExternalJarRunner { public class ExternalJarRunner {
@Value("${spring.profiles.active}") @Value("${spring.profiles.active}")
private String profile; private String profile;
// 0312
private final InferenceProperties inferenceProperties;
private static final long TIMEOUT_MINUTES = TimeUnit.DAYS.toMinutes(3); private static final long TIMEOUT_MINUTES = TimeUnit.DAYS.toMinutes(3);
// java -jar build/libs/shp-exporter.jar --batch --geoserver.enabled=true
// --converter.inference-id=qq99999 --converter.batch-ids[0]=111
// 0312 shp 파일 배치를 통해 생성
public void run(String inferenceLearningId, List<Long> batchIds) {
// JAR 경로 (shape파일 생성용)
String jarPathV2 = inferenceProperties.getJarPathV2();
List<String> args = new ArrayList<>();
args.add(" --spring.profiles.active=" + profile);
args.add(" --batch");
args.add(" --geoserver.enabled=true");
args.add(" --converter.inference-id=" + inferenceLearningId);
batchIds.forEach(batchId -> args.add(" --converter.batch-ids[" + args.size() + "]=" + batchId));
execJar(jarPathV2, args);
}
/** /**
* shp 파일 생성 * shp 파일 생성
* *
@@ -74,7 +96,8 @@ public class ExternalJarRunner {
cmd.add("-jar"); cmd.add("-jar");
cmd.add(jarPath); cmd.add(jarPath);
cmd.addAll(args); cmd.addAll(args);
// 0312
log.info("exec jar command: {}", cmd);
ProcessBuilder pb = new ProcessBuilder(cmd); ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true); pb.redirectErrorStream(true);

View File

@@ -1,6 +1,9 @@
package com.kamco.cd.kamcoback.common.utils; package com.kamco.cd.kamcoback.common.utils;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
public final class HeaderUtil { public final class HeaderUtil {
@@ -20,4 +23,20 @@ public final class HeaderUtil {
public static String getRequired(HttpServletRequest request, String headerName) { public static String getRequired(HttpServletRequest request, String headerName) {
return get(request, headerName); return get(request, headerName);
} }
public static boolean isEnglishRequest() {
RequestAttributes attrs = RequestContextHolder.getRequestAttributes();
if (!(attrs instanceof ServletRequestAttributes servletAttrs)) {
return false;
}
String acceptLanguage = servletAttrs.getRequest().getHeader("Accept-Language");
if (acceptLanguage == null || acceptLanguage.isBlank()) {
return false;
}
return acceptLanguage.toLowerCase().startsWith("en");
}
} }

View File

@@ -5,4 +5,6 @@ public interface EnumType {
String getId(); String getId();
String getText(); String getText();
String getTextEn();
} }

View File

@@ -1,6 +1,7 @@
package com.kamco.cd.kamcoback.common.utils.enums; package com.kamco.cd.kamcoback.common.utils.enums;
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.CodeDto; import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.CodeDto;
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -32,11 +33,12 @@ public class Enums {
// enum -> CodeDto list // enum -> CodeDto list
public static List<CodeDto> toList(Class<? extends Enum<?>> enumClass) { public static List<CodeDto> toList(Class<? extends Enum<?>> enumClass) {
Object[] enums = enumClass.getEnumConstants(); Object[] enums = enumClass.getEnumConstants();
boolean english = HeaderUtil.isEnglishRequest();
return Arrays.stream(enums) return Arrays.stream(enums)
.map(e -> (EnumType) e) .map(e -> (EnumType) e)
.filter(e -> !isHidden(enumClass, (Enum<?>) e)) .filter(e -> !isHidden(enumClass, (Enum<?>) e))
.map(e -> new CodeDto(e.getId(), e.getText())) .map(e -> new CodeDto(e.getId(), english ? e.getTextEn() : e.getText()))
.toList(); .toList();
} }

View File

@@ -16,5 +16,7 @@ public class InferenceProperties {
private String batchUrl; private String batchUrl;
private String geojsonDir; private String geojsonDir;
private String jarPath; private String jarPath;
// 0312
private String jarPathV2;
private String inferenceServerName; private String inferenceServerName;
} }

View File

@@ -71,6 +71,10 @@ public class SecurityConfig {
.requestMatchers("/api/test/review") .requestMatchers("/api/test/review")
.hasAnyRole("ADMIN", "REVIEWER") .hasAnyRole("ADMIN", "REVIEWER")
// shapefile 생성 테스트 API - 인증 없이 접근 가능
.requestMatchers("/api/test/make-shapefile")
.permitAll()
// ASYNC/ERROR 재디스패치는 막지 않기 (다운로드/스트리밍에서 필수) // ASYNC/ERROR 재디스패치는 막지 않기 (다운로드/스트리밍에서 필수)
.dispatcherTypeMatchers(DispatcherType.ASYNC, DispatcherType.ERROR) .dispatcherTypeMatchers(DispatcherType.ASYNC, DispatcherType.ERROR)
.permitAll() .permitAll()

View File

@@ -39,10 +39,10 @@ public class ApiLogFunction {
public static String getXFowardedForIp(HttpServletRequest request) { public static String getXFowardedForIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For"); String ip = request.getHeader("X-Forwarded-For");
if (ip != null) { if (ip != null && !ip.isBlank()) {
ip = ip.split(",")[0].trim(); return ip.split(",")[0].trim();
} }
return ip; return request.getRemoteAddr();
} }
// 사용자 ID 추출 예시 (Spring Security 기준) // 사용자 ID 추출 예시 (Spring Security 기준)

View File

@@ -3,6 +3,7 @@ package com.kamco.cd.kamcoback.config.api;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType; import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import java.util.Arrays;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.ToString; import lombok.ToString;
@@ -192,6 +193,11 @@ public class ApiResponseDto<T> {
return message; return message;
} }
@Override
public String getTextEn() {
return message;
}
public static ApiResponseCode getCode(String name) { public static ApiResponseCode getCode(String name) {
return ApiResponseCode.valueOf(name.toUpperCase()); return ApiResponseCode.valueOf(name.toUpperCase());
} }
@@ -220,5 +226,12 @@ public class ApiResponseDto<T> {
return INTERNAL_SERVER_ERROR; return INTERNAL_SERVER_ERROR;
} }
public static ApiResponseCode fromMessage(String message) {
return Arrays.stream(values())
.filter(code -> code.getMessage().equals(message))
.findFirst()
.orElse(null);
}
} }
} }

View File

@@ -14,9 +14,9 @@ public class GukYuinDto {
public enum GukYuinLinkFailCode implements EnumType { public enum GukYuinLinkFailCode implements EnumType {
OK("연동 가능"), OK("연동 가능"),
NOT_FOUND("대상 회차가 없습니다."), NOT_FOUND("대상 회차가 없습니다."),
SCOPE_PART_NOT_ALLOWED("부분 도엽은 연동 불가능 합니다."), SCOPE_PART_NOT_ALLOWED("부분 도엽 추론 결과는 연동 할 수 없습니다."),
HAS_RUNNING_INFERENCE("라벨링 진행 중 회차가 있습니다."), HAS_RUNNING_INFERENCE("라벨링 진행중 회차가 있습니다.\n진행중인 라벨링 작업을 종료하신 후 다시 연동해주세요."),
OTHER_GUKYUIN_IN_PROGRESS("국유in 연동 진행 중 회차가 있습니다."); OTHER_GUKYUIN_IN_PROGRESS("국유in 연동 진행중입니다. 선행 연동 작업이 종료된 후 진행할 수 있습니다.");
private final String desc; private final String desc;
@@ -29,6 +29,11 @@ public class GukYuinDto {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return desc;
}
} }
@Getter @Getter
@@ -36,8 +41,9 @@ public class GukYuinDto {
public static class GukYuinLinkableRes { public static class GukYuinLinkableRes {
private boolean linkable; private boolean linkable;
// private GukYuinLinkFailCode code; private GukYuinLinkFailCode code;
private String message; private String message;
private UUID inferenceUuid;
} }
// Repository가 반환할 Fact(조회 결과) // Repository가 반환할 Fact(조회 결과)
@@ -45,7 +51,8 @@ public class GukYuinDto {
boolean existsLearn, boolean existsLearn,
boolean isPartScope, boolean isPartScope,
boolean hasRunningInference, boolean hasRunningInference,
boolean hasOtherUnfinishedGukYuin) {} boolean hasOtherUnfinishedGukYuin,
UUID inferenceUuid) {}
@Getter @Getter
@Setter @Setter

View File

@@ -26,4 +26,9 @@ public enum GukYuinStatus implements EnumType {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return desc;
}
} }

View File

@@ -237,9 +237,12 @@ public class GukYuinApiService {
GukYuinLinkFailCode code = decideCode(f); GukYuinLinkFailCode code = decideCode(f);
GukYuinLinkableRes res = new GukYuinLinkableRes(); GukYuinLinkableRes res = new GukYuinLinkableRes();
// res.setCode(code); res.setCode(code);
res.setLinkable(code == GukYuinLinkFailCode.OK); res.setLinkable(code == GukYuinLinkFailCode.OK);
res.setMessage(code.getDesc()); res.setMessage(code.getDesc());
if (code == GukYuinLinkFailCode.HAS_RUNNING_INFERENCE) {
res.setInferenceUuid(f.inferenceUuid());
}
return res; return res;
} }

View File

@@ -8,6 +8,7 @@ import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceServerStatusDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceServerStatusDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceStatusDetailDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceStatusDetailDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.ResultList; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.ResultList;
import com.kamco.cd.kamcoback.inference.service.InferenceAsyncService;
import com.kamco.cd.kamcoback.inference.service.InferenceResultService; import com.kamco.cd.kamcoback.inference.service.InferenceResultService;
import com.kamco.cd.kamcoback.log.dto.AuditLogDto; import com.kamco.cd.kamcoback.log.dto.AuditLogDto;
import com.kamco.cd.kamcoback.log.dto.AuditLogDto.DownloadReq; import com.kamco.cd.kamcoback.log.dto.AuditLogDto.DownloadReq;
@@ -55,6 +56,7 @@ import org.springframework.web.bind.annotation.RestController;
public class InferenceResultApiController { public class InferenceResultApiController {
private final InferenceResultService inferenceResultService; private final InferenceResultService inferenceResultService;
private final InferenceAsyncService inferenceAsyncService;
private final MapSheetMngService mapSheetMngService; private final MapSheetMngService mapSheetMngService;
private final ModelMngService modelMngService; private final ModelMngService modelMngService;
private final RangeDownloadResponder rangeDownloadResponder; private final RangeDownloadResponder rangeDownloadResponder;
@@ -176,7 +178,8 @@ public class InferenceResultApiController {
}) })
@DeleteMapping("/end") @DeleteMapping("/end")
public ApiResponseDto<UUID> getInferenceGeomList() { public ApiResponseDto<UUID> getInferenceGeomList() {
UUID uuid = inferenceResultService.deleteInferenceEnd(); // UUID uuid = inferenceResultService.deleteInferenceEnd();
UUID uuid = inferenceAsyncService.asyncInferenceEnd();
return ApiResponseDto.ok(uuid); return ApiResponseDto.ok(uuid);
} }
@@ -445,4 +448,22 @@ public class InferenceResultApiController {
UUID uuid) { UUID uuid) {
return ApiResponseDto.ok(inferenceResultService.getInferenceRunMapId(uuid)); return ApiResponseDto.ok(inferenceResultService.getInferenceRunMapId(uuid));
} }
@Operation(summary = "추론 삭제", description = "추론관리 > 추론목록 > 추론 상세 > 추론 삭제")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "종료 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Page.class))),
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@DeleteMapping("/delete-inference/{uuid}")
public ApiResponseDto<ApiResponseDto.ResponseObj> deleteInference(@PathVariable UUID uuid) {
return ApiResponseDto.ok(inferenceResultService.deleteInference(uuid));
}
} }

View File

@@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.kamco.cd.kamcoback.common.enums.DetectionClassification; import com.kamco.cd.kamcoback.common.enums.DetectionClassification;
import com.kamco.cd.kamcoback.common.enums.ImageryFitStatus; import com.kamco.cd.kamcoback.common.enums.ImageryFitStatus;
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.DetectOption; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.DetectOption;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.MapSheetScope; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.MapSheetScope;
@@ -156,9 +157,14 @@ public class InferenceDetailDto {
String classAfterName; String classAfterName;
Long classAfterCnt; Long classAfterCnt;
boolean english = HeaderUtil.isEnglishRequest();
public Dashboard(String classAfterCd, Long classAfterCnt) { public Dashboard(String classAfterCd, Long classAfterCnt) {
this.classAfterCd = classAfterCd; this.classAfterCd = classAfterCd;
this.classAfterName = DetectionClassification.fromString(classAfterCd).getDesc(); this.classAfterName =
english
? DetectionClassification.fromString(classAfterCd).getId()
: DetectionClassification.fromString(classAfterCd).getDesc();
this.classAfterCnt = classAfterCnt; this.classAfterCnt = classAfterCnt;
} }
} }
@@ -294,8 +300,10 @@ public class InferenceDetailDto {
} }
@Getter @Getter
@Setter
public static class Geom { public static class Geom {
Long geoUid;
UUID uuid; UUID uuid;
String uid; String uid;
Integer compareYyyy; Integer compareYyyy;
@@ -313,7 +321,10 @@ public class InferenceDetailDto {
String pnu; String pnu;
String fitState; String fitState;
boolean english = HeaderUtil.isEnglishRequest();
public Geom( public Geom(
Long geoUid,
UUID uuid, UUID uuid,
String uid, String uid,
Integer compareYyyy, Integer compareYyyy,
@@ -328,16 +339,23 @@ public class InferenceDetailDto {
String subUid, String subUid,
String pnu, String pnu,
String fitState) { String fitState) {
this.geoUid = geoUid;
this.uuid = uuid; this.uuid = uuid;
this.uid = uid; this.uid = uid;
this.compareYyyy = compareYyyy; this.compareYyyy = compareYyyy;
this.targetYyyy = targetYyyy; this.targetYyyy = targetYyyy;
this.cdProb = cdProb; this.cdProb = cdProb;
this.classBeforeCd = classBeforeCd; this.classBeforeCd = classBeforeCd;
this.classBeforeName = DetectionClassification.fromString(classBeforeCd).getDesc(); this.classBeforeName =
english
? DetectionClassification.fromString(classBeforeCd).getId()
: DetectionClassification.fromString(classBeforeCd).getDesc();
this.classBeforeProb = classBeforeProb; this.classBeforeProb = classBeforeProb;
this.classAfterCd = classAfterCd; this.classAfterCd = classAfterCd;
this.classAfterName = DetectionClassification.fromString(classAfterCd).getDesc(); this.classAfterName =
english
? DetectionClassification.fromString(classAfterCd).getId()
: DetectionClassification.fromString(classAfterCd).getDesc();
this.classAfterProb = classAfterProb; this.classAfterProb = classAfterProb;
this.mapSheetNum = mapSheetNum; this.mapSheetNum = mapSheetNum;
this.mapSheetName = mapSheetName; this.mapSheetName = mapSheetName;
@@ -424,11 +442,13 @@ public class InferenceDetailDto {
private Long m1BatchId; private Long m1BatchId;
private Long m2BatchId; private Long m2BatchId;
private Long m3BatchId; private Long m3BatchId;
private Long m4BatchId;
private String status; private String status;
private String runningModelType; private String runningModelType;
private UUID m1ModelUuid; private UUID m1ModelUuid;
private UUID m2ModelUuid; private UUID m2ModelUuid;
private UUID m3ModelUuid; private UUID m3ModelUuid;
private UUID m4ModelUuid;
private String uid; private String uid;
} }
@@ -443,6 +463,7 @@ public class InferenceDetailDto {
private String modelVer1; private String modelVer1;
private String modelVer2; private String modelVer2;
private String modelVer3; private String modelVer3;
private String modelVer4;
private Integer compareYyyy; private Integer compareYyyy;
private Integer targetYyyy; private Integer targetYyyy;
private String detectOption; private String detectOption;
@@ -465,6 +486,7 @@ public class InferenceDetailDto {
String modelVer1, String modelVer1,
String modelVer2, String modelVer2,
String modelVer3, String modelVer3,
String modelVer4,
Integer compareYyyy, Integer compareYyyy,
Integer targetYyyy, Integer targetYyyy,
String detectOption, String detectOption,
@@ -481,6 +503,7 @@ public class InferenceDetailDto {
this.modelVer1 = modelVer1; this.modelVer1 = modelVer1;
this.modelVer2 = modelVer2; this.modelVer2 = modelVer2;
this.modelVer3 = modelVer3; this.modelVer3 = modelVer3;
this.modelVer4 = modelVer4;
this.compareYyyy = compareYyyy; this.compareYyyy = compareYyyy;
this.targetYyyy = targetYyyy; this.targetYyyy = targetYyyy;
this.detectOption = DetectOption.getDescByCode(detectOption); this.detectOption = DetectOption.getDescByCode(detectOption);

View File

@@ -2,6 +2,7 @@ package com.kamco.cd.kamcoback.inference.dto;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType; import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import com.kamco.cd.kamcoback.common.utils.interfaces.EnumValid; import com.kamco.cd.kamcoback.common.utils.interfaces.EnumValid;
import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
@@ -14,6 +15,8 @@ import java.time.ZonedDateTime;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@@ -51,6 +54,11 @@ public class InferenceResultDto {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return desc;
}
} }
/** 탐지 데이터 옵션 dto */ /** 탐지 데이터 옵션 dto */
@@ -79,6 +87,11 @@ public class InferenceResultDto {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return desc;
}
} }
@Getter @Getter
@@ -87,6 +100,7 @@ public class InferenceResultDto {
READY("대기"), READY("대기"),
IN_PROGRESS("진행중"), IN_PROGRESS("진행중"),
END("완료"), END("완료"),
END_FAIL("종료실패"),
FORCED_END("강제종료"); FORCED_END("강제종료");
private final String desc; private final String desc;
@@ -95,7 +109,12 @@ public class InferenceResultDto {
} }
public static String getDescByCode(String code) { public static String getDescByCode(String code) {
return fromCode(code).getDesc(); boolean english = HeaderUtil.isEnglishRequest();
if (english) {
return fromCode(code).getTextEn();
} else {
return fromCode(code).getDesc();
}
} }
@Override @Override
@@ -107,6 +126,11 @@ public class InferenceResultDto {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return name();
}
} }
@Getter @Getter
@@ -128,6 +152,11 @@ public class InferenceResultDto {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return desc;
}
} }
/** 목록조회 dto */ /** 목록조회 dto */
@@ -210,7 +239,46 @@ public class InferenceResultDto {
long m = (s % 3600) / 60; long m = (s % 3600) / 60;
long sec = s % 60; long sec = s % 60;
return String.format("%d시간 %d분 %d초", h, m, sec); boolean english = HeaderUtil.isEnglishRequest();
if (english) {
return String.format("%dh %dm %ds", h, m, sec);
} else {
return String.format("%d시간 %d분 %d초", h, m, sec);
}
}
@JsonProperty("mapSheetCnt")
public String getMapSheetCnt() {
boolean english = HeaderUtil.isEnglishRequest();
String text = this.mapSheetCnt;
if (!english) {
return text;
}
// "창원 외 34건"
Pattern otherPattern = Pattern.compile("^(.+) 외 (\\d+)건$");
Matcher otherMatcher = otherPattern.matcher(text);
if (otherMatcher.find()) {
String name = otherMatcher.group(1);
int count = Integer.parseInt(otherMatcher.group(2));
return name + " and " + count + (count == 1 ? " other" : " others");
}
// "창원 1건"
Pattern itemPattern = Pattern.compile("^(.+) (\\d+)건$");
Matcher itemMatcher = itemPattern.matcher(text);
if (itemMatcher.find()) {
String name = itemMatcher.group(1);
int count = Integer.parseInt(itemMatcher.group(2));
return name + " (" + count + (count == 1 ? " item" : " items") + ")";
}
return text;
} }
} }
@@ -260,6 +328,10 @@ public class InferenceResultDto {
@NotNull @NotNull
private UUID model3Uuid; private UUID model3Uuid;
@Schema(description = "G4", example = "58c1153e-dec6-4424-82a1-189083a9d9dc")
@NotNull
private UUID model4Uuid;
@Schema(description = "비교년도", example = "2023") @Schema(description = "비교년도", example = "2023")
@NotNull @NotNull
private Integer compareYyyy; private Integer compareYyyy;
@@ -310,6 +382,10 @@ public class InferenceResultDto {
@JsonFormatDttm @JsonFormatDttm
ZonedDateTime m3ModelStartDttm; ZonedDateTime m3ModelStartDttm;
@Schema(description = "모델4 사용시간 시작일시")
@JsonFormatDttm
ZonedDateTime m4ModelStartDttm;
@Schema(description = "모델1 사용시간 종료일시") @Schema(description = "모델1 사용시간 종료일시")
@JsonFormatDttm @JsonFormatDttm
ZonedDateTime m1ModelEndDttm; ZonedDateTime m1ModelEndDttm;
@@ -322,6 +398,10 @@ public class InferenceResultDto {
@JsonFormatDttm @JsonFormatDttm
ZonedDateTime m3ModelEndDttm; ZonedDateTime m3ModelEndDttm;
@Schema(description = "모델4 사용시간 종료일시")
@JsonFormatDttm
ZonedDateTime m4ModelEndDttm;
@Schema(description = "탐지대상 도엽수") @Schema(description = "탐지대상 도엽수")
private Long detectingCnt; private Long detectingCnt;
@@ -334,6 +414,9 @@ public class InferenceResultDto {
@Schema(description = "모델3 분석 대기") @Schema(description = "모델3 분석 대기")
private Integer m3PendingJobs; private Integer m3PendingJobs;
@Schema(description = "모델4 분석 대기")
private Integer m4PendingJobs;
@Schema(description = "모델1 분석 진행중") @Schema(description = "모델1 분석 진행중")
private Integer m1RunningJobs; private Integer m1RunningJobs;
@@ -343,6 +426,9 @@ public class InferenceResultDto {
@Schema(description = "모델3 분석 진행중") @Schema(description = "모델3 분석 진행중")
private Integer m3RunningJobs; private Integer m3RunningJobs;
@Schema(description = "모델4 분석 진행중")
private Integer m4RunningJobs;
@Schema(description = "모델1 분석 완료") @Schema(description = "모델1 분석 완료")
private Integer m1CompletedJobs; private Integer m1CompletedJobs;
@@ -352,6 +438,9 @@ public class InferenceResultDto {
@Schema(description = "모델3 분석 완료") @Schema(description = "모델3 분석 완료")
private Integer m3CompletedJobs; private Integer m3CompletedJobs;
@Schema(description = "모델4 분석 완료")
private Integer m4CompletedJobs;
@Schema(description = "모델1 분석 실패") @Schema(description = "모델1 분석 실패")
private Integer m1FailedJobs; private Integer m1FailedJobs;
@@ -361,6 +450,9 @@ public class InferenceResultDto {
@Schema(description = "모델3 분석 실패") @Schema(description = "모델3 분석 실패")
private Integer m3FailedJobs; private Integer m3FailedJobs;
@Schema(description = "모델4 분석 실패")
private Integer m4FailedJobs;
@Schema(description = "변화탐지 제목") @Schema(description = "변화탐지 제목")
private String title; private String title;
@@ -396,6 +488,9 @@ public class InferenceResultDto {
@Schema(description = "모델3 버전") @Schema(description = "모델3 버전")
private String modelVer3; private String modelVer3;
@Schema(description = "모델4 버전")
private String modelVer4;
@Schema(description = "탑지 도엽 수") @Schema(description = "탑지 도엽 수")
@JsonIgnore @JsonIgnore
private Long totalJobs; private Long totalJobs;
@@ -405,21 +500,27 @@ public class InferenceResultDto {
Integer m1PendingJobs, Integer m1PendingJobs,
Integer m2PendingJobs, Integer m2PendingJobs,
Integer m3PendingJobs, Integer m3PendingJobs,
Integer m4PendingJobs,
Integer m1RunningJobs, Integer m1RunningJobs,
Integer m2RunningJobs, Integer m2RunningJobs,
Integer m3RunningJobs, Integer m3RunningJobs,
Integer m4RunningJobs,
Integer m1CompletedJobs, Integer m1CompletedJobs,
Integer m2CompletedJobs, Integer m2CompletedJobs,
Integer m3CompletedJobs, Integer m3CompletedJobs,
Integer m4CompletedJobs,
Integer m1FailedJobs, Integer m1FailedJobs,
Integer m2FailedJobs, Integer m2FailedJobs,
Integer m3FailedJobs, Integer m3FailedJobs,
Integer m4FailedJobs,
ZonedDateTime m1ModelStartDttm, ZonedDateTime m1ModelStartDttm,
ZonedDateTime m2ModelStartDttm, ZonedDateTime m2ModelStartDttm,
ZonedDateTime m3ModelStartDttm, ZonedDateTime m3ModelStartDttm,
ZonedDateTime m4ModelStartDttm,
ZonedDateTime m1ModelEndDttm, ZonedDateTime m1ModelEndDttm,
ZonedDateTime m2ModelEndDttm, ZonedDateTime m2ModelEndDttm,
ZonedDateTime m3ModelEndDttm, ZonedDateTime m3ModelEndDttm,
ZonedDateTime m4ModelEndDttm,
String title, String title,
Integer compareYyyy, Integer compareYyyy,
Integer targetYyyy, Integer targetYyyy,
@@ -431,26 +532,33 @@ public class InferenceResultDto {
String modelVer1, String modelVer1,
String modelVer2, String modelVer2,
String modelVer3, String modelVer3,
String modelVer4,
Long totalJobs) { Long totalJobs) {
this.detectingCnt = detectingCnt; this.detectingCnt = detectingCnt;
this.m1PendingJobs = m1PendingJobs; this.m1PendingJobs = m1PendingJobs;
this.m2PendingJobs = m2PendingJobs; this.m2PendingJobs = m2PendingJobs;
this.m3PendingJobs = m3PendingJobs; this.m3PendingJobs = m3PendingJobs;
this.m4PendingJobs = m4PendingJobs;
this.m1RunningJobs = m1RunningJobs; this.m1RunningJobs = m1RunningJobs;
this.m2RunningJobs = m2RunningJobs; this.m2RunningJobs = m2RunningJobs;
this.m3RunningJobs = m3RunningJobs; this.m3RunningJobs = m3RunningJobs;
this.m4RunningJobs = m4RunningJobs;
this.m1CompletedJobs = m1CompletedJobs; this.m1CompletedJobs = m1CompletedJobs;
this.m2CompletedJobs = m2CompletedJobs; this.m2CompletedJobs = m2CompletedJobs;
this.m3CompletedJobs = m3CompletedJobs; this.m3CompletedJobs = m3CompletedJobs;
this.m4CompletedJobs = m4CompletedJobs;
this.m1FailedJobs = m1FailedJobs; this.m1FailedJobs = m1FailedJobs;
this.m2FailedJobs = m2FailedJobs; this.m2FailedJobs = m2FailedJobs;
this.m3FailedJobs = m3FailedJobs; this.m3FailedJobs = m3FailedJobs;
this.m4FailedJobs = m4FailedJobs;
this.m1ModelStartDttm = m1ModelStartDttm; this.m1ModelStartDttm = m1ModelStartDttm;
this.m2ModelStartDttm = m2ModelStartDttm; this.m2ModelStartDttm = m2ModelStartDttm;
this.m3ModelStartDttm = m3ModelStartDttm; this.m3ModelStartDttm = m3ModelStartDttm;
this.m4ModelStartDttm = m4ModelStartDttm;
this.m1ModelEndDttm = m1ModelEndDttm; this.m1ModelEndDttm = m1ModelEndDttm;
this.m2ModelEndDttm = m2ModelEndDttm; this.m2ModelEndDttm = m2ModelEndDttm;
this.m3ModelEndDttm = m3ModelEndDttm; this.m3ModelEndDttm = m3ModelEndDttm;
this.m4ModelEndDttm = m4ModelEndDttm;
this.title = title; this.title = title;
this.compareYyyy = compareYyyy; this.compareYyyy = compareYyyy;
this.targetYyyy = targetYyyy; this.targetYyyy = targetYyyy;
@@ -462,6 +570,7 @@ public class InferenceResultDto {
this.modelVer1 = modelVer1; this.modelVer1 = modelVer1;
this.modelVer2 = modelVer2; this.modelVer2 = modelVer2;
this.modelVer3 = modelVer3; this.modelVer3 = modelVer3;
this.modelVer4 = modelVer4;
this.totalJobs = totalJobs; this.totalJobs = totalJobs;
} }
@@ -469,14 +578,16 @@ public class InferenceResultDto {
@JsonProperty("progress") @JsonProperty("progress")
private int getProgress() { private int getProgress() {
long tiles = this.totalJobs == null ? 0L : this.totalJobs; // 도엽수 long tiles = this.totalJobs == null ? 0L : this.totalJobs; // 도엽수
int models = 3; // 모델 개수 int models = 4; // 모델 개수
int completed = int completed =
this.m1CompletedJobs this.m1CompletedJobs
+ this.m2CompletedJobs + this.m2CompletedJobs
+ this.m3CompletedJobs + this.m3CompletedJobs
+ this.m4CompletedJobs
+ this.m1FailedJobs + this.m1FailedJobs
+ this.m2FailedJobs + this.m2FailedJobs
+ this.m3FailedJobs; // 완료수 + this.m3FailedJobs
+ this.m4FailedJobs; // 완료수
long total = tiles * models; // 전체 작업량 long total = tiles * models; // 전체 작업량
if (completed >= total) { if (completed >= total) {
@@ -515,6 +626,12 @@ public class InferenceResultDto {
return formatElapsedTime(this.m3ModelStartDttm, this.m3ModelEndDttm); return formatElapsedTime(this.m3ModelStartDttm, this.m3ModelEndDttm);
} }
@Schema(description = "G4 사용시간")
@JsonProperty("m4ElapsedTim")
public String getM4ElapsedTime() {
return formatElapsedTime(this.m4ModelStartDttm, this.m4ModelEndDttm);
}
private String formatElapsedTime(ZonedDateTime start, ZonedDateTime end) { private String formatElapsedTime(ZonedDateTime start, ZonedDateTime end) {
if (start == null || end == null) { if (start == null || end == null) {
return null; return null;
@@ -683,6 +800,7 @@ public class InferenceResultDto {
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class MapSheetFallbackYearDto { public static class MapSheetFallbackYearDto {
private String mapSheetNum; private String mapSheetNum;
private Integer mngYyyy; private Integer mngYyyy;
} }

View File

@@ -0,0 +1,117 @@
package com.kamco.cd.kamcoback.inference.service;
import com.kamco.cd.kamcoback.common.exception.CustomApiException;
import com.kamco.cd.kamcoback.common.inference.service.InferenceCommonService;
import com.kamco.cd.kamcoback.common.utils.UserUtil;
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient;
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient.ExternalCallResult;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.SaveInferenceAiDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Status;
import com.kamco.cd.kamcoback.postgres.core.AuditLogCoreService;
import com.kamco.cd.kamcoback.postgres.core.InferenceResultCoreService;
import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService;
import com.kamco.cd.kamcoback.postgres.core.ModelMngCoreService;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/** 추론 관리 */
@Service
@Slf4j
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class InferenceAsyncService {
private final InferenceResultCoreService inferenceResultCoreService;
private final MapSheetMngCoreService mapSheetMngCoreService;
private final ModelMngCoreService modelMngCoreService;
private final AuditLogCoreService auditLogCoreService;
private final InferenceCommonService inferenceCommonService;
private final ExternalHttpClient externalHttpClient;
private final UserUtil userUtil;
@Value("${inference.batch-url}")
private String batchUrl;
@Value("${inference.inference-server-name}")
private String inferenceServerName;
@Value("${file.dataset-dir}")
private String datasetDir;
@Value("${spring.profiles.active}")
private String activeEnv;
@Value("${inference.geojson-dir}")
private String inferenceDir;
// 0313
@Transactional
public UUID asyncInferenceEnd() {
SaveInferenceAiDto dto = inferenceResultCoreService.getProcessing();
if (dto == null) {
throw new CustomApiException("NOT_FOUND", HttpStatus.NOT_FOUND);
}
this.deleteInferenceEndAsync(dto); // 비동기 종료 호출
return dto.getUuid();
}
// 0313
@Async("inferenceEndExecutor")
@Transactional
public void deleteInferenceEndAsync(SaveInferenceAiDto dto) {
Long batchId = dto.getBatchId();
String url = batchUrl + "/" + batchId;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
try {
log.info("[추론 종료 비동기 시작] uuid={}, batchId={}", dto.getUuid(), batchId);
ExternalCallResult<String> result =
externalHttpClient.callLong(url, HttpMethod.DELETE, dto, headers, String.class);
if (!result.success()) {
log.error("[추론 종료 실패] 외부 API 호출 실패. uuid={}, batchId={}", dto.getUuid(), batchId);
SaveInferenceAiDto failRequest = new SaveInferenceAiDto();
failRequest.setUuid(dto.getUuid());
failRequest.setStatus(Status.END_FAIL.getId()); // TODO: 종료실패 상태 추가하는 게 맞는지?
failRequest.setUpdateUid(userUtil.getId());
failRequest.setInferEndDttm(ZonedDateTime.now());
inferenceResultCoreService.update(failRequest);
return;
}
SaveInferenceAiDto request = new SaveInferenceAiDto();
request.setStatus(Status.FORCED_END.getId());
request.setUuid(dto.getUuid());
request.setUpdateUid(userUtil.getId());
request.setInferEndDttm(ZonedDateTime.now());
inferenceResultCoreService.update(request);
Long learnId = inferenceResultCoreService.getInferenceLearnIdByUuid(dto.getUuid());
inferenceResultCoreService.upsertGeomData(learnId);
log.info("[추론 종료 비동기 완료] uuid={}, batchId={}", dto.getUuid(), batchId);
} catch (Exception e) {
log.error("[추론 종료 비동기 예외] uuid={}, batchId={}", dto.getUuid(), batchId, e);
}
}
}

View File

@@ -7,24 +7,13 @@ import com.kamco.cd.kamcoback.common.geometry.GeoJsonFileWriter.Scene;
import com.kamco.cd.kamcoback.common.inference.service.InferenceCommonService; import com.kamco.cd.kamcoback.common.inference.service.InferenceCommonService;
import com.kamco.cd.kamcoback.common.inference.utils.GeoJsonValidator; import com.kamco.cd.kamcoback.common.inference.utils.GeoJsonValidator;
import com.kamco.cd.kamcoback.common.utils.UserUtil; import com.kamco.cd.kamcoback.common.utils.UserUtil;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient; import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient;
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient.ExternalCallResult; import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient.ExternalCallResult;
import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.AnalResultInfo; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.*;
import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Dashboard;
import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Detail;
import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Geom;
import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.MapSheet;
import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.SearchGeoReq;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.DetectOption; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.*;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceLearnDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceServerStatusDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceStatusDetailDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.MapSheetScope;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.ResultList;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.SaveInferenceAiDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Status;
import com.kamco.cd.kamcoback.inference.dto.InferenceSendDto; import com.kamco.cd.kamcoback.inference.dto.InferenceSendDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceSendDto.pred_requests_areas; import com.kamco.cd.kamcoback.inference.dto.InferenceSendDto.pred_requests_areas;
import com.kamco.cd.kamcoback.log.dto.AuditLogDto; import com.kamco.cd.kamcoback.log.dto.AuditLogDto;
@@ -44,16 +33,7 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.ArrayList; import java.util.*;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -70,7 +50,7 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@Transactional(readOnly = true) @Transactional
public class InferenceResultService { public class InferenceResultService {
private final InferenceResultCoreService inferenceResultCoreService; private final InferenceResultCoreService inferenceResultCoreService;
@@ -636,8 +616,10 @@ public class InferenceResultService {
modelType = ModelType.G1.getId(); modelType = ModelType.G1.getId();
} else if (modelInfo.getModelType().equals(ModelType.G2.getId())) { } else if (modelInfo.getModelType().equals(ModelType.G2.getId())) {
modelType = ModelType.G2.getId(); modelType = ModelType.G2.getId();
} else { } else if (modelInfo.getModelType().equals(ModelType.G3.getId())) {
modelType = ModelType.G3.getId(); modelType = ModelType.G3.getId();
} else {
modelType = ModelType.G4.getId();
} }
InferenceSendDto sendDto = new InferenceSendDto(); InferenceSendDto sendDto = new InferenceSendDto();
@@ -1033,4 +1015,14 @@ public class InferenceResultService {
} }
return ""; return "";
} }
public ApiResponseDto.ResponseObj deleteInference(UUID uuid) {
long result = inferenceResultCoreService.deleteInference(uuid);
if (result > 0) {
return new ApiResponseDto.ResponseObj(ApiResponseDto.ApiResponseCode.OK, "삭제되었습니다.");
} else {
return new ApiResponseDto.ResponseObj(
ApiResponseDto.ApiResponseCode.INTERNAL_SERVER_ERROR, "삭제 실패하였습니다. 관리자에게 문의해주세요.");
}
}
} }

View File

@@ -37,6 +37,11 @@ public class LabelAllocateDto {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return name();
}
} }
@CodeExpose @CodeExpose
@@ -59,6 +64,11 @@ public class LabelAllocateDto {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return name();
}
} }
@CodeExpose @CodeExpose
@@ -80,6 +90,11 @@ public class LabelAllocateDto {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return name();
}
} }
@Getter @Getter

View File

@@ -1,6 +1,8 @@
package com.kamco.cd.kamcoback.label.dto; package com.kamco.cd.kamcoback.label.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.kamco.cd.kamcoback.common.enums.RoleType;
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
import com.kamco.cd.kamcoback.common.utils.enums.Enums; import com.kamco.cd.kamcoback.common.utils.enums.Enums;
import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelMngState; import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelMngState;
@@ -34,6 +36,7 @@ public class LabelWorkDto {
@AllArgsConstructor @AllArgsConstructor
public static class LabelWorkMng { public static class LabelWorkMng {
private Long analUid;
private UUID uuid; private UUID uuid;
private Integer compareYyyy; private Integer compareYyyy;
private Integer targetYyyy; private Integer targetYyyy;
@@ -108,7 +111,13 @@ public class LabelWorkDto {
if (type == null) { if (type == null) {
return enumId; return enumId;
} }
return type.getText();
boolean english = HeaderUtil.isEnglishRequest();
if (!english) {
return type.getText();
}
return type.getTextEn();
} }
/** /**
@@ -222,10 +231,8 @@ public class LabelWorkDto {
} }
public String getUserRoleName() { public String getUserRoleName() {
if (this.userRole.equals("LABELER")) { RoleType type = Enums.fromId(RoleType.class, this.userRole);
return "라벨러"; return HeaderUtil.isEnglishRequest() ? type.getTextEn() : type.getText();
}
return "검수자";
} }
} }
@@ -260,4 +267,18 @@ public class LabelWorkDto {
return PageRequest.of(page, size); return PageRequest.of(page, size);
} }
} }
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public static class LabelCntInfo {
private Long assignedCnt;
private Long skipCnt;
private Long doneCnt;
private Long unconfirmCnt;
private Long exceptCnt;
private Long completeCnt;
}
} }

View File

@@ -157,6 +157,7 @@ public class LabelAllocateService {
return labelAllocateCoreService.findInferenceDetail(uuid); return labelAllocateCoreService.findInferenceDetail(uuid);
} }
@Transactional
public ApiResponseDto.ResponseObj allocateMove( public ApiResponseDto.ResponseObj allocateMove(
Integer totalCnt, String uuid, List<String> targetUsers, String userId) { Integer totalCnt, String uuid, List<String> targetUsers, String userId) {

View File

@@ -1,7 +1,10 @@
package com.kamco.cd.kamcoback.log.dto; package com.kamco.cd.kamcoback.log.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
import com.kamco.cd.kamcoback.common.utils.enums.CodeExpose; import com.kamco.cd.kamcoback.common.utils.enums.CodeExpose;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType; import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDate; import java.time.LocalDate;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@@ -36,6 +39,11 @@ public class ErrorLogDto {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return desc;
}
} }
@Schema(name = "ErrorLogBasic", description = "에러로그 기본 정보") @Schema(name = "ErrorLogBasic", description = "에러로그 기본 정보")
@@ -56,6 +64,26 @@ public class ErrorLogDto {
private final String errorMessage; private final String errorMessage;
private final String errorDetail; private final String errorDetail;
private final String createDate; // to_char해서 가져옴 private final String createDate; // to_char해서 가져옴
@JsonProperty("errorMessage")
public String getErrorMessage() {
boolean english = HeaderUtil.isEnglishRequest();
if (!english) {
return this.errorMessage;
}
return ApiResponseDto.ApiResponseCode.fromMessage(this.errorMessage).toString();
}
@JsonProperty("errorName")
public String getErrorName() {
boolean english = HeaderUtil.isEnglishRequest();
if (!english) {
return this.errorName;
}
return ApiResponseDto.ApiResponseCode.fromMessage(this.errorName).toString();
}
} }
@Schema(name = "ErrorSearchReq", description = "에러로그 검색 요청") @Schema(name = "ErrorSearchReq", description = "에러로그 검색 요청")

View File

@@ -21,4 +21,9 @@ public enum EventStatus implements EnumType {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return desc;
}
} }

View File

@@ -39,4 +39,9 @@ public enum EventType implements EnumType {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return name();
}
} }

View File

@@ -22,14 +22,7 @@ import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@Tag(name = "영상 관리", description = "영상 관리 API") @Tag(name = "영상 관리", description = "영상 관리 API")
@@ -256,4 +249,11 @@ public class MapSheetMngApiController {
return ApiResponseDto.ok( return ApiResponseDto.ok(
mapSheetMngService.uploadChunkMapSheetFile(hstUid, upAddReqDto, chunkFile)); mapSheetMngService.uploadChunkMapSheetFile(hstUid, upAddReqDto, chunkFile));
} }
@Operation(summary = "영상데이터관리 > 등록된 년도 데이터 전체 삭제", description = "영상데이터관리 > 등록된 년도 데이터 전체 삭제")
@DeleteMapping
public ApiResponseDto<Void> deleteByMngYyyyMngAll(@RequestParam Integer mngYyyy) {
mapSheetMngService.deleteByMngYyyyMngAll(mngYyyy);
return ApiResponseDto.ok(null);
}
} }

View File

@@ -3,6 +3,7 @@ package com.kamco.cd.kamcoback.mapsheet.dto;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.kamco.cd.kamcoback.common.enums.MngStateType; import com.kamco.cd.kamcoback.common.enums.MngStateType;
import com.kamco.cd.kamcoback.common.enums.SyncStateType; import com.kamco.cd.kamcoback.common.enums.SyncStateType;
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType; import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import com.kamco.cd.kamcoback.common.utils.enums.Enums; import com.kamco.cd.kamcoback.common.utils.enums.Enums;
import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
@@ -41,6 +42,11 @@ public class MapSheetMngDto {
public String getText() { public String getText() {
return message; return message;
} }
@Override
public String getTextEn() {
return message;
}
} }
@Schema(name = "MngSearchReq", description = "영상관리 검색 요청") @Schema(name = "MngSearchReq", description = "영상관리 검색 요청")
@@ -217,7 +223,11 @@ public class MapSheetMngDto {
enumId = "NOTYET"; enumId = "NOTYET";
} }
boolean english = HeaderUtil.isEnglishRequest();
MngStateType type = Enums.fromId(MngStateType.class, enumId); MngStateType type = Enums.fromId(MngStateType.class, enumId);
if (english) {
return type.getTextEn();
}
return type.getText(); return type.getText();
} }
} }
@@ -341,6 +351,10 @@ public class MapSheetMngDto {
} }
SyncStateType type = Enums.fromId(SyncStateType.class, enumId); SyncStateType type = Enums.fromId(SyncStateType.class, enumId);
boolean english = HeaderUtil.isEnglishRequest();
if (english) {
return type.getTextEn();
}
return type.getText(); return type.getText();
} }
} }

View File

@@ -40,7 +40,7 @@ import org.springframework.web.multipart.MultipartFile;
@Slf4j @Slf4j
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@Transactional(readOnly = true) @Transactional
public class MapSheetMngService { public class MapSheetMngService {
private final MapSheetMngCoreService mapSheetMngCoreService; private final MapSheetMngCoreService mapSheetMngCoreService;
@@ -489,4 +489,8 @@ public class MapSheetMngService {
return modelUploadResDto; return modelUploadResDto;
} }
public void deleteByMngYyyyMngAll(Integer mngYyyy) {
mapSheetMngCoreService.deleteByMngYyyyMngAll(mngYyyy);
}
} }

View File

@@ -4,6 +4,7 @@ import com.kamco.cd.kamcoback.auth.CustomUserDetails;
import com.kamco.cd.kamcoback.auth.JwtTokenProvider; import com.kamco.cd.kamcoback.auth.JwtTokenProvider;
import com.kamco.cd.kamcoback.auth.RefreshTokenService; import com.kamco.cd.kamcoback.auth.RefreshTokenService;
import com.kamco.cd.kamcoback.common.enums.StatusType; import com.kamco.cd.kamcoback.common.enums.StatusType;
import com.kamco.cd.kamcoback.config.api.ApiLogFunction;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto; import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.members.dto.MembersDto; import com.kamco.cd.kamcoback.members.dto.MembersDto;
import com.kamco.cd.kamcoback.members.dto.SignInRequest; import com.kamco.cd.kamcoback.members.dto.SignInRequest;
@@ -16,11 +17,13 @@ import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.nio.file.AccessDeniedException; import java.nio.file.AccessDeniedException;
import java.time.Duration; import java.time.Duration;
import java.util.UUID; import java.util.UUID;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseCookie; import org.springframework.http.ResponseCookie;
@@ -34,6 +37,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@Slf4j
@Tag(name = "인증(Auth)", description = "로그인, 토큰 재발급, 로그아웃 API") @Tag(name = "인증(Auth)", description = "로그인, 토큰 재발급, 로그아웃 API")
@RestController @RestController
@RequestMapping("/api/auth") @RequestMapping("/api/auth")
@@ -103,8 +107,13 @@ public class AuthController {
required = true) required = true)
@RequestBody @RequestBody
SignInRequest request, SignInRequest request,
HttpServletRequest servletRequest,
HttpServletResponse response) { HttpServletResponse response) {
// TODO: 접속 가능한 IP 대역 조회
String clientIp = ApiLogFunction.getXFowardedForIp(servletRequest);
log.info("####### clientIp: {}", clientIp);
// 사용자 상태 조회 // 사용자 상태 조회
String status = authService.getUserStatus(request); String status = authService.getUserStatus(request);
Authentication authentication = null; Authentication authentication = null;
@@ -169,6 +178,7 @@ public class AuthController {
if (refreshToken == null || !jwtTokenProvider.isValidToken(refreshToken)) { if (refreshToken == null || !jwtTokenProvider.isValidToken(refreshToken)) {
throw new AccessDeniedException("만료되었거나 유효하지 않은 리프레시 토큰 입니다."); throw new AccessDeniedException("만료되었거나 유효하지 않은 리프레시 토큰 입니다.");
} }
String username = jwtTokenProvider.getSubject(refreshToken); String username = jwtTokenProvider.getSubject(refreshToken);
// Redis에 저장된 RefreshToken과 일치하는지 확인 // Redis에 저장된 RefreshToken과 일치하는지 확인

View File

@@ -3,6 +3,7 @@ package com.kamco.cd.kamcoback.members.dto;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.kamco.cd.kamcoback.common.enums.RoleType; import com.kamco.cd.kamcoback.common.enums.RoleType;
import com.kamco.cd.kamcoback.common.enums.StatusType; import com.kamco.cd.kamcoback.common.enums.StatusType;
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
import com.kamco.cd.kamcoback.common.utils.enums.Enums; import com.kamco.cd.kamcoback.common.utils.enums.Enums;
import com.kamco.cd.kamcoback.common.utils.interfaces.EnumValid; import com.kamco.cd.kamcoback.common.utils.interfaces.EnumValid;
import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
@@ -65,16 +66,18 @@ public class MembersDto {
private String getUserRoleName(String roleId) { private String getUserRoleName(String roleId) {
RoleType type = Enums.fromId(RoleType.class, roleId); RoleType type = Enums.fromId(RoleType.class, roleId);
return type.getText(); boolean english = HeaderUtil.isEnglishRequest();
return english ? type.getTextEn() : type.getText();
} }
private String getStatusName(String status, Boolean pwdResetYn) { private String getStatusName(String status, Boolean pwdResetYn) {
StatusType type = Enums.fromId(StatusType.class, status); StatusType type = Enums.fromId(StatusType.class, status);
boolean english = HeaderUtil.isEnglishRequest();
pwdResetYn = pwdResetYn != null && pwdResetYn; pwdResetYn = pwdResetYn != null && pwdResetYn;
if (type.equals(StatusType.PENDING) && pwdResetYn) { if (type.equals(StatusType.PENDING) && pwdResetYn) {
type = StatusType.ACTIVE; type = StatusType.ACTIVE;
} }
return type.getText(); return english ? type.getTextEn() : type.getText();
} }
} }

View File

@@ -31,7 +31,7 @@ public class MenuDto {
@JsonFormatDttm private ZonedDateTime updatedDttm; @JsonFormatDttm private ZonedDateTime updatedDttm;
private String menuApiUrl; private String menuNmEn;
public Basic( public Basic(
String menuUid, String menuUid,
@@ -45,7 +45,8 @@ public class MenuDto {
Long updatedUid, Long updatedUid,
List<MenuDto.Basic> children, List<MenuDto.Basic> children,
ZonedDateTime createdDttm, ZonedDateTime createdDttm,
ZonedDateTime updatedDttm) { ZonedDateTime updatedDttm,
String menuNmEn) {
this.menuUid = menuUid; this.menuUid = menuUid;
this.menuNm = menuNm; this.menuNm = menuNm;
this.menuUrl = menuUrl; this.menuUrl = menuUrl;
@@ -58,6 +59,7 @@ public class MenuDto {
this.children = children; this.children = children;
this.createdDttm = createdDttm; this.createdDttm = createdDttm;
this.updatedDttm = updatedDttm; this.updatedDttm = updatedDttm;
this.menuNmEn = menuNmEn;
} }
} }

View File

@@ -23,7 +23,8 @@ public class ModelMngDto {
public enum ModelType implements EnumType { public enum ModelType implements EnumType {
G1("G1"), G1("G1"),
G2("G2"), G2("G2"),
G3("G3"); G3("G3"),
G4("G4");
private final String desc; private final String desc;
@@ -36,6 +37,11 @@ public class ModelMngDto {
public String getText() { public String getText() {
return desc; return desc;
} }
@Override
public String getTextEn() {
return desc;
}
} }
@Schema(name = "ModelMgmtDto Basic", description = "모델관리 엔티티 기본 정보") @Schema(name = "ModelMgmtDto Basic", description = "모델관리 엔티티 기본 정보")

View File

@@ -47,7 +47,7 @@ public class ModelMngService {
* @param searchReq 페이징 * @param searchReq 페이징
* @param startDate 시작날짜 * @param startDate 시작날짜
* @param endDate 종료날짜 * @param endDate 종료날짜
* @param modelType 모델 타입 G1, G2, G3 * @param modelType 모델 타입 G1, G2, G3, G4
* @param searchVal 모델 ver * @param searchVal 모델 ver
* @return 모델 목록 * @return 모델 목록
*/ */

View File

@@ -117,6 +117,7 @@ public class InferenceResultCoreService {
mapSheetLearnEntity.setM1ModelUuid(req.getModel1Uuid()); mapSheetLearnEntity.setM1ModelUuid(req.getModel1Uuid());
mapSheetLearnEntity.setM2ModelUuid(req.getModel2Uuid()); mapSheetLearnEntity.setM2ModelUuid(req.getModel2Uuid());
mapSheetLearnEntity.setM3ModelUuid(req.getModel3Uuid()); mapSheetLearnEntity.setM3ModelUuid(req.getModel3Uuid());
mapSheetLearnEntity.setM4ModelUuid(req.getModel4Uuid());
mapSheetLearnEntity.setCompareYyyy(req.getCompareYyyy()); mapSheetLearnEntity.setCompareYyyy(req.getCompareYyyy());
mapSheetLearnEntity.setTargetYyyy(req.getTargetYyyy()); mapSheetLearnEntity.setTargetYyyy(req.getTargetYyyy());
mapSheetLearnEntity.setMapSheetScope(req.getMapSheetScope()); mapSheetLearnEntity.setMapSheetScope(req.getMapSheetScope());
@@ -279,7 +280,10 @@ public class InferenceResultCoreService {
List<Long> batchIds = List<Long> batchIds =
Stream.of( Stream.of(
entity.getM1ModelBatchId(), entity.getM2ModelBatchId(), entity.getM3ModelBatchId()) entity.getM1ModelBatchId(),
entity.getM2ModelBatchId(),
entity.getM3ModelBatchId(),
entity.getM4ModelBatchId())
.filter(Objects::nonNull) .filter(Objects::nonNull)
.distinct() // 중복 방지 (선택) .distinct() // 중복 방지 (선택)
.toList(); .toList();
@@ -333,6 +337,16 @@ public class InferenceResultCoreService {
entity::setM3RunningJobs, entity::setM3RunningJobs,
entity::setM3CompletedJobs, entity::setM3CompletedJobs,
entity::setM3FailedJobs); entity::setM3FailedJobs);
case "G4" ->
applyModelFields(
request,
entity::setM4ModelBatchId,
entity::setM4ModelStartDttm,
entity::setM4ModelEndDttm,
entity::setM4PendingJobs,
entity::setM4RunningJobs,
entity::setM4CompletedJobs,
entity::setM4FailedJobs);
default -> throw new IllegalArgumentException("Unknown type: " + request.getType()); default -> throw new IllegalArgumentException("Unknown type: " + request.getType());
} }
} }
@@ -390,11 +404,13 @@ public class InferenceResultCoreService {
inferenceBatchSheet.setM1BatchId(entity.getM1ModelBatchId()); inferenceBatchSheet.setM1BatchId(entity.getM1ModelBatchId());
inferenceBatchSheet.setM2BatchId(entity.getM2ModelBatchId()); inferenceBatchSheet.setM2BatchId(entity.getM2ModelBatchId());
inferenceBatchSheet.setM3BatchId(entity.getM3ModelBatchId()); inferenceBatchSheet.setM3BatchId(entity.getM3ModelBatchId());
inferenceBatchSheet.setM4BatchId(entity.getM4ModelBatchId());
inferenceBatchSheet.setStatus(entity.getStatus()); inferenceBatchSheet.setStatus(entity.getStatus());
inferenceBatchSheet.setRunningModelType(entity.getRunningModelType()); inferenceBatchSheet.setRunningModelType(entity.getRunningModelType());
inferenceBatchSheet.setM1ModelUuid(entity.getM1ModelUuid()); inferenceBatchSheet.setM1ModelUuid(entity.getM1ModelUuid());
inferenceBatchSheet.setM2ModelUuid(entity.getM2ModelUuid()); inferenceBatchSheet.setM2ModelUuid(entity.getM2ModelUuid());
inferenceBatchSheet.setM3ModelUuid(entity.getM3ModelUuid()); inferenceBatchSheet.setM3ModelUuid(entity.getM3ModelUuid());
inferenceBatchSheet.setM4ModelUuid(entity.getM4ModelUuid());
inferenceBatchSheet.setUid(entity.getUid()); inferenceBatchSheet.setUid(entity.getUid());
return inferenceBatchSheet; return inferenceBatchSheet;
} }
@@ -435,6 +451,9 @@ public class InferenceResultCoreService {
SaveInferenceAiDto dto = new SaveInferenceAiDto(); SaveInferenceAiDto dto = new SaveInferenceAiDto();
dto.setUuid(entity.getUuid()); dto.setUuid(entity.getUuid());
if (entity.getM4ModelBatchId() != null) {
dto.setBatchId(entity.getM4ModelBatchId());
}
if (entity.getM3ModelBatchId() != null) { if (entity.getM3ModelBatchId() != null) {
dto.setBatchId(entity.getM3ModelBatchId()); dto.setBatchId(entity.getM3ModelBatchId());
} }
@@ -626,4 +645,8 @@ public class InferenceResultCoreService {
public List<InferenceResultsTestingDto.Basic> getInferenceResultGroupList(List<Long> batchIds) { public List<InferenceResultsTestingDto.Basic> getInferenceResultGroupList(List<Long> batchIds) {
return inferenceResultsTestingRepository.getInferenceResultGroupList(batchIds); return inferenceResultsTestingRepository.getInferenceResultGroupList(batchIds);
} }
public long deleteInference(UUID uuid) {
return inferenceResultRepository.deleteInference(uuid);
}
} }

View File

@@ -379,4 +379,8 @@ public class MapSheetMngCoreService {
return result; return result;
} }
public void deleteByMngYyyyMngAll(Integer mngYyyy) {
mapSheetMngRepository.deleteByMngYyyyMngAll(mngYyyy);
}
} }

View File

@@ -1,5 +1,6 @@
package com.kamco.cd.kamcoback.postgres.core; package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
import com.kamco.cd.kamcoback.menu.dto.MenuDto; import com.kamco.cd.kamcoback.menu.dto.MenuDto;
import com.kamco.cd.kamcoback.menu.dto.MyMenuDto; import com.kamco.cd.kamcoback.menu.dto.MyMenuDto;
import com.kamco.cd.kamcoback.postgres.entity.MenuEntity; import com.kamco.cd.kamcoback.postgres.entity.MenuEntity;
@@ -7,8 +8,10 @@ import com.kamco.cd.kamcoback.postgres.repository.menu.MenuRepository;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Slf4j
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class MenuCoreService { public class MenuCoreService {
@@ -27,6 +30,8 @@ public class MenuCoreService {
*/ */
public List<MyMenuDto.Basic> getFindByRole(String role) { public List<MyMenuDto.Basic> getFindByRole(String role) {
List<MenuEntity> entities = menuRepository.getFindByRole(role); List<MenuEntity> entities = menuRepository.getFindByRole(role);
boolean english = HeaderUtil.isEnglishRequest();
log.info("[LANG CHECK] english={}", english);
return entities.stream() return entities.stream()
.map( .map(
@@ -34,7 +39,7 @@ public class MenuCoreService {
MyMenuDto.Basic p = MyMenuDto.Basic p =
new MyMenuDto.Basic( new MyMenuDto.Basic(
parent.getMenuUid(), parent.getMenuUid(),
parent.getMenuNm(), english ? parent.getMenuNmEn() : parent.getMenuNm(),
parent.getMenuUrl(), parent.getMenuUrl(),
parent.getMenuOrder()); parent.getMenuOrder());
@@ -48,7 +53,10 @@ public class MenuCoreService {
.map( .map(
c -> c ->
new MyMenuDto.Basic( new MyMenuDto.Basic(
c.getMenuUid(), c.getMenuNm(), c.getMenuUrl(), c.getMenuOrder())) c.getMenuUid(),
english ? c.getMenuNmEn() : c.getMenuNm(),
c.getMenuUrl(),
c.getMenuOrder()))
.forEach(childDto -> p.getChildren().add(childDto)); .forEach(childDto -> p.getChildren().add(childDto));
return p; return p;

View File

@@ -136,6 +136,10 @@ public class MapSheetAnalInferenceEntity {
@Column(name = "model_m3_ver", length = 50) @Column(name = "model_m3_ver", length = 50)
private String modelM3Ver; private String modelM3Ver;
@Size(max = 50)
@Column(name = "model_m4_ver", length = 50)
private String modelM4Ver;
@Size(max = 20) @Size(max = 20)
@Column(name = "anal_target_type", length = 20) @Column(name = "anal_target_type", length = 20)
private String analTargetType; private String analTargetType;

View File

@@ -64,6 +64,9 @@ public class MapSheetLearn5kEntity {
@Column(name = "is_m3_fail") @Column(name = "is_m3_fail")
private Boolean isM3Fail = false; private Boolean isM3Fail = false;
@Column(name = "is_m4_fail")
private Boolean isM4Fail = false;
@Column(name = "m1_error_message", columnDefinition = "text") @Column(name = "m1_error_message", columnDefinition = "text")
private String m1ErrorMessage; private String m1ErrorMessage;
@@ -73,6 +76,9 @@ public class MapSheetLearn5kEntity {
@Column(name = "m3_error_message", columnDefinition = "text") @Column(name = "m3_error_message", columnDefinition = "text")
private String m3ErrorMessage; private String m3ErrorMessage;
@Column(name = "m4_error_message", columnDefinition = "text")
private String m4ErrorMessage;
@Column(name = "m1_job_id") @Column(name = "m1_job_id")
private Long m1JobId; private Long m1JobId;
@@ -81,4 +87,7 @@ public class MapSheetLearn5kEntity {
@Column(name = "m3_job_id") @Column(name = "m3_job_id")
private Long m3JobId; private Long m3JobId;
@Column(name = "m4_job_id")
private Long m4JobId;
} }

View File

@@ -54,6 +54,9 @@ public class MapSheetLearnEntity {
@Column(name = "m3_model_uuid") @Column(name = "m3_model_uuid")
private UUID m3ModelUuid; private UUID m3ModelUuid;
@Column(name = "m4_model_uuid")
private UUID m4ModelUuid;
@Column(name = "compare_yyyy") @Column(name = "compare_yyyy")
private Integer compareYyyy; private Integer compareYyyy;
@@ -187,6 +190,29 @@ public class MapSheetLearnEntity {
@Column(name = "m3_failed_jobs", nullable = false) @Column(name = "m3_failed_jobs", nullable = false)
private int m3FailedJobs = 0; private int m3FailedJobs = 0;
/* ===================== M4 ===================== */
@Column(name = "m4_model_batch_id")
private Long m4ModelBatchId;
@Column(name = "m4_model_start_dttm")
private ZonedDateTime m4ModelStartDttm;
@Column(name = "m4_model_end_dttm")
private ZonedDateTime m4ModelEndDttm;
@Column(name = "m4_pending_jobs", nullable = false)
private int m4PendingJobs = 0;
@Column(name = "m4_running_jobs", nullable = false)
private int m4RunningJobs = 0;
@Column(name = "m4_completed_jobs", nullable = false)
private int m4CompletedJobs = 0;
@Column(name = "m4_failed_jobs", nullable = false)
private int m4FailedJobs = 0;
@Column(name = "apply_status") @Column(name = "apply_status")
private String applyStatus = GukYuinStatus.PENDING.getId(); private String applyStatus = GukYuinStatus.PENDING.getId();
@@ -229,6 +255,9 @@ public class MapSheetLearnEntity {
@Column(name = "shp_error_message") @Column(name = "shp_error_message")
private String shp_error_message; private String shp_error_message;
@Column(name = "is_deleted")
private Boolean isDeleted;
public InferenceResultDto.ResultList toDto() { public InferenceResultDto.ResultList toDto() {
return new InferenceResultDto.ResultList( return new InferenceResultDto.ResultList(
this.uuid, this.uuid,

View File

@@ -58,6 +58,9 @@ public class MenuEntity extends CommonDateEntity {
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL) @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<MenuEntity> children = new ArrayList<>(); private List<MenuEntity> children = new ArrayList<>();
@Column(name = "menu_nm_en")
private String menuNmEn; // 영문 메뉴명
public MenuDto.Basic toDto() { public MenuDto.Basic toDto() {
return new MenuDto.Basic( return new MenuDto.Basic(
this.menuUid, this.menuUid,
@@ -71,6 +74,7 @@ public class MenuEntity extends CommonDateEntity {
this.updatedUid, this.updatedUid,
this.children.stream().map(MenuEntity::toDto).toList(), this.children.stream().map(MenuEntity::toDto).toList(),
this.getCreatedDate(), this.getCreatedDate(),
this.getModifiedDate()); this.getModifiedDate(),
this.menuNmEn);
} }
} }

View File

@@ -62,4 +62,11 @@ public interface InferenceResultRepositoryCustom {
* @return * @return
*/ */
Optional<MapSheetAnalInferenceEntity> getAnalInferenceDataByLearnId(Long id); Optional<MapSheetAnalInferenceEntity> getAnalInferenceDataByLearnId(Long id);
/**
* 추론 삭제
*
* @param uuid
*/
long deleteInference(UUID uuid);
} }

View File

@@ -38,6 +38,7 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
m1_model_batch_id, m1_model_batch_id,
m2_model_batch_id, m2_model_batch_id,
m3_model_batch_id, m3_model_batch_id,
m4_model_batch_id,
learn_id, learn_id,
anal_state anal_state
) )
@@ -51,6 +52,7 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
r.m1_model_batch_id, r.m1_model_batch_id,
r.m2_model_batch_id, r.m2_model_batch_id,
r.m3_model_batch_id, r.m3_model_batch_id,
r.m4_model_batch_id,
r.id, r.id,
:pendingStateId :pendingStateId
FROM tb_map_sheet_learn r FROM tb_map_sheet_learn r
@@ -111,7 +113,8 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
ON r.batch_id IN ( ON r.batch_id IN (
msl.m1_model_batch_id, msl.m1_model_batch_id,
msl.m2_model_batch_id, msl.m2_model_batch_id,
msl.m3_model_batch_id msl.m3_model_batch_id,
msl.m4_model_batch_id
) )
WHERE msl.anal_uid = :analId WHERE msl.anal_uid = :analId
group by msl.anal_uid, group by msl.anal_uid,
@@ -207,7 +210,8 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
ON r.batch_id IN ( ON r.batch_id IN (
msl.m1_model_batch_id, msl.m1_model_batch_id,
msl.m2_model_batch_id, msl.m2_model_batch_id,
msl.m3_model_batch_id msl.m3_model_batch_id,
msl.m4_model_batch_id
) )
INNER JOIN tb_map_sheet_anal_data_inference msadi INNER JOIN tb_map_sheet_anal_data_inference msadi
ON msadi.anal_uid = msl.anal_uid ON msadi.anal_uid = msl.anal_uid
@@ -346,4 +350,13 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
.where(mapSheetAnalInferenceEntity.learnId.eq(id)) .where(mapSheetAnalInferenceEntity.learnId.eq(id))
.fetchOne()); .fetchOne());
} }
@Override
public long deleteInference(UUID uuid) {
return queryFactory
.update(mapSheetLearnEntity)
.set(mapSheetLearnEntity.isDeleted, true)
.where(mapSheetLearnEntity.uuid.eq(uuid))
.execute();
}
} }

View File

@@ -50,6 +50,11 @@ public class MapSheetLearn5kRepositoryImpl implements MapSheetLearn5kRepositoryC
jobIdPath = mapSheetLearn5kEntity.m3JobId; jobIdPath = mapSheetLearn5kEntity.m3JobId;
errorMsgPath = mapSheetLearn5kEntity.m3ErrorMessage; errorMsgPath = mapSheetLearn5kEntity.m3ErrorMessage;
} }
case "G4" -> {
failPath = mapSheetLearn5kEntity.isM4Fail;
jobIdPath = mapSheetLearn5kEntity.m4JobId;
errorMsgPath = mapSheetLearn5kEntity.m4ErrorMessage;
}
default -> { default -> {
return; return;
} }
@@ -97,6 +102,10 @@ public class MapSheetLearn5kRepositoryImpl implements MapSheetLearn5kRepositoryC
failPath = mapSheetLearn5kEntity.isM3Fail; failPath = mapSheetLearn5kEntity.isM3Fail;
jobIdPath = mapSheetLearn5kEntity.m3JobId; jobIdPath = mapSheetLearn5kEntity.m3JobId;
} }
case "G4" -> {
failPath = mapSheetLearn5kEntity.isM4Fail;
jobIdPath = mapSheetLearn5kEntity.m4JobId;
}
default -> { default -> {
return; return;
} }
@@ -147,6 +156,10 @@ public class MapSheetLearn5kRepositoryImpl implements MapSheetLearn5kRepositoryC
jobIdPath = mapSheetLearn5kEntity.m3JobId; jobIdPath = mapSheetLearn5kEntity.m3JobId;
failPath = mapSheetLearn5kEntity.isM3Fail; failPath = mapSheetLearn5kEntity.isM3Fail;
} }
case "G4" -> {
jobIdPath = mapSheetLearn5kEntity.m4JobId;
failPath = mapSheetLearn5kEntity.isM4Fail;
}
default -> { default -> {
return List.of(); return List.of();
} }
@@ -189,6 +202,9 @@ public class MapSheetLearn5kRepositoryImpl implements MapSheetLearn5kRepositoryC
case "G3" -> { case "G3" -> {
jobIdPath = mapSheetLearn5kEntity.m3JobId; jobIdPath = mapSheetLearn5kEntity.m3JobId;
} }
case "G4" -> {
jobIdPath = mapSheetLearn5kEntity.m4JobId;
}
default -> { default -> {
return List.of(); return List.of();
} }

View File

@@ -30,6 +30,7 @@ import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalInferenceEntity;
import com.kamco.cd.kamcoback.postgres.entity.QMapSheetLearnEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapSheetLearnEntity;
import com.kamco.cd.kamcoback.postgres.entity.QModelMngEntity; import com.kamco.cd.kamcoback.postgres.entity.QModelMngEntity;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Expression; import com.querydsl.core.types.Expression;
import com.querydsl.core.types.Projections; import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
@@ -37,13 +38,10 @@ import com.querydsl.core.types.dsl.CaseBuilder;
import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.core.types.dsl.NumberExpression;
import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.util.List; import java.util.*;
import java.util.Objects; import java.util.stream.Collectors;
import java.util.Optional;
import java.util.UUID;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@@ -90,6 +88,9 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
builder.and(mapSheetLearnEntity.title.containsIgnoreCase(req.getTitle())); builder.and(mapSheetLearnEntity.title.containsIgnoreCase(req.getTitle()));
} }
// 삭제여부 값 추가
builder.and(mapSheetLearnEntity.isDeleted.eq(false).or(mapSheetLearnEntity.isDeleted.isNull()));
List<MapSheetLearnEntity> content = List<MapSheetLearnEntity> content =
queryFactory queryFactory
.select(mapSheetLearnEntity) .select(mapSheetLearnEntity)
@@ -195,6 +196,7 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
QModelMngEntity m1Model = new QModelMngEntity("m1Model"); QModelMngEntity m1Model = new QModelMngEntity("m1Model");
QModelMngEntity m2Model = new QModelMngEntity("m2Model"); QModelMngEntity m2Model = new QModelMngEntity("m2Model");
QModelMngEntity m3Model = new QModelMngEntity("m3Model"); QModelMngEntity m3Model = new QModelMngEntity("m3Model");
QModelMngEntity m4Model = new QModelMngEntity("m4Model");
InferenceStatusDetailDto foundContent = InferenceStatusDetailDto foundContent =
queryFactory queryFactory
@@ -205,21 +207,27 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
mapSheetLearnEntity.m1PendingJobs, mapSheetLearnEntity.m1PendingJobs,
mapSheetLearnEntity.m2PendingJobs, mapSheetLearnEntity.m2PendingJobs,
mapSheetLearnEntity.m3PendingJobs, mapSheetLearnEntity.m3PendingJobs,
mapSheetLearnEntity.m4PendingJobs,
mapSheetLearnEntity.m1RunningJobs, mapSheetLearnEntity.m1RunningJobs,
mapSheetLearnEntity.m2RunningJobs, mapSheetLearnEntity.m2RunningJobs,
mapSheetLearnEntity.m3RunningJobs, mapSheetLearnEntity.m3RunningJobs,
mapSheetLearnEntity.m4RunningJobs,
mapSheetLearnEntity.m1CompletedJobs, mapSheetLearnEntity.m1CompletedJobs,
mapSheetLearnEntity.m2CompletedJobs, mapSheetLearnEntity.m2CompletedJobs,
mapSheetLearnEntity.m3CompletedJobs, mapSheetLearnEntity.m3CompletedJobs,
mapSheetLearnEntity.m4CompletedJobs,
mapSheetLearnEntity.m1FailedJobs, mapSheetLearnEntity.m1FailedJobs,
mapSheetLearnEntity.m2FailedJobs, mapSheetLearnEntity.m2FailedJobs,
mapSheetLearnEntity.m3FailedJobs, mapSheetLearnEntity.m3FailedJobs,
mapSheetLearnEntity.m4FailedJobs,
mapSheetLearnEntity.m1ModelStartDttm, mapSheetLearnEntity.m1ModelStartDttm,
mapSheetLearnEntity.m2ModelStartDttm, mapSheetLearnEntity.m2ModelStartDttm,
mapSheetLearnEntity.m3ModelStartDttm, mapSheetLearnEntity.m3ModelStartDttm,
mapSheetLearnEntity.m4ModelStartDttm,
mapSheetLearnEntity.m1ModelEndDttm, mapSheetLearnEntity.m1ModelEndDttm,
mapSheetLearnEntity.m2ModelEndDttm, mapSheetLearnEntity.m2ModelEndDttm,
mapSheetLearnEntity.m3ModelEndDttm, mapSheetLearnEntity.m3ModelEndDttm,
mapSheetLearnEntity.m4ModelEndDttm,
mapSheetLearnEntity.title, mapSheetLearnEntity.title,
mapSheetLearnEntity.compareYyyy, mapSheetLearnEntity.compareYyyy,
mapSheetLearnEntity.targetYyyy, mapSheetLearnEntity.targetYyyy,
@@ -231,6 +239,7 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
m1Model.modelVer.as("model1Ver"), m1Model.modelVer.as("model1Ver"),
m2Model.modelVer.as("model2Ver"), m2Model.modelVer.as("model2Ver"),
m3Model.modelVer.as("model3Ver"), m3Model.modelVer.as("model3Ver"),
m4Model.modelVer.as("model4Ver"),
mapSheetLearnEntity.totalJobs)) mapSheetLearnEntity.totalJobs))
.from(mapSheetLearnEntity) .from(mapSheetLearnEntity)
.leftJoin(m1Model) .leftJoin(m1Model)
@@ -239,6 +248,8 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
.on(m2Model.uuid.eq(mapSheetLearnEntity.m2ModelUuid)) .on(m2Model.uuid.eq(mapSheetLearnEntity.m2ModelUuid))
.leftJoin(m3Model) .leftJoin(m3Model)
.on(m3Model.uuid.eq(mapSheetLearnEntity.m3ModelUuid)) .on(m3Model.uuid.eq(mapSheetLearnEntity.m3ModelUuid))
.leftJoin(m4Model)
.on(m4Model.uuid.eq(mapSheetLearnEntity.m4ModelUuid))
.where(mapSheetLearnEntity.uuid.eq(uuid)) .where(mapSheetLearnEntity.uuid.eq(uuid))
.fetchOne(); .fetchOne();
@@ -296,6 +307,7 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
QModelMngEntity m1 = new QModelMngEntity("m1"); QModelMngEntity m1 = new QModelMngEntity("m1");
QModelMngEntity m2 = new QModelMngEntity("m2"); QModelMngEntity m2 = new QModelMngEntity("m2");
QModelMngEntity m3 = new QModelMngEntity("m3"); QModelMngEntity m3 = new QModelMngEntity("m3");
QModelMngEntity m4 = new QModelMngEntity("m4");
return queryFactory return queryFactory
.select( .select(
@@ -305,6 +317,7 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
m1.modelVer, m1.modelVer,
m2.modelVer, m2.modelVer,
m3.modelVer, m3.modelVer,
m4.modelVer,
mapSheetLearnEntity.compareYyyy, mapSheetLearnEntity.compareYyyy,
mapSheetLearnEntity.targetYyyy, mapSheetLearnEntity.targetYyyy,
mapSheetLearnEntity.detectOption, mapSheetLearnEntity.detectOption,
@@ -324,6 +337,8 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
.on(mapSheetLearnEntity.m2ModelUuid.eq(m2.uuid)) .on(mapSheetLearnEntity.m2ModelUuid.eq(m2.uuid))
.leftJoin(m3) .leftJoin(m3)
.on(mapSheetLearnEntity.m3ModelUuid.eq(m3.uuid)) .on(mapSheetLearnEntity.m3ModelUuid.eq(m3.uuid))
.leftJoin(m4)
.on(mapSheetLearnEntity.m4ModelUuid.eq(m4.uuid))
.leftJoin(mapSheetAnalInferenceEntity) .leftJoin(mapSheetAnalInferenceEntity)
.on(mapSheetAnalInferenceEntity.learnId.eq(mapSheetLearnEntity.id)) .on(mapSheetAnalInferenceEntity.learnId.eq(mapSheetLearnEntity.id))
.where(mapSheetLearnEntity.uuid.eq(uuid)) .where(mapSheetLearnEntity.uuid.eq(uuid))
@@ -445,12 +460,14 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
NumberExpression<Long> inkxNoAsLong = NumberExpression<Long> inkxNoAsLong =
Expressions.numberTemplate(Long.class, "cast({0} as long)", mapInkx5kEntity.mapidcdNo); Expressions.numberTemplate(Long.class, "cast({0} as long)", mapInkx5kEntity.mapidcdNo);
/* 미사용
StringExpression pnu = StringExpression pnu =
Expressions.stringTemplate( Expressions.stringTemplate(
"nullif(({0}), '')", "nullif(({0}), '')",
JPAExpressions.select(Expressions.stringTemplate("string_agg({0}, ',')", pnuEntity.pnu)) JPAExpressions.select(Expressions.stringTemplate("string_agg({0}, ',')", pnuEntity.pnu))
.from(pnuEntity) .from(pnuEntity)
.where(pnuEntity.geo.geoUid.eq(mapSheetAnalDataInferenceGeomEntity.geoUid))); .where(pnuEntity.geo.geoUid.eq(mapSheetAnalDataInferenceGeomEntity.geoUid)));
*/
// 4) content // 4) content
List<Geom> content = List<Geom> content =
@@ -458,6 +475,7 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
.select( .select(
Projections.constructor( Projections.constructor(
Geom.class, Geom.class,
mapSheetAnalDataInferenceGeomEntity.geoUid,
mapSheetAnalDataInferenceGeomEntity.uuid, mapSheetAnalDataInferenceGeomEntity.uuid,
mapSheetAnalDataInferenceGeomEntity.resultUid, mapSheetAnalDataInferenceGeomEntity.resultUid,
mapSheetAnalDataInferenceGeomEntity.compareYyyy, mapSheetAnalDataInferenceGeomEntity.compareYyyy,
@@ -472,7 +490,7 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
Expressions.stringTemplate( Expressions.stringTemplate(
"substring({0} from 1 for 8)", "substring({0} from 1 for 8)",
mapSheetAnalDataInferenceGeomEntity.resultUid), mapSheetAnalDataInferenceGeomEntity.resultUid),
pnu, Expressions.constant(""),
mapSheetAnalDataInferenceGeomEntity.fitState)) mapSheetAnalDataInferenceGeomEntity.fitState))
.from(mapSheetAnalInferenceEntity) .from(mapSheetAnalInferenceEntity)
.join(mapSheetAnalDataInferenceEntity) .join(mapSheetAnalDataInferenceEntity)
@@ -487,6 +505,33 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
.limit(pageable.getPageSize()) .limit(pageable.getPageSize())
.fetch(); .fetch();
// 4-1) pnu 를 geoUid 로 검색하기 -> AS-IS 에서는 전체 tb_pnu 를 조회해서 오래 걸렸음
List<Long> geoUids = content.stream().map(Geom::getGeoUid).filter(Objects::nonNull).toList();
Map<Long, String> pnuMap = new HashMap<>();
if (!geoUids.isEmpty()) {
StringExpression pnuAgg = Expressions.stringTemplate("string_agg({0}, ',')", pnuEntity.pnu);
List<Tuple> pnuRows =
queryFactory
.select(
pnuEntity.geo.geoUid,
Expressions.stringTemplate("string_agg({0}, ',')", pnuEntity.pnu))
.from(pnuEntity)
.where(pnuEntity.geo.geoUid.in(geoUids))
.groupBy(pnuEntity.geo.geoUid)
.fetch();
pnuMap =
pnuRows.stream()
.collect(
Collectors.toMap(row -> row.get(pnuEntity.geo.geoUid), row -> row.get(pnuAgg)));
}
for (Geom geom : content) {
geom.setPnu(pnuMap.get(geom.getGeoUid()));
}
// 5) total (조인 최소화 유지) // 5) total (조인 최소화 유지)
Long total = Long total =
queryFactory queryFactory
@@ -519,7 +564,7 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
.fetchOne(); .fetchOne();
if (learn == null) { if (learn == null) {
return new GukYuinLinkFacts(false, false, false, false); return new GukYuinLinkFacts(false, false, false, false, null);
} }
// 부분 도엽 실행인지 확인 // 부분 도엽 실행인지 확인
@@ -529,19 +574,21 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
QMapSheetLearnEntity learn2 = new QMapSheetLearnEntity("learn2"); QMapSheetLearnEntity learn2 = new QMapSheetLearnEntity("learn2");
QMapSheetLearnEntity learnQ = QMapSheetLearnEntity.mapSheetLearnEntity; QMapSheetLearnEntity learnQ = QMapSheetLearnEntity.mapSheetLearnEntity;
// 실행중인 추론 있는지 확인 // 현재 국유인 연동하려는 추론의 비교년도,기준년도와 같은 회차 중, 할당되거나 진행중인 학습데이터 uuid 조회
boolean hasRunningInference = // ex. 2022-2023년도 9회차 학습데이터 제작 진행중 -> 10회차 연동하려고 할 시, 먼저 9회차를 종료해야 함
UUID runningInferenceUuid =
queryFactory queryFactory
.selectOne() .select(inf.uuid)
.from(inf) .from(inf)
.join(learn2) .join(learn2)
.on(inf.learnId.eq(learn2.id)) .on(inf.learnId.eq(learn2.id))
.where( .where(
learn2.compareYyyy.eq(learn.getCompareYyyy()), learn2.compareYyyy.eq(learn.getCompareYyyy()),
learn2.targetYyyy.eq(learn.getTargetYyyy()), learn2.targetYyyy.eq(learn.getTargetYyyy()),
inf.analState.in("ASSIGNED", "ING")) inf.analState.in("ASSIGNED", "ING"))
.fetchFirst() .fetchFirst();
!= null;
boolean hasRunningInference = runningInferenceUuid != null;
// 국유인 작업 진행중 있는지 확인 // 국유인 작업 진행중 있는지 확인
boolean hasOtherUnfinishedGukYuin = boolean hasOtherUnfinishedGukYuin =
@@ -556,6 +603,7 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
.fetchFirst() .fetchFirst()
!= null; != null;
return new GukYuinLinkFacts(true, isPartScope, hasRunningInference, hasOtherUnfinishedGukYuin); return new GukYuinLinkFacts(
true, isPartScope, hasRunningInference, hasOtherUnfinishedGukYuin, runningInferenceUuid);
} }
} }

View File

@@ -211,8 +211,9 @@ public class ChangeDetectionRepositoryImpl extends QuerydslRepositorySupport
.where( .where(
l.status l.status
.eq(Status.END.getId()) .eq(Status.END.getId())
.and(JPAExpressions.selectOne().from(d).where(d.analUid.eq(a.id)).exists())) .and(JPAExpressions.selectOne().from(d).where(d.analUid.eq(a.id)).exists()),
.orderBy(l.id.asc()) l.isDeleted.eq(false).or(l.isDeleted.isNull()))
.orderBy(l.id.desc())
.fetch(); .fetch();
} }

View File

@@ -7,6 +7,7 @@ import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.InspectState;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelMngState; import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelMngState;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelState; import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelState;
import com.kamco.cd.kamcoback.label.dto.LabelWorkDto; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto;
import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelCntInfo;
import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelWorkMng; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelWorkMng;
import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelWorkMngDetail; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelWorkMngDetail;
import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.WorkerState; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.WorkerState;
@@ -18,7 +19,6 @@ import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceGeomEnti
import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalInferenceEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalInferenceEntity;
import com.kamco.cd.kamcoback.postgres.entity.QMemberEntity; import com.kamco.cd.kamcoback.postgres.entity.QMemberEntity;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Projections; import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
@@ -86,7 +86,7 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom {
} }
/** /**
* 라벨링 작업관리 목록 조회 (복잡한 집계 쿼리로 인해 DTO 직접 반환) * 라벨링 작업관리 목록 조회 :: 전체 geom 집계 -> inference 먼저 쿼리 하고 count 정보 따로 집계하도록 수정
* *
* @param searchReq 검색 조건 * @param searchReq 검색 조건
* @return 라벨링 작업관리 목록 페이지 * @return 라벨링 작업관리 목록 페이지
@@ -95,9 +95,8 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom {
public Page<LabelWorkMng> labelWorkMngList(LabelWorkDto.LabelWorkMngSearchReq searchReq) { public Page<LabelWorkMng> labelWorkMngList(LabelWorkDto.LabelWorkMngSearchReq searchReq) {
Pageable pageable = PageRequest.of(searchReq.getPage(), searchReq.getSize()); Pageable pageable = PageRequest.of(searchReq.getPage(), searchReq.getSize());
BooleanBuilder whereBuilder = new BooleanBuilder();
BooleanBuilder whereSubDataBuilder = new BooleanBuilder(); BooleanBuilder baseWhereBuilder = new BooleanBuilder();
BooleanBuilder whereSubBuilder = new BooleanBuilder();
if (StringUtils.isNotBlank(searchReq.getDetectYear())) { if (StringUtils.isNotBlank(searchReq.getDetectYear())) {
String[] years = searchReq.getDetectYear().split("-"); String[] years = searchReq.getDetectYear().split("-");
@@ -106,67 +105,14 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom {
Integer compareYear = Integer.valueOf(years[0]); Integer compareYear = Integer.valueOf(years[0]);
Integer targetYear = Integer.valueOf(years[1]); Integer targetYear = Integer.valueOf(years[1]);
whereBuilder.and( baseWhereBuilder.and(
mapSheetAnalDataInferenceEntity mapSheetAnalInferenceEntity
.compareYyyy .compareYyyy
.eq(compareYear) .eq(compareYear)
.and(mapSheetAnalDataInferenceEntity.targetYyyy.eq(targetYear))); .and(mapSheetAnalInferenceEntity.targetYyyy.eq(targetYear)));
} }
} }
whereSubDataBuilder.and(
mapSheetAnalInferenceEntity.id.eq(mapSheetAnalDataInferenceEntity.analUid));
whereSubBuilder.and(
mapSheetAnalDataInferenceGeomEntity.dataUid.eq(mapSheetAnalDataInferenceEntity.id));
if (searchReq.getStrtDttm() != null && searchReq.getEndDttm() != null) {
ZoneId zoneId = ZoneId.of("Asia/Seoul");
ZonedDateTime start = searchReq.getStrtDttm().atStartOfDay(zoneId);
ZonedDateTime end = searchReq.getEndDttm().plusDays(1).atStartOfDay(zoneId);
whereSubBuilder.and(
mapSheetAnalDataInferenceGeomEntity
.labelStateDttm
.goe(start)
.and(mapSheetAnalDataInferenceGeomEntity.labelStateDttm.lt(end)));
}
// labelTotCnt: pnu가 있고 fitState = UNFIT 인 건수만 라벨링 대상
NumberExpression<Long> labelTotCntExpr =
new CaseBuilder()
.when(
mapSheetAnalDataInferenceGeomEntity
.pnu
.gt(0)
.and(
mapSheetAnalDataInferenceGeomEntity.fitState.eq(
ImageryFitStatus.UNFIT.getId())))
.then(1L)
.otherwise(0L)
.sum();
// stagnation_yn = 'N'인 정상 진행 건수 (서브쿼리로 별도 집계)
Expression<Long> normalProgressCntSubQuery =
JPAExpressions.select(
new CaseBuilder()
.when(labelingAssignmentEntity.stagnationYn.eq('N'))
.then(1L)
.otherwise(0L)
.sum()
.coalesce(0L))
.from(labelingAssignmentEntity)
.where(labelingAssignmentEntity.analUid.eq(mapSheetAnalInferenceEntity.id));
// 총 배정 건수 (서브쿼리로 별도 집계)
Expression<Long> totalAssignmentCntSubQuery =
JPAExpressions.select(labelingAssignmentEntity.count().coalesce(0L))
.from(labelingAssignmentEntity)
.where(labelingAssignmentEntity.analUid.eq(mapSheetAnalInferenceEntity.id));
/** 순서 ING 진행중 ASSIGNED 작업할당 PENDING 작업대기 FINISH 종료 */ /** 순서 ING 진행중 ASSIGNED 작업할당 PENDING 작업대기 FINISH 종료 */
NumberExpression<Integer> stateOrder = NumberExpression<Integer> stateOrder =
new CaseBuilder() new CaseBuilder()
@@ -180,64 +126,31 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom {
.then(3) .then(3)
.otherwise(99); .otherwise(99);
// 1단계: anal_inference 기준으로 상위 페이지 목록만 조회
List<LabelWorkMng> foundContent = List<LabelWorkMng> foundContent =
queryFactory queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
LabelWorkMng.class, LabelWorkMng.class,
mapSheetAnalInferenceEntity.id, // analUid 추가
mapSheetAnalInferenceEntity.uuid, mapSheetAnalInferenceEntity.uuid,
mapSheetAnalInferenceEntity.compareYyyy, mapSheetAnalInferenceEntity.compareYyyy,
mapSheetAnalInferenceEntity.targetYyyy, mapSheetAnalInferenceEntity.targetYyyy,
mapSheetAnalInferenceEntity.stage, mapSheetAnalInferenceEntity.stage,
// 국유인 반영 컬럼 gukyuinApplyDttm
mapSheetAnalInferenceEntity.gukyuinApplyDttm, mapSheetAnalInferenceEntity.gukyuinApplyDttm,
mapSheetAnalDataInferenceGeomEntity.dataUid.count(), mapSheetAnalInferenceEntity.detectingCnt,
// labelTotCnt: pnu 있고 pass_yn = false인 건수 Expressions.constant(0L),
labelTotCntExpr, Expressions.constant(0L),
new CaseBuilder() Expressions.constant(0L),
.when( Expressions.constant(0L),
mapSheetAnalDataInferenceGeomEntity.labelState.eq( mapSheetAnalInferenceEntity.createdDttm,
LabelState.ASSIGNED.getId()))
.then(1L)
.otherwise(0L)
.sum(),
new CaseBuilder()
.when(
mapSheetAnalDataInferenceGeomEntity.labelState.eq(
LabelState.SKIP.getId())) // "STOP"?
.then(1L)
.otherwise(0L)
.sum(),
new CaseBuilder()
.when(
mapSheetAnalDataInferenceGeomEntity.labelState.eq(
LabelState.DONE.getId()))
.then(1L)
.otherwise(0L)
.sum(),
mapSheetAnalDataInferenceGeomEntity.labelStateDttm.min(),
// analState: tb_map_sheet_anal_inference.anal_state
mapSheetAnalInferenceEntity.analState, mapSheetAnalInferenceEntity.analState,
// normalProgressCnt: stagnation_yn = 'N'인 건수 (서브쿼리) Expressions.constant(0L),
normalProgressCntSubQuery, Expressions.constant(0L),
// totalAssignmentCnt: 총 배정 건수 (서브쿼리)
totalAssignmentCntSubQuery,
mapSheetAnalInferenceEntity.labelingClosedYn, mapSheetAnalInferenceEntity.labelingClosedYn,
mapSheetAnalInferenceEntity.inspectionClosedYn, mapSheetAnalInferenceEntity.inspectionClosedYn,
new CaseBuilder() Expressions.constant(0L),
.when( Expressions.constant(0L),
mapSheetAnalDataInferenceGeomEntity.testState.eq(
InspectState.COMPLETE.getId()))
.then(1L)
.otherwise(0L)
.sum(),
new CaseBuilder()
.when(
mapSheetAnalDataInferenceGeomEntity.testState.eq(
InspectState.UNCONFIRM.getId()))
.then(1L)
.otherwise(0L)
.sum(),
new CaseBuilder() new CaseBuilder()
.when(mapSheetAnalInferenceEntity.inspectionClosedYn.eq("Y")) .when(mapSheetAnalInferenceEntity.inspectionClosedYn.eq("Y"))
.then(mapSheetAnalInferenceEntity.updatedDttm) .then(mapSheetAnalInferenceEntity.updatedDttm)
@@ -247,23 +160,11 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom {
"substring({0} from 1 for 8)", mapSheetLearnEntity.uid), "substring({0} from 1 for 8)", mapSheetLearnEntity.uid),
mapSheetLearnEntity.uuid)) mapSheetLearnEntity.uuid))
.from(mapSheetAnalInferenceEntity) .from(mapSheetAnalInferenceEntity)
.innerJoin(mapSheetAnalDataInferenceEntity) .innerJoin(mapSheetLearnEntity)
.on(whereSubDataBuilder) .on(
.innerJoin(mapSheetAnalDataInferenceGeomEntity) mapSheetAnalInferenceEntity.learnId.eq(mapSheetLearnEntity.id),
.on(whereSubBuilder) mapSheetLearnEntity.isDeleted.eq(false).or(mapSheetLearnEntity.isDeleted.isNull()))
.leftJoin(mapSheetLearnEntity) .where(baseWhereBuilder)
.on(mapSheetAnalInferenceEntity.learnId.eq(mapSheetLearnEntity.id))
.where(whereBuilder)
.groupBy(
mapSheetAnalInferenceEntity.uuid,
mapSheetAnalInferenceEntity.compareYyyy,
mapSheetAnalInferenceEntity.targetYyyy,
mapSheetAnalInferenceEntity.stage,
mapSheetAnalInferenceEntity.createdDttm,
mapSheetAnalInferenceEntity.analState,
mapSheetAnalInferenceEntity.id,
mapSheetLearnEntity.uid,
mapSheetLearnEntity.uuid)
.orderBy( .orderBy(
stateOrder.asc(), stateOrder.asc(),
mapSheetAnalInferenceEntity.targetYyyy.desc(), mapSheetAnalInferenceEntity.targetYyyy.desc(),
@@ -273,20 +174,122 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom {
.limit(pageable.getPageSize()) .limit(pageable.getPageSize())
.fetch(); .fetch();
// Count 쿼리 별도 실행 (null safe handling) // total count
long total = long total =
Optional.ofNullable( Optional.ofNullable(
queryFactory queryFactory
.select(mapSheetAnalInferenceEntity.uuid.countDistinct()) .select(mapSheetAnalInferenceEntity.count())
.from(mapSheetAnalInferenceEntity) .from(mapSheetAnalInferenceEntity)
.innerJoin(mapSheetAnalDataInferenceEntity) .where(baseWhereBuilder)
.on(whereSubDataBuilder)
.innerJoin(mapSheetAnalDataInferenceGeomEntity)
.on(whereSubBuilder)
.where(whereBuilder)
.fetchOne()) .fetchOne())
.orElse(0L); .orElse(0L);
// 2단계: 각 analUid별 count 조회 후 세팅
for (LabelWorkMng item : foundContent) {
Long analUid = item.getAnalUid();
BooleanBuilder geomWhereBuilder = new BooleanBuilder();
geomWhereBuilder.and(mapSheetAnalDataInferenceEntity.analUid.eq(analUid));
geomWhereBuilder.and(
mapSheetAnalDataInferenceGeomEntity.dataUid.eq(mapSheetAnalDataInferenceEntity.id));
if (searchReq.getStrtDttm() != null && searchReq.getEndDttm() != null) {
ZoneId zoneId = ZoneId.of("Asia/Seoul");
ZonedDateTime start = searchReq.getStrtDttm().atStartOfDay(zoneId);
ZonedDateTime end = searchReq.getEndDttm().plusDays(1).atStartOfDay(zoneId);
geomWhereBuilder.and(
mapSheetAnalDataInferenceGeomEntity
.createdDttm
.goe(start)
.and(mapSheetAnalDataInferenceGeomEntity.createdDttm.lt(end)));
}
// labelTotCnt: pnu > 0 and fitState = UNFIT
Long labelTotCnt =
Optional.ofNullable(
queryFactory
.select(mapSheetAnalDataInferenceGeomEntity.count())
.from(mapSheetAnalDataInferenceEntity)
.innerJoin(mapSheetAnalDataInferenceGeomEntity)
.on(
mapSheetAnalDataInferenceGeomEntity.dataUid.eq(
mapSheetAnalDataInferenceEntity.id))
.where(
geomWhereBuilder,
mapSheetAnalDataInferenceGeomEntity.pnu.gt(0),
mapSheetAnalDataInferenceGeomEntity.fitState.eq(
ImageryFitStatus.UNFIT.getId()))
.fetchOne())
.orElse(0L);
LabelCntInfo cntInfo =
queryFactory
.select(
Projections.constructor(
LabelCntInfo.class,
new CaseBuilder()
.when(labelingAssignmentEntity.workState.eq(LabelState.ASSIGNED.getId()))
.then(1L)
.otherwise(0L)
.sum()
.coalesce(0L),
new CaseBuilder()
.when(labelingAssignmentEntity.workState.eq(LabelState.SKIP.getId()))
.then(1L)
.otherwise(0L)
.sum()
.coalesce(0L),
new CaseBuilder()
.when(labelingAssignmentEntity.workState.eq(LabelState.DONE.getId()))
.then(1L)
.otherwise(0L)
.sum()
.coalesce(0L),
new CaseBuilder()
.when(
labelingAssignmentEntity.inspectState.eq(
InspectState.UNCONFIRM.getId()))
.then(1L)
.otherwise(0L)
.sum()
.coalesce(0L),
new CaseBuilder()
.when(
labelingAssignmentEntity.inspectState.eq(InspectState.EXCEPT.getId()))
.then(1L)
.otherwise(0L)
.sum()
.coalesce(0L),
new CaseBuilder()
.when(
labelingAssignmentEntity.inspectState.eq(
InspectState.COMPLETE.getId()))
.then(1L)
.otherwise(0L)
.sum()
.coalesce(0L)))
.from(labelingAssignmentEntity)
.where(labelingAssignmentEntity.analUid.eq(analUid))
.fetchOne();
Long normalProgressCnt = 0L;
Long totalAssignmentCnt = 0L;
if (cntInfo == null) {
cntInfo = new LabelCntInfo(0L, 0L, 0L, 0L, 0L, 0L);
}
item.setLabelTotCnt(labelTotCnt);
item.setLabelAssignCnt(cntInfo.getAssignedCnt());
item.setLabelSkipTotCnt(cntInfo.getSkipCnt());
item.setLabelCompleteTotCnt(cntInfo.getDoneCnt());
item.setNormalProgressCnt(normalProgressCnt);
item.setTotalAssignmentCnt(totalAssignmentCnt);
item.setInspectorCompleteTotCnt(cntInfo.getCompleteCnt());
item.setInspectorRemainCnt(cntInfo.getUnconfirmCnt());
}
return new PageImpl<>(foundContent, pageable, total); return new PageImpl<>(foundContent, pageable, total);
} }

View File

@@ -5,6 +5,7 @@ import static com.kamco.cd.kamcoback.postgres.entity.QErrorLogEntity.errorLogEnt
import static com.kamco.cd.kamcoback.postgres.entity.QMemberEntity.memberEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMemberEntity.memberEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMenuEntity.menuEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMenuEntity.menuEntity;
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
import com.kamco.cd.kamcoback.log.dto.AuditLogDto; import com.kamco.cd.kamcoback.log.dto.AuditLogDto;
import com.kamco.cd.kamcoback.log.dto.AuditLogDto.DownloadReq; import com.kamco.cd.kamcoback.log.dto.AuditLogDto.DownloadReq;
import com.kamco.cd.kamcoback.log.dto.ErrorLogDto; import com.kamco.cd.kamcoback.log.dto.ErrorLogDto;
@@ -13,6 +14,7 @@ import com.kamco.cd.kamcoback.log.dto.EventType;
import com.kamco.cd.kamcoback.postgres.entity.AuditLogEntity; import com.kamco.cd.kamcoback.postgres.entity.AuditLogEntity;
import com.kamco.cd.kamcoback.postgres.entity.QMenuEntity; import com.kamco.cd.kamcoback.postgres.entity.QMenuEntity;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.Projections; import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.CaseBuilder; import com.querydsl.core.types.dsl.CaseBuilder;
@@ -83,13 +85,16 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport
public Page<AuditLogDto.MenuAuditList> findLogByMenu( public Page<AuditLogDto.MenuAuditList> findLogByMenu(
AuditLogDto.searchReq searchReq, String searchValue) { AuditLogDto.searchReq searchReq, String searchValue) {
Pageable pageable = searchReq.toPageable(); Pageable pageable = searchReq.toPageable();
boolean english = HeaderUtil.isEnglishRequest();
Expression<String> menuNameExpr = english ? menuEntity.menuNmEn.max() : menuEntity.menuNm.max();
List<AuditLogDto.MenuAuditList> foundContent = List<AuditLogDto.MenuAuditList> foundContent =
queryFactory queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
AuditLogDto.MenuAuditList.class, AuditLogDto.MenuAuditList.class,
auditLogEntity.menuUid.as("menuId"), auditLogEntity.menuUid.as("menuId"),
menuEntity.menuNm.max().as("menuName"), menuNameExpr,
readCount().as("readCount"), readCount().as("readCount"),
cudCount().as("cudCount"), cudCount().as("cudCount"),
printCount().as("printCount"), printCount().as("printCount"),
@@ -217,21 +222,24 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport
@Override @Override
public Page<AuditLogDto.DailyDetail> findLogByDailyResult( public Page<AuditLogDto.DailyDetail> findLogByDailyResult(
AuditLogDto.searchReq searchReq, LocalDate logDate) { AuditLogDto.searchReq searchReq, LocalDate logDate) {
boolean english = HeaderUtil.isEnglishRequest();
Pageable pageable = searchReq.toPageable(); Pageable pageable = searchReq.toPageable();
QMenuEntity parent = new QMenuEntity("parent"); QMenuEntity parent = new QMenuEntity("parent");
// 1depth menu name // 1depth menu name
StringExpression parentMenuName = StringExpression parentMenuName =
new CaseBuilder() new CaseBuilder()
.when(parent.menuUid.isNull()) .when(parent.menuUid.isNull())
.then(menuEntity.menuNm) .then(english ? menuEntity.menuNmEn : menuEntity.menuNm)
.otherwise(parent.menuNm); .otherwise(english ? parent.menuNmEn : parent.menuNm);
// 2depth menu name // 2depth menu name
StringExpression menuName = StringExpression menuName =
new CaseBuilder() new CaseBuilder()
.when(parent.menuUid.isNull()) .when(parent.menuUid.isNull())
.then(NULL_STRING) .then(NULL_STRING)
.otherwise(menuEntity.menuNm); .otherwise(english ? menuEntity.menuNmEn : menuEntity.menuNm);
StringExpression menuNm = (english ? menuEntity.menuNmEn : menuEntity.menuNm);
List<AuditLogDto.DailyDetail> foundContent = List<AuditLogDto.DailyDetail> foundContent =
queryFactory queryFactory
@@ -241,20 +249,20 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport
auditLogEntity.id.as("logId"), auditLogEntity.id.as("logId"),
memberEntity.name.as("userName"), memberEntity.name.as("userName"),
memberEntity.employeeNo.as("loginId"), memberEntity.employeeNo.as("loginId"),
menuEntity.menuNm.as("menuName"), menuNm.as("menuName"),
auditLogEntity.eventType.as("eventType"), auditLogEntity.eventType.as("eventType"),
Expressions.stringTemplate( Expressions.stringTemplate(
"to_char({0}, 'YYYY-MM-DD HH24:MI')", auditLogEntity.createdDate) "to_char({0}, 'YYYY-MM-DD HH24:MI')", auditLogEntity.createdDate)
.as("logDateTime"), .as("logDateTime"),
Projections.constructor( Projections.constructor(
AuditLogDto.LogDetail.class, AuditLogDto.LogDetail.class,
Expressions.constant("한국자산관리공사"), // serviceName Expressions.constant(english ? "Kamco" : "한국자산관리공사"), // serviceName
parentMenuName.as("parentMenuName"), parentMenuName.as("parentMenuName"),
menuName, menuName,
menuEntity.menuUrl.as("menuUrl"), menuEntity.menuUrl.as("menuUrl"),
menuEntity.description.as("menuDescription"), menuEntity.description.as("menuDescription"),
menuEntity.menuOrder.as("sortOrder"), menuEntity.menuOrder.as("sortOrder"),
menuEntity.isUse.as("used")))) // TODO menuEntity.isUse.as("used"))))
.from(auditLogEntity) .from(auditLogEntity)
.leftJoin(menuEntity) .leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid)) .on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
@@ -285,21 +293,22 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport
@Override @Override
public Page<AuditLogDto.MenuDetail> findLogByMenuResult( public Page<AuditLogDto.MenuDetail> findLogByMenuResult(
AuditLogDto.searchReq searchReq, String menuUid) { AuditLogDto.searchReq searchReq, String menuUid) {
boolean english = HeaderUtil.isEnglishRequest();
Pageable pageable = searchReq.toPageable(); Pageable pageable = searchReq.toPageable();
QMenuEntity parent = new QMenuEntity("parent"); QMenuEntity parent = new QMenuEntity("parent");
// 1depth menu name // 1depth menu name
StringExpression parentMenuName = StringExpression parentMenuName =
new CaseBuilder() new CaseBuilder()
.when(parent.menuUid.isNull()) .when(parent.menuUid.isNull())
.then(menuEntity.menuNm) .then(english ? menuEntity.menuNmEn : menuEntity.menuNm)
.otherwise(parent.menuNm); .otherwise(english ? parent.menuNmEn : parent.menuNm);
// 2depth menu name // 2depth menu name
StringExpression menuName = StringExpression menuName =
new CaseBuilder() new CaseBuilder()
.when(parent.menuUid.isNull()) .when(parent.menuUid.isNull())
.then(NULL_STRING) .then(NULL_STRING)
.otherwise(menuEntity.menuNm); .otherwise(english ? menuEntity.menuNmEn : menuEntity.menuNm);
List<AuditLogDto.MenuDetail> foundContent = List<AuditLogDto.MenuDetail> foundContent =
queryFactory queryFactory
@@ -315,7 +324,7 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport
auditLogEntity.eventType.as("eventType"), auditLogEntity.eventType.as("eventType"),
Projections.constructor( Projections.constructor(
AuditLogDto.LogDetail.class, AuditLogDto.LogDetail.class,
Expressions.constant("한국자산관리공사"), // serviceName Expressions.constant(english ? "Kamco" : "한국자산관리공사"), // serviceName
parentMenuName.as("parentMenuName"), parentMenuName.as("parentMenuName"),
menuName, menuName,
menuEntity.menuUrl.as("menuUrl"), menuEntity.menuUrl.as("menuUrl"),
@@ -352,21 +361,24 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport
@Override @Override
public Page<AuditLogDto.UserDetail> findLogByAccountResult( public Page<AuditLogDto.UserDetail> findLogByAccountResult(
AuditLogDto.searchReq searchReq, Long userUid) { AuditLogDto.searchReq searchReq, Long userUid) {
boolean english = HeaderUtil.isEnglishRequest();
Pageable pageable = searchReq.toPageable(); Pageable pageable = searchReq.toPageable();
QMenuEntity parent = new QMenuEntity("parent"); QMenuEntity parent = new QMenuEntity("parent");
// 1depth menu name // 1depth menu name
StringExpression parentMenuName = StringExpression parentMenuName =
new CaseBuilder() new CaseBuilder()
.when(parent.menuUid.isNull()) .when(parent.menuUid.isNull())
.then(menuEntity.menuNm) .then(english ? menuEntity.menuNmEn : menuEntity.menuNm)
.otherwise(parent.menuNm); .otherwise(english ? parent.menuNmEn : parent.menuNm);
// 2depth menu name // 2depth menu name
StringExpression menuName = StringExpression menuName =
new CaseBuilder() new CaseBuilder()
.when(parent.menuUid.isNull()) .when(parent.menuUid.isNull())
.then(NULL_STRING) .then(NULL_STRING)
.otherwise(menuEntity.menuNm); .otherwise(english ? menuEntity.menuNmEn : menuEntity.menuNm);
StringExpression menuNm = (english ? menuEntity.menuNmEn : menuEntity.menuNm);
List<AuditLogDto.UserDetail> foundContent = List<AuditLogDto.UserDetail> foundContent =
queryFactory queryFactory
@@ -377,11 +389,11 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport
Expressions.stringTemplate( Expressions.stringTemplate(
"to_char({0}, 'YYYY-MM-DD HH24:MI')", auditLogEntity.createdDate) "to_char({0}, 'YYYY-MM-DD HH24:MI')", auditLogEntity.createdDate)
.as("logDateTime"), .as("logDateTime"),
menuEntity.menuNm.as("menuName"), menuNm.as("menuName"),
auditLogEntity.eventType.as("eventType"), auditLogEntity.eventType.as("eventType"),
Projections.constructor( Projections.constructor(
AuditLogDto.LogDetail.class, AuditLogDto.LogDetail.class,
Expressions.constant("한국자산관리공사"), // serviceName Expressions.constant(english ? "Kamco" : "한국자산관리공사"), // serviceName
parentMenuName.as("parentMenuName"), parentMenuName.as("parentMenuName"),
menuName, menuName,
menuEntity.menuUrl.as("menuUrl"), menuEntity.menuUrl.as("menuUrl"),
@@ -442,7 +454,7 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport
if (StringUtils.isBlank(searchValue)) { if (StringUtils.isBlank(searchValue)) {
return null; return null;
} }
return menuEntity.menuNm.contains(searchValue); return menuEntity.menuNm.contains(searchValue).or(menuEntity.menuNmEn.contains(searchValue));
} }
private BooleanExpression loginIdOrUsernameContains(String searchValue) { private BooleanExpression loginIdOrUsernameContains(String searchValue) {

View File

@@ -5,6 +5,7 @@ import static com.kamco.cd.kamcoback.postgres.entity.QErrorLogEntity.errorLogEnt
import static com.kamco.cd.kamcoback.postgres.entity.QMemberEntity.memberEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMemberEntity.memberEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMenuEntity.menuEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMenuEntity.menuEntity;
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
import com.kamco.cd.kamcoback.log.dto.ErrorLogDto; import com.kamco.cd.kamcoback.log.dto.ErrorLogDto;
import com.kamco.cd.kamcoback.log.dto.EventStatus; import com.kamco.cd.kamcoback.log.dto.EventStatus;
import com.kamco.cd.kamcoback.log.dto.EventType; import com.kamco.cd.kamcoback.log.dto.EventType;
@@ -38,14 +39,17 @@ public class ErrorLogRepositoryImpl extends QuerydslRepositorySupport
@Override @Override
public Page<ErrorLogDto.Basic> findLogByError(ErrorLogDto.ErrorSearchReq searchReq) { public Page<ErrorLogDto.Basic> findLogByError(ErrorLogDto.ErrorSearchReq searchReq) {
Pageable pageable = searchReq.toPageable(); Pageable pageable = searchReq.toPageable();
boolean english = HeaderUtil.isEnglishRequest();
StringExpression menuNm = (english ? menuEntity.menuNmEn : menuEntity.menuNm);
List<ErrorLogDto.Basic> foundContent = List<ErrorLogDto.Basic> foundContent =
queryFactory queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
ErrorLogDto.Basic.class, ErrorLogDto.Basic.class,
errorLogEntity.id.as("logId"), errorLogEntity.id.as("logId"),
Expressions.stringTemplate("{0}", "한국자산관리공사"), // serviceName Expressions.constant(english ? "Kamco" : "한국자산관리공사"), // serviceName
menuEntity.menuNm.as("menuName"), menuNm.as("menuName"),
memberEntity.employeeNo.as("loginId"), memberEntity.employeeNo.as("loginId"),
memberEntity.name.as("userName"), memberEntity.name.as("userName"),
errorLogEntity.errorType.as("eventType"), errorLogEntity.errorType.as("eventType"),

View File

@@ -748,6 +748,13 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport
.delete(mapSheetMngTileEntity) .delete(mapSheetMngTileEntity)
.where(mapSheetMngTileEntity.mngYyyy.eq(mngYyyy)) .where(mapSheetMngTileEntity.mngYyyy.eq(mngYyyy))
.execute(); .execute();
long updateNotYetCount =
queryFactory
.update(yearEntity)
.set(yearEntity.status, "NOTYET")
.where(yearEntity.yyyy.eq(mngYyyy))
.execute();
} }
@Override @Override

View File

@@ -4,7 +4,6 @@ import static com.kamco.cd.kamcoback.postgres.entity.QModelMngEntity.modelMngEnt
import static com.kamco.cd.kamcoback.postgres.entity.QModelResultMetricEntity.modelResultMetricEntity; import static com.kamco.cd.kamcoback.postgres.entity.QModelResultMetricEntity.modelResultMetricEntity;
import com.kamco.cd.kamcoback.model.dto.ModelMngDto; import com.kamco.cd.kamcoback.model.dto.ModelMngDto;
import com.kamco.cd.kamcoback.postgres.QuerydslOrderUtil;
import com.kamco.cd.kamcoback.postgres.entity.ModelMngEntity; import com.kamco.cd.kamcoback.postgres.entity.ModelMngEntity;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Expression; import com.querydsl.core.types.Expression;
@@ -101,9 +100,10 @@ public class ModelMngRepositoryImpl extends QuerydslRepositorySupport
modelMngEntity.deleted.isFalse().or(modelMngEntity.deleted.isNull())) modelMngEntity.deleted.isFalse().or(modelMngEntity.deleted.isNull()))
.offset(pageable.getOffset()) .offset(pageable.getOffset())
.limit(pageable.getPageSize()) .limit(pageable.getPageSize())
.orderBy( .orderBy(modelMngEntity.createCompleteDttm.desc())
QuerydslOrderUtil.getOrderSpecifiers( // .orderBy(
pageable, ModelMngEntity.class, "modelMngEntity")) // QuerydslOrderUtil.getOrderSpecifiers(
// pageable, ModelMngEntity.class, "modelMngEntity"))
.fetch(); .fetch();
Long countQuery = Long countQuery =

View File

@@ -63,6 +63,8 @@ public class TrainingDataReviewJobRepositoryImpl extends QuerydslRepositorySuppo
.then(ModelType.G1.getId()) .then(ModelType.G1.getId())
.when(mapSheetLearnDataGeomEntity.classAfterCd.eq("waste")) .when(mapSheetLearnDataGeomEntity.classAfterCd.eq("waste"))
.then(ModelType.G2.getId()) .then(ModelType.G2.getId())
.when(mapSheetLearnDataGeomEntity.classAfterCd.eq("solar"))
.then(ModelType.G4.getId())
.otherwise(ModelType.G3.getId()), .otherwise(ModelType.G3.getId()),
mapSheetLearnDataGeomEntity.classBeforeCd, mapSheetLearnDataGeomEntity.classBeforeCd,
mapSheetLearnDataGeomEntity.classAfterCd))) mapSheetLearnDataGeomEntity.classAfterCd)))

View File

@@ -508,7 +508,7 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport
: "") : "")
.classificationName( .classificationName(
DetectionClassification.fromStrDesc( DetectionClassification.fromStrDesc(
mapSheetAnalDataInferenceGeomEntityEntity.getClassAfterCd())) mapSheetAnalDataInferenceGeomEntityEntity.getClassBeforeCd()))
.probability( .probability(
mapSheetAnalDataInferenceGeomEntityEntity.getClassBeforeProb() != null mapSheetAnalDataInferenceGeomEntityEntity.getClassBeforeProb() != null
? mapSheetAnalDataInferenceGeomEntityEntity.getClassBeforeProb() ? mapSheetAnalDataInferenceGeomEntityEntity.getClassBeforeProb()

View File

@@ -534,7 +534,7 @@ public class TrainingDataReviewRepositoryImpl extends QuerydslRepositorySupport
: "") : "")
.classificationName( .classificationName(
DetectionClassification.fromStrDesc( DetectionClassification.fromStrDesc(
mapSheetAnalDataInferenceGeomEntityEntity.getClassAfterCd())) mapSheetAnalDataInferenceGeomEntityEntity.getClassBeforeCd()))
.probability( .probability(
mapSheetAnalDataInferenceGeomEntityEntity.getClassBeforeProb() != null mapSheetAnalDataInferenceGeomEntityEntity.getClassBeforeProb() != null
? mapSheetAnalDataInferenceGeomEntityEntity.getClassBeforeProb() ? mapSheetAnalDataInferenceGeomEntityEntity.getClassBeforeProb()

View File

@@ -3,24 +3,30 @@ package com.kamco.cd.kamcoback.scheduler;
import com.kamco.cd.kamcoback.scheduler.service.MapSheetMngFileJobService; import com.kamco.cd.kamcoback.scheduler.service.MapSheetMngFileJobService;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Slf4j
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
public class MapSheetMngFileJobController { public class MapSheetMngFileJobController {
private final MapSheetMngFileJobService mapSheetMngFileJobService; private final MapSheetMngFileJobService mapSheetMngFileJobService;
@Value("${spring.profiles.active}")
private String profile;
// 현재 상태 확인용 Getter // 현재 상태 확인용 Getter
@Getter private boolean isSchedulerEnabled = false; @Getter private boolean isSchedulerEnabled = true;
@Getter private boolean isFileSyncSchedulerEnabled = false; @Getter private boolean isFileSyncSchedulerEnabled = false;
@Getter private int mngSyncPageSize = 20; @Getter private int mngSyncPageSize = 20;
// 파일싱크 진행여부 확인하기 // 파일싱크 진행여부 확인하기
@Scheduled(fixedDelay = 1000 * 10) @Scheduled(fixedDelay = 1000 * 10)
public void checkMngFileSync() { public void checkMngFileSync() {
if (!isSchedulerEnabled) { if ("local".equals(profile) || !isSchedulerEnabled) {
return; return;
} }

View File

@@ -21,6 +21,17 @@ public class AsyncConfig {
return ex; return ex;
} }
@Bean(name = "makeShapeFile")
public Executor makeShapeFileExecutor() {
ThreadPoolTaskExecutor ex = new ThreadPoolTaskExecutor();
ex.setCorePoolSize(2);
ex.setMaxPoolSize(4);
ex.setQueueCapacity(50);
ex.setThreadNamePrefix("makeShapeFile-");
ex.initialize();
return ex;
}
@Bean(name = "auditLogExecutor") @Bean(name = "auditLogExecutor")
public Executor auditLogExecutor() { public Executor auditLogExecutor() {
ThreadPoolTaskExecutor exec = new ThreadPoolTaskExecutor(); ThreadPoolTaskExecutor exec = new ThreadPoolTaskExecutor();
@@ -31,4 +42,16 @@ public class AsyncConfig {
exec.initialize(); exec.initialize();
return exec; return exec;
} }
// 0313
@Bean(name = "inferenceEndExecutor")
public Executor inferenceEndExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("inference-async-");
executor.initialize();
return executor;
}
} }

View File

@@ -121,7 +121,10 @@ public class MapSheetInferenceJobService {
* @return * @return
*/ */
private Long resolveBatchId(InferenceBatchSheet sheet) { private Long resolveBatchId(InferenceBatchSheet sheet) {
// G3 > G2 > G1 // G4 > G3 > G2 > G1
if (sheet.getM4BatchId() != null) {
return sheet.getM4BatchId();
}
if (sheet.getM3BatchId() != null) { if (sheet.getM3BatchId() != null) {
return sheet.getM3BatchId(); return sheet.getM3BatchId();
} }
@@ -214,8 +217,8 @@ public class MapSheetInferenceJobService {
// 현재 모델 종료 업데이트 // 현재 모델 종료 업데이트
updateProcessingEndTimeByModel(job, sheet.getUuid(), now, currentType); updateProcessingEndTimeByModel(job, sheet.getUuid(), now, currentType);
// G3이면 전체 종료 // G3이면 전체 종료 -> G4 이면 전체 종료(7/14)
if (ModelType.G3.getId().equals(currentType)) { if (ModelType.G4.getId().equals(currentType)) {
endAll(sheet, now); endAll(sheet, now);
return; return;
} }
@@ -237,7 +240,11 @@ public class MapSheetInferenceJobService {
private void endAll(InferenceBatchSheet sheet, ZonedDateTime now) { private void endAll(InferenceBatchSheet sheet, ZonedDateTime now) {
List<Long> batchIds = List<Long> batchIds =
Stream.of(sheet.getM1BatchId(), sheet.getM2BatchId(), sheet.getM3BatchId()) Stream.of(
sheet.getM1BatchId(),
sheet.getM2BatchId(),
sheet.getM3BatchId(),
sheet.getM4BatchId())
.filter(Objects::nonNull) .filter(Objects::nonNull)
.distinct() .distinct()
.toList(); .toList();
@@ -246,7 +253,7 @@ public class MapSheetInferenceJobService {
save.setUuid(sheet.getUuid()); save.setUuid(sheet.getUuid());
save.setStatus(Status.END.getId()); save.setStatus(Status.END.getId());
save.setInferEndDttm(now); save.setInferEndDttm(now);
save.setType(ModelType.G3.getId()); // 마지막 모델 기준 save.setType(ModelType.G4.getId()); // 마지막 모델 기준 -> G4 (7/14)
inferenceResultCoreService.update(save); inferenceResultCoreService.update(save);
// 추론 종료일때 geom 데이터 저장 // 추론 종료일때 geom 데이터 저장
@@ -255,7 +262,9 @@ public class MapSheetInferenceJobService {
// 추론 종료일때 shp 파일 생성 // 추론 종료일때 shp 파일 생성
String batchIdStr = batchIds.stream().map(String::valueOf).collect(Collectors.joining(",")); String batchIdStr = batchIds.stream().map(String::valueOf).collect(Collectors.joining(","));
// shp 파일 비동기 생성 // 0312 shp 파일 비동기 생성 (바꿔주세요)
// shpPipelineService.makeShapeFile(sheet.getUid(), batchIds);
// 0511 shp-exporter-v2.jar 에 에러가 있어 우선 기존 로직으로 변경함
shpPipelineService.runPipeline(jarPath, datasetDir, batchIdStr, sheet.getUid()); shpPipelineService.runPipeline(jarPath, datasetDir, batchIdStr, sheet.getUid());
} }
@@ -272,6 +281,9 @@ public class MapSheetInferenceJobService {
if (ModelType.G2.getId().equals(currentType)) { if (ModelType.G2.getId().equals(currentType)) {
return ModelType.G3.getId(); return ModelType.G3.getId();
} }
if (ModelType.G3.getId().equals(currentType)) {
return ModelType.G4.getId();
}
throw new IllegalArgumentException("Unknown runningModelType: " + currentType); throw new IllegalArgumentException("Unknown runningModelType: " + currentType);
} }
@@ -292,6 +304,9 @@ public class MapSheetInferenceJobService {
if (ModelType.G3.getId().equals(type)) { if (ModelType.G3.getId().equals(type)) {
return sheet.getM3ModelUuid(); return sheet.getM3ModelUuid();
} }
if (ModelType.G4.getId().equals(type)) {
return sheet.getM4ModelUuid();
}
throw new IllegalArgumentException("Unknown type: " + type); throw new IllegalArgumentException("Unknown type: " + type);
} }

View File

@@ -3,7 +3,7 @@ package com.kamco.cd.kamcoback.scheduler.service;
import com.kamco.cd.kamcoback.common.service.ExternalJarRunner; import com.kamco.cd.kamcoback.common.service.ExternalJarRunner;
import com.kamco.cd.kamcoback.postgres.core.InferenceResultCoreService; import com.kamco.cd.kamcoback.postgres.core.InferenceResultCoreService;
import com.kamco.cd.kamcoback.scheduler.config.ShpKeyLock; import com.kamco.cd.kamcoback.scheduler.config.ShpKeyLock;
import java.nio.file.Paths; import java.util.List;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
@@ -18,6 +18,30 @@ public class ShpPipelineService {
private final ExternalJarRunner externalJarRunner; private final ExternalJarRunner externalJarRunner;
private final ShpKeyLock shpKeyLock; private final ShpKeyLock shpKeyLock;
// 0312 shp 파일 비동기 생성
@Async("makeShapeFile")
public void makeShapeFile(String inferenceId, List<Long> batchIds) {
if (!shpKeyLock.tryLock(inferenceId)) {
log.info("");
log.info("============================================================");
log.info("SHP pipeline already running. inferenceId={}", inferenceId);
log.info("============================================================");
try {
log.info("SHP pipeline already start. inferenceId={}", inferenceId);
externalJarRunner.run(inferenceId, batchIds);
} catch (Exception e) {
log.error("SHP pipeline failed. inferenceId={}", inferenceId, e);
// TODO 실패 상태 업데이트 로직 추가
} finally {
log.info("============================================================");
log.info("SHP pipeline DONE. inferenceId={}", inferenceId);
log.info("============================================================");
log.info("");
shpKeyLock.unlock(inferenceId);
}
}
}
/** /**
* shp 파일 생성 1. merge 생성 2. 생성된 merge shp 파일로 geoserver 등록, 3.도엽별로 shp 생성 * shp 파일 생성 1. merge 생성 2. 생성된 merge shp 파일로 geoserver 등록, 3.도엽별로 shp 생성
* *
@@ -36,24 +60,33 @@ public class ShpPipelineService {
} }
try { try {
log.info("");
log.info("============================================================");
log.info("SHP pipeline started. inferenceId={}", inferenceId);
log.info("============================================================");
// uid 기준 merge shp, geojson 파일 생성 // uid 기준 merge shp, geojson 파일 생성
externalJarRunner.run(jarPath, batchIds, inferenceId, "", "MERGED"); externalJarRunner.run(jarPath, batchIds, inferenceId, "", "MERGED");
// uid 기준 shp 파일 geoserver 등록 // uid 기준 shp 파일 geoserver 등록
String register = // String register =
Paths.get(datasetDir, inferenceId, "merge", inferenceId + ".shp").toString(); // Paths.get(datasetDir, inferenceId, "merge", inferenceId + ".shp").toString();
log.info("register={}", register); // log.info("register={}", register);
externalJarRunner.run(jarPath, register, inferenceId); // externalJarRunner.run(jarPath, register, inferenceId);
//
// uid 기준 도엽별 shp, geojson 파일 생성 // // uid 기준 도엽별 shp, geojson 파일 생성
externalJarRunner.run(jarPath, batchIds, inferenceId, "", "RESOLVE"); // externalJarRunner.run(jarPath, batchIds, inferenceId, "", "RESOLVE");
//
log.info("SHP pipeline finished. inferenceId={}", inferenceId); // log.info("SHP pipeline finished. inferenceId={}", inferenceId);
} catch (Exception e) { } catch (Exception e) {
log.error("SHP pipeline failed. inferenceId={}", inferenceId, e); log.error("SHP pipeline failed. inferenceId={}", inferenceId, e);
// TODO 실패 상태 업데이트 로직 추가 // TODO 실패 상태 업데이트 로직 추가
} finally { } finally {
log.info("============================================================");
log.info("SHP pipeline DONE. inferenceId={}", inferenceId);
log.info("============================================================");
shpKeyLock.unlock(inferenceId); shpKeyLock.unlock(inferenceId);
} }
} }

View File

@@ -0,0 +1,83 @@
package com.kamco.cd.kamcoback.test;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.scheduler.service.ShpPipelineService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.ErrorResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "test shape api", description = "test shape api")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/test")
public class TestShapeApiController {
private final ShpPipelineService shpPipelineService;
@Value("${inference.jar-path}")
private String jarPath;
@Value("${file.dataset-dir}")
private String datasetDir;
@Operation(
summary = "shapefile 생성 테스트",
description = "지정된 inference ID와 batch ID 목록으로 shapefile을 생성합니다.")
@ApiResponses({
@ApiResponse(
responseCode = "200",
description = "shapefile 생성 요청 성공",
content = @Content(schema = @Schema(implementation = String.class))),
@ApiResponse(
responseCode = "400",
description = "잘못된 요청 데이터",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(
responseCode = "500",
description = "서버 오류",
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@GetMapping("/make-shapefile")
public ApiResponseDto<String> makeShapeFile(
@RequestParam String inferenceId, @RequestParam List<Long> batchIds) {
shpPipelineService.makeShapeFile(inferenceId, batchIds);
return ApiResponseDto.ok("Shapefile 생성이 시작되었습니다. inferenceId: " + inferenceId);
}
@Operation(
summary = "기존 run pipeline 테스트",
description = "지정된 inference ID와 batch ID 목록으로 shapefile을 생성합니다.")
@ApiResponses({
@ApiResponse(
responseCode = "200",
description = "shapefile 생성 요청 성공",
content = @Content(schema = @Schema(implementation = String.class))),
@ApiResponse(
responseCode = "400",
description = "잘못된 요청 데이터",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(
responseCode = "500",
description = "서버 오류",
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@GetMapping("/run-pipeline")
public ApiResponseDto<String> runPipeline(
@RequestParam String inferenceId, @RequestParam List<Long> batchIds) {
String batchIdStr = batchIds.stream().map(String::valueOf).collect(Collectors.joining(","));
shpPipelineService.runPipeline(jarPath, datasetDir, batchIdStr, inferenceId);
return ApiResponseDto.ok("runPipeline 생성이 시작되었습니다. inferenceId: " + inferenceId);
}
}

View File

@@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.kamco.cd.kamcoback.common.enums.ImageryFitStatus; import com.kamco.cd.kamcoback.common.enums.ImageryFitStatus;
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
import com.kamco.cd.kamcoback.common.utils.geometry.GeometryDeserializer; import com.kamco.cd.kamcoback.common.utils.geometry.GeometryDeserializer;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List; import java.util.List;
@@ -399,7 +400,10 @@ public class TrainingDataLabelDto {
private String memo; private String memo;
public InspectionResultInfo(String verificationResult, String inappropriateReason) { public InspectionResultInfo(String verificationResult, String inappropriateReason) {
this.verificationResult = ImageryFitStatus.fromCode(verificationResult).getText(); this.verificationResult =
HeaderUtil.isEnglishRequest()
? ImageryFitStatus.fromCode(verificationResult).getTextEn()
: ImageryFitStatus.fromCode(verificationResult).getText();
this.inappropriateReason = inappropriateReason; this.inappropriateReason = inappropriateReason;
} }
} }

View File

@@ -39,7 +39,7 @@ spring:
data: data:
redis: redis:
host: 192.168.2.109 host: 192.168.2.126
port: 6379 port: 6379
password: kamco password: kamco
@@ -59,8 +59,8 @@ jwt:
secret: "kamco_token_9b71e778-19a3-4c1d-97bf-2d687de17d5b" secret: "kamco_token_9b71e778-19a3-4c1d-97bf-2d687de17d5b"
access-token-validity-in-ms: 86400000 # 1일 access-token-validity-in-ms: 86400000 # 1일
refresh-token-validity-in-ms: 604800000 # 7일 refresh-token-validity-in-ms: 604800000 # 7일
#access-token-validity-in-ms: 60000 # 1 #access-token-validity-in-ms: 300000 # 5
#refresh-token-validity-in-ms: 300000 # 5 #refresh-token-validity-in-ms: 600000 # 10
token: token:
refresh-cookie-name: kamco-dev # 개발용 쿠키 이름 refresh-cookie-name: kamco-dev # 개발용 쿠키 이름
@@ -100,6 +100,7 @@ inference:
url: http://192.168.2.183:8000/jobs url: http://192.168.2.183:8000/jobs
batch-url: http://192.168.2.183:8000/batches batch-url: http://192.168.2.183:8000/batches
jar-path: ${inference.nfs}/repo/jar/shp-exporter.jar jar-path: ${inference.nfs}/repo/jar/shp-exporter.jar
jar-path-v2: ${inference.nfs}/repo/jar/shp-exporter-v2.jar
inference-server-name: server1,server2,server3,server4 inference-server-name: server1,server2,server3,server4
output-dir: ${inference.nfs}/model_output/export output-dir: ${inference.nfs}/model_output/export

View File

@@ -27,7 +27,7 @@ spring:
data: data:
redis: redis:
host: 192.168.2.109 host: 192.168.2.126
port: 6379 port: 6379
password: kamco password: kamco
@@ -78,6 +78,7 @@ inference:
url: http://10.100.0.11:8000/jobs url: http://10.100.0.11:8000/jobs
batch-url: http://10.100.0.11:8000/batches batch-url: http://10.100.0.11:8000/batches
jar-path: jar/shp-exporter.jar jar-path: jar/shp-exporter.jar
jar-path-v2: jar/shp-exporter-v2.jar
inference-server-name: server1,server2,server3,server4 inference-server-name: server1,server2,server3,server4
output-dir: ${inference.nfs}/model_output/export output-dir: ${inference.nfs}/model_output/export

View File

@@ -95,6 +95,8 @@ inference:
url: http://172.16.4.56:8000/jobs url: http://172.16.4.56:8000/jobs
batch-url: http://172.16.4.56:8000/batches batch-url: http://172.16.4.56:8000/batches
jar-path: ${inference.nfs}/repo/jar/shp-exporter.jar jar-path: ${inference.nfs}/repo/jar/shp-exporter.jar
# //0312
jar-path-v2: ${inference.nfs}/repo/jar/shp-exporter-v2.jar
inference-server-name: server1,server2,server3,server4 inference-server-name: server1,server2,server3,server4
output-dir: ${inference.nfs}/model_output/export output-dir: ${inference.nfs}/model_output/export

View File

@@ -88,3 +88,6 @@ inference:
nfs: /kamco-nfs nfs: /kamco-nfs
geojson-dir: ${inference.nfs}/requests/ # 추론실행을 위한 파일생성경로 geojson-dir: ${inference.nfs}/requests/ # 추론실행을 위한 파일생성경로
jar-path: ${inference.nfs}/repo/jar/shp-exporter.jar jar-path: ${inference.nfs}/repo/jar/shp-exporter.jar
# //0312
jar-path-v2: ${inference.nfs}/repo/jar/shp-exporter-v2.jar