스케줄링 수동 호출, 영상관리 싱크 자동추론제외 수정 #90

Merged
gina merged 1 commits from feat/infer_dev_260211 into develop 2026-02-24 15:06:45 +09:00
25 changed files with 330 additions and 188 deletions

View File

@@ -11,11 +11,6 @@ import com.kamco.cd.kamcoback.gukyuin.dto.DetectMastDto.Basic;
import com.kamco.cd.kamcoback.gukyuin.dto.DetectMastDto.DetectMastReq; import com.kamco.cd.kamcoback.gukyuin.dto.DetectMastDto.DetectMastReq;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GukYuinLinkableRes; import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GukYuinLinkableRes;
import com.kamco.cd.kamcoback.gukyuin.service.GukYuinApiService; import com.kamco.cd.kamcoback.gukyuin.service.GukYuinApiService;
import com.kamco.cd.kamcoback.scheduler.service.GukYuinApiLabelJobService;
import com.kamco.cd.kamcoback.scheduler.service.GukYuinApiPnuJobService;
import com.kamco.cd.kamcoback.scheduler.service.GukYuinApiStatusJobService;
import com.kamco.cd.kamcoback.scheduler.service.GukYuinApiStbltJobService;
import io.swagger.v3.oas.annotations.Hidden;
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.Parameter;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
@@ -43,10 +38,6 @@ import org.springframework.web.bind.annotation.RestController;
public class GukYuinApiController { public class GukYuinApiController {
private final GukYuinApiService gukYuinApiService; private final GukYuinApiService gukYuinApiService;
private final GukYuinApiPnuJobService gukYuinApiPnuJobService;
private final GukYuinApiStatusJobService gukYuinApiStatusJobService;
private final GukYuinApiLabelJobService gukYuinApiLabelJobService;
private final GukYuinApiStbltJobService gukYuinApiStbltJobService;
/** 탐지결과 등록 */ /** 탐지결과 등록 */
@Operation(summary = "탐지결과 등록", description = "탐지결과 등록") @Operation(summary = "탐지결과 등록", description = "탐지결과 등록")
@@ -331,36 +322,4 @@ public class GukYuinApiController {
@PathVariable String chnDtctObjtId) { @PathVariable String chnDtctObjtId) {
return ApiResponseDto.ok(gukYuinApiService.findRlbDtctObject(chnDtctObjtId)); return ApiResponseDto.ok(gukYuinApiService.findRlbDtctObject(chnDtctObjtId));
} }
@Hidden
@Operation(summary = "job test pnu", description = "job test pnu")
@GetMapping("/job-test/pnu")
public ApiResponseDto<Void> findGukYuinContListPnuUpdate() {
gukYuinApiPnuJobService.findGukYuinContListPnuUpdate();
return ApiResponseDto.ok(null);
}
@Hidden
@Operation(summary = "job test status", description = "job test status")
@GetMapping("/job-test/status")
public ApiResponseDto<Void> findGukYuinMastCompleteYn() {
gukYuinApiStatusJobService.findGukYuinMastCompleteYn();
return ApiResponseDto.ok(null);
}
@Hidden
@Operation(summary = "job test label", description = "job test label")
@GetMapping("/job-test/label")
public ApiResponseDto<Void> findLabelingCompleteSend() {
gukYuinApiLabelJobService.findLabelingCompleteSend();
return ApiResponseDto.ok(null);
}
@Hidden
@Operation(summary = "job test stblt", description = "job test stblt")
@GetMapping("/job-test/stblt")
public ApiResponseDto<Void> findGukYuinEligibleForSurvey() {
gukYuinApiStbltJobService.findGukYuinEligibleForSurvey();
return ApiResponseDto.ok(null);
}
} }

View File

@@ -5,7 +5,6 @@ import com.kamco.cd.kamcoback.members.dto.MembersDto;
import com.kamco.cd.kamcoback.members.dto.MembersDto.Basic; import com.kamco.cd.kamcoback.members.dto.MembersDto.Basic;
import com.kamco.cd.kamcoback.members.service.AdminService; import com.kamco.cd.kamcoback.members.service.AdminService;
import com.kamco.cd.kamcoback.members.service.MembersService; import com.kamco.cd.kamcoback.members.service.MembersService;
import com.kamco.cd.kamcoback.scheduler.service.MemberInactiveJobService;
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.Parameter;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
@@ -35,7 +34,6 @@ public class MembersApiController {
private final MembersService membersService; private final MembersService membersService;
private final AdminService adminService; private final AdminService adminService;
private final MemberInactiveJobService memberInactiveJobService;
@Operation(summary = "회원정보 목록", description = "회원정보 조회") @Operation(summary = "회원정보 목록", description = "회원정보 조회")
@ApiResponses( @ApiResponses(
@@ -159,13 +157,4 @@ public class MembersApiController {
String employeeNo) { String employeeNo) {
return ApiResponseDto.ok(adminService.existsByEmployeeNo(employeeNo)); return ApiResponseDto.ok(adminService.existsByEmployeeNo(employeeNo));
} }
@Operation(
summary = "라벨러/검수자 최종로그인 28일 경과 이후 사용중지(스케줄링 실행)",
description = "라벨러/검수자 최종로그인 28일 경과 이후 사용중지 처리")
@GetMapping("/member-inactive-job")
public ApiResponseDto<Void> memberInactiveJob() {
memberInactiveJobService.memberActive28daysToInactive();
return ApiResponseDto.ok(null);
}
} }

View File

@@ -2,6 +2,7 @@ package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GeomUidDto; import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GeomUidDto;
import com.kamco.cd.kamcoback.postgres.repository.gukyuin.GukYuinLabelJobRepository; import com.kamco.cd.kamcoback.postgres.repository.gukyuin.GukYuinLabelJobRepository;
import java.time.LocalDate;
import java.util.List; import java.util.List;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -15,8 +16,8 @@ public class GukYuinLabelJobCoreService {
this.gukYuinLabelRepository = gukYuinLabelRepository; this.gukYuinLabelRepository = gukYuinLabelRepository;
} }
public List<GeomUidDto> findYesterdayLabelingCompleteList() { public List<GeomUidDto> findYesterdayLabelingCompleteList(LocalDate baseDate) {
return gukYuinLabelRepository.findYesterdayLabelingCompleteList(); return gukYuinLabelRepository.findYesterdayLabelingCompleteList(baseDate);
} }
@Transactional @Transactional

View File

@@ -6,6 +6,7 @@ import com.kamco.cd.kamcoback.postgres.repository.mapsheet.MapSheetMngYearReposi
import com.kamco.cd.kamcoback.postgres.repository.scheduler.MapSheetMngFileJobRepository; import com.kamco.cd.kamcoback.postgres.repository.scheduler.MapSheetMngFileJobRepository;
import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto; import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngHstDto; import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngHstDto;
import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.YearMinMax;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import java.util.List; import java.util.List;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@@ -67,9 +68,10 @@ public class MapSheetMngFileJobCoreService {
return mapSheetMngFileJobRepository.findNotYetMapSheetMng(); return mapSheetMngFileJobRepository.findNotYetMapSheetMng();
} }
public Long findByHstMapSheetBeforeYyyyListCount(int strtYyyy, int endYyyy, String mapSheetNum) { public Long findByHstMapSheetBeforeYyyyListCount(
int mngYyyy, int strtYyyy, int endYyyy, String mapSheetNum) {
return mapSheetMngFileJobRepository.findByHstMapSheetBeforeYyyyListCount( return mapSheetMngFileJobRepository.findByHstMapSheetBeforeYyyyListCount(
strtYyyy, endYyyy, mapSheetNum); mngYyyy, strtYyyy, endYyyy, mapSheetNum);
} }
public void updateException5kMapSheet(String mapSheetNum, CommonUseStatus commonUseStatus) { public void updateException5kMapSheet(String mapSheetNum, CommonUseStatus commonUseStatus) {
@@ -79,4 +81,8 @@ public class MapSheetMngFileJobCoreService {
public void saveSheetMngYear() { public void saveSheetMngYear() {
mapSheetMngYearRepository.saveFileInfo(); mapSheetMngYearRepository.saveFileInfo();
} }
public YearMinMax findYearMinMaxInfo() {
return mapSheetMngYearRepository.findYearMinMaxInfo();
}
} }

View File

@@ -3,6 +3,7 @@ package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.postgres.repository.scheduler.TrainingDataLabelJobRepository; import com.kamco.cd.kamcoback.postgres.repository.scheduler.TrainingDataLabelJobRepository;
import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.InspectorPendingDto; import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.InspectorPendingDto;
import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.Tasks; import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.Tasks;
import java.time.LocalDate;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@@ -14,8 +15,8 @@ public class TrainingDataLabelJobCoreService {
private final TrainingDataLabelJobRepository trainingDataLabelJobRepository; private final TrainingDataLabelJobRepository trainingDataLabelJobRepository;
public List<Tasks> findCompletedYesterdayUnassigned() { public List<Tasks> findCompletedYesterdayUnassigned(LocalDate baseDate) {
return trainingDataLabelJobRepository.findCompletedYesterdayUnassigned(); return trainingDataLabelJobRepository.findCompletedYesterdayUnassigned(baseDate);
} }
public void assignReviewerBatch(List<UUID> assignmentUids, String reviewerId) { public void assignReviewerBatch(List<UUID> assignmentUids, String reviewerId) {

View File

@@ -4,6 +4,7 @@ import com.kamco.cd.kamcoback.postgres.repository.scheduler.TrainingDataReviewJo
import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.AnalCntInfo; import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.AnalCntInfo;
import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.AnalMapSheetList; import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.AnalMapSheetList;
import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.CompleteLabelData; import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.CompleteLabelData;
import java.time.LocalDate;
import java.util.List; import java.util.List;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -15,12 +16,13 @@ public class TrainingDataReviewJobCoreService {
private final TrainingDataReviewJobRepository trainingDataReviewJobRepository; private final TrainingDataReviewJobRepository trainingDataReviewJobRepository;
public List<CompleteLabelData> findCompletedYesterdayLabelingList( public List<CompleteLabelData> findCompletedYesterdayLabelingList(
Long analUid, String mapSheetNum) { Long analUid, String mapSheetNum, LocalDate baseDate) {
return trainingDataReviewJobRepository.findCompletedYesterdayLabelingList(analUid, mapSheetNum); return trainingDataReviewJobRepository.findCompletedYesterdayLabelingList(
analUid, mapSheetNum, baseDate);
} }
public List<AnalMapSheetList> findCompletedAnalMapSheetList(Long analUid) { public List<AnalMapSheetList> findCompletedAnalMapSheetList(Long analUid, LocalDate baseDate) {
return trainingDataReviewJobRepository.findCompletedAnalMapSheetList(analUid); return trainingDataReviewJobRepository.findCompletedAnalMapSheetList(analUid, baseDate);
} }
public List<AnalCntInfo> findAnalCntInfoList() { public List<AnalCntInfo> findAnalCntInfoList() {

View File

@@ -1,11 +1,12 @@
package com.kamco.cd.kamcoback.postgres.repository.gukyuin; package com.kamco.cd.kamcoback.postgres.repository.gukyuin;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GeomUidDto; import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GeomUidDto;
import java.time.LocalDate;
import java.util.List; import java.util.List;
public interface GukYuinLabelJobRepositoryCustom { public interface GukYuinLabelJobRepositoryCustom {
List<GeomUidDto> findYesterdayLabelingCompleteList(); List<GeomUidDto> findYesterdayLabelingCompleteList(LocalDate baseDate);
void updateAnalDataInferenceGeomSendDttm(Long geoUid); void updateAnalDataInferenceGeomSendDttm(Long geoUid);
} }

View File

@@ -13,6 +13,7 @@ import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext; import jakarta.persistence.PersistenceContext;
import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.List; import java.util.List;
@@ -27,22 +28,21 @@ public class GukYuinLabelJobRepositoryImpl implements GukYuinLabelJobRepositoryC
@PersistenceContext private EntityManager em; @PersistenceContext private EntityManager em;
@Override @Override
public List<GeomUidDto> findYesterdayLabelingCompleteList() { public List<GeomUidDto> findYesterdayLabelingCompleteList(LocalDate baseDate) {
ZoneId zone = ZoneId.of("Asia/Seoul"); ZoneId zone = ZoneId.of("Asia/Seoul");
ZonedDateTime todayStart = ZonedDateTime.now(zone).toLocalDate().atStartOfDay(zone);
ZonedDateTime tomorrowStart = todayStart.plusDays(1);
ZonedDateTime yesterdayStart = todayStart.minusDays(1);
// BooleanExpression isYesterday = // baseDate가 null이면 기존처럼 "어제"로 처리
// labelingAssignmentEntity LocalDate targetDate =
// .inspectStatDttm (baseDate != null) ? baseDate : ZonedDateTime.now(zone).toLocalDate().minusDays(1);
// .goe(yesterdayStart)
// .and(labelingAssignmentEntity.inspectStatDttm.lt(todayStart)); ZonedDateTime targetStart = targetDate.atStartOfDay(zone);
BooleanExpression isYesterday = ZonedDateTime nextStart = targetStart.plusDays(1);
BooleanExpression inTargetDay =
labelingAssignmentEntity labelingAssignmentEntity
.inspectStatDttm .inspectStatDttm
.goe(todayStart) .goe(targetStart)
.and(labelingAssignmentEntity.inspectStatDttm.lt(tomorrowStart)); .and(labelingAssignmentEntity.inspectStatDttm.lt(nextStart));
return queryFactory return queryFactory
.select( .select(
@@ -62,7 +62,7 @@ public class GukYuinLabelJobRepositoryImpl implements GukYuinLabelJobRepositoryC
mapSheetAnalInferenceEntity.learnId.eq(mapSheetLearnEntity.id), mapSheetAnalInferenceEntity.learnId.eq(mapSheetLearnEntity.id),
mapSheetLearnEntity.applyStatus.in( mapSheetLearnEntity.applyStatus.in(
GukYuinStatus.GUK_COMPLETED.getId(), GukYuinStatus.PNU_COMPLETED.getId())) GukYuinStatus.GUK_COMPLETED.getId(), GukYuinStatus.PNU_COMPLETED.getId()))
.where(labelingAssignmentEntity.inspectState.eq(InspectState.COMPLETE.getId()), isYesterday) .where(labelingAssignmentEntity.inspectState.eq(InspectState.COMPLETE.getId()), inTargetDay)
.fetch(); .fetch();
} }

View File

@@ -1,10 +1,14 @@
package com.kamco.cd.kamcoback.postgres.repository.mapsheet; package com.kamco.cd.kamcoback.postgres.repository.mapsheet;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngListCompareDto; import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngListCompareDto;
import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.YearMinMax;
import java.util.List; import java.util.List;
public interface MapSheetMngYearRepositoryCustom { public interface MapSheetMngYearRepositoryCustom {
void saveFileInfo(); void saveFileInfo();
List<MngListCompareDto> findByHstMapSheetCompareList(int mngYyyy, List<String> mapIds); List<MngListCompareDto> findByHstMapSheetCompareList(int mngYyyy, List<String> mapIds);
YearMinMax findYearMinMaxInfo();
} }

View File

@@ -1,7 +1,10 @@
package com.kamco.cd.kamcoback.postgres.repository.mapsheet; package com.kamco.cd.kamcoback.postgres.repository.mapsheet;
import static com.kamco.cd.kamcoback.postgres.entity.QYearEntity.yearEntity;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngListCompareDto; import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngListCompareDto;
import com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngYearYnEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngYearYnEntity;
import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.YearMinMax;
import com.querydsl.core.types.Projections; import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.core.types.dsl.StringExpression;
@@ -26,52 +29,52 @@ public class MapSheetMngYearRepositoryImpl implements MapSheetMngYearRepositoryC
String sql = String sql =
""" """
WITH bounds AS ( WITH bounds AS (
SELECT
map_sheet_num,
MIN(mng_yyyy::int) AS min_y,
MAX(mng_yyyy::int) AS max_y
FROM tb_map_sheet_mng_files
GROUP BY map_sheet_num
),
years AS (
SELECT
b.map_sheet_num,
gs.y AS mng_yyyy
FROM bounds b
CROSS JOIN LATERAL generate_series(b.min_y, b.max_y) AS gs(y)
),
exist AS (
SELECT DISTINCT
map_sheet_num,
mng_yyyy::int AS mng_yyyy
FROM tb_map_sheet_mng_files
),
src AS (
SELECT
y.map_sheet_num,
y.mng_yyyy,
CASE
WHEN e.map_sheet_num IS NULL THEN 'N'
ELSE 'Y'
END AS yn
FROM years y
LEFT JOIN exist e
ON e.map_sheet_num = y.map_sheet_num
AND e.mng_yyyy = y.mng_yyyy
)
INSERT INTO tb_map_sheet_mng_year_yn
(map_sheet_num, mng_yyyy, yn)
SELECT SELECT
map_sheet_num, map_sheet_num,
MIN(mng_yyyy::int) AS min_y, mng_yyyy,
MAX(mng_yyyy::int) AS max_y yn
FROM tb_map_sheet_mng_files FROM src
GROUP BY map_sheet_num ON CONFLICT (map_sheet_num, mng_yyyy)
), DO UPDATE SET
years AS ( yn = EXCLUDED.yn,
SELECT updated_dttm = now()
b.map_sheet_num, """;
gs.y AS mng_yyyy
FROM bounds b
CROSS JOIN LATERAL generate_series(b.min_y, b.max_y) AS gs(y)
),
exist AS (
SELECT DISTINCT
map_sheet_num,
mng_yyyy::int AS mng_yyyy
FROM tb_map_sheet_mng_files
),
src AS (
SELECT
y.map_sheet_num,
y.mng_yyyy,
CASE
WHEN e.map_sheet_num IS NULL THEN 'N'
ELSE 'Y'
END AS yn
FROM years y
LEFT JOIN exist e
ON e.map_sheet_num = y.map_sheet_num
AND e.mng_yyyy = y.mng_yyyy
)
INSERT INTO tb_map_sheet_mng_year_yn
(map_sheet_num, mng_yyyy, yn)
SELECT
map_sheet_num,
mng_yyyy,
yn
FROM src
ON CONFLICT (map_sheet_num, mng_yyyy)
DO UPDATE SET
yn = EXCLUDED.yn,
updated_dttm = now()
""";
em.createNativeQuery(sql).executeUpdate(); em.createNativeQuery(sql).executeUpdate();
} }
@@ -98,4 +101,13 @@ public class MapSheetMngYearRepositoryImpl implements MapSheetMngYearRepositoryC
.groupBy(y.id.mapSheetNum) .groupBy(y.id.mapSheetNum)
.fetch(); .fetch();
} }
@Override
public YearMinMax findYearMinMaxInfo() {
return queryFactory
.select(
Projections.constructor(YearMinMax.class, yearEntity.yyyy.min(), yearEntity.yyyy.max()))
.from(yearEntity)
.fetchOne();
}
} }

View File

@@ -20,7 +20,8 @@ public interface MapSheetMngFileJobRepositoryCustom {
public Integer findNotYetMapSheetMng(); public Integer findNotYetMapSheetMng();
public Long findByHstMapSheetBeforeYyyyListCount(int strtYyyy, int endYyyy, String mapSheetNum); public Long findByHstMapSheetBeforeYyyyListCount(
int mngYyyy, int strtYyyy, int endYyyy, String mapSheetNum);
public void updateException5kMapSheet(String mapSheetNum, CommonUseStatus commonUseStatus); public void updateException5kMapSheet(String mapSheetNum, CommonUseStatus commonUseStatus);
} }

View File

@@ -233,7 +233,8 @@ public class MapSheetMngFileJobRepositoryImpl extends QuerydslRepositorySupport
} }
@Override @Override
public Long findByHstMapSheetBeforeYyyyListCount(int strtYyyy, int endYyyy, String mapSheetNum) { public Long findByHstMapSheetBeforeYyyyListCount(
int mngYyyy, int strtYyyy, int endYyyy, String mapSheetNum) {
Long countQuery = Long countQuery =
queryFactory queryFactory
@@ -244,8 +245,8 @@ public class MapSheetMngFileJobRepositoryImpl extends QuerydslRepositorySupport
.mngYyyy .mngYyyy
.goe(strtYyyy) .goe(strtYyyy)
.and(mapSheetMngHstEntity.mngYyyy.loe(endYyyy)) .and(mapSheetMngHstEntity.mngYyyy.loe(endYyyy))
.and(mapSheetMngHstEntity.mngYyyy.ne(mngYyyy))
.and(mapSheetMngHstEntity.mapSheetNum.eq(mapSheetNum)) .and(mapSheetMngHstEntity.mapSheetNum.eq(mapSheetNum))
.and(mapSheetMngHstEntity.useInference.eq("USE"))
.and( .and(
mapSheetMngHstEntity mapSheetMngHstEntity
.syncState .syncState

View File

@@ -2,12 +2,13 @@ package com.kamco.cd.kamcoback.postgres.repository.scheduler;
import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.InspectorPendingDto; import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.InspectorPendingDto;
import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.Tasks; import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.Tasks;
import java.time.LocalDate;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
public interface TrainingDataLabelJobRepositoryCustom { public interface TrainingDataLabelJobRepositoryCustom {
List<Tasks> findCompletedYesterdayUnassigned(); List<Tasks> findCompletedYesterdayUnassigned(LocalDate baseDate);
List<InspectorPendingDto> findInspectorPendingByRound(Long analUid); List<InspectorPendingDto> findInspectorPendingByRound(Long analUid);

View File

@@ -14,6 +14,7 @@ import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.impl.JPAQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory;
import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.List; import java.util.List;
@@ -34,16 +35,23 @@ public class TrainingDataLabelJobRepositoryImpl extends QuerydslRepositorySuppor
} }
@Override @Override
public List<Tasks> findCompletedYesterdayUnassigned() { public List<Tasks> findCompletedYesterdayUnassigned(LocalDate baseDate) {
ZoneId zone = ZoneId.of("Asia/Seoul"); ZoneId zone = ZoneId.of("Asia/Seoul");
ZonedDateTime todayStart = ZonedDateTime.now(zone).toLocalDate().atStartOfDay(zone);
ZonedDateTime yesterdayStart = todayStart.minusDays(1); // baseDate가 null이면 "어제"를 타겟으로, 아니면 baseDate
LocalDate targetDate = (baseDate != null) ? baseDate : LocalDate.now(zone).minusDays(1);
// end: targetDate + 1일 00:00
ZonedDateTime baseStart = targetDate.plusDays(1).atStartOfDay(zone);
// start: targetDate 00:00
ZonedDateTime yesterdayStart = baseStart.minusDays(1);
BooleanExpression isYesterday = BooleanExpression isYesterday =
labelingAssignmentEntity labelingAssignmentEntity
.workStatDttm .workStatDttm
.goe(yesterdayStart) .goe(yesterdayStart)
.and(labelingAssignmentEntity.workStatDttm.lt(todayStart)); .and(labelingAssignmentEntity.workStatDttm.lt(baseStart));
return queryFactory return queryFactory
.select( .select(

View File

@@ -3,13 +3,15 @@ package com.kamco.cd.kamcoback.postgres.repository.scheduler;
import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.AnalCntInfo; import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.AnalCntInfo;
import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.AnalMapSheetList; import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.AnalMapSheetList;
import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.CompleteLabelData; import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.CompleteLabelData;
import java.time.LocalDate;
import java.util.List; import java.util.List;
public interface TrainingDataReviewJobRepositoryCustom { public interface TrainingDataReviewJobRepositoryCustom {
List<CompleteLabelData> findCompletedYesterdayLabelingList(Long analUid, String mapSheetNum); List<CompleteLabelData> findCompletedYesterdayLabelingList(
Long analUid, String mapSheetNum, LocalDate baseDate);
List<AnalMapSheetList> findCompletedAnalMapSheetList(Long analUid); List<AnalMapSheetList> findCompletedAnalMapSheetList(Long analUid, LocalDate baseDate);
List<AnalCntInfo> findAnalCntInfoList(); List<AnalCntInfo> findAnalCntInfoList();

View File

@@ -41,12 +41,13 @@ public class TrainingDataReviewJobRepositoryImpl extends QuerydslRepositorySuppo
@Override @Override
public List<CompleteLabelData> findCompletedYesterdayLabelingList( public List<CompleteLabelData> findCompletedYesterdayLabelingList(
Long analUid, String mapSheetNum) { Long analUid, String mapSheetNum, LocalDate baseDate) {
ZoneId zoneId = ZoneId.of("Asia/Seoul"); ZoneId zoneId = ZoneId.of("Asia/Seoul");
// 오늘 날짜 (시간 없음) // baseDate가 null이면 기존처럼 오늘 기준
LocalDate today = LocalDate.now(zoneId); LocalDate targetDate = (baseDate != null) ? baseDate : LocalDate.now(zoneId);
ZonedDateTime end = today.atStartOfDay(zoneId); // 오늘 00:00
ZonedDateTime end = targetDate.plusDays(1).atStartOfDay(zoneId);
return queryFactory return queryFactory
.select( .select(
@@ -77,10 +78,13 @@ public class TrainingDataReviewJobRepositoryImpl extends QuerydslRepositorySuppo
} }
@Override @Override
public List<AnalMapSheetList> findCompletedAnalMapSheetList(Long analUid) { public List<AnalMapSheetList> findCompletedAnalMapSheetList(Long analUid, LocalDate baseDate) {
ZoneId zoneId = ZoneId.of("Asia/Seoul"); ZoneId zoneId = ZoneId.of("Asia/Seoul");
LocalDate today = LocalDate.now(zoneId);
ZonedDateTime end = today.atStartOfDay(zoneId); // 오늘 00:00 // baseDate가 null이면 기존처럼 오늘 기준
LocalDate targetDate = (baseDate != null) ? baseDate : LocalDate.now(zoneId);
ZonedDateTime end = targetDate.plusDays(1).atStartOfDay(zoneId);
return queryFactory return queryFactory
.select( .select(

View File

@@ -4,6 +4,7 @@ import com.kamco.cd.kamcoback.code.dto.CommonCodeDto;
import com.kamco.cd.kamcoback.code.service.CommonCodeService; import com.kamco.cd.kamcoback.code.service.CommonCodeService;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto; import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.scheduler.service.MapSheetInferenceJobService; import com.kamco.cd.kamcoback.scheduler.service.MapSheetInferenceJobService;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
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;
@@ -17,6 +18,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
/** SchedulerApiController로 다 옮김 */
@Hidden
@Tag(name = "스캐쥴러 API", description = "스캐쥴러 API") @Tag(name = "스캐쥴러 API", description = "스캐쥴러 API")
@RestController @RestController
@RequiredArgsConstructor @RequiredArgsConstructor

View File

@@ -0,0 +1,120 @@
package com.kamco.cd.kamcoback.scheduler;
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.scheduler.service.GukYuinApiLabelJobService;
import com.kamco.cd.kamcoback.scheduler.service.GukYuinApiPnuJobService;
import com.kamco.cd.kamcoback.scheduler.service.GukYuinApiStatusJobService;
import com.kamco.cd.kamcoback.scheduler.service.GukYuinApiStbltJobService;
import com.kamco.cd.kamcoback.scheduler.service.MemberInactiveJobService;
import com.kamco.cd.kamcoback.scheduler.service.TrainingDataLabelJobService;
import com.kamco.cd.kamcoback.scheduler.service.TrainingDataReviewJobService;
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.time.LocalDate;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "스케줄링 수동 호출 테스트", description = "스케줄링 수동 호출 테스트 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/schedule")
public class SchedulerApiController {
private final GukYuinApiPnuJobService gukYuinApiPnuJobService;
private final GukYuinApiStatusJobService gukYuinApiStatusJobService;
private final GukYuinApiLabelJobService gukYuinApiLabelJobService;
private final GukYuinApiStbltJobService gukYuinApiStbltJobService;
private final TrainingDataLabelJobService trainingDataLabelJobService;
private final TrainingDataReviewJobService trainingDataReviewJobService;
private final MemberInactiveJobService memberInactiveJobService;
private final MapSheetMngFileJobController mapSheetMngFileJobController;
@Operation(summary = "국유인 탐지객체 조회 PNU 업데이트 스케줄링", description = "국유인 탐지객체 조회 PNU 업데이트 스케줄링")
@GetMapping("/gukyuin/pnu")
public ApiResponseDto<Void> findGukYuinContListPnuUpdate() {
gukYuinApiPnuJobService.findGukYuinContListPnuUpdate();
return ApiResponseDto.ok(null);
}
@Operation(summary = "국유인 등록 상태 체크 스케줄링", description = "국유인 등록 상태 체크 스케줄링")
@GetMapping("/gukyuin/status")
public ApiResponseDto<Void> findGukYuinMastCompleteYn() {
gukYuinApiStatusJobService.findGukYuinMastCompleteYn();
return ApiResponseDto.ok(null);
}
@Operation(summary = "국유인 라벨 완료 전송 스케줄링", description = "국유인 라벨 완료 전송 스케줄링")
@GetMapping("/gukyuin/label")
public ApiResponseDto<Void> findLabelingCompleteSend(
@RequestParam(required = false) LocalDate baseDate) {
gukYuinApiLabelJobService.findLabelingCompleteSend(baseDate);
return ApiResponseDto.ok(null);
}
@Operation(summary = "국유인 실태조사 적합여부 업데이트 스케줄링", description = "국유인 실태조사 적합여부 업데이트 스케줄링")
@GetMapping("/gukyuin/stblt")
public ApiResponseDto<Void> findGukYuinEligibleForSurvey(
@RequestParam(required = false) LocalDate baseDate) {
gukYuinApiStbltJobService.findGukYuinEligibleForSurvey(baseDate);
return ApiResponseDto.ok(null);
}
@Operation(
summary = "라벨완료 -> 검수할당 스케줄링",
description = "스케줄링이 실패한 경우 수동 호출하는 API, 어제 라벨링 완료된 것을 해당 검수자들에게 할당함")
@GetMapping("/label-to-review")
public ApiResponseDto<Void> runTrainingReviewSchedule(
@RequestParam(required = false) LocalDate baseDate) {
trainingDataLabelJobService.assignReviewerYesterdayLabelComplete(baseDate);
return ApiResponseDto.ok(null);
}
@Operation(summary = "검수완료된 라벨링 geojson 생성 스케줄링", description = "검수완료된 라벨링 geojson 생성")
@GetMapping("/review-to-geojson")
public ApiResponseDto<Long> runExportGeojsonLabelingGeom(
@RequestParam(required = false) LocalDate baseDate) {
trainingDataReviewJobService.exportGeojsonLabelingGeom(baseDate);
return ApiResponseDto.ok(0L);
}
@Operation(
summary = "라벨러/검수자 최종로그인 28일 경과 이후 사용중지 스케줄링",
description = "라벨러/검수자 최종로그인 28일 경과 이후 사용중지 처리")
@GetMapping("/member-inactive-job")
public ApiResponseDto<Void> memberInactiveJob() {
memberInactiveJobService.memberActive28daysToInactive();
return ApiResponseDto.ok(null);
}
@Operation(summary = "영상관리 파일 싱크 스캐쥴러 Start/Stop", description = "영상관리 파일 싱크 스캐쥴러 Start/Stop API")
@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)
})
@PutMapping("/mng-sync-job")
public ApiResponseDto<String> mngSyncOnOff(
@RequestParam boolean jobStart, @RequestParam int pageSize) {
mapSheetMngFileJobController.setSchedulerEnabled(jobStart);
mapSheetMngFileJobController.setMngSyncPageSize(pageSize);
return ApiResponseDto.createOK("OK");
}
}

View File

@@ -40,6 +40,7 @@ public class MapSheetMngDto {
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class MngDto { public static class MngDto {
private int rowNum; private int rowNum;
private int mngYyyy; private int mngYyyy;
private String mngState; private String mngState;
@@ -61,6 +62,7 @@ public class MapSheetMngDto {
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class MngHstDto { public static class MngHstDto {
private long hstUid; private long hstUid;
private int mngYyyy; private int mngYyyy;
private String mapSheetNum; private String mapSheetNum;
@@ -86,6 +88,7 @@ public class MapSheetMngDto {
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class MngFileAddReq { public static class MngFileAddReq {
private int mngYyyy; private int mngYyyy;
private String mapSheetNum; private String mapSheetNum;
private String refMapSheetNum; private String refMapSheetNum;
@@ -103,6 +106,7 @@ public class MapSheetMngDto {
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class MngFilesDto { public static class MngFilesDto {
private long fileUid; private long fileUid;
private int mngYyyy; private int mngYyyy;
private String mapSheetNum; private String mapSheetNum;
@@ -132,7 +136,19 @@ public class MapSheetMngDto {
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class DmlReturn { public static class DmlReturn {
private String flag; private String flag;
private String message; private String message;
} }
@Schema(name = "MngYyyyDto", description = "년도 값")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class YearMinMax {
private Integer minYyyy;
private Integer maxYyyy;
}
} }

View File

@@ -4,6 +4,7 @@ import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GeomUidDto; import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GeomUidDto;
import com.kamco.cd.kamcoback.gukyuin.service.GukYuinApiService; import com.kamco.cd.kamcoback.gukyuin.service.GukYuinApiService;
import com.kamco.cd.kamcoback.postgres.core.GukYuinLabelJobCoreService; import com.kamco.cd.kamcoback.postgres.core.GukYuinLabelJobCoreService;
import java.time.LocalDate;
import java.util.List; import java.util.List;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
@@ -31,14 +32,18 @@ public class GukYuinApiLabelJobService {
return "local".equalsIgnoreCase(profile); return "local".equalsIgnoreCase(profile);
} }
/** 어제 라벨링 검수 완료된 것 -> 국유인에 전송 */
@Scheduled(cron = "0 0 2 * * *") @Scheduled(cron = "0 0 2 * * *")
public void findLabelingCompleteSend() { public void runTask() {
findLabelingCompleteSend(null);
}
/** 어제 라벨링 검수 완료된 것 -> 국유인에 전송 */
public void findLabelingCompleteSend(LocalDate baseDate) {
if (isLocalProfile()) { if (isLocalProfile()) {
return; return;
} }
List<GeomUidDto> list = gukYuinLabelJobCoreService.findYesterdayLabelingCompleteList(); List<GeomUidDto> list = gukYuinLabelJobCoreService.findYesterdayLabelingCompleteList(baseDate);
if (list.isEmpty()) { if (list.isEmpty()) {
return; return;
} }

View File

@@ -39,9 +39,13 @@ public class GukYuinApiStbltJobService {
return "local".equalsIgnoreCase(profile); return "local".equalsIgnoreCase(profile);
} }
/** 국유인 연동 후, 실태조사 적합여부 확인하여 update */
@Scheduled(cron = "0 0 3 * * *") @Scheduled(cron = "0 0 3 * * *")
public void findGukYuinEligibleForSurvey() { public void runTask() {
findGukYuinEligibleForSurvey(null);
}
/** 국유인 연동 후, 실태조사 적합여부 확인하여 update */
public void findGukYuinEligibleForSurvey(LocalDate baseDate) {
if (isLocalProfile()) { if (isLocalProfile()) {
return; return;
} }
@@ -55,11 +59,16 @@ public class GukYuinApiStbltJobService {
for (LearnKeyDto dto : list) { for (LearnKeyDto dto : list) {
try { try {
String yesterday = String targetDate =
LocalDate.now(ZoneId.of("Asia/Seoul")) LocalDate.now(ZoneId.of("Asia/Seoul"))
.minusDays(1) .minusDays(1)
.format(DateTimeFormatter.ofPattern("yyyyMMdd")); .format(DateTimeFormatter.ofPattern("yyyyMMdd"));
RlbDtctDto result = gukYuinApiService.findRlbDtctList(dto.getUid(), yesterday, "Y");
if (baseDate != null) { // 파라미터가 있으면
targetDate = baseDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
}
RlbDtctDto result = gukYuinApiService.findRlbDtctList(dto.getUid(), targetDate, "Y");
if (result == null || result.getResult() == null || result.getResult().isEmpty()) { if (result == null || result.getResult() == null || result.getResult().isEmpty()) {
log.warn("[GUKYUIN] empty result chnDtctMstId={}", dto.getChnDtctMstId()); log.warn("[GUKYUIN] empty result chnDtctMstId={}", dto.getChnDtctMstId());

View File

@@ -11,6 +11,7 @@ import com.kamco.cd.kamcoback.scheduler.dto.FileDto.SrchFilesDepthDto;
import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.DmlReturn; import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.DmlReturn;
import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngFileAddReq; import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngFileAddReq;
import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngHstDto; import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.MngHstDto;
import com.kamco.cd.kamcoback.scheduler.dto.MapSheetMngDto.YearMinMax;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
@@ -212,28 +213,26 @@ public class MapSheetMngFileJobService {
return notyetCnt; return notyetCnt;
} }
public Long mapSheetAutoExceptionUpdate(int mngYyyy, String mapSheetNum) { public Long mapSheetAutoExceptionUpdate(Integer mngYyyy, String mapSheetNum) {
// 2025년 이전 파일싱크는 무조건 이전3년이 존재하지 않으므로 자동추론제외를 진행하지 않는다.(전년도 파일이 무조건 존재하는 것으로 리턴) // tb_year 에 있는 년도 min,max 가져오기
// if (syncAutoExceptionStartYear > mngYyyy) { YearMinMax yearInfo = mapSheetMngFileJobCoreService.findYearMinMaxInfo();
// return 1L; int strtYyyy = yearInfo.getMinYyyy();
// } int endYyyy = yearInfo.getMaxYyyy();
// int strtYyyy = mngYyyy - syncAutoExceptionBeforeYearCnt + 1; // tb_map_sheet_mng_hst 에 도엽 정보가 하나라도 DONE 인 게 있는지 count 가져오기
int strtYyyy = 2020;
int endYyyy = mngYyyy;
// 본년도+이전년도가 3개년인 도엽 확인 -> 2020년도부터 현재까지
Long beforeCnt = Long beforeCnt =
mapSheetMngFileJobCoreService.findByHstMapSheetBeforeYyyyListCount( mapSheetMngFileJobCoreService.findByHstMapSheetBeforeYyyyListCount(
strtYyyy, endYyyy, mapSheetNum); mngYyyy, strtYyyy, endYyyy, mapSheetNum);
if (beforeCnt == 0) { if (beforeCnt == 0) {
System.out.println("mapSheetAutoExceptionUpdate inference == 자동추론제외"); System.out.println("beforeCnt: 0, mapSheetAutoExceptionUpdate inference == 자동추론제외");
mapSheetMngFileJobCoreService.updateException5kMapSheet( mapSheetMngFileJobCoreService.updateException5kMapSheet(
mapSheetNum, CommonUseStatus.AUTO_EXCEPT); mapSheetNum, CommonUseStatus.AUTO_EXCEPT);
} else { } else {
// 하나라도 있으면 USE // 하나라도 있으면 USE
System.out.println(
"beforeCnt: " + beforeCnt + ", mapSheetAutoExceptionUpdate inference == 자동추론제외 해제");
mapSheetMngFileJobCoreService.updateException5kMapSheet(mapSheetNum, CommonUseStatus.USE); mapSheetMngFileJobCoreService.updateException5kMapSheet(mapSheetNum, CommonUseStatus.USE);
} }

View File

@@ -4,6 +4,7 @@ import com.kamco.cd.kamcoback.postgres.core.TrainingDataLabelJobCoreService;
import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.InspectorPendingDto; import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.InspectorPendingDto;
import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.Tasks; import com.kamco.cd.kamcoback.scheduler.dto.TrainingDataReviewJobDto.Tasks;
import jakarta.transaction.Transactional; import jakarta.transaction.Transactional;
import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
@@ -13,6 +14,7 @@ import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor; 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.context.ApplicationContext;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -22,6 +24,7 @@ import org.springframework.stereotype.Service;
public class TrainingDataLabelJobService { public class TrainingDataLabelJobService {
private final TrainingDataLabelJobCoreService trainingDataLabelJobCoreService; private final TrainingDataLabelJobCoreService trainingDataLabelJobCoreService;
private final ApplicationContext applicationContext;
@Value("${spring.profiles.active}") @Value("${spring.profiles.active}")
private String profile; private String profile;
@@ -30,16 +33,24 @@ public class TrainingDataLabelJobService {
return "local".equalsIgnoreCase(profile); return "local".equalsIgnoreCase(profile);
} }
@Transactional
@Scheduled(cron = "0 0 0 * * *") @Scheduled(cron = "0 0 0 * * *")
public void assignReviewerYesterdayLabelComplete() { public void runTask() {
// 프록시를 통해 호출해야 @Transactional이 적용됨
applicationContext
.getBean(TrainingDataLabelJobService.class)
.assignReviewerYesterdayLabelComplete(null);
}
if (isLocalProfile()) { @Transactional
return; public void assignReviewerYesterdayLabelComplete(LocalDate baseDate) {
}
// if (isLocalProfile()) {
// return;
// }
try { try {
List<Tasks> tasks = trainingDataLabelJobCoreService.findCompletedYesterdayUnassigned(); List<Tasks> tasks =
trainingDataLabelJobCoreService.findCompletedYesterdayUnassigned(baseDate);
if (tasks.isEmpty()) { if (tasks.isEmpty()) {
return; return;
@@ -88,6 +99,7 @@ public class TrainingDataLabelJobService {
} }
} catch (Exception e) { } catch (Exception e) {
log.error("배치 처리 중 예외", e); log.error("배치 처리 중 예외", e);
throw e;
} }
} }

View File

@@ -13,6 +13,7 @@ import java.io.IOException;
import java.nio.file.Files; 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.LocalDate;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@@ -40,11 +41,15 @@ public class TrainingDataReviewJobService {
@Transactional @Transactional
@Scheduled(cron = "0 0 2 * * *") @Scheduled(cron = "0 0 2 * * *")
public void exportGeojsonLabelingGeom() { public void runTask() {
exportGeojsonLabelingGeom(null);
}
if (isLocalProfile()) { public void exportGeojsonLabelingGeom(LocalDate baseDate) {
return;
} // if (isLocalProfile()) {
// return;
// }
// 1) 경로/파일명 결정 // 1) 경로/파일명 결정
String targetDir = String targetDir =
@@ -62,7 +67,8 @@ public class TrainingDataReviewJobService {
// 3) 회차 + 어제까지 검수 완료된 총 데이터의 도엽별 목록 가져오기 // 3) 회차 + 어제까지 검수 완료된 총 데이터의 도엽별 목록 가져오기
List<AnalMapSheetList> analMapList = List<AnalMapSheetList> analMapList =
trainingDataReviewJobCoreService.findCompletedAnalMapSheetList(info.getAnalUid()); trainingDataReviewJobCoreService.findCompletedAnalMapSheetList(
info.getAnalUid(), baseDate);
if (analMapList.isEmpty()) { if (analMapList.isEmpty()) {
continue; continue;
@@ -72,7 +78,7 @@ public class TrainingDataReviewJobService {
// 4) 도엽별 geom 데이터 가지고 와서 geojson 만들기 // 4) 도엽별 geom 데이터 가지고 와서 geojson 만들기
List<CompleteLabelData> completeList = List<CompleteLabelData> completeList =
trainingDataReviewJobCoreService.findCompletedYesterdayLabelingList( trainingDataReviewJobCoreService.findCompletedYesterdayLabelingList(
info.getAnalUid(), mapSheet.getMapSheetNum()); info.getAnalUid(), mapSheet.getMapSheetNum(), baseDate);
if (!completeList.isEmpty()) { if (!completeList.isEmpty()) {

View File

@@ -3,8 +3,6 @@ package com.kamco.cd.kamcoback.trainingdata;
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto; import com.kamco.cd.kamcoback.code.dto.CommonCodeDto;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto; import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ResponseObj; import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ResponseObj;
import com.kamco.cd.kamcoback.scheduler.service.TrainingDataLabelJobService;
import com.kamco.cd.kamcoback.scheduler.service.TrainingDataReviewJobService;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto; import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto.ReviewGeometryInfo; import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto.ReviewGeometryInfo;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto.ReviewListDto; import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto.ReviewListDto;
@@ -33,8 +31,6 @@ import org.springframework.web.bind.annotation.RestController;
public class TrainingDataReviewApiController { public class TrainingDataReviewApiController {
private final TrainingDataReviewService trainingDataReviewService; private final TrainingDataReviewService trainingDataReviewService;
private final TrainingDataLabelJobService trainingDataLabelJobService;
private final TrainingDataReviewJobService trainingDataReviewJobService;
@Operation(summary = "목록 조회", description = "검수 할당 목록 조회") @Operation(summary = "목록 조회", description = "검수 할당 목록 조회")
@ApiResponses( @ApiResponses(
@@ -558,20 +554,4 @@ public class TrainingDataReviewApiController {
return ApiResponseDto.ok( return ApiResponseDto.ok(
trainingDataReviewService.getCogImageUrl(mapSheetNum, beforeYear, afterYear)); trainingDataReviewService.getCogImageUrl(mapSheetNum, beforeYear, afterYear));
} }
@Operation(
summary = "검수할당 스케줄링(수동 호출)",
description = "스케줄링이 실패한 경우 수동 호출하는 API, 어제 라벨링 완료된 것을 해당 검수자들에게 할당함")
@GetMapping("/run-schedule")
public ApiResponseDto<Void> runTrainingReviewSchedule() {
trainingDataLabelJobService.assignReviewerYesterdayLabelComplete();
return ApiResponseDto.ok(null);
}
@Operation(summary = "검수완료된 라벨링 geojson 생성(스케줄링 수동 호출)", description = "검수완료된 라벨링 geojson 생성")
@GetMapping("/run-label-geojson")
public ApiResponseDto<Long> runExportGeojsonLabelingGeom() {
trainingDataReviewJobService.exportGeojsonLabelingGeom();
return ApiResponseDto.ok(0L);
}
} }