gukyuin label-send 커밋

This commit is contained in:
2026-02-25 15:22:05 +09:00
parent 2a32fae177
commit fb3d8a424d
100 changed files with 2784 additions and 626 deletions

8
gukyuin/label-send/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# 디폴트 무시된 파일
/shelf/
/workspace.xml
# 에디터 기반 HTTP 클라이언트 요청
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

1
gukyuin/label-send/.idea/.name generated Normal file
View File

@@ -0,0 +1 @@
kamco-label-send-job

28
gukyuin/label-send/.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Gradle Imported" enabled="true">
<outputRelativeToContentRoot value="true" />
<processorPath useClasspath="false">
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.projectlombok/lombok/1.18.42/8365263844ebb62398e0dc33057ba10ba472d3b8/lombok-1.18.42.jar" />
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.querydsl/querydsl-apt/5.0.0/d48657412f2b96d787bbe5ae393e33815c94b4d0/querydsl-apt-5.0.0-jakarta.jar" />
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/jakarta.annotation/jakarta.annotation-api/2.1.1/48b9bda22b091b1f48b13af03fe36db3be6e1ae3/jakarta.annotation-api-2.1.1.jar" />
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/jakarta.persistence/jakarta.persistence-api/3.1.0/66901fa1c373c6aff65c13791cc11da72060a8d6/jakarta.persistence-api-3.1.0.jar" />
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.querydsl/querydsl-codegen/5.1.0/a8504ea51fbc2258543cedab6a37fe6039b2d20a/querydsl-codegen-5.1.0.jar" />
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.querydsl/querydsl-core/5.1.0/be322c3fe98de8e7c204afb8860bfabd81a3bafd/querydsl-core-5.1.0.jar" />
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.querydsl/codegen-utils/5.1.0/ba401554d613760617992eafb6cdba175c811e6f/codegen-utils-5.1.0.jar" />
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/6975da39a7040257bd51d21a231b76c915872d38/javax.inject-1.jar" />
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.github.classgraph/classgraph/4.8.146/360448a09bfa5689d89cfa97fea53b3fdefa9c23/classgraph-4.8.146.jar" />
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.mysema.commons/mysema-commons-lang/0.2.4/d09c8489d54251a6c22fbce804bdd4a070557317/mysema-commons-lang-0.2.4.jar" />
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.eclipse.jdt/ecj/3.26.0/4837be609a3368a0f7e7cf0dc1bdbc7fe94993de/ecj-3.26.0.jar" />
</processorPath>
<module name="kamco-label-send-job.main" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel target="21" />
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_STRING" value="-parameters" />
</component>
</project>

16
gukyuin/label-send/.idea/gradle.xml generated Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
gukyuin/label-send/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="KubernetesApiProvider"><![CDATA[{}]]></component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK" />
</project>

8
gukyuin/label-send/.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/modules/kamco-label-send-job.main.iml" filepath="$PROJECT_DIR$/.idea/modules/kamco-label-send-job.main.iml" />
</modules>
</component>
</project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$/../../build/generated/sources/annotationProcessor/java/main">
<sourceFolder url="file://$MODULE_DIR$/../../build/generated/sources/annotationProcessor/java/main" isTestSource="false" generated="true" />
</content>
</component>
</module>

View File

@@ -1,37 +0,0 @@
package com.kamco.cd.kamcoback.postgres.entity;
import static com.querydsl.core.types.PathMetadataFactory.*;
import com.querydsl.core.types.dsl.*;
import com.querydsl.core.types.PathMetadata;
import javax.annotation.processing.Generated;
import com.querydsl.core.types.Path;
/**
* QCommonCreateEntity is a Querydsl query type for CommonCreateEntity
*/
@Generated("com.querydsl.codegen.DefaultSupertypeSerializer")
public class QCommonCreateEntity extends EntityPathBase<CommonCreateEntity> {
private static final long serialVersionUID = 2072822841L;
public static final QCommonCreateEntity commonCreateEntity = new QCommonCreateEntity("commonCreateEntity");
public final DateTimePath<java.time.ZonedDateTime> createdDate = createDateTime("createdDate", java.time.ZonedDateTime.class);
public QCommonCreateEntity(String variable) {
super(CommonCreateEntity.class, forVariable(variable));
}
public QCommonCreateEntity(Path<? extends CommonCreateEntity> path) {
super(path.getType(), path.getMetadata());
}
public QCommonCreateEntity(PathMetadata metadata) {
super(CommonCreateEntity.class, metadata);
}
}

View File

@@ -0,0 +1,81 @@
package com.kamco.cd.kamcoback.postgres.entity;
import static com.querydsl.core.types.PathMetadataFactory.*;
import com.querydsl.core.types.dsl.*;
import com.querydsl.core.types.PathMetadata;
import javax.annotation.processing.Generated;
import com.querydsl.core.types.Path;
/**
* QMapSheetAnalDataInferenceEntity is a Querydsl query type for MapSheetAnalDataInferenceEntity
*/
@Generated("com.querydsl.codegen.DefaultEntitySerializer")
public class QMapSheetAnalDataInferenceEntity extends EntityPathBase<MapSheetAnalDataInferenceEntity> {
private static final long serialVersionUID = -1712290584L;
public static final QMapSheetAnalDataInferenceEntity mapSheetAnalDataInferenceEntity = new QMapSheetAnalDataInferenceEntity("mapSheetAnalDataInferenceEntity");
public final StringPath analState = createString("analState");
public final NumberPath<Long> analUid = createNumber("analUid", Long.class);
public final NumberPath<Integer> compareYyyy = createNumber("compareYyyy", Integer.class);
public final DateTimePath<java.time.ZonedDateTime> createdDttm = createDateTime("createdDttm", java.time.ZonedDateTime.class);
public final NumberPath<Long> createdUid = createNumber("createdUid", Long.class);
public final DateTimePath<java.time.ZonedDateTime> fileCreatedDttm = createDateTime("fileCreatedDttm", java.time.ZonedDateTime.class);
public final BooleanPath fileCreatedYn = createBoolean("fileCreatedYn");
public final StringPath fitState = createString("fitState");
public final StringPath fitStateCmmnt = createString("fitStateCmmnt");
public final DateTimePath<java.time.ZonedDateTime> fitStateDttm = createDateTime("fitStateDttm", java.time.ZonedDateTime.class);
public final NumberPath<Long> id = createNumber("id", Long.class);
public final NumberPath<Long> labelerUid = createNumber("labelerUid", Long.class);
public final StringPath labelState = createString("labelState");
public final DateTimePath<java.time.ZonedDateTime> labelStateDttm = createDateTime("labelStateDttm", java.time.ZonedDateTime.class);
public final NumberPath<Long> mapSheetNum = createNumber("mapSheetNum", Long.class);
public final NumberPath<Long> refMapSheetNum = createNumber("refMapSheetNum", Long.class);
public final NumberPath<Integer> stage = createNumber("stage", Integer.class);
public final NumberPath<Integer> targetYyyy = createNumber("targetYyyy", Integer.class);
public final NumberPath<Long> testerUid = createNumber("testerUid", Long.class);
public final StringPath testState = createString("testState");
public final DateTimePath<java.time.ZonedDateTime> testStateDttm = createDateTime("testStateDttm", java.time.ZonedDateTime.class);
public final DateTimePath<java.time.ZonedDateTime> updatedDttm = createDateTime("updatedDttm", java.time.ZonedDateTime.class);
public final NumberPath<Long> updatedUid = createNumber("updatedUid", Long.class);
public QMapSheetAnalDataInferenceEntity(String variable) {
super(MapSheetAnalDataInferenceEntity.class, forVariable(variable));
}
public QMapSheetAnalDataInferenceEntity(Path<? extends MapSheetAnalDataInferenceEntity> path) {
super(path.getType(), path.getMetadata());
}
public QMapSheetAnalDataInferenceEntity(PathMetadata metadata) {
super(MapSheetAnalDataInferenceEntity.class, metadata);
}
}

View File

@@ -22,18 +22,86 @@ public class QPnuEntity extends EntityPathBase<PnuEntity> {
public static final QPnuEntity pnuEntity = new QPnuEntity("pnuEntity"); public static final QPnuEntity pnuEntity = new QPnuEntity("pnuEntity");
public final DateTimePath<java.time.OffsetDateTime> createdDttm = createDateTime("createdDttm", java.time.OffsetDateTime.class); public final StringPath afClsCd = createString("afClsCd");
public final StringPath afClsProb = createString("afClsProb");
public final StringPath bfClsCd = createString("bfClsCd");
public final StringPath bfClsProb = createString("bfClsProb");
public final StringPath chgDt = createString("chgDt");
public final StringPath chgEpno = createString("chgEpno");
public final StringPath chgIp = createString("chgIp");
public final StringPath chgYn = createString("chgYn");
public final StringPath chnCd = createString("chnCd");
public final StringPath chnDtctContId = createString("chnDtctContId");
public final StringPath chnDtctId = createString("chnDtctId");
public final StringPath chnDtctMstId = createString("chnDtctMstId");
public final StringPath chnDtctObjtId = createString("chnDtctObjtId");
public final StringPath chnDtctProb = createString("chnDtctProb");
public final StringPath chnDtctSno = createString("chnDtctSno");
public final StringPath chnDtctSqms = createString("chnDtctSqms");
public final StringPath cprsYr = createString("cprsYr");
public final DateTimePath<java.time.ZonedDateTime> createdDttm = createDateTime("createdDttm", java.time.ZonedDateTime.class);
public final NumberPath<Long> createdUid = createNumber("createdUid", Long.class); public final NumberPath<Long> createdUid = createNumber("createdUid", Long.class);
public final StringPath crtDt = createString("crtDt");
public final StringPath crtEpno = createString("crtEpno");
public final StringPath crtIp = createString("crtIp");
public final StringPath crtrYr = createString("crtrYr");
public final BooleanPath delYn = createBoolean("delYn"); public final BooleanPath delYn = createBoolean("delYn");
public final QMapSheetAnalDataInferenceGeomEntity geo; public final QMapSheetAnalDataInferenceGeomEntity geo;
public final NumberPath<Long> id = createNumber("id", Long.class); public final NumberPath<Long> id = createNumber("id", Long.class);
public final StringPath incyCd = createString("incyCd");
public final StringPath incyRsnCont = createString("incyRsnCont");
public final StringPath lblYn = createString("lblYn");
public final StringPath lockYn = createString("lockYn");
public final StringPath lrmSyncYmd = createString("lrmSyncYmd");
public final StringPath mpqdNo = createString("mpqdNo");
public final StringPath pnu = createString("pnu"); public final StringPath pnu = createString("pnu");
public final StringPath pnuDtctId = createString("pnuDtctId");
public final StringPath pnuDtctSqms = createString("pnuDtctSqms");
public final StringPath pnuSqms = createString("pnuSqms");
public final StringPath pnuSyncYmd = createString("pnuSyncYmd");
public final StringPath rmk = createString("rmk");
public final StringPath rsatctNo = createString("rsatctNo");
public final StringPath stbltYn = createString("stbltYn");
public QPnuEntity(String variable) { public QPnuEntity(String variable) {
this(PnuEntity.class, forVariable(variable), INITS); this(PnuEntity.class, forVariable(variable), INITS);
} }

View File

@@ -650,7 +650,7 @@ code + .copy-button {
<script type="text/javascript"> <script type="text/javascript">
function configurationCacheProblems() { return ( function configurationCacheProblems() { return (
// begin-report-data // begin-report-data
{"diagnostics":[{"locations":[{}],"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10.0."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/8.14/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('url = <value>') instead."}]]},{"locations":[{"path":"C:\\workspace\\kamco-cd-cron\\gukyuin\\label-send\\src\\main\\java\\com\\kamco\\cd\\kamcoback\\config\\resttemplate\\ExternalHttpClient.java"},{"taskPath":":compileJava"}],"problem":[{"text":"Some input files use or override a deprecated API."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Some input files use or override a deprecated API."}],"contextualLabel":"Some input files use or override a deprecated API.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.deprecated.plural","displayName":"Some input files use or override a deprecated API."}]},{"locations":[{"path":"C:\\workspace\\kamco-cd-cron\\gukyuin\\label-send\\src\\main\\java\\com\\kamco\\cd\\kamcoback\\config\\resttemplate\\ExternalHttpClient.java"},{"taskPath":":compileJava"}],"problem":[{"text":"Recompile with -Xlint:deprecation for details."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Recompile with -Xlint:deprecation for details."}],"contextualLabel":"Recompile with -Xlint:deprecation for details.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.deprecated.recompile","displayName":"Recompile with -Xlint:deprecation for details."}]},{"locations":[{"path":"C:\\workspace\\kamco-cd-cron\\gukyuin\\label-send\\src\\main\\java\\com\\kamco\\cd\\kamcoback\\common\\utils\\enums\\Enums.java"},{"taskPath":":compileJava"}],"problem":[{"text":"Some input files use unchecked or unsafe operations."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Some input files use unchecked or unsafe operations."}],"contextualLabel":"Some input files use unchecked or unsafe operations.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.unchecked.plural","displayName":"Some input files use unchecked or unsafe operations."}]},{"locations":[{"path":"C:\\workspace\\kamco-cd-cron\\gukyuin\\label-send\\src\\main\\java\\com\\kamco\\cd\\kamcoback\\common\\utils\\enums\\Enums.java"},{"taskPath":":compileJava"}],"problem":[{"text":"Recompile with -Xlint:unchecked for details."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Recompile with -Xlint:unchecked for details."}],"contextualLabel":"Recompile with -Xlint:unchecked for details.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.unchecked.recompile","displayName":"Recompile with -Xlint:unchecked for details."}]}],"problemsReport":{"totalProblemCount":5,"buildName":"kamco-label-send-job","requestedTasks":"clean build","documentationLink":"https://docs.gradle.org/8.14/userguide/reporting_problems.html","documentationLinkCaption":"Problem report","summaries":[]}} {"diagnostics":[{"locations":[{}],"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10.0."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/8.14/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('url = <value>') instead."}]]},{"locations":[{"path":"C:\\workspace\\kamco-gukyuin-label\\src\\main\\java\\com\\kamco\\cd\\kamcoback\\config\\resttemplate\\ExternalHttpClient.java"},{"taskPath":":compileJava"}],"problem":[{"text":"Some input files use or override a deprecated API."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Some input files use or override a deprecated API."}],"contextualLabel":"Some input files use or override a deprecated API.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.deprecated.plural","displayName":"Some input files use or override a deprecated API."}]},{"locations":[{"path":"C:\\workspace\\kamco-gukyuin-label\\src\\main\\java\\com\\kamco\\cd\\kamcoback\\config\\resttemplate\\ExternalHttpClient.java"},{"taskPath":":compileJava"}],"problem":[{"text":"Recompile with -Xlint:deprecation for details."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Recompile with -Xlint:deprecation for details."}],"contextualLabel":"Recompile with -Xlint:deprecation for details.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.deprecated.recompile","displayName":"Recompile with -Xlint:deprecation for details."}]},{"locations":[{"path":"C:\\workspace\\kamco-gukyuin-label\\src\\main\\java\\com\\kamco\\cd\\kamcoback\\common\\utils\\enums\\Enums.java"},{"taskPath":":compileJava"}],"problem":[{"text":"Some input files use unchecked or unsafe operations."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Some input files use unchecked or unsafe operations."}],"contextualLabel":"Some input files use unchecked or unsafe operations.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.unchecked.plural","displayName":"Some input files use unchecked or unsafe operations."}]},{"locations":[{"path":"C:\\workspace\\kamco-gukyuin-label\\src\\main\\java\\com\\kamco\\cd\\kamcoback\\common\\utils\\enums\\Enums.java"},{"taskPath":":compileJava"}],"problem":[{"text":"Recompile with -Xlint:unchecked for details."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Recompile with -Xlint:unchecked for details."}],"contextualLabel":"Recompile with -Xlint:unchecked for details.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.unchecked.recompile","displayName":"Recompile with -Xlint:unchecked for details."}]}],"problemsReport":{"totalProblemCount":5,"buildName":"kamco-label-send-job","requestedTasks":"clean build","documentationLink":"https://docs.gradle.org/8.14/userguide/reporting_problems.html","documentationLinkCaption":"Problem report","summaries":[]}}
// end-report-data // end-report-data
);} );}
</script> </script>

View File

@@ -0,0 +1,136 @@
spring:
config:
activate:
on-profile: dev
jpa:
show-sql: false
hibernate:
ddl-auto: validate
properties:
hibernate:
default_batch_fetch_size: 100 # ✅ 성능 - N+1 쿼리 방지
order_updates: true # ✅ 성능 - 업데이트 순서 정렬로 데드락 방지
order_inserts: true
use_sql_comments: true # ⚠️ 선택 - SQL에 주석 추가 (디버깅용)
format_sql: true # ⚠️ 선택 - SQL 포맷팅 (가독성)
jdbc:
batch_size: 1000 # ✅ 추가 (JDBC batch)
open-in-view: false
mvc:
async:
request-timeout: 300s # 5분 (예: 30s, 120s, 10m 등도 가능)
datasource:
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:
minimum-idle: 10
maximum-pool-size: 20
connection-timeout: 60000 # 60초 연결 타임아웃
idle-timeout: 300000 # 5분 유휴 타임아웃
max-lifetime: 1800000 # 30분 최대 수명
leak-detection-threshold: 60000 # 연결 누수 감지
transaction:
default-timeout: 300 # 5분 트랜잭션 타임아웃
data:
redis:
host: 192.168.2.109
port: 6379
password: kamco
servlet:
multipart:
enabled: true
max-file-size: 4GB
max-request-size: 4GB
file-size-threshold: 10MB
server:
tomcat:
max-swallow-size: 4GB
max-http-form-post-size: 4GB
jwt:
secret: "kamco_token_9b71e778-19a3-4c1d-97bf-2d687de17d5b"
access-token-validity-in-ms: 86400000 # 1일
refresh-token-validity-in-ms: 604800000 # 7일
#access-token-validity-in-ms: 60000 # 1분
#refresh-token-validity-in-ms: 300000 # 5분
token:
refresh-cookie-name: kamco-dev # 개발용 쿠키 이름
refresh-cookie-secure: false # 로컬 http 테스트면 false
springdoc:
swagger-ui:
persist-authorization: true # 스웨거 새로고침해도 토큰 유지, 로컬스토리지에 저장
logging:
level:
root: INFO
org.springframework.web: DEBUG
org.springframework.security: DEBUG
# 헬스체크 노이즈 핵심만 다운
org.springframework.security.web.FilterChainProxy: INFO
org.springframework.security.web.authentication.AnonymousAuthenticationFilter: INFO
org.springframework.security.web.authentication.Http403ForbiddenEntryPoint: INFO
org.springframework.web.servlet.DispatcherServlet: INFO
mapsheet:
upload:
skipGdalValidation: true
shp:
baseurl: /app/tmp/detect/result #현재사용안함
file:
#sync-root-dir: D:/kamco-nfs/images/
sync-root-dir: /kamco-nfs/images/
sync-tmp-dir: /kamco-nfs/requests/temp # image upload temp dir
#sync-tmp-dir: ${file.sync-root-dir}/tmp
sync-file-extention: tfw,tif
sync-auto-exception-start-year: 2024
sync-auto-exception-before-year-cnt: 3
#dataset-dir: D:/kamco-nfs/model_output/
dataset-dir: /kamco-nfs/model_output/export/ # 마운트경로 AI 추론결과
dataset-tmp-dir: ${file.dataset-dir}tmp/
#model-dir: D:/kamco-nfs/ckpt/model/
model-dir: /kamco-nfs/ckpt/model/ # 학습서버에서 트레이닝한 모델업로드경로
model-tmp-dir: ${file.model-dir}tmp/
model-file-extention: pth,json,py
pt-path: /kamco-nfs/ckpt/model/v6-cls-checkpoints/
pt-FileName: yolov8_6th-6m.pt
dataset-response: /kamco-nfs/dataset/response/
inference:
url: http://192.168.2.183:8000/jobs
batch-url: http://192.168.2.183:8000/batches
geojson-dir: /kamco-nfs/requests/ # 추론실행을 위한 파일생성경로
jar-path: /kamco-nfs/repo/jar/shp-exporter.jar
inference-server-name: server1,server2,server3,server4
gukyuin:
#url: http://localhost:8080
url: http://192.168.2.129:5301
cdi: ${gukyuin.url}/api/kcd/cdi
training-data:
geojson-dir: /kamco-nfs/dataset/request/
layer:
geoserver-url: https://kamco.geo-dev.gs.dabeeo.com
wms-path: geoserver/cd
wmts-path: geoserver/cd/gwc/service
workspace: cd

View File

@@ -0,0 +1,114 @@
spring:
config:
activate:
on-profile: local
jpa:
show-sql: false
hibernate:
ddl-auto: validate # 로컬만 완화(시킬려면 update으로 변경)
properties:
hibernate:
default_batch_fetch_size: 100 # ✅ 성능 - N+1 쿼리 방지
order_updates: true # ✅ 성능 - 업데이트 순서 정렬로 데드락 방지
use_sql_comments: true # ⚠️ 선택 - SQL에 주석 추가 (디버깅용)
format_sql: true # ⚠️ 선택 - SQL 포맷팅 (가독성)
datasource:
url: jdbc:postgresql://192.168.2.127:15432/kamco_cds
# url: jdbc:postgresql://localhost:5432/local_0128
username: kamco_cds
password: kamco_cds_Q!W@E#R$
# username: postgres
# password: 1234
hikari:
minimum-idle: 1
maximum-pool-size: 5
data:
redis:
host: 192.168.2.109
port: 6379
password: kamco
servlet:
multipart:
enabled: true
max-file-size: 4GB
max-request-size: 4GB
file-size-threshold: 10MB
server:
tomcat:
max-swallow-size: 4GB
max-http-form-post-size: 4GB
jwt:
secret: "kamco_token_9b71e778-19a3-4c1d-97bf-2d687de17d5b"
access-token-validity-in-ms: 86400000 # 1일
refresh-token-validity-in-ms: 604800000 # 7일
token:
refresh-cookie-name: kamco-local # 개발용 쿠키 이름
refresh-cookie-secure: false # 로컬 http 테스트면 false
springdoc:
swagger-ui:
persist-authorization: true # 스웨거 새로고침해도 토큰 유지, 로컬스토리지에 저장
logging:
level:
org.hibernate.SQL: debug
org.hibernate.orm.jdbc.bind: trace
mapsheet:
upload:
skipGdalValidation: true
shp:
baseurl: /Users/bokmin/detect/result
file:
sync-root-dir: C:/Users/gypark/kamco-nfs/images/
#sync-root-dir: /kamco-nfs/images/
sync-tmp-dir: ${file.sync-root-dir}/tmp/
sync-file-extention: tfw,tif
sync-auto-exception-start-year: 2025
sync-auto-exception-before-year-cnt: 3
dataset-dir: C:/Users/gypark/kamco-nfs/dataset/
#dataset-dir: /kamco-nfs/dataset/export/
dataset-tmp-dir: ${file.dataset-dir}tmp/
model-dir: C:/Users/gypark/kamco-nfs/ckpt/model/
#model-dir: /kamco-nfs/ckpt/model/
model-tmp-dir: ${file.model-dir}tmp/
model-file-extention: pth,json,py
pt-path: /kamco-nfs/ckpt/classification/
pt-FileName: v5-best.pt
dataset-response: /kamco-nfs/dataset/response/
inference:
url: http://10.100.0.11:8000/jobs
batch-url: http://10.100.0.11:8000/batches
geojson-dir: /kamco-nfs/requests/
jar-path: jar/makeshp-1.0.0.jar
inference-server-name: server1,server2,server3,server4
gukyuin:
#url: http://localhost:8080
url: http://192.168.2.129:5301
cdi: ${gukyuin.url}/api/kcd/cdi
training-data:
geojson-dir: /kamco-nfs/model_output/labeling/
layer:
geoserver-url: https://kamco.geo-dev.gs.dabeeo.com
wms-path: geoserver/cd
wmts-path: geoserver/cd/gwc/service
workspace: cd

View File

@@ -0,0 +1,122 @@
spring:
config:
activate:
on-profile: prod
jpa:
show-sql: true
hibernate:
ddl-auto: validate
properties:
hibernate:
default_batch_fetch_size: 100 # ✅ 성능 - N+1 쿼리 방지
order_updates: true # ✅ 성능 - 업데이트 순서 정렬로 데드락 방지
order_inserts: true
use_sql_comments: true # ⚠️ 선택 - SQL에 주석 추가 (디버깅용)
format_sql: true # ⚠️ 선택 - SQL 포맷팅 (가독성)
jdbc:
batch_size: 1000 # ✅ 추가 (JDBC batch)
open-in-view: false
mvc:
async:
request-timeout: 300s # 5분 (예: 30s, 120s, 10m 등도 가능)
datasource:
url: jdbc:postgresql://kamco-cd-postgis:5432/kamco_cds
#url: jdbc:postgresql://localhost:15432/kamco_cds
username: kamco_cds
password: kamco_cds_Q!W@E#R$
hikari:
minimum-idle: 10
maximum-pool-size: 20
connection-timeout: 60000 # 60초 연결 타임아웃
idle-timeout: 300000 # 5분 유휴 타임아웃
max-lifetime: 1800000 # 30분 최대 수명
leak-detection-threshold: 60000 # 연결 누수 감지
transaction:
default-timeout: 300 # 5분 트랜잭션 타임아웃
data:
redis:
host: 127.0.0.1
port: 16379
password: kamco
servlet:
multipart:
enabled: true
max-file-size: 4GB
max-request-size: 4GB
file-size-threshold: 10MB
server:
tomcat:
max-swallow-size: 4GB
max-http-form-post-size: 4GB
jwt:
secret: "kamco_token_9b71e778-19a3-4c1d-97bf-2d687de17d5b"
access-token-validity-in-ms: 86400000 # 1일
refresh-token-validity-in-ms: 604800000 # 7일
token:
refresh-cookie-name: kamco # 개발용 쿠키 이름
refresh-cookie-secure: true # 로컬 http 테스트면 false
logging:
level:
root: INFO
org.springframework.web: DEBUG
org.springframework.security: DEBUG
# 헬스체크 노이즈 핵심만 다운
org.springframework.security.web.FilterChainProxy: INFO
org.springframework.security.web.authentication.AnonymousAuthenticationFilter: INFO
org.springframework.security.web.authentication.Http403ForbiddenEntryPoint: INFO
org.springframework.web.servlet.DispatcherServlet: INFO
mapsheet:
upload:
skipGdalValidation: true
shp:
baseurl: /app/detect/result #현재사용안함
file:
sync-root-dir: /kamco-nfs/images/
sync-tmp-dir: /kamco-nfs/repo/tmp # image upload temp dir
sync-file-extention: tfw,tif
#dataset-dir: D:/kamco-nfs/model_output/ #변경 model_output
dataset-dir: /kamco-nfs/model_output/export/ # 마운트경로 AI 추론결과
dataset-tmp-dir: ${file.dataset-dir}tmp/
#model-dir: D:/kamco-nfs/ckpt/model/
model-dir: /kamco-nfs/ckpt/model/ # 학습서버에서 트레이닝한 모델업로드경로
model-tmp-dir: ${file.model-dir}tmp/
model-file-extention: pth,json,py
pt-path: /kamco-nfs/ckpt/v6-cls-checkpoints/
pt-FileName: yolov8_6th-6m.pt
dataset-response: /kamco-nfs/dataset/response/
inference:
url: http://127.0.0.1:8000/jobs
batch-url: http://127.0.0.1:8000/batches
geojson-dir: /kamco-nfs/requests/ # 학습서버에서 트레이닝한 모델업로드경로
jar-path: /kamco-nfs/repo/jar/shp-exporter.jar # 추론실행을 위한 파일생성경로
inference-server-name: server1,server2,server3,server4
gukyuin:
url: http://127.0.0.1:5301
cdi: ${gukyuin.url}/api/kcd/cdi
training-data:
geojson-dir: /kamco-nfs/dataset/request/
layer:
geoserver-url: https://kamco.geo-dev.gs.dabeeo.com
wms-path: geoserver/cd
wmts-path: geoserver/cd/gwc/service
workspace: cd

View File

@@ -1,4 +1,8 @@
server: server:
port: 9080 port: 8080
spring:
application:
name: kamco-gukyuin-label
profiles:
active: prod # 사용할 프로파일 지정 (ex. dev, prod, test)

View File

@@ -1,71 +0,0 @@
server:
port: 9080
spring:
application:
name: label-to-review
profiles:
active: dev # 사용할 프로파일 지정 (ex. dev, prod, test)
datasource:
url: jdbc:postgresql://192.168.2.127:15432/kamco_cds
#url: jdbc:postgresql://localhost:5432/kamco_cds
username: kamco_cds
password: kamco_cds_Q!W@E#R$
hikari:
minimum-idle: 1
maximum-pool-size: 5
jpa:
hibernate:
ddl-auto: update # 테이블이 없으면 생성, 있으면 업데이트
properties:
hibernate:
jdbc:
batch_size: 50
default_batch_fetch_size: 100
logging:
level:
root: INFO
org.springframework.web: DEBUG
org.springframework.security: DEBUG
# 헬스체크 노이즈 핵심만 다운
org.springframework.security.web.FilterChainProxy: INFO
org.springframework.security.web.authentication.AnonymousAuthenticationFilter: INFO
org.springframework.security.web.authentication.Http403ForbiddenEntryPoint: INFO
org.springframework.web.servlet.DispatcherServlet: INFO
# actuator
management:
health:
readinessstate:
enabled: true
livenessstate:
enabled: true
endpoint:
health:
probes:
enabled: true
show-details: always
endpoints:
jmx:
exposure:
exclude: "*"
web:
base-path: /monitor
exposure:
include:
- "health"
file:
#sync-root-dir: D:/kamco-nfs/images/
sync-root-dir: /kamco-nfs/images/
sync-tmp-dir: ${file.sync-root-dir}/tmp
sync-file-extention: tfw,tif
sync-auto-exception-start-year: 2025
sync-auto-exception-before-year-cnt: 3
gukyuin:
#url: http://localhost:8080
url: http://192.168.2.129:5301
cdi: ${gukyuin.url}/api/kcd/cdi

View File

@@ -1,71 +0,0 @@
server:
port: 9080
spring:
application:
name: imagery-make-dataset
profiles:
active: local # 사용할 프로파일 지정 (ex. dev, prod, test)
datasource:
url: jdbc:postgresql://192.168.2.127:15432/kamco_cds
#url: jdbc:postgresql://localhost:5432/kamco_cds
username: kamco_cds
password: kamco_cds_Q!W@E#R$
hikari:
minimum-idle: 1
maximum-pool-size: 5
jpa:
hibernate:
ddl-auto: update # 테이블이 없으면 생성, 있으면 업데이트
properties:
hibernate:
jdbc:
batch_size: 50
default_batch_fetch_size: 100
logging:
level:
root: INFO
org.springframework.web: DEBUG
org.springframework.security: DEBUG
# 헬스체크 노이즈 핵심만 다운
org.springframework.security.web.FilterChainProxy: INFO
org.springframework.security.web.authentication.AnonymousAuthenticationFilter: INFO
org.springframework.security.web.authentication.Http403ForbiddenEntryPoint: INFO
org.springframework.web.servlet.DispatcherServlet: INFO
# actuator
management:
health:
readinessstate:
enabled: true
livenessstate:
enabled: true
endpoint:
health:
probes:
enabled: true
show-details: always
endpoints:
jmx:
exposure:
exclude: "*"
web:
base-path: /monitor
exposure:
include:
- "health"
file:
#sync-root-dir: D:/kamco-nfs/images/
sync-root-dir: /kamco-nfs/images/
sync-tmp-dir: ${file.sync-root-dir}/tmp
sync-file-extention: tfw,tif
sync-auto-exception-start-year: 2025
sync-auto-exception-before-year-cnt: 3
gukyuin:
#url: http://localhost:8080
url: http://192.168.2.129:5301
cdi: ${gukyuin.url}/api/kcd/cdi

View File

@@ -1,71 +0,0 @@
server:
port: 9080
spring:
application:
name: imagery-make-dataset
profiles:
active: prod # 사용할 프로파일 지정 (ex. dev, prod, test)
datasource:
url: jdbc:postgresql://192.168.2.127:15432/kamco_cds
#url: jdbc:postgresql://localhost:5432/kamco_cds
username: kamco_cds
password: kamco_cds_Q!W@E#R$
hikari:
minimum-idle: 1
maximum-pool-size: 5
jpa:
hibernate:
ddl-auto: update # 테이블이 없으면 생성, 있으면 업데이트
properties:
hibernate:
jdbc:
batch_size: 50
default_batch_fetch_size: 100
logging:
level:
root: INFO
org.springframework.web: DEBUG
org.springframework.security: DEBUG
# 헬스체크 노이즈 핵심만 다운
org.springframework.security.web.FilterChainProxy: INFO
org.springframework.security.web.authentication.AnonymousAuthenticationFilter: INFO
org.springframework.security.web.authentication.Http403ForbiddenEntryPoint: INFO
org.springframework.web.servlet.DispatcherServlet: INFO
# actuator
management:
health:
readinessstate:
enabled: true
livenessstate:
enabled: true
endpoint:
health:
probes:
enabled: true
show-details: always
endpoints:
jmx:
exposure:
exclude: "*"
web:
base-path: /monitor
exposure:
include:
- "health"
file:
#sync-root-dir: D:/kamco-nfs/images/
sync-root-dir: /kamco-nfs/images/
sync-tmp-dir: ${file.sync-root-dir}/tmp
sync-file-extention: tfw,tif
sync-auto-exception-start-year: 2025
sync-auto-exception-before-year-cnt: 3
gukyuin:
#url: http://localhost:8080
url: http://192.168.2.129:5301
cdi: ${gukyuin.url}/api/kcd/cdi

View File

@@ -1,27 +0,0 @@
package com.kamco.cd.kamcoback.common.enums;
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 {
ADMIN("관리자"),
LABELER("라벨러"),
REVIEWER("검수자");
private final String desc;
@Override
public String getId() {
return name();
}
@Override
public String getText() {
return desc;
}
}

View File

@@ -1,27 +0,0 @@
package com.kamco.cd.kamcoback.common.enums;
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 {
ACTIVE("사용"),
INACTIVE("사용중지"),
PENDING("계정등록");
private final String desc;
@Override
public String getId() {
return name();
}
@Override
public String getText() {
return desc;
}
}

View File

@@ -0,0 +1,15 @@
package com.kamco.cd.kamcoback.config;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
}

View File

@@ -0,0 +1,223 @@
package com.kamco.cd.kamcoback.config.api;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import org.springframework.http.HttpStatus;
@Getter
@ToString
public class ApiResponseDto<T> {
private T data;
@JsonInclude(JsonInclude.Include.NON_NULL)
private Error error;
@JsonInclude(JsonInclude.Include.NON_NULL)
private T errorData;
@JsonIgnore private HttpStatus httpStatus;
@JsonIgnore private Long errorLogUid;
public ApiResponseDto(T data) {
this.data = data;
}
private ApiResponseDto(T data, HttpStatus httpStatus) {
this.data = data;
this.httpStatus = httpStatus;
}
public ApiResponseDto(ApiResponseCode code) {
this.error = new Error(code.getId(), code.getMessage());
}
public ApiResponseDto(ApiResponseCode code, String message) {
this.error = new Error(code.getId(), message);
}
public ApiResponseDto(ApiResponseCode code, String message, HttpStatus httpStatus) {
this.error = new Error(code.getId(), message);
this.httpStatus = httpStatus;
}
public ApiResponseDto(
ApiResponseCode code, String message, HttpStatus httpStatus, Long errorLogUid) {
this.error = new Error(code.getId(), message);
this.httpStatus = httpStatus;
this.errorLogUid = errorLogUid;
}
public ApiResponseDto(ApiResponseCode code, String message, T errorData) {
this.error = new Error(code.getId(), message);
this.errorData = errorData;
}
// HTTP 상태 코드가 내장된 ApiResponseDto 반환 메서드들
public static <T> ApiResponseDto<T> createOK(T data) {
return new ApiResponseDto<>(data, HttpStatus.CREATED);
}
public static <T> ApiResponseDto<T> ok(T data) {
return new ApiResponseDto<>(data, HttpStatus.OK);
}
public static <T> ApiResponseDto<ResponseObj> okObject(ResponseObj data) {
if (data.getCode().equals(ApiResponseCode.OK)) {
return new ApiResponseDto<>(data, HttpStatus.NO_CONTENT);
} else {
return new ApiResponseDto<>(data.getCode(), data.getMessage(), HttpStatus.CONFLICT);
}
}
public static <T> ApiResponseDto<T> deleteOk(T data) {
return new ApiResponseDto<>(data, HttpStatus.NO_CONTENT);
}
public static ApiResponseDto<String> createException(ApiResponseCode code) {
return new ApiResponseDto<>(code);
}
public static ApiResponseDto<String> createException(ApiResponseCode code, String message) {
return new ApiResponseDto<>(code, message);
}
public static ApiResponseDto<String> createException(
ApiResponseCode code, String message, HttpStatus httpStatus) {
return new ApiResponseDto<>(code, message, httpStatus);
}
public static ApiResponseDto<String> createException(
ApiResponseCode code, String message, HttpStatus httpStatus, Long errorLogUid) {
return new ApiResponseDto<>(code, message, httpStatus, errorLogUid);
}
public static <T> ApiResponseDto<T> createException(
ApiResponseCode code, String message, T data) {
return new ApiResponseDto<>(code, message, data);
}
@Getter
public static class Error {
private final String code;
private final String message;
public Error(String code, String message) {
this.code = code;
this.message = message;
}
}
/** Error가 아닌 Business상 성공이거나 실패인 경우, 메세지 함께 전달하기 위한 object */
@Getter
public static class ResponseObj {
private final ApiResponseCode code;
private final String message;
public ResponseObj(ApiResponseCode code, String message) {
this.code = code;
this.message = message;
}
}
@Getter
@RequiredArgsConstructor
public enum ApiResponseCode implements EnumType {
// @formatter:off
OK("요청이 성공하였습니다."),
BAD_REQUEST("요청 파라미터가 잘못되었습니다."),
BAD_GATEWAY("네트워크 상태가 불안정합니다."),
ALREADY_EXIST_MALL("이미 등록된 쇼핑센터입니다."),
NOT_FOUND_MAP("지도를 찾을 수 없습니다."),
UNAUTHORIZED("권한이 없습니다."),
CONFLICT("이미 등록된 컨텐츠입니다."),
NOT_FOUND("Resource를 찾을 수 없습니다."),
NOT_FOUND_DATA("데이터를 찾을 수 없습니다."),
NOT_FOUND_WEATHER_DATA("날씨 데이터를 찾을 수 없습니다."),
FAIL_SEND_MESSAGE("메시지를 전송하지 못했습니다."),
TOO_MANY_CONNECTED_MACHINES("연결된 기기가 너무 많습니다."),
UNAUTHENTICATED("인증에 실패하였습니다."),
INVALID_TOKEN("잘못된 토큰입니다."),
EXPIRED_TOKEN("만료된 토큰입니다."),
INTERNAL_SERVER_ERROR("서버에 문제가 발생 하였습니다."),
FORBIDDEN("권한을 확인해주세요."),
INVALID_PASSWORD("잘못된 비밀번호 입니다."),
NOT_FOUND_CAR_IN("입차정보가 없습니다."),
WRONG_STATUS("잘못된 상태입니다."),
FAIL_VERIFICATION("인증에 실패하였습니다."),
INVALID_EMAIL("잘못된 형식의 이메일입니다."),
REQUIRED_EMAIL("이메일은 필수 항목입니다."),
WRONG_PASSWORD("잘못된 패스워드입니다."),
DUPLICATE_EMAIL("이미 가입된 이메일입니다."),
DUPLICATE_DATA("이미 등록되어 있습니다."),
DATA_INTEGRITY_ERROR("데이터 무결성이 위반되어 요청을 처리할수 없습니다."),
FOREIGN_KEY_ERROR("참조 중인 데이터가 있어 삭제할 수 없습니다."),
DUPLICATE_EMPLOYEEID("이미 가입된 사번입니다."),
NOT_FOUND_USER_FOR_EMAIL("이메일로 유저를 찾을 수 없습니다."),
NOT_FOUND_USER("사용자를 찾을 수 없습니다."),
UNPROCESSABLE_ENTITY("이 데이터는 삭제할 수 없습니다."),
LOGIN_ID_NOT_FOUND("아이디를 잘못 입력하셨습니다."),
LOGIN_PASSWORD_MISMATCH("비밀번호를 잘못 입력하셨습니다."),
LOGIN_PASSWORD_EXCEEDED("비밀번호 오류 횟수를 초과하여 이용하실 수 없습니다.\n로그인 오류에 대해 관리자에게 문의하시기 바랍니다."),
INACTIVE_ID("사용할 수 없는 계정입니다."),
INVALID_EMAIL_TOKEN(
"You can only reset your password within 24 hours from when the email was sent.\n"
+ "To reset your password again, please submit a new request through \"Forgot"
+ " Password.\""),
PAYLOAD_TOO_LARGE("업로드 용량 제한을 초과했습니다."),
NOT_FOUND_TARGET_YEAR("기준년도 도엽을 찾을 수 없습니다."),
NOT_FOUND_COMPARE_YEAR("비교년도 도엽을 찾을 수 없습니다."),
FAIL_SAVE_MAP_SHEET("도엽 저장 중 오류가 발생했습니다."),
FAIL_CREATE_MAP_SHEET_FILE("도엽 설정파일 생성 중 오류가 발생했습니다."),
;
// @formatter:on
private final String message;
@Override
public String getId() {
return name();
}
@Override
public String getText() {
return message;
}
public static ApiResponseCode getCode(String name) {
return ApiResponseCode.valueOf(name.toUpperCase());
}
public static String getMessage(String name) {
return ApiResponseCode.valueOf(name.toUpperCase()).getText();
}
public static ApiResponseCode from(String codeName, HttpStatus status) {
if (codeName != null && !codeName.isBlank()) {
try {
return ApiResponseCode.valueOf(codeName.toUpperCase());
} catch (IllegalArgumentException ignore) {
// fallback
}
}
if (status != null) {
try {
return ApiResponseCode.valueOf(status.name());
} catch (IllegalArgumentException ignore) {
// fallback
}
}
return INTERNAL_SERVER_ERROR;
}
}
}

View File

@@ -0,0 +1,43 @@
package com.kamco.cd.kamcoback.enums;
import com.kamco.cd.kamcoback.common.utils.enums.CodeExpose;
import com.kamco.cd.kamcoback.common.utils.enums.EnumType;
import java.util.Arrays;
import lombok.AllArgsConstructor;
import lombok.Getter;
@CodeExpose
@Getter
@AllArgsConstructor
public enum ImageryFitStatus implements EnumType {
FIT("적합"),
UNFIT("부적합");
private final String desc;
@Override
public String getId() {
return name();
}
@Override
public String getText() {
return desc;
}
public static ImageryFitStatus fromCode(String code) {
if (code == null) {
return null;
}
String c = code.trim();
return Arrays.stream(values())
.filter(v -> v.name().equalsIgnoreCase(c))
.findFirst()
.orElse(null);
}
public static String getDescByCode(String code) {
ImageryFitStatus status = fromCode(code);
return status != null ? status.getDesc() : null;
}
}

View File

@@ -114,4 +114,38 @@ public class ChngDetectContDto {
private List<DtoPnuDetectMpng> result; private List<DtoPnuDetectMpng> result;
private Boolean success; private Boolean success;
} }
@Schema(name = "ResultLabelDto", description = "ResultLabelDto list 리턴 형태")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class ResultLabelDto {
private Integer code;
private String message;
private DtoPnuDetectMpng result;
private Boolean success;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class ReqInfo {
private String reqIp;
private String reqEpno;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class StbltResult {
private String stbltYn;
private String incyCd;
private String incyCmnt;
}
} }

View File

@@ -247,45 +247,58 @@ public class ChngDetectMastDto {
@AllArgsConstructor @AllArgsConstructor
public static class RlbDtctMastDto { public static class RlbDtctMastDto {
private String pnuDtctId; private String pnuDtctId; // PNU탐지ID
private String pnu; private String pnu; // PNU코드(19자리)
private String lrmSyncYmd; private String lrmSyncYmd; // 지적도동기화일자(YYYYMMDD)
private String pnuSyncYmd; private String pnuSyncYmd; // PNU동기화일자(YYYYMMDD)
private String mpqdNo; // 도번호 private String mpqdNo; // 도번호
private String cprsYr; // 비교년도 private String cprsYr; // 비교년도
private String crtrYr; // 기준년도 private String crtrYr; // 기준년도
private String chnDtctSno; // 회차 private String chnDtctSno; // 회차, 변화탐지순번
private String chnDtctId; private String chnDtctId; // 변화탐지ID(UUID)
private String chnDtctMstId; private String chnDtctMstId; // 변화탐지마스터ID
private String chnDtctObjtId; private String chnDtctObjtId; // 변화탐지객체ID
private String chnDtctContId; private String chnDtctContId; // 변화탐지내용ID
private String chnCd; private String chnCd; // 변화코드
private String chnDtctProb; private String chnDtctProb; // 변화탐지정확도(0~1)
private String bfClsCd; // 이전분류코드 private String bfClsCd; // 이전분류코드
private String bfClsProb; // 이전분류정확도 private String bfClsProb; // 이전분류정확도(0~1)
private String afClsCd; // 이후분류코드 private String afClsCd; // 이후분류코드
private String afClsProb; // 이후분류정확도 private String afClsProb; // 이후분류정확도(0~1)
private String pnuSqms; private String pnuSqms; // PNU면적(㎡)
private String pnuDtctSqms; private String pnuDtctSqms; // PNU탐지면적(㎡)
private String chnDtctSqms; private String chnDtctSqms; // 변화탐지면적(㎡)
private String stbltYn; private String stbltYn; // 적합여부(Y/N) - 안정성 (Y:부적합, N:적합)
private String incyCd; private String incyCd; // 부적합코드
private String incyRsnCont; private String incyRsnCont; // 부적합사유내용
private String lockYn; private String lockYn; // 잠금여부(Y/N)
private String lblYn; private String lblYn; // 라벨여부(Y/N)
private String chgYn; private String chgYn; // 변경여부(Y/N)
private String rsatctNo; private String rsatctNo; // 부동산등기번호
private String rmk; private String rmk; // 비고
private String crtDt; // 생성일시 private String crtDt; // 생성일시
private String crtEpno; // 생성사원번호 private String crtEpno; // 생성사원번호
private String crtIp; // 생성사원아이피 private String crtIp; // 생성사원아이피
private String chgDt; private String chgDt; // 변경일시
private String chgEpno; private String chgEpno; // 변경자사번
private String chgIp; private String chgIp; // 변경자IP
private String delYn; // 삭제여부 private String delYn; // 삭제여부
} }
@Schema(name = "RemoveResDto", description = "remove 후 리턴 형태")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class RemoveResDto {
private Integer code;
private String message;
private Boolean result;
private Boolean success;
}
} }

View File

@@ -0,0 +1,67 @@
package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.Basic;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.LabelSendDto;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.LearnInfo;
import com.kamco.cd.kamcoback.postgres.repository.gukyuin.GukYuinRepository;
import java.time.LocalDate;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class GukYuinCoreService {
private final GukYuinRepository gukYuinRepository;
public void updateGukYuinMastRegResult(Basic resultBody) {
gukYuinRepository.updateGukYuinMastRegResult(resultBody);
}
public void updateGukYuinMastRegRemove(String chnDtctId) {
gukYuinRepository.updateGukYuinMastRegRemove(chnDtctId);
}
public void updateInferenceGeomDataPnuCnt(String chnDtctObjtId, long pnuCnt) {
gukYuinRepository.updateInferenceGeomDataPnuCnt(chnDtctObjtId, pnuCnt);
}
public Long findMapSheetAnalDataInferenceGeomUid(String chnDtctObjtId) {
return gukYuinRepository.findMapSheetAnalDataInferenceGeomUid(chnDtctObjtId);
}
public void insertGeoUidPnuData(Long geoUid, String[] pnuList, String chnDtctObjtId) {
gukYuinRepository.insertGeoUidPnuData(geoUid, pnuList, chnDtctObjtId);
}
public LearnInfo findMapSheetLearnInfo(UUID uuid) {
return gukYuinRepository.findMapSheetLearnInfo(uuid);
}
public Integer findMapSheetLearnYearStage(Integer compareYyyy, Integer targetYyyy) {
return gukYuinRepository.findMapSheetLearnYearStage(compareYyyy, targetYyyy);
}
public void updateAnalInferenceApplyDttm(Basic registRes) {
gukYuinRepository.updateAnalInferenceApplyDttm(registRes);
}
public List<LabelSendDto> findLabelingCompleteSendList(LocalDate yesterday) {
return gukYuinRepository.findLabelingCompleteSendList(yesterday);
}
public Long findMapSheetLearnInfoByYyyy(
Integer compareYyyy, Integer targetYyyy, Integer maxStage) {
return gukYuinRepository.findMapSheetLearnInfoByYyyy(compareYyyy, targetYyyy, maxStage);
}
public void updateMapSheetLearnGukyuinEndStatus(Long learnId) {
gukYuinRepository.updateMapSheetLearnGukyuinEndStatus(learnId);
}
public void updateMapSheetInferenceLabelEndStatus(Long learnId) {
gukYuinRepository.updateMapSheetInferenceLabelEndStatus(learnId);
}
}

View File

@@ -2,8 +2,10 @@ 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;
@Service @Service
public class GukYuinLabelJobCoreService { public class GukYuinLabelJobCoreService {
@@ -14,10 +16,11 @@ 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
public void updateAnalDataInferenceGeomSendDttm(Long geoUid) { public void updateAnalDataInferenceGeomSendDttm(Long geoUid) {
gukYuinLabelRepository.updateAnalDataInferenceGeomSendDttm(geoUid); gukYuinLabelRepository.updateAnalDataInferenceGeomSendDttm(geoUid);
} }

View File

@@ -1,22 +0,0 @@
package com.kamco.cd.kamcoback.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.PrePersist;
import java.time.ZonedDateTime;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
@Getter
@MappedSuperclass
public class CommonCreateEntity {
@CreatedDate
@Column(name = "created_dttm", updatable = false, nullable = false)
private ZonedDateTime createdDate;
@PrePersist
protected void onPersist() {
this.createdDate = ZonedDateTime.now();
}
}

View File

@@ -1,5 +1,6 @@
package com.kamco.cd.kamcoback.postgres.entity; package com.kamco.cd.kamcoback.postgres.entity;
import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.MapSheet;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
@@ -45,4 +46,8 @@ public class MapInkx50kEntity extends CommonDateEntity {
this.mapidNo = mapidNo; this.mapidNo = mapidNo;
this.geom = geom; this.geom = geom;
} }
public MapSheet toEntity() {
return new MapSheet(mapidcdNo, mapidNm);
}
} }

View File

@@ -3,6 +3,7 @@ package com.kamco.cd.kamcoback.postgres.entity;
import com.kamco.cd.kamcoback.enums.CommonUseStatus; import com.kamco.cd.kamcoback.enums.CommonUseStatus;
import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.MapSheet; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.MapSheet;
import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto.MapListEntity;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.EnumType; import jakarta.persistence.EnumType;
@@ -53,10 +54,6 @@ public class MapInkx5kEntity extends CommonDateEntity {
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
private CommonUseStatus useInference; private CommonUseStatus useInference;
public InferenceDetailDto.MapSheet toEntity() {
return new MapSheet(mapidcdNo, mapidNm);
}
// Constructor // Constructor
public MapInkx5kEntity( public MapInkx5kEntity(
String mapidcdNo, String mapidNm, Geometry geom, MapInkx50kEntity mapInkx50k) { String mapidcdNo, String mapidNm, Geometry geom, MapInkx50kEntity mapInkx50k) {
@@ -72,4 +69,18 @@ public class MapInkx5kEntity extends CommonDateEntity {
public void updateUseInference(CommonUseStatus useInference) { public void updateUseInference(CommonUseStatus useInference) {
this.useInference = useInference; this.useInference = useInference;
} }
public InferenceDetailDto.MapSheet toEntity() {
return new MapSheet(mapidcdNo, mapidNm);
}
public MapListEntity toDto() {
return MapListEntity.builder()
.scene5k(this.toEntity())
.scene50k(this.mapInkx50k.toEntity())
.useInference(useInference)
.createdDttm(super.getCreatedDate())
.updatedDttm(super.getModifiedDate())
.build();
}
} }

View File

@@ -0,0 +1,167 @@
package com.kamco.cd.kamcoback.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@Table(name = "tb_map_sheet_anal_data_inference")
public class MapSheetAnalDataInferenceEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "data_uid", nullable = false)
private Long id;
// @Size(max = 128)
// @Column(name = "data_name", length = 128)
// private String dataName;
//
// @Size(max = 255)
// @Column(name = "data_path")
// private String dataPath;
//
// @Size(max = 128)
// @Column(name = "data_type", length = 128)
// private String dataType;
//
// @Size(max = 128)
// @Column(name = "data_crs_type", length = 128)
// private String dataCrsType;
//
// @Size(max = 255)
// @Column(name = "data_crs_type_name")
// private String dataCrsTypeName;
@ColumnDefault("now()")
@Column(name = "created_dttm")
private ZonedDateTime createdDttm;
@Column(name = "created_uid")
private Long createdUid;
@ColumnDefault("now()")
@Column(name = "updated_dttm")
private ZonedDateTime updatedDttm;
@Column(name = "updated_uid")
private Long updatedUid;
@Column(name = "compare_yyyy")
private Integer compareYyyy;
@Column(name = "target_yyyy")
private Integer targetYyyy;
// @Column(name = "data_json", length = Integer.MAX_VALUE)
// private String dataJson;
//
// @Size(max = 20)
// @ColumnDefault("'0'")
// @Column(name = "data_state", length = 20)
// private String dataState;
// @ColumnDefault("now()")
// @Column(name = "data_state_dttm")
// private ZonedDateTime dataStateDttm;
//
// @Column(name = "anal_strt_dttm")
// private ZonedDateTime analStrtDttm;
//
// @Column(name = "anal_end_dttm")
// private ZonedDateTime analEndDttm;
//
// @ColumnDefault("0")
// @Column(name = "anal_sec")
// private Long analSec;
@Size(max = 20)
@Column(name = "anal_state", length = 20)
private String analState;
@Column(name = "anal_uid")
private Long analUid;
@Column(name = "map_sheet_num")
private Long mapSheetNum;
// @ColumnDefault("0")
// @Column(name = "detecting_cnt")
// private Long detectingCnt;
// @ColumnDefault("0")
// @Column(name = "pnu")
// private Long pnu;
// @Size(max = 20)
// @Column(name = "down_state", length = 20)
// private String downState;
//
// @Column(name = "down_state_dttm")
// private ZonedDateTime downStateDttm;
@Size(max = 20)
@Column(name = "fit_state", length = 20)
private String fitState;
@Column(name = "fit_state_dttm")
private ZonedDateTime fitStateDttm;
@Column(name = "labeler_uid")
private Long labelerUid;
@Size(max = 20)
@ColumnDefault("NULL")
@Column(name = "label_state", length = 20)
private String labelState;
@Column(name = "label_state_dttm")
private ZonedDateTime labelStateDttm;
@Column(name = "tester_uid")
private Long testerUid;
@Size(max = 20)
@Column(name = "test_state", length = 20)
private String testState;
@Column(name = "test_state_dttm")
private ZonedDateTime testStateDttm;
@Column(name = "fit_state_cmmnt", length = Integer.MAX_VALUE)
private String fitStateCmmnt;
@Column(name = "ref_map_sheet_num")
private Long refMapSheetNum;
@Column(name = "stage")
private Integer stage;
@Column(name = "file_created_yn")
private Boolean fileCreatedYn;
@Column(name = "file_created_dttm")
private ZonedDateTime fileCreatedDttm;
// @Size(max = 100)
// @Column(name = "m1", length = 100)
// private String m1;
//
// @Size(max = 100)
// @Column(name = "m2", length = 100)
// private String m2;
//
// @Size(max = 100)
// @Column(name = "m3", length = 100)
// private String m3;
}

View File

@@ -12,7 +12,7 @@ import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import java.time.OffsetDateTime; import java.time.ZonedDateTime;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.hibernate.annotations.ColumnDefault; import org.hibernate.annotations.ColumnDefault;
@@ -39,7 +39,7 @@ public class PnuEntity {
private String pnu; private String pnu;
@Column(name = "created_dttm") @Column(name = "created_dttm")
private OffsetDateTime createdDttm; private ZonedDateTime createdDttm;
@Column(name = "created_uid") @Column(name = "created_uid")
private Long createdUid; private Long createdUid;
@@ -47,4 +47,140 @@ public class PnuEntity {
@ColumnDefault("false") @ColumnDefault("false")
@Column(name = "del_yn") @Column(name = "del_yn")
private Boolean delYn; private Boolean delYn;
@Size(max = 40)
@Column(name = "pnu_dtct_id", length = 40)
private String pnuDtctId;
@Size(max = 10)
@Column(name = "lrm_sync_ymd", length = 10)
private String lrmSyncYmd;
@Size(max = 10)
@Column(name = "pnu_sync_ymd", length = 10)
private String pnuSyncYmd;
@Size(max = 20)
@Column(name = "mpqd_no", length = 20)
private String mpqdNo;
@Size(max = 10)
@Column(name = "cprs_yr", length = 10)
private String cprsYr;
@Size(max = 10)
@Column(name = "crtr_yr", length = 10)
private String crtrYr;
@Size(max = 255)
@Column(name = "chn_dtct_id")
private String chnDtctId;
@Size(max = 10)
@Column(name = "chn_dtct_mst_id", length = 10)
private String chnDtctMstId;
@Size(max = 255)
@Column(name = "chn_dtct_objt_id")
private String chnDtctObjtId;
@Size(max = 255)
@Column(name = "chn_dtct_cont_id")
private String chnDtctContId;
@Size(max = 50)
@Column(name = "chn_cd", length = 50)
private String chnCd;
@Size(max = 50)
@Column(name = "chn_dtct_prob", length = 50)
private String chnDtctProb;
@Size(max = 50)
@Column(name = "bf_cls_cd", length = 50)
private String bfClsCd;
@Size(max = 50)
@Column(name = "bf_cls_prob", length = 50)
private String bfClsProb;
@Size(max = 50)
@Column(name = "af_cls_cd", length = 50)
private String afClsCd;
@Size(max = 50)
@Column(name = "af_cls_prob", length = 50)
private String afClsProb;
@Size(max = 100)
@Column(name = "pnu_sqms", length = 100)
private String pnuSqms;
@Size(max = 100)
@Column(name = "pnu_dtct_sqms", length = 100)
private String pnuDtctSqms;
@Size(max = 100)
@Column(name = "chn_dtct_sqms", length = 100)
private String chnDtctSqms;
@Size(max = 1)
@Column(name = "stblt_yn", length = 1)
private String stbltYn;
@Size(max = 30)
@Column(name = "incy_cd", length = 30)
private String incyCd;
@Size(max = 255)
@Column(name = "incy_rsn_cont")
private String incyRsnCont;
@Size(max = 1)
@Column(name = "lock_yn", length = 1)
private String lockYn;
@Size(max = 1)
@Column(name = "lbl_yn", length = 1)
private String lblYn;
@Size(max = 1)
@Column(name = "chg_yn", length = 1)
private String chgYn;
@Size(max = 50)
@Column(name = "rsatct_no", length = 50)
private String rsatctNo;
@Size(max = 100)
@Column(name = "rmk", length = 100)
private String rmk;
@Size(max = 20)
@Column(name = "crt_dt", length = 20)
private String crtDt;
@Size(max = 20)
@Column(name = "crt_epno", length = 20)
private String crtEpno;
@Size(max = 20)
@Column(name = "crt_ip", length = 20)
private String crtIp;
@Size(max = 20)
@Column(name = "chg_dt", length = 20)
private String chgDt;
@Size(max = 20)
@Column(name = "chg_epno", length = 20)
private String chgEpno;
@Size(max = 20)
@Column(name = "chg_ip", length = 20)
private String chgIp;
@Size(max = 10)
@Column(name = "chn_dtct_sno", length = 10)
private String chnDtctSno;
} }

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,16 +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 yesterdayStart = todayStart.minusDays(1);
BooleanExpression isYesterday = // baseDate가 null이면 기존처럼 "어제"로 처리
LocalDate targetDate =
(baseDate != null) ? baseDate : ZonedDateTime.now(zone).toLocalDate().minusDays(1);
ZonedDateTime targetStart = targetDate.atStartOfDay(zone);
ZonedDateTime nextStart = targetStart.plusDays(1);
BooleanExpression inTargetDay =
labelingAssignmentEntity labelingAssignmentEntity
.inspectStatDttm .inspectStatDttm
.goe(yesterdayStart) .goe(targetStart)
.and(labelingAssignmentEntity.inspectStatDttm.lt(todayStart)); .and(labelingAssignmentEntity.inspectStatDttm.lt(nextStart));
return queryFactory return queryFactory
.select( .select(
@@ -56,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

@@ -0,0 +1,7 @@
package com.kamco.cd.kamcoback.postgres.repository.gukyuin;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface GukYuinRepository
extends JpaRepository<MapSheetLearnEntity, Long>, GukYuinRepositoryCustom {}

View File

@@ -0,0 +1,48 @@
package com.kamco.cd.kamcoback.postgres.repository.gukyuin;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.Basic;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.LabelSendDto;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.LearnKeyDto;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GeomUidDto;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.LearnInfo;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinStatus;
import java.time.LocalDate;
import java.util.List;
import java.util.UUID;
public interface GukYuinRepositoryCustom {
void updateGukYuinMastRegResult(Basic resultBody);
void updateGukYuinMastRegRemove(String chnDtctId);
void updateInferenceGeomDataPnuCnt(String chnDtctObjtId, long pnuCnt);
Long findMapSheetAnalDataInferenceGeomUid(String chnDtctObjtId);
void insertGeoUidPnuData(Long geoUid, String[] pnuList, String chnDtctObjtId);
void updateGukYuinApplyStateComplete(Long id, GukYuinStatus status);
List<LearnKeyDto> findGukyuinApplyStatusUidList(List<String> gukYuinStatus);
long upsertMapSheetDataAnalGeomPnu(String uid, String[] pnuList);
LearnInfo findMapSheetLearnInfo(UUID uuid);
Integer findMapSheetLearnYearStage(Integer compareYyyy, Integer targetYyyy);
void updateAnalInferenceApplyDttm(Basic registRes);
List<GeomUidDto> findYesterdayLabelingCompleteList();
void updateAnalDataInferenceGeomSendDttm(Long geoUid);
List<LabelSendDto> findLabelingCompleteSendList(LocalDate yesterday);
Long findMapSheetLearnInfoByYyyy(Integer compareYyyy, Integer targetYyyy, Integer maxStage);
void updateMapSheetLearnGukyuinEndStatus(Long learnId);
void updateMapSheetInferenceLabelEndStatus(Long learnId);
}

View File

@@ -0,0 +1,331 @@
package com.kamco.cd.kamcoback.postgres.repository.gukyuin;
import static com.kamco.cd.kamcoback.postgres.entity.QLabelingAssignmentEntity.labelingAssignmentEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceGeomEntity.mapSheetAnalDataInferenceGeomEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalInferenceEntity.mapSheetAnalInferenceEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetLearnEntity.mapSheetLearnEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QPnuEntity.pnuEntity;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.Basic;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.LabelSendDto;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.LearnKeyDto;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GeomUidDto;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.LearnInfo;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinStatus;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.InspectState;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelMngState;
import com.kamco.cd.kamcoback.postgres.entity.PnuEntity;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.NumberExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class GukYuinRepositoryImpl implements GukYuinRepositoryCustom {
private final JPAQueryFactory queryFactory;
@PersistenceContext private EntityManager em;
@Override
public void updateGukYuinMastRegResult(Basic resultBody) {
int excnPgrt = Integer.parseInt(resultBody.getExcnPgrt());
int stage = Integer.parseInt(resultBody.getChnDtctSno());
GukYuinStatus status = GukYuinStatus.IN_PROGRESS;
if (excnPgrt == 100) {
status = GukYuinStatus.GUK_COMPLETED;
}
queryFactory
.update(mapSheetLearnEntity)
.set(mapSheetLearnEntity.stage, stage)
.set(mapSheetLearnEntity.applyStatus, status.getId())
.set(mapSheetLearnEntity.applyStatusDttm, ZonedDateTime.now())
.set(mapSheetLearnEntity.chnDtctMstId, resultBody.getChnDtctMstId())
.set(mapSheetLearnEntity.applyYn, true)
.set(mapSheetLearnEntity.applyDttm, ZonedDateTime.now())
.where(mapSheetLearnEntity.uid.eq(resultBody.getChnDtctId()))
.execute();
}
@Override
public void updateGukYuinMastRegRemove(String chnDtctId) {
queryFactory
.update(mapSheetLearnEntity)
.set(mapSheetLearnEntity.applyStatus, GukYuinStatus.CANCELED.getId())
.set(mapSheetLearnEntity.applyStatusDttm, ZonedDateTime.now())
.set(mapSheetLearnEntity.applyYn, false)
.where(mapSheetLearnEntity.uid.eq(chnDtctId))
.execute();
}
@Override
public void updateInferenceGeomDataPnuCnt(String chnDtctObjtId, long pnuCnt) {
queryFactory
.update(mapSheetAnalDataInferenceGeomEntity)
.set(mapSheetAnalDataInferenceGeomEntity.pnu, pnuCnt)
.where(mapSheetAnalDataInferenceGeomEntity.resultUid.eq(chnDtctObjtId))
.execute();
}
@Override
public Long findMapSheetAnalDataInferenceGeomUid(String chnDtctObjtId) {
return queryFactory
.select(mapSheetAnalDataInferenceGeomEntity.geoUid)
.from(mapSheetAnalDataInferenceGeomEntity)
.where(mapSheetAnalDataInferenceGeomEntity.resultUid.eq(chnDtctObjtId))
.fetchOne();
}
@Override
public void insertGeoUidPnuData(Long geoUid, String[] pnuList, String chnDtctObjtId) {
for (String pnu : pnuList) {
PnuEntity entity =
queryFactory
.selectFrom(pnuEntity)
.where(
pnuEntity.geo.geoUid.eq(geoUid),
pnuEntity.pnu.eq(pnu),
pnuEntity.chnDtctObjtId.eq(chnDtctObjtId))
.fetchOne();
if (entity == null) {
queryFactory
.insert(pnuEntity)
.columns(
pnuEntity.geo.geoUid, pnuEntity.pnu, pnuEntity.createdDttm, pnuEntity.chnDtctObjtId)
.values(geoUid, pnu, ZonedDateTime.now(), chnDtctObjtId)
.execute();
}
}
}
@Override
public List<LearnKeyDto> findGukyuinApplyStatusUidList(List<String> status) {
return queryFactory
.select(
Projections.constructor(
LearnKeyDto.class,
mapSheetLearnEntity.id,
mapSheetLearnEntity.uid,
mapSheetLearnEntity.chnDtctMstId))
.from(mapSheetLearnEntity)
.where(mapSheetLearnEntity.applyStatus.in(status))
.fetch();
}
@Override
public long upsertMapSheetDataAnalGeomPnu(String chnDtctObjtId, String[] pnuList) {
long length = pnuList.length;
queryFactory
.update(mapSheetAnalDataInferenceGeomEntity)
.set(mapSheetAnalDataInferenceGeomEntity.pnu, length)
.where(mapSheetAnalDataInferenceGeomEntity.resultUid.eq(chnDtctObjtId))
.execute();
Long geoUid =
queryFactory
.select(mapSheetAnalDataInferenceGeomEntity.geoUid)
.from(mapSheetAnalDataInferenceGeomEntity)
.where(mapSheetAnalDataInferenceGeomEntity.resultUid.eq(chnDtctObjtId))
.fetchOne();
long succCnt = 0;
for (String pnu : pnuList) {
long result =
queryFactory
.insert(pnuEntity)
.columns(pnuEntity.geo.geoUid, pnuEntity.pnu, pnuEntity.createdDttm)
.values(geoUid, pnu, ZonedDateTime.now())
.execute();
if (result > 0) {
succCnt++;
}
}
return succCnt;
}
@Override
public LearnInfo findMapSheetLearnInfo(UUID uuid) {
return queryFactory
.select(
Projections.constructor(
LearnInfo.class,
mapSheetLearnEntity.id,
mapSheetLearnEntity.uuid,
mapSheetLearnEntity.compareYyyy,
mapSheetLearnEntity.targetYyyy,
mapSheetLearnEntity.stage,
mapSheetLearnEntity.uid,
mapSheetLearnEntity.applyStatus,
mapSheetLearnEntity.applyYn))
.from(mapSheetLearnEntity)
.where(mapSheetLearnEntity.uuid.eq(uuid))
.fetchOne();
}
@Override
public Integer findMapSheetLearnYearStage(Integer compareYyyy, Integer targetYyyy) {
NumberExpression<Integer> stageExpr =
Expressions.numberTemplate(Integer.class, "coalesce({0}, 0)", mapSheetLearnEntity.stage);
return queryFactory
.select(stageExpr.max().coalesce(0))
.from(mapSheetLearnEntity)
.where(
mapSheetLearnEntity.compareYyyy.eq(compareYyyy),
mapSheetLearnEntity.targetYyyy.eq(targetYyyy),
mapSheetLearnEntity.applyStatus.isNotNull(),
mapSheetLearnEntity.applyStatus.ne(GukYuinStatus.PENDING.getId()))
.fetchOne();
}
@Override
public void updateAnalInferenceApplyDttm(Basic registRes) {
Long learnId =
queryFactory
.select(mapSheetLearnEntity.id)
.from(mapSheetLearnEntity)
.where(mapSheetLearnEntity.uid.eq(registRes.getChnDtctId()))
.fetchOne();
queryFactory
.update(mapSheetAnalInferenceEntity)
.set(mapSheetAnalInferenceEntity.gukyuinUsed, "Y")
.set(mapSheetAnalInferenceEntity.gukyuinApplyDttm, ZonedDateTime.now())
.set(mapSheetAnalInferenceEntity.stage, Integer.parseInt(registRes.getChnDtctSno()))
.where(mapSheetAnalInferenceEntity.learnId.eq(learnId))
.execute();
}
@Override
public List<GeomUidDto> findYesterdayLabelingCompleteList() {
ZoneId zone = ZoneId.of("Asia/Seoul");
ZonedDateTime todayStart = ZonedDateTime.now(zone).toLocalDate().atStartOfDay(zone);
ZonedDateTime yesterdayStart = todayStart.minusDays(1);
BooleanExpression isYesterday =
labelingAssignmentEntity
.inspectStatDttm
.goe(yesterdayStart)
.and(labelingAssignmentEntity.inspectStatDttm.lt(todayStart));
return queryFactory
.select(
Projections.constructor(
GeomUidDto.class,
labelingAssignmentEntity.inferenceGeomUid,
mapSheetAnalDataInferenceGeomEntity.resultUid))
.from(labelingAssignmentEntity)
.innerJoin(mapSheetAnalDataInferenceGeomEntity)
.on(
labelingAssignmentEntity.inferenceGeomUid.eq(
mapSheetAnalDataInferenceGeomEntity.geoUid))
.innerJoin(mapSheetAnalInferenceEntity)
.on(labelingAssignmentEntity.analUid.eq(mapSheetAnalInferenceEntity.id))
.innerJoin(mapSheetLearnEntity)
.on(
mapSheetAnalInferenceEntity.learnId.eq(mapSheetLearnEntity.id),
mapSheetLearnEntity.applyStatus.in(
GukYuinStatus.GUK_COMPLETED.getId(), GukYuinStatus.PNU_COMPLETED.getId()))
.where(labelingAssignmentEntity.inspectState.eq(InspectState.COMPLETE.getId()), isYesterday)
.fetch();
}
@Override
public void updateAnalDataInferenceGeomSendDttm(Long geoUid) {
queryFactory
.update(mapSheetAnalDataInferenceGeomEntity)
.set(mapSheetAnalDataInferenceGeomEntity.labelSendDttm, ZonedDateTime.now())
.where(mapSheetAnalDataInferenceGeomEntity.geoUid.eq(geoUid))
.execute();
}
@Override
public List<LabelSendDto> findLabelingCompleteSendList(LocalDate yesterday) {
ZoneId zone = ZoneId.of("Asia/Seoul");
ZonedDateTime from = yesterday.atStartOfDay(zone);
ZonedDateTime to = from.plusDays(1);
BooleanExpression isYesterday =
labelingAssignmentEntity
.inspectStatDttm
.goe(from)
.and(labelingAssignmentEntity.inspectStatDttm.lt(to));
return queryFactory
.select(
Projections.constructor(
LabelSendDto.class,
mapSheetAnalDataInferenceGeomEntity.resultUid,
labelingAssignmentEntity.workerUid,
labelingAssignmentEntity.workStatDttm,
labelingAssignmentEntity.inspectorUid,
labelingAssignmentEntity.inspectStatDttm,
mapSheetAnalDataInferenceGeomEntity.labelSendDttm))
.from(labelingAssignmentEntity)
.innerJoin(mapSheetAnalDataInferenceGeomEntity)
.on(
labelingAssignmentEntity.inferenceGeomUid.eq(
mapSheetAnalDataInferenceGeomEntity.geoUid))
.where(labelingAssignmentEntity.inspectState.eq(InspectState.COMPLETE.getId()), isYesterday)
.fetch();
}
@Override
public Long findMapSheetLearnInfoByYyyy(
Integer compareYyyy, Integer targetYyyy, Integer maxStage) {
return queryFactory
.select(mapSheetLearnEntity.id)
.from(mapSheetLearnEntity)
.where(
mapSheetLearnEntity.compareYyyy.eq(compareYyyy),
mapSheetLearnEntity.targetYyyy.eq(targetYyyy),
mapSheetLearnEntity.stage.eq(maxStage))
.fetchOne();
}
@Override
public void updateMapSheetLearnGukyuinEndStatus(Long learnId) {
queryFactory
.update(mapSheetLearnEntity)
.set(mapSheetLearnEntity.applyStatus, GukYuinStatus.END.getId())
.set(mapSheetLearnEntity.applyStatusDttm, ZonedDateTime.now())
.where(mapSheetLearnEntity.id.eq(learnId))
.execute();
}
@Override
public void updateMapSheetInferenceLabelEndStatus(Long learnId) {
queryFactory
.update(mapSheetAnalInferenceEntity)
.set(mapSheetAnalInferenceEntity.analState, LabelMngState.FINISH.getId())
.set(mapSheetAnalInferenceEntity.updatedDttm, ZonedDateTime.now())
.where(mapSheetAnalInferenceEntity.learnId.eq(learnId))
.execute();
}
@Override
@Transactional
public void updateGukYuinApplyStateComplete(Long id, GukYuinStatus status) {
queryFactory
.update(mapSheetLearnEntity)
.set(mapSheetLearnEntity.applyStatus, status.getId())
.set(mapSheetLearnEntity.applyStatusDttm, ZonedDateTime.now())
.where(mapSheetLearnEntity.id.eq(id))
.execute();
}
}

View File

@@ -0,0 +1,220 @@
package com.kamco.cd.kamcoback.scene.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.JsonNode;
import com.kamco.cd.kamcoback.enums.ApiConfigEnum.EnumDto;
import com.kamco.cd.kamcoback.enums.CommonUseStatus;
import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.EntityNotFoundException;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
public class MapInkxMngDto {
// CommonUseStatus class로 통합 20251230
// @CodeExpose
// @Getter
// @AllArgsConstructor
// public enum UseInferenceType implements EnumType {
// USE("사용중"),
// EXCEPT("영구 추론제외");
//
// private final String desc;
//
// @Override
// public String getId() {
// return name();
// }
//
// @Override
// public String getText() {
// return desc;
// }
// }
@Schema(name = "Basic", description = "Basic")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class Basic {
private Integer fid;
private String mapidcdNo;
private String mapidNm;
private JsonNode geom;
private String useInference;
private ZonedDateTime createdDttm;
private ZonedDateTime updatedDttm;
}
@Getter
@Schema(name = "MapListEntity", description = "목록 항목")
public static class MapListEntity {
private InferenceDetailDto.MapSheet scene50k;
private InferenceDetailDto.MapSheet scene5k;
private CommonUseStatus useInference;
@JsonFormat(
shape = JsonFormat.Shape.STRING,
pattern = "yyyy-MM-dd'T'HH:mm:ssXXX",
timezone = "Asia/Seoul")
private ZonedDateTime createdDttm;
@JsonFormat(
shape = JsonFormat.Shape.STRING,
pattern = "yyyy-MM-dd'T'HH:mm:ssXXX",
timezone = "Asia/Seoul")
private ZonedDateTime updatedDttm;
public EnumDto<CommonUseStatus> getUseInference() {
EnumDto<CommonUseStatus> enumDto = useInference.getEnumDto();
return enumDto;
}
@Builder
public MapListEntity(
InferenceDetailDto.MapSheet scene50k,
InferenceDetailDto.MapSheet scene5k,
CommonUseStatus useInference,
ZonedDateTime createdDttm,
ZonedDateTime updatedDttm) {
this.scene50k = scene50k;
this.scene5k = scene5k;
this.useInference = useInference;
this.createdDttm = createdDttm;
this.updatedDttm = updatedDttm;
}
}
@Schema(name = "MapList", description = "목록 항목")
@Getter
@Setter
@NoArgsConstructor
public static class MapList {
private Integer rowNum;
private String mapidcdNo5k;
private String mapidcdNo50k;
private String mapidNm;
private String createdDttm;
private String updatedDttm;
private String useInference;
private ZonedDateTime createdDttmTime;
private ZonedDateTime updatedDttmTime;
// 목록 Querydsl 에서 리턴 받는 건 생성자 기준임 -> 쿼리 컬럼 그대로 받고 여기서 Java 형변환 해서 return 하기
public MapList(
Integer rowNum,
String mapidcdNo5k,
String mapidcdNo50k,
String mapidNm,
ZonedDateTime createdDttmTime,
ZonedDateTime updatedDttmTime,
CommonUseStatus useInference) {
this.rowNum = rowNum;
this.mapidcdNo5k = mapidcdNo5k;
this.mapidcdNo50k = mapidcdNo50k;
this.mapidNm = mapidNm;
DateTimeFormatter fmt =
DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("Asia/Seoul"));
this.createdDttm = fmt.format(createdDttmTime);
this.updatedDttm = fmt.format(updatedDttmTime);
this.createdDttmTime = createdDttmTime;
this.updatedDttmTime = updatedDttmTime;
this.useInference = useInference.getId();
}
}
@Schema(name = "searchReq", description = "검색 요청")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class searchReq {
// 페이징 파라미터
private int page = 0;
private int size = 20;
private String sort;
public Pageable toPageable() {
if (sort != null && !sort.isEmpty()) {
String[] sortParams = sort.split(",");
String property = sortParams[0];
Sort.Direction direction =
sortParams.length > 1 ? Sort.Direction.fromString(sortParams[1]) : Sort.Direction.ASC;
return PageRequest.of(page, size, Sort.by(direction, property));
}
return PageRequest.of(page, size);
}
}
@Schema(name = "AddMapReq", description = "등록 요청")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class AddMapReq {
@Schema(description = "도엽번호", example = "31540687")
private String mapidcdNo;
@Schema(description = "도엽명", example = "공덕")
private String mapidNm;
@Schema(
description = "좌표 목록 (한 줄에 한 점, '경도 위도' 형식)",
example =
"127.17500001632317 36.17499998262991\n"
+ "127.14999995475043 36.17500002877932\n"
+ "127.15000004313612 36.199999984012415\n"
+ "127.1750000466954 36.20000001863179")
private String coordinates;
}
@Schema(name = "UseInferReq", description = "추론제외 업데이트 요청")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class UseInferReq {
private String mapidcdNo;
private CommonUseStatus useInference; // 변경하고자하는 상태
public void valid() {
if (mapidcdNo == null || mapidcdNo.isEmpty()) {
throw new IllegalArgumentException("도엽번호는 필수 입력값입니다.");
}
// 공백제거
mapidcdNo = mapidcdNo.trim();
if (!mapidcdNo.matches("^\\d{8}$")) {
throw new EntityNotFoundException("도엽번호는 8자리 숫자로 구성되어야 합니다.");
}
}
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class Search5kReq {
private String mapidcdNo;
private String useInference;
}
}

View File

@@ -1,18 +1,13 @@
package com.kamco.cd.kamcoback.scheduler.service; package com.kamco.cd.kamcoback.service;
import com.kamco.cd.kamcoback.common.utils.NetUtils;
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient;
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient.ExternalCallResult;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto.ResultPnuDto;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GeomUidDto; import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GeomUidDto;
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;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Log4j2 @Log4j2
@@ -21,19 +16,11 @@ import org.springframework.stereotype.Service;
public class GukYuinApiLabelJobService { public class GukYuinApiLabelJobService {
private final GukYuinLabelJobCoreService gukYuinLabelJobCoreService; private final GukYuinLabelJobCoreService gukYuinLabelJobCoreService;
private final GukYuinApiService gukYuinApiService;
private final ExternalHttpClient externalHttpClient;
private final NetUtils netUtils = new NetUtils();
@Value("${spring.profiles.active}") @Value("${spring.profiles.active}")
private String profile; private String profile;
@Value("${gukyuin.url}")
private String gukyuinUrl;
@Value("${gukyuin.cdi}")
private String gukyuinCdiUrl;
/** /**
* 실행중인 profile * 실행중인 profile
* *
@@ -43,33 +30,29 @@ public class GukYuinApiLabelJobService {
return "local".equalsIgnoreCase(profile); return "local".equalsIgnoreCase(profile);
} }
/** 어제 라벨링 검수 완료된 것 -> 국유인에 전송 */ // @Scheduled(cron = "0 * * * * *")
@Scheduled(cron = "0 0 2 * * *") public void runTask() {
public void findLabelingCompleteSend() { findLabelingCompleteSend(null);
if (isLocalProfile()) { }
return;
}
List<GeomUidDto> list = gukYuinLabelJobCoreService.findYesterdayLabelingCompleteList(); /** 어제 라벨링 검수 완료된 것 -> 국유인에 전송 */
public void findLabelingCompleteSend(LocalDate baseDate) {
// if (isLocalProfile()) {
// return;
// }
List<GeomUidDto> list = gukYuinLabelJobCoreService.findYesterdayLabelingCompleteList(baseDate);
if (list.isEmpty()) { if (list.isEmpty()) {
return; return;
} }
for (GeomUidDto gto : list) { for (GeomUidDto gto : list) {
String url = gukyuinCdiUrl + "/rlb/objt/" + gto.getResultUid() + "/lbl/" + "Y"; ChngDetectContDto.ResultLabelDto dto =
gukYuinApiService.updateChnDtctObjtLabelingYn(gto.getResultUid(), "Y", "Y");
ExternalCallResult<ResultPnuDto> result = if (dto.getSuccess()) {
externalHttpClient.call( // inference_geom 에 label_send_dttm 업데이트 하기
url, gukYuinLabelJobCoreService.updateAnalDataInferenceGeomSendDttm(gto.getGeoUid());
HttpMethod.POST, }
null,
netUtils.jsonHeaders(),
ChngDetectContDto.ResultPnuDto.class);
ChngDetectContDto.ResultPnuDto dto = result.body();
// inference_geom 에 label_send_dttm 업데이트 하기
gukYuinLabelJobCoreService.updateAnalDataInferenceGeomSendDttm(gto.getGeoUid());
} }
} }
} }

View File

@@ -0,0 +1,390 @@
package com.kamco.cd.kamcoback.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kamco.cd.kamcoback.common.utils.NetUtils;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ApiResponseCode;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ResponseObj;
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient;
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient.ExternalCallResult;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto.ContBasic;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto.ReqInfo;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto.ResultContDto;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto.ResultPnuDto;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.ChnDetectMastReqDto;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.ErrorResDto;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.LabelSendDto;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.ResultDto;
import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.RlbDtctDto;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GukYuinLinkFacts;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GukYuinLinkFailCode;
import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.LearnInfo;
import com.kamco.cd.kamcoback.postgres.core.GukYuinCoreService;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDate;
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.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Slf4j
@Service
@Transactional
@RequiredArgsConstructor
public class GukYuinApiService {
private final GukYuinCoreService gukyuinCoreService;
private final ExternalHttpClient externalHttpClient;
private final NetUtils netUtils = new NetUtils();
private final ObjectMapper objectMapper;
private final String myip = netUtils.getLocalIP();
@Value("${spring.profiles.active:local}")
private String profile;
@Value("${gukyuin.url}")
private String gukyuinUrl;
@Value("${gukyuin.cdi}")
private String gukyuinCdiUrl;
@Value("${file.dataset-dir}")
private String datasetDir;
@Transactional
public ChngDetectMastDto.RegistResDto regist(ChnDetectMastReqDto chnDetectMastReq) {
String url = gukyuinCdiUrl + "/chn/mast/regist";
chnDetectMastReq.setReqIp(myip);
chnDetectMastReq.setReqEpno("BATCH");
ExternalCallResult<ChngDetectMastDto.RegistResDto> result =
externalHttpClient.call(
url,
HttpMethod.POST,
chnDetectMastReq,
netUtils.jsonHeaders(),
ChngDetectMastDto.RegistResDto.class);
ChngDetectMastDto.RegistResDto resultBody = result.body();
boolean success = false;
if (resultBody != null && resultBody.getSuccess() != null) {
ChngDetectMastDto.Basic registRes = resultBody.getResult();
success = resultBody.getSuccess();
// 이미 등록한 경우에는 result가 없음
if (resultBody.getResult() == null) {
return resultBody;
}
// 추론 회차에 applyStatus, applyStatusDttm 업데이트
gukyuinCoreService.updateGukYuinMastRegResult(registRes);
// anal_inference 에도 국유인 반영여부, applyDttm 업데이트
gukyuinCoreService.updateAnalInferenceApplyDttm(registRes);
} else {
String errBody = result.errBody();
ErrorResDto error = null;
try {
error = objectMapper.readValue(errBody, ErrorResDto.class);
return new ChngDetectMastDto.RegistResDto(error.getStatus(), error.getError(), null, false);
} catch (JsonProcessingException e) {
log.error("에러 응답 파싱 실패. rawBody={}", errBody, e);
return new ChngDetectMastDto.RegistResDto(
result.statusCode(), // HTTP status
errBody, // 원문 그대로
null,
false);
}
}
return resultBody;
}
@Transactional
public ChngDetectMastDto.RemoveResDto remove(ChnDetectMastReqDto chnDetectMastReq) {
String url = gukyuinCdiUrl + "/chn/mast/remove";
chnDetectMastReq.setReqIp(myip);
chnDetectMastReq.setReqEpno("BATCH");
boolean success = false;
ExternalCallResult<ChngDetectMastDto.RemoveResDto> result =
externalHttpClient.call(
url,
HttpMethod.POST,
chnDetectMastReq,
netUtils.jsonHeaders(),
ChngDetectMastDto.RemoveResDto.class);
ChngDetectMastDto.RemoveResDto resultBody = result.body();
if (resultBody != null && resultBody.getSuccess() != null) {
success = resultBody.getSuccess();
if (resultBody.getSuccess()) {
gukyuinCoreService.updateGukYuinMastRegRemove(chnDetectMastReq.getChnDtctId());
}
}
return resultBody;
}
// 등록목록 1개 확인
public ResultDto detail(String chnDtctMstId) {
String url =
gukyuinCdiUrl + "/chn/mast/list/" + chnDtctMstId + "?reqIp=" + myip + "&reqEpno=" + "BATCH";
ExternalCallResult<ResultDto> result =
externalHttpClient.call(url, HttpMethod.GET, null, netUtils.jsonHeaders(), ResultDto.class);
return result.body();
}
// 등록목록 비교년도,기준년도,차수 조합해서 n개 확인
public ResultDto listYearStage(ChngDetectMastDto.ChngDetectMastSearchDto searchDto) {
String queryString = netUtils.dtoToQueryString(searchDto, null);
String url =
gukyuinCdiUrl + "/chn/mast" + queryString + "&reqIp=" + myip + "&reqEpno=" + "BATCH";
ExternalCallResult<ResultDto> result =
externalHttpClient.call(url, HttpMethod.GET, null, netUtils.jsonHeaders(), ResultDto.class);
return result.body();
}
private GukYuinLinkFailCode decideCode(GukYuinLinkFacts f) {
if (!f.existsLearn()) {
return GukYuinLinkFailCode.NOT_FOUND;
}
if (f.isPartScope()) {
return GukYuinLinkFailCode.SCOPE_PART_NOT_ALLOWED;
}
if (f.hasRunningInference()) {
return GukYuinLinkFailCode.HAS_RUNNING_INFERENCE;
}
if (f.hasOtherUnfinishedGukYuin()) {
return GukYuinLinkFailCode.OTHER_GUKYUIN_IN_PROGRESS;
}
return GukYuinLinkFailCode.OK;
}
// 탐지객체 리스트 조회
public ResultContDto findChnContList(
String chnDtctId, Integer pageIndex, Integer pageSize, String batchYn) {
String url =
gukyuinCdiUrl
+ "/chn/cont/"
+ chnDtctId
+ "?pageIndex="
+ pageIndex
+ "&pageSize="
+ pageSize
+ "&reqIp="
+ myip
+ "&reqEpno="
+ "BATCH";
ExternalCallResult<ResultContDto> result =
externalHttpClient.call(
url, HttpMethod.GET, null, netUtils.jsonHeaders(), ResultContDto.class);
List<ContBasic> contList = result.body().getResult();
if (contList == null || contList.isEmpty()) {
return new ResultContDto(
result.body().getCode(),
result.body().getMessage(),
result.body().getResult(),
result.body().getSuccess());
}
return result.body();
}
public ResultPnuDto findPnuObjMgmtList(String chnDtctId, String chnDtctObjtId) {
String url =
gukyuinCdiUrl
+ "/chn/pnu/"
+ chnDtctId
+ "/objt/"
+ chnDtctObjtId
+ "?reqIp="
+ myip
+ "&reqEpno="
+ "BATCH";
ExternalCallResult<ResultPnuDto> result =
externalHttpClient.call(
url, HttpMethod.GET, null, netUtils.jsonHeaders(), ResultPnuDto.class);
return result.body();
}
public ChngDetectContDto.ResultLabelDto updateChnDtctObjtLabelingYn(
String chnDtctObjtId, String lblYn, String batchYn) {
String url = gukyuinCdiUrl + "/rlb/objt/" + chnDtctObjtId + "/lbl/" + lblYn;
ReqInfo info = new ReqInfo();
info.setReqIp(myip);
info.setReqEpno("BATCH");
ExternalCallResult<ChngDetectContDto.ResultLabelDto> result =
externalHttpClient.call(
url,
HttpMethod.POST,
info,
netUtils.jsonHeaders(),
ChngDetectContDto.ResultLabelDto.class);
return result.body();
}
public ResultContDto findChnPnuToContList(String chnDtctId, String pnu) {
String url =
gukyuinCdiUrl
+ "/chn/cont/"
+ chnDtctId
+ "/pnu/"
+ pnu
+ "?reqIp="
+ myip
+ "&reqEpno="
+ "BATCH";
ExternalCallResult<ResultContDto> result =
externalHttpClient.call(
url, HttpMethod.GET, null, netUtils.jsonHeaders(), ResultContDto.class);
return result.body();
}
public ResultDto listChnDtctId(String chnDtctId, String batchYn) {
String url =
gukyuinCdiUrl + "/chn/mast/" + chnDtctId + "?reqIp=" + myip + "&reqEpno=" + "BATCH";
ExternalCallResult<ResultDto> result =
externalHttpClient.call(url, HttpMethod.GET, null, netUtils.jsonHeaders(), ResultDto.class);
return result.body();
}
public ResponseObj connectChnMastRegist(UUID uuid) {
// uuid로 추론 회차 조회
LearnInfo info = gukyuinCoreService.findMapSheetLearnInfo(uuid);
if (info.getApplyYn() != null && info.getApplyYn()) {
return new ResponseObj(ApiResponseCode.DUPLICATE_DATA, "이미 국유인 연동을 한 회차입니다.");
}
if (!Files.isDirectory(Path.of("/kamco-nfs/dataset/export/" + info.getUid()))) {
return new ResponseObj(
ApiResponseCode.NOT_FOUND_DATA, "파일 경로에 회차 실행 파일이 생성되지 않았습니다. 확인 부탁드립니다.");
}
// 비교년도,기준년도로 전송한 데이터 있는지 확인 후 회차 번호 생성
Integer maxStage =
gukyuinCoreService.findMapSheetLearnYearStage(info.getCompareYyyy(), info.getTargetYyyy());
// reqDto 셋팅
ChnDetectMastReqDto reqDto = new ChnDetectMastReqDto();
reqDto.setCprsYr(String.valueOf(info.getCompareYyyy()));
reqDto.setCrtrYr(String.valueOf(info.getTargetYyyy()));
reqDto.setChnDtctSno(String.valueOf(maxStage + 1));
reqDto.setChnDtctId(info.getUid());
reqDto.setPathNm("/kamco-nfs/dataset/export/" + info.getUid());
// 1회차를 종료 상태로 처리하고 2회차를 보내야 함
// 추론(learn), 학습데이터(inference) 둘 다 종료 처리
if (maxStage > 0) {
Long learnId =
gukyuinCoreService.findMapSheetLearnInfoByYyyy(
info.getCompareYyyy(), info.getTargetYyyy(), maxStage);
gukyuinCoreService.updateMapSheetLearnGukyuinEndStatus(learnId);
gukyuinCoreService.updateMapSheetInferenceLabelEndStatus(learnId);
}
// 국유인 /chn/mast/regist 전송
ChngDetectMastDto.RegistResDto result = this.regist(reqDto);
if (result.getSuccess()) {
return new ResponseObj(ApiResponseCode.OK, "연동되었습니다.");
} else {
return new ResponseObj(ApiResponseCode.INTERNAL_SERVER_ERROR, result.getMessage());
}
}
public List<LabelSendDto> findLabelingCompleteSendList(LocalDate yesterday) {
return gukyuinCoreService.findLabelingCompleteSendList(yesterday);
}
public ResultContDto findChnPnuToContObject(
String chnDtctId, String chnDtctObjtId, Integer pageIndex, Integer pageSize) {
String url =
gukyuinCdiUrl
+ "/chn/cont/"
+ chnDtctId
+ "/chnDtctObjtId/"
+ chnDtctObjtId
+ "?pageIndex="
+ pageIndex
+ "&pageSize="
+ pageSize
+ "&reqIp="
+ myip
+ "&reqEpno="
+ "BATCH";
ExternalCallResult<ResultContDto> result =
externalHttpClient.call(
url, HttpMethod.GET, null, netUtils.jsonHeaders(), ResultContDto.class);
return result.body();
}
public RlbDtctDto findRlbDtctList(String chnDtctId, String yyyymmdd, String batchYn) {
String url =
gukyuinCdiUrl
+ "/rlb/dtct/"
+ chnDtctId
+ "?reqIp="
+ myip
+ "&reqEpno="
+ "BATCH"
+ "&yyyymmdd="
+ yyyymmdd;
ExternalCallResult<RlbDtctDto> result =
externalHttpClient.call(
url, HttpMethod.GET, null, netUtils.jsonHeaders(), RlbDtctDto.class);
return result.body();
}
public RlbDtctDto findRlbDtctObject(String chnDtctObjtId) {
String url =
gukyuinCdiUrl + "/rlb/objt/" + chnDtctObjtId + "?reqIp=" + myip + "&reqEpno=" + "BATCH";
ExternalCallResult<RlbDtctDto> result =
externalHttpClient.call(
url, HttpMethod.GET, null, netUtils.jsonHeaders(), RlbDtctDto.class);
return result.body();
}
}

View File

@@ -0,0 +1,136 @@
spring:
config:
activate:
on-profile: dev
jpa:
show-sql: false
hibernate:
ddl-auto: validate
properties:
hibernate:
default_batch_fetch_size: 100 # ✅ 성능 - N+1 쿼리 방지
order_updates: true # ✅ 성능 - 업데이트 순서 정렬로 데드락 방지
order_inserts: true
use_sql_comments: true # ⚠️ 선택 - SQL에 주석 추가 (디버깅용)
format_sql: true # ⚠️ 선택 - SQL 포맷팅 (가독성)
jdbc:
batch_size: 1000 # ✅ 추가 (JDBC batch)
open-in-view: false
mvc:
async:
request-timeout: 300s # 5분 (예: 30s, 120s, 10m 등도 가능)
datasource:
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:
minimum-idle: 10
maximum-pool-size: 20
connection-timeout: 60000 # 60초 연결 타임아웃
idle-timeout: 300000 # 5분 유휴 타임아웃
max-lifetime: 1800000 # 30분 최대 수명
leak-detection-threshold: 60000 # 연결 누수 감지
transaction:
default-timeout: 300 # 5분 트랜잭션 타임아웃
data:
redis:
host: 192.168.2.109
port: 6379
password: kamco
servlet:
multipart:
enabled: true
max-file-size: 4GB
max-request-size: 4GB
file-size-threshold: 10MB
server:
tomcat:
max-swallow-size: 4GB
max-http-form-post-size: 4GB
jwt:
secret: "kamco_token_9b71e778-19a3-4c1d-97bf-2d687de17d5b"
access-token-validity-in-ms: 86400000 # 1일
refresh-token-validity-in-ms: 604800000 # 7일
#access-token-validity-in-ms: 60000 # 1분
#refresh-token-validity-in-ms: 300000 # 5분
token:
refresh-cookie-name: kamco-dev # 개발용 쿠키 이름
refresh-cookie-secure: false # 로컬 http 테스트면 false
springdoc:
swagger-ui:
persist-authorization: true # 스웨거 새로고침해도 토큰 유지, 로컬스토리지에 저장
logging:
level:
root: INFO
org.springframework.web: DEBUG
org.springframework.security: DEBUG
# 헬스체크 노이즈 핵심만 다운
org.springframework.security.web.FilterChainProxy: INFO
org.springframework.security.web.authentication.AnonymousAuthenticationFilter: INFO
org.springframework.security.web.authentication.Http403ForbiddenEntryPoint: INFO
org.springframework.web.servlet.DispatcherServlet: INFO
mapsheet:
upload:
skipGdalValidation: true
shp:
baseurl: /app/tmp/detect/result #현재사용안함
file:
#sync-root-dir: D:/kamco-nfs/images/
sync-root-dir: /kamco-nfs/images/
sync-tmp-dir: /kamco-nfs/requests/temp # image upload temp dir
#sync-tmp-dir: ${file.sync-root-dir}/tmp
sync-file-extention: tfw,tif
sync-auto-exception-start-year: 2024
sync-auto-exception-before-year-cnt: 3
#dataset-dir: D:/kamco-nfs/model_output/
dataset-dir: /kamco-nfs/model_output/export/ # 마운트경로 AI 추론결과
dataset-tmp-dir: ${file.dataset-dir}tmp/
#model-dir: D:/kamco-nfs/ckpt/model/
model-dir: /kamco-nfs/ckpt/model/ # 학습서버에서 트레이닝한 모델업로드경로
model-tmp-dir: ${file.model-dir}tmp/
model-file-extention: pth,json,py
pt-path: /kamco-nfs/ckpt/model/v6-cls-checkpoints/
pt-FileName: yolov8_6th-6m.pt
dataset-response: /kamco-nfs/dataset/response/
inference:
url: http://192.168.2.183:8000/jobs
batch-url: http://192.168.2.183:8000/batches
geojson-dir: /kamco-nfs/requests/ # 추론실행을 위한 파일생성경로
jar-path: /kamco-nfs/repo/jar/shp-exporter.jar
inference-server-name: server1,server2,server3,server4
gukyuin:
#url: http://localhost:8080
url: http://192.168.2.129:5301
cdi: ${gukyuin.url}/api/kcd/cdi
training-data:
geojson-dir: /kamco-nfs/dataset/request/
layer:
geoserver-url: https://kamco.geo-dev.gs.dabeeo.com
wms-path: geoserver/cd
wmts-path: geoserver/cd/gwc/service
workspace: cd

View File

@@ -0,0 +1,114 @@
spring:
config:
activate:
on-profile: local
jpa:
show-sql: false
hibernate:
ddl-auto: validate # 로컬만 완화(시킬려면 update으로 변경)
properties:
hibernate:
default_batch_fetch_size: 100 # ✅ 성능 - N+1 쿼리 방지
order_updates: true # ✅ 성능 - 업데이트 순서 정렬로 데드락 방지
use_sql_comments: true # ⚠️ 선택 - SQL에 주석 추가 (디버깅용)
format_sql: true # ⚠️ 선택 - SQL 포맷팅 (가독성)
datasource:
url: jdbc:postgresql://192.168.2.127:15432/kamco_cds
# url: jdbc:postgresql://localhost:5432/local_0128
username: kamco_cds
password: kamco_cds_Q!W@E#R$
# username: postgres
# password: 1234
hikari:
minimum-idle: 1
maximum-pool-size: 5
data:
redis:
host: 192.168.2.109
port: 6379
password: kamco
servlet:
multipart:
enabled: true
max-file-size: 4GB
max-request-size: 4GB
file-size-threshold: 10MB
server:
tomcat:
max-swallow-size: 4GB
max-http-form-post-size: 4GB
jwt:
secret: "kamco_token_9b71e778-19a3-4c1d-97bf-2d687de17d5b"
access-token-validity-in-ms: 86400000 # 1일
refresh-token-validity-in-ms: 604800000 # 7일
token:
refresh-cookie-name: kamco-local # 개발용 쿠키 이름
refresh-cookie-secure: false # 로컬 http 테스트면 false
springdoc:
swagger-ui:
persist-authorization: true # 스웨거 새로고침해도 토큰 유지, 로컬스토리지에 저장
logging:
level:
org.hibernate.SQL: debug
org.hibernate.orm.jdbc.bind: trace
mapsheet:
upload:
skipGdalValidation: true
shp:
baseurl: /Users/bokmin/detect/result
file:
sync-root-dir: C:/Users/gypark/kamco-nfs/images/
#sync-root-dir: /kamco-nfs/images/
sync-tmp-dir: ${file.sync-root-dir}/tmp/
sync-file-extention: tfw,tif
sync-auto-exception-start-year: 2025
sync-auto-exception-before-year-cnt: 3
dataset-dir: C:/Users/gypark/kamco-nfs/dataset/
#dataset-dir: /kamco-nfs/dataset/export/
dataset-tmp-dir: ${file.dataset-dir}tmp/
model-dir: C:/Users/gypark/kamco-nfs/ckpt/model/
#model-dir: /kamco-nfs/ckpt/model/
model-tmp-dir: ${file.model-dir}tmp/
model-file-extention: pth,json,py
pt-path: /kamco-nfs/ckpt/classification/
pt-FileName: v5-best.pt
dataset-response: /kamco-nfs/dataset/response/
inference:
url: http://10.100.0.11:8000/jobs
batch-url: http://10.100.0.11:8000/batches
geojson-dir: /kamco-nfs/requests/
jar-path: jar/makeshp-1.0.0.jar
inference-server-name: server1,server2,server3,server4
gukyuin:
#url: http://localhost:8080
url: http://192.168.2.129:5301
cdi: ${gukyuin.url}/api/kcd/cdi
training-data:
geojson-dir: /kamco-nfs/model_output/labeling/
layer:
geoserver-url: https://kamco.geo-dev.gs.dabeeo.com
wms-path: geoserver/cd
wmts-path: geoserver/cd/gwc/service
workspace: cd

View File

@@ -0,0 +1,122 @@
spring:
config:
activate:
on-profile: prod
jpa:
show-sql: true
hibernate:
ddl-auto: validate
properties:
hibernate:
default_batch_fetch_size: 100 # ✅ 성능 - N+1 쿼리 방지
order_updates: true # ✅ 성능 - 업데이트 순서 정렬로 데드락 방지
order_inserts: true
use_sql_comments: true # ⚠️ 선택 - SQL에 주석 추가 (디버깅용)
format_sql: true # ⚠️ 선택 - SQL 포맷팅 (가독성)
jdbc:
batch_size: 1000 # ✅ 추가 (JDBC batch)
open-in-view: false
mvc:
async:
request-timeout: 300s # 5분 (예: 30s, 120s, 10m 등도 가능)
datasource:
url: jdbc:postgresql://kamco-cd-postgis:5432/kamco_cds
#url: jdbc:postgresql://localhost:15432/kamco_cds
username: kamco_cds
password: kamco_cds_Q!W@E#R$
hikari:
minimum-idle: 10
maximum-pool-size: 20
connection-timeout: 60000 # 60초 연결 타임아웃
idle-timeout: 300000 # 5분 유휴 타임아웃
max-lifetime: 1800000 # 30분 최대 수명
leak-detection-threshold: 60000 # 연결 누수 감지
transaction:
default-timeout: 300 # 5분 트랜잭션 타임아웃
data:
redis:
host: 127.0.0.1
port: 16379
password: kamco
servlet:
multipart:
enabled: true
max-file-size: 4GB
max-request-size: 4GB
file-size-threshold: 10MB
server:
tomcat:
max-swallow-size: 4GB
max-http-form-post-size: 4GB
jwt:
secret: "kamco_token_9b71e778-19a3-4c1d-97bf-2d687de17d5b"
access-token-validity-in-ms: 86400000 # 1일
refresh-token-validity-in-ms: 604800000 # 7일
token:
refresh-cookie-name: kamco # 개발용 쿠키 이름
refresh-cookie-secure: true # 로컬 http 테스트면 false
logging:
level:
root: INFO
org.springframework.web: DEBUG
org.springframework.security: DEBUG
# 헬스체크 노이즈 핵심만 다운
org.springframework.security.web.FilterChainProxy: INFO
org.springframework.security.web.authentication.AnonymousAuthenticationFilter: INFO
org.springframework.security.web.authentication.Http403ForbiddenEntryPoint: INFO
org.springframework.web.servlet.DispatcherServlet: INFO
mapsheet:
upload:
skipGdalValidation: true
shp:
baseurl: /app/detect/result #현재사용안함
file:
sync-root-dir: /kamco-nfs/images/
sync-tmp-dir: /kamco-nfs/repo/tmp # image upload temp dir
sync-file-extention: tfw,tif
#dataset-dir: D:/kamco-nfs/model_output/ #변경 model_output
dataset-dir: /kamco-nfs/model_output/export/ # 마운트경로 AI 추론결과
dataset-tmp-dir: ${file.dataset-dir}tmp/
#model-dir: D:/kamco-nfs/ckpt/model/
model-dir: /kamco-nfs/ckpt/model/ # 학습서버에서 트레이닝한 모델업로드경로
model-tmp-dir: ${file.model-dir}tmp/
model-file-extention: pth,json,py
pt-path: /kamco-nfs/ckpt/v6-cls-checkpoints/
pt-FileName: yolov8_6th-6m.pt
dataset-response: /kamco-nfs/dataset/response/
inference:
url: http://127.0.0.1:8000/jobs
batch-url: http://127.0.0.1:8000/batches
geojson-dir: /kamco-nfs/requests/ # 학습서버에서 트레이닝한 모델업로드경로
jar-path: /kamco-nfs/repo/jar/shp-exporter.jar # 추론실행을 위한 파일생성경로
inference-server-name: server1,server2,server3,server4
gukyuin:
url: http://127.0.0.1:5301
cdi: ${gukyuin.url}/api/kcd/cdi
training-data:
geojson-dir: /kamco-nfs/dataset/request/
layer:
geoserver-url: https://kamco.geo-dev.gs.dabeeo.com
wms-path: geoserver/cd
wmts-path: geoserver/cd/gwc/service
workspace: cd

View File

@@ -1,4 +1,8 @@
server: server:
port: 9080 port: 8080
spring:
application:
name: kamco-gukyuin-label
profiles:
active: prod # 사용할 프로파일 지정 (ex. dev, prod, test)

View File

@@ -1,71 +0,0 @@
server:
port: 9080
spring:
application:
name: label-to-review
profiles:
active: dev # 사용할 프로파일 지정 (ex. dev, prod, test)
datasource:
url: jdbc:postgresql://192.168.2.127:15432/kamco_cds
#url: jdbc:postgresql://localhost:5432/kamco_cds
username: kamco_cds
password: kamco_cds_Q!W@E#R$
hikari:
minimum-idle: 1
maximum-pool-size: 5
jpa:
hibernate:
ddl-auto: update # 테이블이 없으면 생성, 있으면 업데이트
properties:
hibernate:
jdbc:
batch_size: 50
default_batch_fetch_size: 100
logging:
level:
root: INFO
org.springframework.web: DEBUG
org.springframework.security: DEBUG
# 헬스체크 노이즈 핵심만 다운
org.springframework.security.web.FilterChainProxy: INFO
org.springframework.security.web.authentication.AnonymousAuthenticationFilter: INFO
org.springframework.security.web.authentication.Http403ForbiddenEntryPoint: INFO
org.springframework.web.servlet.DispatcherServlet: INFO
# actuator
management:
health:
readinessstate:
enabled: true
livenessstate:
enabled: true
endpoint:
health:
probes:
enabled: true
show-details: always
endpoints:
jmx:
exposure:
exclude: "*"
web:
base-path: /monitor
exposure:
include:
- "health"
file:
#sync-root-dir: D:/kamco-nfs/images/
sync-root-dir: /kamco-nfs/images/
sync-tmp-dir: ${file.sync-root-dir}/tmp
sync-file-extention: tfw,tif
sync-auto-exception-start-year: 2025
sync-auto-exception-before-year-cnt: 3
gukyuin:
#url: http://localhost:8080
url: http://192.168.2.129:5301
cdi: ${gukyuin.url}/api/kcd/cdi

View File

@@ -1,71 +0,0 @@
server:
port: 9080
spring:
application:
name: imagery-make-dataset
profiles:
active: local # 사용할 프로파일 지정 (ex. dev, prod, test)
datasource:
url: jdbc:postgresql://192.168.2.127:15432/kamco_cds
#url: jdbc:postgresql://localhost:5432/kamco_cds
username: kamco_cds
password: kamco_cds_Q!W@E#R$
hikari:
minimum-idle: 1
maximum-pool-size: 5
jpa:
hibernate:
ddl-auto: update # 테이블이 없으면 생성, 있으면 업데이트
properties:
hibernate:
jdbc:
batch_size: 50
default_batch_fetch_size: 100
logging:
level:
root: INFO
org.springframework.web: DEBUG
org.springframework.security: DEBUG
# 헬스체크 노이즈 핵심만 다운
org.springframework.security.web.FilterChainProxy: INFO
org.springframework.security.web.authentication.AnonymousAuthenticationFilter: INFO
org.springframework.security.web.authentication.Http403ForbiddenEntryPoint: INFO
org.springframework.web.servlet.DispatcherServlet: INFO
# actuator
management:
health:
readinessstate:
enabled: true
livenessstate:
enabled: true
endpoint:
health:
probes:
enabled: true
show-details: always
endpoints:
jmx:
exposure:
exclude: "*"
web:
base-path: /monitor
exposure:
include:
- "health"
file:
#sync-root-dir: D:/kamco-nfs/images/
sync-root-dir: /kamco-nfs/images/
sync-tmp-dir: ${file.sync-root-dir}/tmp
sync-file-extention: tfw,tif
sync-auto-exception-start-year: 2025
sync-auto-exception-before-year-cnt: 3
gukyuin:
#url: http://localhost:8080
url: http://192.168.2.129:5301
cdi: ${gukyuin.url}/api/kcd/cdi

View File

@@ -1,71 +0,0 @@
server:
port: 9080
spring:
application:
name: imagery-make-dataset
profiles:
active: prod # 사용할 프로파일 지정 (ex. dev, prod, test)
datasource:
url: jdbc:postgresql://192.168.2.127:15432/kamco_cds
#url: jdbc:postgresql://localhost:5432/kamco_cds
username: kamco_cds
password: kamco_cds_Q!W@E#R$
hikari:
minimum-idle: 1
maximum-pool-size: 5
jpa:
hibernate:
ddl-auto: update # 테이블이 없으면 생성, 있으면 업데이트
properties:
hibernate:
jdbc:
batch_size: 50
default_batch_fetch_size: 100
logging:
level:
root: INFO
org.springframework.web: DEBUG
org.springframework.security: DEBUG
# 헬스체크 노이즈 핵심만 다운
org.springframework.security.web.FilterChainProxy: INFO
org.springframework.security.web.authentication.AnonymousAuthenticationFilter: INFO
org.springframework.security.web.authentication.Http403ForbiddenEntryPoint: INFO
org.springframework.web.servlet.DispatcherServlet: INFO
# actuator
management:
health:
readinessstate:
enabled: true
livenessstate:
enabled: true
endpoint:
health:
probes:
enabled: true
show-details: always
endpoints:
jmx:
exposure:
exclude: "*"
web:
base-path: /monitor
exposure:
include:
- "health"
file:
#sync-root-dir: D:/kamco-nfs/images/
sync-root-dir: /kamco-nfs/images/
sync-tmp-dir: ${file.sync-root-dir}/tmp
sync-file-extention: tfw,tif
sync-auto-exception-start-year: 2025
sync-auto-exception-before-year-cnt: 3
gukyuin:
#url: http://localhost:8080
url: http://192.168.2.129:5301
cdi: ${gukyuin.url}/api/kcd/cdi