Merge pull request 'feat/dev_251201' (#144) from feat/dev_251201 into develop

Reviewed-on: https://kamco.gitea.gs.dabeeo.com/dabeeo/kamco-dabeeo-backoffice/pulls/144
This commit is contained in:
2026-01-05 16:33:30 +09:00
5 changed files with 58 additions and 44 deletions

View File

@@ -7,6 +7,7 @@ import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastSearch;
import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.FeaturePnuDto; import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.FeaturePnuDto;
import com.kamco.cd.kamcoback.Innopam.service.DetectMastService; import com.kamco.cd.kamcoback.Innopam.service.DetectMastService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponse;
@@ -14,6 +15,7 @@ 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.validation.Valid; import jakarta.validation.Valid;
import java.util.List; import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@@ -123,32 +125,42 @@ public class InnopamApiController {
content = content =
@Content( @Content(
mediaType = "application/json", mediaType = "application/json",
schema = @Schema(implementation = Basic.class))), schema = @Schema(implementation = FeaturePnuDto.class))),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
}) })
@GetMapping("/pnu/{cprsBfYr}/{cprsAfYr}/{dtctSno}") @GetMapping("/pnu/{cprsBfYr}/{cprsAfYr}/{dtctSno}")
public List<FeaturePnuDto> selectPnuList( public List<FeaturePnuDto> selectPnuList(
@PathVariable String cprsBfYr, @PathVariable String cprsAfYr, @PathVariable String dtctSno) { @PathVariable String cprsBfYr, @PathVariable String cprsAfYr, @PathVariable Integer dtctSno) {
DetectMastSearch detectMastSearch = new DetectMastSearch(); DetectMastSearch detectMastSearch = new DetectMastSearch();
detectMastSearch.setCprsAdYr(cprsAfYr); detectMastSearch.setCprsAdYr(cprsAfYr);
detectMastSearch.setCprsBfYr(cprsBfYr); detectMastSearch.setCprsBfYr(cprsBfYr);
detectMastSearch.setDtctSno(Integer.parseInt(dtctSno)); detectMastSearch.setDtctSno(dtctSno);
return detectMastService.findPnuData(detectMastSearch); return detectMastService.findPnuData(detectMastSearch);
} }
@Operation(summary = "탐지객체 랜덤 PNU 상세 조회", description = "탐지객체 PNU 랜덤값을 생성해서 보여준다")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "목록 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = FeaturePnuDto.class))),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@GetMapping("/pnu/{cprsBfYr}/{cprsAfYr}/{dtctSno}/{featureId}") @GetMapping("/pnu/{cprsBfYr}/{cprsAfYr}/{dtctSno}/{featureId}")
public FeaturePnuDto selectPnuDetail( public FeaturePnuDto selectPnuDetail(
@PathVariable String cprsBfYr, @Parameter(description = "이전년도", example = "2022") @PathVariable String cprsBfYr,
@PathVariable String cprsAfYr, @Parameter(description = "기준년도", example = "2024") @PathVariable String cprsAfYr,
@PathVariable String dtctSno, @Parameter(description = "회차", example = "4") @PathVariable Integer dtctSno,
@PathVariable String featureId) { @Parameter(description = "featureId", example = "000e161b-1955-4c89-ad87-0b3b4a91d00f")
DetectMastSearch detectMastSearch = new DetectMastSearch(); @PathVariable
detectMastSearch.setCprsAdYr(cprsAfYr); UUID featureId) {
detectMastSearch.setCprsBfYr(cprsBfYr); return detectMastService.selectPnuDetail(featureId);
detectMastSearch.setDtctSno(Integer.parseInt(dtctSno));
detectMastSearch.setFeatureId(featureId);
return new FeaturePnuDto();
} }
@Operation( @Operation(
@@ -168,11 +180,11 @@ public class InnopamApiController {
}) })
@PutMapping("/pnu/{cprsBfYr}/{cprsAfYr}/{dtctSno}") @PutMapping("/pnu/{cprsBfYr}/{cprsAfYr}/{dtctSno}")
public Integer updatePnuList( public Integer updatePnuList(
@PathVariable String cprsBfYr, @PathVariable String cprsAfYr, @PathVariable String dtctSno) { @PathVariable String cprsBfYr, @PathVariable String cprsAfYr, @PathVariable Integer dtctSno) {
DetectMastSearch detectMastSearch = new DetectMastSearch(); DetectMastSearch detectMastSearch = new DetectMastSearch();
detectMastSearch.setCprsAdYr(cprsAfYr); detectMastSearch.setCprsAdYr(cprsAfYr);
detectMastSearch.setCprsBfYr(cprsBfYr); detectMastSearch.setCprsBfYr(cprsBfYr);
detectMastSearch.setDtctSno(Integer.parseInt(dtctSno)); detectMastSearch.setDtctSno(dtctSno);
return detectMastService.updatePnuData(detectMastSearch); return detectMastService.updatePnuData(detectMastSearch);
} }
} }

View File

@@ -14,6 +14,7 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Stream; import java.util.stream.Stream;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@@ -68,6 +69,13 @@ public class DetectMastService {
return extractFeaturePnusRandom(dirPath); return extractFeaturePnusRandom(dirPath);
} }
public FeaturePnuDto selectPnuDetail(UUID uuid) {
FeaturePnuDto dto = new FeaturePnuDto();
dto.setPnu(randomPnu());
dto.setFeatureId(uuid.toString());
return dto;
}
@Transactional @Transactional
public Integer updatePnuData(DetectMastSearch detectMast) { public Integer updatePnuData(DetectMastSearch detectMast) {

View File

@@ -40,6 +40,7 @@ public class LabelWorkDto {
@JsonFormatDttm private ZonedDateTime createdDttm; @JsonFormatDttm private ZonedDateTime createdDttm;
private Long detectionTotCnt; private Long detectionTotCnt;
private Long labelTotCnt; private Long labelTotCnt;
private Long labelAssignCnt;
private Long labelStopTotCnt; private Long labelStopTotCnt;
private Long labelIngTotCnt; private Long labelIngTotCnt;
private Long labelCompleteTotCnt; private Long labelCompleteTotCnt;
@@ -59,7 +60,7 @@ public class LabelWorkDto {
if (this.labelTotCnt == 0) { if (this.labelTotCnt == 0) {
mngState = "PENDING"; mngState = "PENDING";
} else if (this.labelTotCnt > 0 && this.labelIngTotCnt == 0) { } else if (this.labelTotCnt > 0 && this.labelAssignCnt > 0 && this.labelIngTotCnt == 0) {
mngState = "ASSIGNED"; mngState = "ASSIGNED";
} else if (this.labelIngTotCnt > 0) { } else if (this.labelIngTotCnt > 0) {
mngState = "LABEL_ING"; mngState = "LABEL_ING";

View File

@@ -41,8 +41,6 @@ import java.time.format.DateTimeFormatter;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@@ -72,6 +70,7 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
.from(mapSheetAnalDataInferenceGeomEntity) .from(mapSheetAnalDataInferenceGeomEntity)
.where( .where(
lastId == null ? null : mapSheetAnalDataInferenceGeomEntity.geoUid.gt(lastId), lastId == null ? null : mapSheetAnalDataInferenceGeomEntity.geoUid.gt(lastId),
mapSheetAnalDataInferenceGeomEntity.pnu.isNotNull(),
mapSheetAnalDataInferenceGeomEntity.compareYyyy.eq(compareYyyy), mapSheetAnalDataInferenceGeomEntity.compareYyyy.eq(compareYyyy),
mapSheetAnalDataInferenceGeomEntity.targetYyyy.eq(targetYyyy), mapSheetAnalDataInferenceGeomEntity.targetYyyy.eq(targetYyyy),
mapSheetAnalDataInferenceGeomEntity.stage.eq(stage), mapSheetAnalDataInferenceGeomEntity.stage.eq(stage),
@@ -160,6 +159,7 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
.select(mapSheetAnalDataInferenceGeomEntity.geoUid.count()) .select(mapSheetAnalDataInferenceGeomEntity.geoUid.count())
.from(mapSheetAnalDataInferenceGeomEntity) .from(mapSheetAnalDataInferenceGeomEntity)
.where( .where(
mapSheetAnalDataInferenceGeomEntity.pnu.isNotNull(),
mapSheetAnalDataInferenceGeomEntity.compareYyyy.eq(compareYyyy), mapSheetAnalDataInferenceGeomEntity.compareYyyy.eq(compareYyyy),
mapSheetAnalDataInferenceGeomEntity.targetYyyy.eq(targetYyyy), mapSheetAnalDataInferenceGeomEntity.targetYyyy.eq(targetYyyy),
mapSheetAnalDataInferenceGeomEntity.stage.eq(stage), mapSheetAnalDataInferenceGeomEntity.stage.eq(stage),
@@ -648,9 +648,9 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
.select( .select(
mapSheetAnalInferenceEntity.compareYyyy, mapSheetAnalInferenceEntity.compareYyyy,
mapSheetAnalInferenceEntity.targetYyyy, mapSheetAnalInferenceEntity.targetYyyy,
mapSheetAnalInferenceEntity.analTitle, mapSheetAnalInferenceEntity.stage,
mapSheetAnalInferenceEntity.gukyuinApplyDttm, mapSheetAnalInferenceEntity.gukyuinApplyDttm,
mapSheetAnalInferenceEntity.analStrtDttm, mapSheetAnalInferenceEntity.createdDttm,
mapSheetAnalInferenceEntity.uuid) mapSheetAnalInferenceEntity.uuid)
.from(mapSheetAnalInferenceEntity) .from(mapSheetAnalInferenceEntity)
.where(mapSheetAnalInferenceEntity.id.eq(analUid)) .where(mapSheetAnalInferenceEntity.id.eq(analUid))
@@ -662,23 +662,23 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
Integer compareYyyy = result.get(mapSheetAnalInferenceEntity.compareYyyy); Integer compareYyyy = result.get(mapSheetAnalInferenceEntity.compareYyyy);
Integer targetYyyy = result.get(mapSheetAnalInferenceEntity.targetYyyy); Integer targetYyyy = result.get(mapSheetAnalInferenceEntity.targetYyyy);
String analTitle = result.get(mapSheetAnalInferenceEntity.analTitle); Integer stage = result.get(mapSheetAnalInferenceEntity.stage);
ZonedDateTime gukyuinApplyDttm = result.get(mapSheetAnalInferenceEntity.gukyuinApplyDttm); ZonedDateTime gukyuinApplyDttm = result.get(mapSheetAnalInferenceEntity.gukyuinApplyDttm);
ZonedDateTime analStrtDttm = result.get(mapSheetAnalInferenceEntity.analStrtDttm); ZonedDateTime createdDttm = result.get(mapSheetAnalInferenceEntity.createdDttm);
UUID uuid = result.get(mapSheetAnalInferenceEntity.uuid); UUID uuid = result.get(mapSheetAnalInferenceEntity.uuid);
// 변화탐지년도 생성 // 변화탐지년도 생성
String detectionYear = String detectionYear =
(compareYyyy != null && targetYyyy != null) ? compareYyyy + "-" + targetYyyy : null; (compareYyyy != null && targetYyyy != null) ? compareYyyy + "-" + targetYyyy : null;
// 회차 추출 (예: "8회차" → "8") // 회차를 stage 컬럼에서 가져옴
String round = extractRoundFromTitle(analTitle); String round = stage != null ? String.valueOf(stage) : null;
return ProjectInfo.builder() return ProjectInfo.builder()
.detectionYear(detectionYear) .detectionYear(detectionYear)
.round(round) .round(round)
.reflectionDate(formatDate(gukyuinApplyDttm)) .reflectionDate(formatDate(gukyuinApplyDttm))
.startDate(formatDate(analStrtDttm)) .startDate(formatDate(createdDttm))
.uuid(uuid != null ? uuid.toString() : null) .uuid(uuid != null ? uuid.toString() : null)
.build(); .build();
} }
@@ -691,9 +691,9 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
.select( .select(
mapSheetAnalInferenceEntity.compareYyyy, mapSheetAnalInferenceEntity.compareYyyy,
mapSheetAnalInferenceEntity.targetYyyy, mapSheetAnalInferenceEntity.targetYyyy,
mapSheetAnalInferenceEntity.analTitle, mapSheetAnalInferenceEntity.stage,
mapSheetAnalInferenceEntity.gukyuinApplyDttm, mapSheetAnalInferenceEntity.gukyuinApplyDttm,
mapSheetAnalInferenceEntity.analStrtDttm, mapSheetAnalInferenceEntity.createdDttm,
mapSheetAnalInferenceEntity.uuid) mapSheetAnalInferenceEntity.uuid)
.from(mapSheetAnalInferenceEntity) .from(mapSheetAnalInferenceEntity)
.orderBy( .orderBy(
@@ -709,39 +709,27 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
Integer compareYyyy = result.get(mapSheetAnalInferenceEntity.compareYyyy); Integer compareYyyy = result.get(mapSheetAnalInferenceEntity.compareYyyy);
Integer targetYyyy = result.get(mapSheetAnalInferenceEntity.targetYyyy); Integer targetYyyy = result.get(mapSheetAnalInferenceEntity.targetYyyy);
String analTitle = result.get(mapSheetAnalInferenceEntity.analTitle); Integer stage = result.get(mapSheetAnalInferenceEntity.stage);
ZonedDateTime gukyuinApplyDttm = result.get(mapSheetAnalInferenceEntity.gukyuinApplyDttm); ZonedDateTime gukyuinApplyDttm = result.get(mapSheetAnalInferenceEntity.gukyuinApplyDttm);
ZonedDateTime analStrtDttm = result.get(mapSheetAnalInferenceEntity.analStrtDttm); ZonedDateTime createdDttm = result.get(mapSheetAnalInferenceEntity.createdDttm);
UUID uuid = result.get(mapSheetAnalInferenceEntity.uuid); UUID uuid = result.get(mapSheetAnalInferenceEntity.uuid);
// 변화탐지년도 생성 // 변화탐지년도 생성
String detectionYear = String detectionYear =
(compareYyyy != null && targetYyyy != null) ? compareYyyy + "-" + targetYyyy : null; (compareYyyy != null && targetYyyy != null) ? compareYyyy + "-" + targetYyyy : null;
// 회차 추출 (예: "8회차" → "8") // 회차를 stage 컬럼에서 가져옴
String round = extractRoundFromTitle(analTitle); String round = stage != null ? String.valueOf(stage) : null;
return ProjectInfo.builder() return ProjectInfo.builder()
.detectionYear(detectionYear) .detectionYear(detectionYear)
.round(round) .round(round)
.reflectionDate(formatDate(gukyuinApplyDttm)) .reflectionDate(formatDate(gukyuinApplyDttm))
.startDate(formatDate(analStrtDttm)) .startDate(formatDate(createdDttm))
.uuid(uuid != null ? uuid.toString() : null) .uuid(uuid != null ? uuid.toString() : null)
.build(); .build();
} }
/** 제목에서 회차 숫자 추출 예: "8회차", "제8회차" → "8" */
private String extractRoundFromTitle(String title) {
if (title == null || title.isEmpty()) {
return null;
}
Pattern pattern = Pattern.compile("(\\d+)회차");
Matcher matcher = pattern.matcher(title);
return matcher.find() ? matcher.group(1) : null;
}
/** ZonedDateTime을 "yyyy-MM-dd" 형식으로 변환 */ /** ZonedDateTime을 "yyyy-MM-dd" 형식으로 변환 */
private String formatDate(ZonedDateTime dateTime) { private String formatDate(ZonedDateTime dateTime) {
if (dateTime == null) { if (dateTime == null) {

View File

@@ -137,6 +137,11 @@ public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport
.then(1L) .then(1L)
.otherwise(0L) .otherwise(0L)
.sum(), .sum(),
new CaseBuilder()
.when(mapSheetAnalDataInferenceGeomEntity.labelState.eq("ASSIGNED"))
.then(1L)
.otherwise(0L)
.sum(),
new CaseBuilder() new CaseBuilder()
.when(mapSheetAnalDataInferenceGeomEntity.labelState.eq("STOP")) .when(mapSheetAnalDataInferenceGeomEntity.labelState.eq("STOP"))
.then(1L) .then(1L)