Merge remote-tracking branch 'origin/feat/dev_251201' into feat/dev_251201

# Conflicts:
#	src/main/java/com/kamco/cd/kamcoback/mapsheet/dto/MapSheetMngDto.java
#	src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java
This commit is contained in:
Moon
2025-12-18 16:28:46 +09:00
26 changed files with 240 additions and 79 deletions

View File

@@ -80,6 +80,7 @@ dependencies {
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.5' // JSON (Jackson)
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
implementation 'org.reflections:reflections:0.10.2'
}
configurations.configureEach {

View File

@@ -2,6 +2,7 @@ package com.kamco.cd.kamcoback.code;
import com.kamco.cd.kamcoback.code.config.CommonCodeCacheManager;
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto;
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.CodeDto;
import com.kamco.cd.kamcoback.code.service.CommonCodeService;
import com.kamco.cd.kamcoback.common.utils.CommonCodeUtil;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
@@ -13,6 +14,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
@@ -288,4 +290,38 @@ public class CommonCodeApiController {
int count = commonCodeCacheManager.getCachedCommonCodeCount();
return ApiResponseDto.ok(count);
}
@Operation(summary = "코드 조회", description = "코드 리스트 조회")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "코드 조회 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = CodeDto.class))),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@GetMapping("/type/codes")
public ApiResponseDto<Map<String, List<CodeDto>>> getTypeCodes() {
return ApiResponseDto.ok(commonCodeService.getTypeCodes());
}
@Operation(summary = "코드 단건 조회", description = "코드 조회")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "코드 조회 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = CodeDto.class))),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@GetMapping("/type/{type}")
public ApiResponseDto<List<CodeDto>> getTypeCode(@PathVariable String type) {
return ApiResponseDto.ok(commonCodeService.getTypeCode(type));
}
}

View File

@@ -50,6 +50,7 @@ public class CommonCodeDto {
@NoArgsConstructor
@AllArgsConstructor
public static class ModifyReq {
@NotEmpty private String name;
private String description;
private boolean used;
@@ -70,6 +71,7 @@ public class CommonCodeDto {
@NoArgsConstructor
@AllArgsConstructor
public static class OrderReq {
@NotNull private Long id;
@NotNull private Integer order;
}
@@ -176,4 +178,12 @@ public class CommonCodeDto {
this.color = color;
}
}
@Getter
@AllArgsConstructor
public static class CodeDto {
private String code;
private String name;
}
}

View File

@@ -2,11 +2,14 @@ package com.kamco.cd.kamcoback.code.service;
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.AddReq;
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.Basic;
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.CodeDto;
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.ModifyReq;
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.OrderReq;
import com.kamco.cd.kamcoback.common.utils.enums.Enums;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.postgres.core.CommonCodeCoreService;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
@@ -118,4 +121,17 @@ public class CommonCodeService {
public Optional<String> getCode(String parentCodeCd, String childCodeCd) {
return commonCodeCoreService.getCode(parentCodeCd, childCodeCd);
}
public List<CodeDto> getTypeCode(String type) {
return Enums.getCodes(type);
}
/**
* 공통코드 리스트 조회
*
* @return
*/
public Map<String, List<CodeDto>> getTypeCodes() {
return Enums.getAllCodes();
}
}

View File

@@ -1,9 +1,11 @@
package com.kamco.cd.kamcoback.common.enums;
import com.kamco.cd.kamcoback.config.enums.EnumType;
import com.kamco.cd.kamcoback.common.utils.enums.CodeExpose;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import lombok.AllArgsConstructor;
import lombok.Getter;
@CodeExpose
@Getter
@AllArgsConstructor
public enum MngStateType implements EnumType {

View File

@@ -1,9 +1,11 @@
package com.kamco.cd.kamcoback.common.enums;
import com.kamco.cd.kamcoback.config.enums.EnumType;
import com.kamco.cd.kamcoback.common.utils.enums.CodeExpose;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import lombok.AllArgsConstructor;
import lombok.Getter;
@CodeExpose
@Getter
@AllArgsConstructor
public enum RoleType implements EnumType {

View File

@@ -1,9 +1,11 @@
package com.kamco.cd.kamcoback.common.enums;
import com.kamco.cd.kamcoback.config.enums.EnumType;
import com.kamco.cd.kamcoback.common.utils.enums.CodeExpose;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import lombok.AllArgsConstructor;
import lombok.Getter;
@CodeExpose
@Getter
@AllArgsConstructor
public enum StatusType implements EnumType {

View File

@@ -1,9 +1,11 @@
package com.kamco.cd.kamcoback.common.enums;
import com.kamco.cd.kamcoback.config.enums.EnumType;
import com.kamco.cd.kamcoback.common.utils.enums.CodeExpose;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import lombok.AllArgsConstructor;
import lombok.Getter;
@CodeExpose
@Getter
@AllArgsConstructor
public enum SyncStateType implements EnumType {

View File

@@ -1,19 +0,0 @@
package com.kamco.cd.kamcoback.common.utils;
import com.kamco.cd.kamcoback.config.enums.EnumType;
public class Enums {
// code로 text
public static <E extends Enum<E> & EnumType> E fromId(Class<E> enumClass, String id) {
if (id == null) {
return null;
}
for (E e : enumClass.getEnumConstants()) {
if (id.equalsIgnoreCase(e.getId())) {
return e;
}
}
return null; // 못 찾으면 null
}
}

View File

@@ -0,0 +1,20 @@
package com.kamco.cd.kamcoback.common.utils.enums;
public class CodeDto {
private String code;
private String name;
public CodeDto(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public String getName() {
return name;
}
}

View File

@@ -0,0 +1,10 @@
package com.kamco.cd.kamcoback.common.utils.enums;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CodeExpose {}

View File

@@ -1,4 +1,4 @@
package com.kamco.cd.kamcoback.config.enums;
package com.kamco.cd.kamcoback.common.utils.enums;
public interface EnumType {

View File

@@ -1,4 +1,4 @@
package com.kamco.cd.kamcoback.common.utils;
package com.kamco.cd.kamcoback.common.utils.enums;
import com.kamco.cd.kamcoback.common.utils.interfaces.EnumValid;
import jakarta.validation.ConstraintValidator;

View File

@@ -0,0 +1,75 @@
package com.kamco.cd.kamcoback.common.utils.enums;
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.CodeDto;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.reflections.Reflections;
public class Enums {
private static final String BASE_PACKAGE = "com.kamco.cd.kamcoback";
/** 노출 가능한 enum만 모아둔 맵 key: enum simpleName (예: RoleType) value: enum Class */
private static final Map<String, Class<? extends Enum<?>>> exposedEnumMap = scanExposedEnumMap();
// code로 enum 찾기
public static <E extends Enum<E> & EnumType> E fromId(Class<E> enumClass, String id) {
if (id == null) {
return null;
}
for (E e : enumClass.getEnumConstants()) {
if (id.equalsIgnoreCase(e.getId())) {
return e;
}
}
return null;
}
// enum -> CodeDto list
public static List<CodeDto> toList(Class<? extends Enum<?>> enumClass) {
Object[] enums = enumClass.getEnumConstants();
return Arrays.stream(enums)
.map(e -> (EnumType) e)
.map(e -> new CodeDto(e.getId(), e.getText()))
.toList();
}
/** 특정 타입(enum)만 조회 /codes/{type} -> type = RoleType 같은 값 */
public static List<CodeDto> getCodes(String type) {
Class<? extends Enum<?>> enumClass = exposedEnumMap.get(type);
if (enumClass == null) {
throw new IllegalArgumentException("지원하지 않는 코드 타입: " + type);
}
return toList(enumClass);
}
/** 전체 enum 코드 조회 */
public static Map<String, List<CodeDto>> getAllCodes() {
Map<String, List<CodeDto>> result = new HashMap<>();
for (Map.Entry<String, Class<? extends Enum<?>>> e : exposedEnumMap.entrySet()) {
result.put(e.getKey(), toList(e.getValue()));
}
return result;
}
/** ✅ @CodeExpose + EnumType 인 enum만 스캔해서 Map 구성 */
private static Map<String, Class<? extends Enum<?>>> scanExposedEnumMap() {
Reflections reflections = new Reflections(BASE_PACKAGE);
Set<Class<?>> types = reflections.getTypesAnnotatedWith(CodeExpose.class);
Map<String, Class<? extends Enum<?>>> result = new HashMap<>();
for (Class<?> clazz : types) {
if (clazz.isEnum() && EnumType.class.isAssignableFrom(clazz)) {
result.put(clazz.getSimpleName(), (Class<? extends Enum<?>>) clazz);
}
}
return result;
}
}

View File

@@ -1,6 +1,6 @@
package com.kamco.cd.kamcoback.common.utils.interfaces;
import com.kamco.cd.kamcoback.common.utils.EnumValidator;
import com.kamco.cd.kamcoback.common.utils.enums.EnumValidator;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.ElementType;

View File

@@ -2,7 +2,7 @@ package com.kamco.cd.kamcoback.config.api;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.kamco.cd.kamcoback.config.enums.EnumType;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

View File

@@ -1,6 +1,6 @@
package com.kamco.cd.kamcoback.log.dto;
import com.kamco.cd.kamcoback.config.enums.EnumType;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDate;
import lombok.AllArgsConstructor;

View File

@@ -1,6 +1,6 @@
package com.kamco.cd.kamcoback.log.dto;
import com.kamco.cd.kamcoback.config.enums.EnumType;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import lombok.AllArgsConstructor;
import lombok.Getter;

View File

@@ -1,6 +1,6 @@
package com.kamco.cd.kamcoback.log.dto;
import com.kamco.cd.kamcoback.config.enums.EnumType;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import lombok.AllArgsConstructor;
import lombok.Getter;

View File

@@ -107,17 +107,17 @@ public class MapSheetMngApiController {
@Operation(summary = "영상 데이터 관리 년도 목록", description = "영상 데이터 관리 년도 목록")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "조회 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = CommonCodeDto.Basic.class))),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "200",
description = "조회 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = CommonCodeDto.Basic.class))),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PostMapping("/mng-year-list")
public ApiResponseDto<List<Integer>> findMapSheetMngYyyyList() {
@@ -126,24 +126,23 @@ public class MapSheetMngApiController {
@Operation(summary = "영상 데이터 관리 오류 목록", description = "영상 데이터 관리 오류 목록")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "조회 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = CommonCodeDto.Basic.class))),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "200",
description = "조회 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = CommonCodeDto.Basic.class))),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PostMapping("/error-list")
public ApiResponseDto<Page<MapSheetMngDto.ErrorDataDto>> findMapSheetErrorList(
@RequestBody @Valid MapSheetMngDto.ErrorSearchReq searchReq) {
return ApiResponseDto.ok(mapSheetMngService.findMapSheetErrorList(searchReq));
}
@Operation(summary = "오류데이터 팝업 > 업로드 처리", description = "오류데이터 팝업 > 업로드 처리")
@ApiResponses(
value = {
@@ -164,7 +163,6 @@ public class MapSheetMngApiController {
return ApiResponseDto.ok(mapSheetMngService.uploadProcess(hstUidList));
}
@Operation(summary = "오류데이터 팝업 > 추론 제외", description = "오류데이터 팝업 > 추론 제외")
@PutMapping("/except-inference")
public ApiResponseDto<MapSheetMngDto.DmlReturn> updateExceptUseInference(
@@ -183,18 +181,18 @@ public class MapSheetMngApiController {
@Operation(summary = "영상관리 > 파일조회", description = "영상관리 > 파일조회")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "파일삭제 처리 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Long.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "201",
description = "파일삭제 처리 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Long.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@GetMapping("/mng-file-list")
public ApiResponseDto<List<MapSheetMngDto.MngFilesDto>> findHstUidToMapSheetFileList(
@RequestParam @Valid Long hstUid) {

View File

@@ -2,7 +2,7 @@ package com.kamco.cd.kamcoback.members.dto;
import com.kamco.cd.kamcoback.common.enums.RoleType;
import com.kamco.cd.kamcoback.common.enums.StatusType;
import com.kamco.cd.kamcoback.common.utils.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.JsonFormatDttm;
import io.swagger.v3.oas.annotations.media.Schema;

View File

@@ -41,7 +41,6 @@ public class MapSheetMngCoreService {
return mapSheetMngRepository.findMapSheetMngYyyyList();
}
public MapSheetMngDto.MngDto findMapSheetMng(int mngYyyy) {
return mapSheetMngRepository.findMapSheetMng(mngYyyy);
}

View File

@@ -170,14 +170,14 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport
return foundContent;
}
public List<Integer> findMapSheetMngYyyyList(){
public List<Integer> findMapSheetMngYyyyList() {
List<Integer> foundContent =
queryFactory
.select(mapSheetMngEntity.mngYyyy)
.from(mapSheetMngEntity)
.where(mapSheetMngEntity.mngState.ne("COMPLETE"))
.orderBy(mapSheetMngEntity.mngYyyy.desc())
.fetch();
queryFactory
.select(mapSheetMngEntity.mngYyyy)
.from(mapSheetMngEntity)
.where(mapSheetMngEntity.mngState.ne("COMPLETE"))
.orderBy(mapSheetMngEntity.mngYyyy.desc())
.fetch();
return foundContent;
}

View File

@@ -65,7 +65,14 @@ public class ModelMgmtRepositoryImpl extends QuerydslRepositorySupport
ModelMgmtDto.ModelList.class,
Expressions.numberTemplate(
Integer.class, "row_number() over(order by {0} desc)", sortColumn),
modelMgmtEntity.modelVer,
Expressions.stringTemplate(
"concat({0}, {1}, {2}, {3}, {4})",
modelMgmtEntity.modelVer,
".",
modelMgmtEntity.hyperVer,
".",
modelMgmtEntity.epochVer)
.as("modelVer"),
modelMgmtEntity.dockerFileNm,
modelMgmtEntity.modelVer.as("modelType"),
Expressions.stringTemplate(

View File

@@ -2,7 +2,7 @@ package com.kamco.cd.kamcoback.zoo.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.kamco.cd.kamcoback.config.enums.EnumType;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.ZonedDateTime;
import lombok.AllArgsConstructor;

View File

@@ -15,8 +15,8 @@ spring:
format_sql: true # ⚠️ 선택 - SQL 포맷팅 (가독성)
datasource:
#url: jdbc:postgresql://192.168.2.127:15432/kamco_cds
url: jdbc:postgresql://localhost:15432/kamco_cds
url: jdbc:postgresql://192.168.2.127:15432/kamco_cds
#url: jdbc:postgresql://localhost:15432/kamco_cds
username: kamco_cds
password: kamco_cds_Q!W@E#R$
hikari: