Compare commits
74 Commits
master
...
feature/re
Author | SHA1 | Date |
---|---|---|
qkr7828 | 1f5ad17f5e | 7 months ago |
qkr7828 | 2712ce1700 | 7 months ago |
qkr7828 | 106055c062 | 7 months ago |
qkr7828 | def31f6b71 | 7 months ago |
qkr7828 | d2ae669797 | 7 months ago |
qkr7828 | 55d664215d | 7 months ago |
lkd9125(이경도) | c6a2564b5f | 7 months ago |
lkd9125 | 44011e96b1 | 7 months ago |
지대한 | 946dc35c24 | 7 months ago |
지대한 | c22d5a1424 | 7 months ago |
지대한 | 05e2c63fec | 7 months ago |
지대한 | 4a787f054c | 7 months ago |
지대한 | 359c96ee8b | 7 months ago |
지대한 | 04b1913753 | 7 months ago |
지대한 | 322103ad9b | 7 months ago |
지대한 | 3d17bec1bb | 7 months ago |
지대한 | e28b1b01ea | 7 months ago |
지대한 | 56b0c72f63 | 7 months ago |
지대한 | 061663c8b5 | 7 months ago |
지대한 | ac6865a15e | 7 months ago |
지대한 | 395972cd3f | 7 months ago |
지대한 | 6c32044d93 | 7 months ago |
지대한 | 67ab2bba16 | 7 months ago |
lkd9125(이경도) | 1463649563 | 7 months ago |
lkd9125(이경도) | d69d14e15a | 8 months ago |
lkd9125(이경도) | b679f86a08 | 8 months ago |
lkd9125(이경도) | 1ccf1140a3 | 8 months ago |
지대한 | 5a974631e9 | 8 months ago |
지대한 | 90802890de | 8 months ago |
lkd9125(이경도) | e63d7a64db | 8 months ago |
qkr7828 | 6b714c0f46 | 8 months ago |
lkd9125(이경도) | 0fcad045a6 | 8 months ago |
lkd9125(이경도) | 17e1affce5 | 8 months ago |
lkd9125(이경도) | 487af94496 | 8 months ago |
lkd9125(이경도) | 562df6b0ce | 8 months ago |
qkr7828 | 536dff756b | 8 months ago |
지대한 | a085711156 | 8 months ago |
지대한 | 36d78d82c5 | 8 months ago |
lkd9125(이경도) | d584d8c0b7 | 8 months ago |
지대한 | c06fe45fe1 | 8 months ago |
지대한 | c9422c1a66 | 8 months ago |
지대한 | 1c27a48858 | 8 months ago |
lkd9125(이경도) | 1d5bed9ce7 | 8 months ago |
지대한 | 6fa8d61898 | 8 months ago |
지대한 | 1fc4f1c93d | 8 months ago |
지대한 | 1274960091 | 8 months ago |
lkd9125 | 27d26daa46 | 8 months ago |
lkd9125(이경도) | e5f77b3de6 | 8 months ago |
lkd9125(이경도) | 95562bf996 | 8 months ago |
지대한 | c736566683 | 8 months ago |
지대한 | 679e50bed0 | 8 months ago |
지대한 | 9806887ee8 | 8 months ago |
지대한 | 0970cba328 | 8 months ago |
박재우 | 59b6625881 | 8 months ago |
지대한 | 41aacc4c14 | 8 months ago |
지대한 | 0276f9b767 | 8 months ago |
지대한 | 7cc65313c4 | 8 months ago |
지대한 | 5b9398b44f | 8 months ago |
지대한 | 56bd7d5142 | 8 months ago |
지대한 | 069406969c | 8 months ago |
지대한 | 40c4e8dcb5 | 8 months ago |
박재우 | 708534570a | 8 months ago |
박재우 | cf07273d30 | 8 months ago |
지대한 | e986ad4848 | 8 months ago |
지대한 | c8c16724bc | 8 months ago |
lkd9125 | 7777f85203 | 8 months ago |
lkd9125(이경도) | 44214a819c | 8 months ago |
지대한 | 087d11efa1 | 8 months ago |
지대한 | 18d1e99b23 | 8 months ago |
지대한 | 4fd51aa4da | 8 months ago |
지대한 | f3edb2286e | 8 months ago |
지대한 | c36929b090 | 8 months ago |
지대한 | 0c0eb8ba30 | 8 months ago |
지대한 | d713a2cb8e | 9 months ago |
217 changed files with 18602 additions and 55 deletions
Binary file not shown.
@ -0,0 +1,61 @@ |
|||||||
|
# Spec |
||||||
|
|
||||||
|
## 환경 구성 |
||||||
|
|
||||||
|
### 기본 정보 |
||||||
|
|
||||||
|
- java 21 |
||||||
|
- spring boot 3.2.1 |
||||||
|
- jpa |
||||||
|
- mysql |
||||||
|
|
||||||
|
|
||||||
|
## 작업전 준비 |
||||||
|
|
||||||
|
### 1. mysql 설치 |
||||||
|
|
||||||
|
``` |
||||||
|
docker-compose up -d database |
||||||
|
``` |
||||||
|
|
||||||
|
### 2. application.yml 설정 변경 |
||||||
|
|
||||||
|
최초 실행시 table 생성하기 위한 작업 |
||||||
|
`ddl-auto: create`로 변경 후 실행한 다음 Table이 생성되었는지 확인하고 원래 설정값으로 변경한다. |
||||||
|
|
||||||
|
```yaml |
||||||
|
spring: |
||||||
|
jpa: |
||||||
|
hibernate: |
||||||
|
ddl-auto: create |
||||||
|
``` |
||||||
|
|
||||||
|
## 설정 정보 |
||||||
|
|
||||||
|
### log4jdbc.log4j2.properties 속성 |
||||||
|
|
||||||
|
| 속성 | 설명 | |
||||||
|
|--------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------| |
||||||
|
| log4jdbc.spylogdelegator.name | 로그4jdbc에서 사용할 로그 델리게이트(Delegate)의 이름을 지정합니다. 이 구성을 통해 로그 델리게이트를 변경할 수 있습니다. 이 코드에서는 SLF4J를 사용하는 net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator가 지정되어 있습니다. | |
||||||
|
| log4jdbc.dump.sql.maxlinelength | SQL문의 최대 길이를 지정합니다. 이 속성은 SQL문을 자동 줄 바꿈하는 데 사용됩니다. 이 코드에서는 0으로 설정되어 있으므로 SQL문의 길이에 제한이 없습니다. | |
||||||
|
| log4jdbc.spylogdelegator.name | 로그4jdbc에서 사용할 로그 델리게이트(Delegate)의 이름을 지정합니다. 이 구성을 통해 로그 델리게이트를 변경할 수 있습니다. 이 코드에서는 SLF4J를 사용하는 net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator가 지정되어 있습니다. | |
||||||
|
| log4jdbc.dump.sql.maxlinelength | SQL문의 최대 길이를 지정합니다. 이 속성은 SQL문을 자동 줄 바꿈하는 데 사용됩니다. 이 코드에서는 0으로 설정되어 있으므로 SQL문의 길이에 제한이 없습니다. | |
||||||
|
| log4jdbc.auto.load.popular.drivers | 자주 사용되는 드라이버를 자동으로 로드할지 여부를 지정합니다. 이 코드에서는 true로 설정되어 있습니다. | |
||||||
|
| log4jdbc.trim.sql.enabled | SQL 문의 앞뒤 공백을 자동으로 제거할지 여부를 지정합니다. 이 코드에서는 true로 설정되어 있습니다. | |
||||||
|
| log4jdbc.trim.sql.extrablanklines | SQL 문의 공백 라인을 제거할지 여부를 지정합니다. 이 코드에서는 false로 설정되어 있습니다. | |
||||||
|
| log4jdbc.suppress.generated.keys.exception | SQL 문에서 생성된 키 예외를 억제할지 여부를 지정합니다. 이 코드에서는 false로 설정되어 있습니다. |
||||||
|
|
||||||
|
|
||||||
|
## spring rest doc |
||||||
|
|
||||||
|
### URL |
||||||
|
|
||||||
|
- uri : `/docs/index.html` |
||||||
|
- local : http://localhost:8080/docs/index.html |
||||||
|
|
||||||
|
## spring swagger |
||||||
|
|
||||||
|
### URL |
||||||
|
|
||||||
|
- uri : `/swagger-ui/index.html` |
||||||
|
- local : http://localhost:8080/swagger-ui/index.html |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,10 @@ |
|||||||
|
FROM openjdk:21 |
||||||
|
|
||||||
|
ENV TZ=Asia/Seoul |
||||||
|
|
||||||
|
EXPOSE 8080 |
||||||
|
|
||||||
|
WORKDIR /app |
||||||
|
ADD ./build/libs/*.jar /app/app.jar |
||||||
|
|
||||||
|
ENTRYPOINT ["java","-jar","/app/app.jar"] |
@ -1,9 +1,94 @@ |
|||||||
|
plugins { |
||||||
|
id "org.asciidoctor.jvm.convert" version "3.3.2" |
||||||
|
} |
||||||
|
|
||||||
|
configurations { |
||||||
|
compileOnly { |
||||||
|
extendsFrom annotationProcessor |
||||||
|
} |
||||||
|
asciidoctorExt |
||||||
|
} |
||||||
|
|
||||||
dependencies { |
dependencies { |
||||||
implementation "$boot:spring-boot-starter-web" |
implementation "$boot:spring-boot-starter-web" |
||||||
runtimeOnly 'com.mysql:mysql-connector-j' |
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0' |
||||||
|
// security |
||||||
|
implementation "$boot:spring-boot-starter-security" |
||||||
|
// implementation "com.auth0:java-jwt:4.4.0" |
||||||
|
|
||||||
|
// db |
||||||
|
// runtimeOnly "com.mysql:mysql-connector-j" |
||||||
|
// implementation "org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4:1.16" |
||||||
|
implementation("org.springframework:spring-tx") |
||||||
|
// jpa |
||||||
|
// implementation "$boot:spring-boot-starter-data-jpa" |
||||||
|
// querydsl |
||||||
|
// implementation "com.querydsl:querydsl-jpa:5.0.0:jakarta" |
||||||
|
|
||||||
|
|
||||||
|
// rest doc |
||||||
|
asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor' |
||||||
|
|
||||||
|
// test |
||||||
|
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' |
||||||
|
testImplementation 'org.springframework.boot:spring-boot-starter-test' |
||||||
|
|
||||||
|
|
||||||
|
implementation project(":common:core") |
||||||
|
// implementation project(":common:config-db") |
||||||
|
implementation project(":common:util") |
||||||
|
implementation project(":web:security") |
||||||
|
implementation project(":web:api-common") |
||||||
|
implementation project(":web:api-user") |
||||||
|
implementation project(":web:api-cns") |
||||||
|
} |
||||||
|
|
||||||
|
ext { |
||||||
|
snippetsDir = file('build/generated-snippets') |
||||||
|
} |
||||||
|
|
||||||
|
tasks { |
||||||
|
def isTest = gradle.startParameter.excludedTaskNames.contains('test') |
||||||
|
|
||||||
|
if (!isTest) { |
||||||
|
asciidoctor { |
||||||
|
dependsOn test |
||||||
|
inputs.dir snippetsDir |
||||||
|
doFirst { |
||||||
|
delete file('src/main/resources/static/docs') |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
test { |
||||||
|
outputs.dir snippetsDir |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
bootJar { |
||||||
|
if (!isTest) { |
||||||
|
dependsOn asciidoctor |
||||||
|
from("${asciidoctor.outputDir}/html5") { |
||||||
|
into 'static/docs' |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
task copyDocument(type: Copy) { |
||||||
|
if (!isTest) { |
||||||
|
dependsOn asciidoctor |
||||||
|
from file("build/docs/asciidoc") |
||||||
|
into file("src/main/resources/static/docs") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
build { |
||||||
|
if (!isTest) { |
||||||
|
dependsOn copyDocument |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
compileOnly project(":data-user") |
|
||||||
} |
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,3 @@ |
|||||||
|
sh ../../gradlew clean && ../../gradlew bootJar |
||||||
|
docker cp ./build/libs/app-kac-app-1.0.0.jar kac-app:/app/app.jar |
||||||
|
docker restart kac-app |
Binary file not shown.
@ -0,0 +1,244 @@ |
|||||||
|
ifndef::snippets[] |
||||||
|
:snippets: ./build/generated-snippets |
||||||
|
endif::[] |
||||||
|
|
||||||
|
= KAC App Docs |
||||||
|
API 문서 |
||||||
|
:doctype: book |
||||||
|
:icons: font |
||||||
|
:source-highlighter: highlightjs |
||||||
|
:toc: left |
||||||
|
:toclevels: 2 |
||||||
|
:sectlinks: |
||||||
|
|
||||||
|
[[Common-Code-API]] |
||||||
|
== Common-Code API |
||||||
|
|
||||||
|
[[Code-All]] |
||||||
|
=== [Code 전체코드 조회] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/com/code/all/http-request.adoc[] |
||||||
|
include::{snippets}/com/code/all/query-parameters.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/com/code/all/http-response.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/all/response-fields.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [Code 코드목록 조회] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/com/code/code/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/code/query-parameters.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/com/code/code/http-response.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/code/response-fields.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [Code 그룹목록 조회] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/com/code/group/http-request.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/com/code/group/http-response.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/group/response-fields.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [Code 그룹 등록] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/com/code/group/create/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/group/create/request-fields.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/com/code/group/create/http-response.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/group/create/response-fields.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [Code 코드 등록] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/com/code/code/create/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/code/create/request-fields.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/com/code/code/create/http-response.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/code/create/response-fields.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [Code 코드언어 등록] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/com/code/lang/create/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/lang/create/request-fields.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/com/code/lang/create/http-response.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/lang/create/response-fields.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [Code 그룹 수정] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/com/code/group/update/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/group/update/request-fields.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/com/code/group/update/http-response.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/group/update/response-fields.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [Code 코드 수정] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/com/code/code/update/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/code/update/request-fields.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/com/code/code/update/http-response.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/code/update/response-fields.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [Code 코드언어 수정] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/com/code/lang/update/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/lang/update/request-fields.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/com/code/lang/update/http-response.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/lang/update/response-fields.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [Code 그룹 삭제] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/com/code/group/delete/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/group/delete/query-parameters.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/com/code/group/delete/http-response.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [Code 코드 삭제] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/com/code/code/delete/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/code/delete/query-parameters.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/com/code/code/delete/http-response.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [Code 언어 삭제] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/com/code/lang/delete/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/com/code/lang/delete/query-parameters.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/com/code/lang/delete/http-response.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
[[User-Account-API]] |
||||||
|
== User-Account API |
||||||
|
|
||||||
|
=== [User 회원가입] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/user/account/register/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/user/account/register/request-fields.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/user/account/register/http-response.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [User 회원탈퇴] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/user/account/delete/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/user/account/delete/request-headers.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/user/account/delete/http-response.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [User 회원정보 조회] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/user/account/profile/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/user/account/profile/request-headers.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/user/account/profile/http-response.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/user/account/profile/response-fields.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [User 회원암호 변경] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/user/account/update/pswd/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/user/account/update/pswd/request-headers.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/user/account/update/pswd/request-fields.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/user/account/update/pswd/http-response.adoc[] |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
=== [User 회원정보 변경] |
||||||
|
|
||||||
|
==== [HTTP REQUEST INFO] |
||||||
|
include::{snippets}/user/account/update/http-request.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/user/account/update/request-headers.adoc[] |
||||||
|
|
||||||
|
include::{snippets}/user/account/update/request-fields.adoc[] |
||||||
|
|
||||||
|
==== [HTTP RESPONSE INFO] |
||||||
|
include::{snippets}/user/account/update/http-response.adoc[] |
||||||
|
|
||||||
|
*** |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,26 @@ |
|||||||
|
package kr.co.palnet.kac.app.config; |
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier; |
||||||
|
import org.springframework.context.MessageSource; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.context.support.MessageSourceAccessor; |
||||||
|
import org.springframework.context.support.ReloadableResourceBundleMessageSource; |
||||||
|
|
||||||
|
@Configuration |
||||||
|
public class MessageSourceConfig { |
||||||
|
|
||||||
|
@Bean(name = "errorMessageSource") |
||||||
|
public MessageSource getErrorMessageSource() { |
||||||
|
ReloadableResourceBundleMessageSource errorMessageSource = new ReloadableResourceBundleMessageSource(); |
||||||
|
errorMessageSource.setBasenames("classpath:messages/errors/error"); |
||||||
|
errorMessageSource.setDefaultEncoding("UTF-8"); |
||||||
|
errorMessageSource.setCacheSeconds(300); |
||||||
|
return errorMessageSource; |
||||||
|
} |
||||||
|
|
||||||
|
@Bean(name = "errorMessageSourceAccessor") |
||||||
|
public MessageSourceAccessor errorMessageSourceAccessor(@Qualifier("errorMessageSource") MessageSource errorMessageSource) { |
||||||
|
return new MessageSourceAccessor(errorMessageSource); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,112 @@ |
|||||||
|
package kr.co.palnet.kac.app.config; |
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.Components; |
||||||
|
import io.swagger.v3.oas.models.OpenAPI; |
||||||
|
import io.swagger.v3.oas.models.info.Info; |
||||||
|
import io.swagger.v3.oas.models.security.SecurityRequirement; |
||||||
|
import io.swagger.v3.oas.models.security.SecurityScheme; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
|
||||||
|
import org.springdoc.core.models.GroupedOpenApi; |
||||||
|
import org.springframework.boot.web.servlet.FilterRegistrationBean; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.core.Ordered; |
||||||
|
import org.springframework.web.cors.CorsConfiguration; |
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; |
||||||
|
import org.springframework.web.filter.CorsFilter; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
@Slf4j |
||||||
|
@Configuration |
||||||
|
public class SwaggerConfig { |
||||||
|
|
||||||
|
// @Bean
|
||||||
|
// public Docket api() {
|
||||||
|
// return new Docket(DocumentationType.OAS_30) // open api spec 3.0
|
||||||
|
// .apiInfo(new ApiInfoBuilder().version("1.0").title("PAV").build())
|
||||||
|
// .forCodeGeneration(true).securitySchemes(Arrays.asList(apiKey()))
|
||||||
|
// .select()
|
||||||
|
// .apis(RequestHandlerSelectors.any())
|
||||||
|
// .paths(PathSelectors.any())
|
||||||
|
// .build()
|
||||||
|
// .apiInfo(apiInfo())
|
||||||
|
// .directModelSubstitute(Date.class, String.class)
|
||||||
|
// .directModelSubstitute(LocalDate.class, String.class)
|
||||||
|
// .directModelSubstitute(LocalDateTime.class, String.class)
|
||||||
|
// .directModelSubstitute(Pageable.class, SwaggerPageable.class)
|
||||||
|
// .securityContexts(Arrays.asList(securityContext()))
|
||||||
|
// .securitySchemes(Arrays.asList(apiKey()));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// private ApiInfo apiInfo() {
|
||||||
|
// return new ApiInfoBuilder()
|
||||||
|
// .title("PAV API")
|
||||||
|
// .description("----")
|
||||||
|
// .version("1.0")
|
||||||
|
// .build();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //ApiKey 정의
|
||||||
|
// private ApiKey apiKey() {
|
||||||
|
// return new ApiKey("Authorization", "Authorization", "header");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //JWT SecurityContext 구성
|
||||||
|
// private SecurityContext securityContext() {
|
||||||
|
// return SecurityContext.builder().securityReferences(defaultAuth()).build();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private List<SecurityReference> defaultAuth() {
|
||||||
|
// AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEveryThing");
|
||||||
|
// AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
|
||||||
|
// authorizationScopes[0] = authorizationScope;
|
||||||
|
// return Arrays.asList(new SecurityReference("Authorization", authorizationScopes));
|
||||||
|
// }
|
||||||
|
|
||||||
|
private static final String BEARER_TOKEN_PREFIX = "palnet"; |
||||||
|
|
||||||
|
@Bean |
||||||
|
public OpenAPI openAPI() { |
||||||
|
final String securitySchemeName = "BearerAuth"; |
||||||
|
|
||||||
|
SecurityRequirement securityRequirement = new SecurityRequirement().addList(securitySchemeName, List.of("read", "write")); |
||||||
|
|
||||||
|
Components components = new Components() |
||||||
|
.addSecuritySchemes(securitySchemeName, new SecurityScheme() |
||||||
|
.type(SecurityScheme.Type.APIKEY) |
||||||
|
.in(SecurityScheme.In.HEADER) |
||||||
|
.name("Authorization") |
||||||
|
.description("prefix add 'palnet ' + token") |
||||||
|
); |
||||||
|
|
||||||
|
// Swagger UI 접속 후, 딱 한 번만 accessToken을 입력해주면 모든 API에 토큰 인증 작업이 적용됩니다.
|
||||||
|
return new OpenAPI() |
||||||
|
.addSecurityItem(securityRequirement) |
||||||
|
.components(components) |
||||||
|
.info(new Info() |
||||||
|
.title("PAV API") |
||||||
|
.version("1.0") |
||||||
|
.description("PAV API") |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
@Bean |
||||||
|
public GroupedOpenApi commonCode() { |
||||||
|
return GroupedOpenApi.builder() |
||||||
|
.group("공통-코드") |
||||||
|
.pathsToMatch("/v1/com/code/**") |
||||||
|
.build(); |
||||||
|
} |
||||||
|
|
||||||
|
@Bean |
||||||
|
public GroupedOpenApi selectAll() { |
||||||
|
return GroupedOpenApi.builder() |
||||||
|
.group("All") |
||||||
|
.pathsToMatch("/**") |
||||||
|
.build(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,19 @@ |
|||||||
|
package kr.co.palnet.kac.app.config; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.app.core.web.BaseAcceptHeaderLocaleResolver; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.web.servlet.LocaleResolver; |
||||||
|
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; |
||||||
|
|
||||||
|
import java.util.Locale; |
||||||
|
|
||||||
|
@Configuration |
||||||
|
public class WebConfig { |
||||||
|
@Bean |
||||||
|
public LocaleResolver localeResolver() { |
||||||
|
AcceptHeaderLocaleResolver localeResolver = new BaseAcceptHeaderLocaleResolver(); |
||||||
|
localeResolver.setDefaultLocale(Locale.KOREA); |
||||||
|
return localeResolver; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,132 @@ |
|||||||
|
package kr.co.palnet.kac.app.core.exception; |
||||||
|
|
||||||
|
|
||||||
|
import kr.co.palnet.kac.core.exception.BaseErrorCode; |
||||||
|
import kr.co.palnet.kac.core.exception.BaseException; |
||||||
|
import kr.co.palnet.kac.core.exception.Level; |
||||||
|
import kr.co.palnet.kac.core.exception.model.BaseErrorModel; |
||||||
|
import lombok.RequiredArgsConstructor; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.beans.factory.annotation.Qualifier; |
||||||
|
import org.springframework.context.NoSuchMessageException; |
||||||
|
import org.springframework.context.i18n.LocaleContextHolder; |
||||||
|
import org.springframework.context.support.MessageSourceAccessor; |
||||||
|
import org.springframework.http.ResponseEntity; |
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler; |
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice; |
||||||
|
import org.springframework.web.context.request.RequestContextHolder; |
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes; |
||||||
|
import org.springframework.web.servlet.resource.NoResourceFoundException; |
||||||
|
|
||||||
|
import java.time.Instant; |
||||||
|
|
||||||
|
@Slf4j |
||||||
|
@RequiredArgsConstructor |
||||||
|
@RestControllerAdvice |
||||||
|
public class ServerExceptionHandler { |
||||||
|
|
||||||
|
@Qualifier("errorMessageSourceAccessor") |
||||||
|
private final MessageSourceAccessor errorMessageSourceAccessor; |
||||||
|
|
||||||
|
@ExceptionHandler(BaseException.class) |
||||||
|
public ResponseEntity<BaseErrorModel> appExceptionHandle(BaseException e) { |
||||||
|
|
||||||
|
BaseErrorCode errorType = e.getErrorCode(); |
||||||
|
|
||||||
|
BaseErrorModel baseBody = new BaseErrorModel(); |
||||||
|
baseBody.setTimestamp(Instant.now()); |
||||||
|
baseBody.setStatus(errorType.status().value()); |
||||||
|
baseBody.setError(errorType.status().getReasonPhrase()); |
||||||
|
baseBody.setCode(errorType.code()); |
||||||
|
baseBody.setMessage(this.getMessage(errorType)); |
||||||
|
baseBody.setPath(this.getUrl()); |
||||||
|
|
||||||
|
this.printLog(e); |
||||||
|
|
||||||
|
return ResponseEntity.status(errorType.status()).body(baseBody); |
||||||
|
} |
||||||
|
|
||||||
|
@ExceptionHandler(NoResourceFoundException.class) |
||||||
|
public ResponseEntity<BaseErrorModel> noResourceFoundException(NoResourceFoundException e) { |
||||||
|
|
||||||
|
BaseErrorModel baseBody = new BaseErrorModel(); |
||||||
|
baseBody.setTimestamp(Instant.now()); |
||||||
|
baseBody.setStatus(e.getBody().getStatus()); |
||||||
|
baseBody.setError(e.getBody().getDetail()); |
||||||
|
baseBody.setCode(BaseErrorCode.WEB_NOT_FOUND.code()); |
||||||
|
baseBody.setMessage(this.getMessage(BaseErrorCode.WEB_NOT_FOUND)); |
||||||
|
baseBody.setPath(e.getResourcePath()); |
||||||
|
|
||||||
|
log.warn("", e); |
||||||
|
|
||||||
|
return ResponseEntity.status(e.getBody().getStatus()).body(baseBody); |
||||||
|
} |
||||||
|
|
||||||
|
@ExceptionHandler(Exception.class) |
||||||
|
public ResponseEntity<BaseErrorModel> exceptionHandle(Exception e) { |
||||||
|
BaseErrorCode errorType = BaseErrorCode.UNKNOWN; |
||||||
|
|
||||||
|
BaseErrorModel baseBody = new BaseErrorModel(); |
||||||
|
baseBody.setTimestamp(Instant.now()); |
||||||
|
baseBody.setStatus(errorType.status().value()); |
||||||
|
baseBody.setError(errorType.status().getReasonPhrase()); |
||||||
|
baseBody.setCode(errorType.code()); |
||||||
|
baseBody.setMessage(this.getMessage(errorType)); |
||||||
|
baseBody.setPath(this.getUrl()); |
||||||
|
|
||||||
|
log.error("", e); |
||||||
|
|
||||||
|
return ResponseEntity.status(errorType.status()).body(baseBody); |
||||||
|
} |
||||||
|
|
||||||
|
private String getUrl() { |
||||||
|
ServletRequestAttributes servletRequestAttr = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); |
||||||
|
if (servletRequestAttr != null) return servletRequestAttr.getRequest().getRequestURI(); |
||||||
|
else return null; |
||||||
|
} |
||||||
|
|
||||||
|
private String getMessage(BaseErrorCode e) { |
||||||
|
String message = null; |
||||||
|
try { |
||||||
|
// message = errorMessageSourceAccessor.getMessage(e.code(), LocaleContextHolder.getLocale());
|
||||||
|
message = errorMessageSourceAccessor.getMessage(e.code()); |
||||||
|
} catch (NoSuchMessageException noSuchMessageException) { |
||||||
|
message = "관리자에게 문의해주세요."; |
||||||
|
} |
||||||
|
return message; |
||||||
|
} |
||||||
|
|
||||||
|
private void printLog(BaseException e) { |
||||||
|
Level level = e.getLevel(); |
||||||
|
String message = e.getLogMessage() == null ? e.getMessage() : e.getLogMessage(); |
||||||
|
Object[] paramArray = e.getParamArray(); |
||||||
|
|
||||||
|
switch (level) { |
||||||
|
case TRACE: |
||||||
|
log.trace("message: {}, params: {}, trace: {}", message, paramArray, e.getStackTrace()); |
||||||
|
log.trace("", e); |
||||||
|
break; |
||||||
|
case DEBUG: |
||||||
|
log.debug("message: {}, params: {}, trace: {}", message, paramArray, e.getStackTrace()); |
||||||
|
log.debug("", e); |
||||||
|
break; |
||||||
|
case INFO: |
||||||
|
log.info("message: {}, params: {}, trace: {}", message, paramArray, e.getStackTrace()); |
||||||
|
log.info("", e); |
||||||
|
break; |
||||||
|
case WARN: |
||||||
|
log.warn("message: {}, params: {}, trace: {}", message, paramArray, e.getStackTrace()); |
||||||
|
log.warn("", e); |
||||||
|
break; |
||||||
|
case ERROR: |
||||||
|
log.trace("message: {}, params: {}, trace: {}", message, paramArray, e.getStackTrace()); |
||||||
|
log.error("", e); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
@ -0,0 +1,60 @@ |
|||||||
|
package kr.co.palnet.kac.app.core.security; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.config.security.SecurityConfig; |
||||||
|
import kr.co.palnet.kac.config.security.exception.BaseAccessDeniedHandler; |
||||||
|
import kr.co.palnet.kac.config.security.exception.BaseAuthenticationEntryPoint; |
||||||
|
import kr.co.palnet.kac.config.security.service.BaseUserDetailsService; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; |
||||||
|
import org.springframework.security.web.SecurityFilterChain; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
|
||||||
|
@Slf4j |
||||||
|
@EnableWebSecurity |
||||||
|
@Configuration |
||||||
|
public class AppSecurityConfig extends SecurityConfig { |
||||||
|
|
||||||
|
// 시큐리티 적용 안하는 URL 목록
|
||||||
|
private final String[] IGNORE_URL = { |
||||||
|
"/v1/**", |
||||||
|
"/v1/user/account/register", |
||||||
|
}; |
||||||
|
|
||||||
|
// 권한(ROLE)별 URL
|
||||||
|
private final String[] USER_URL = { |
||||||
|
}; |
||||||
|
|
||||||
|
public AppSecurityConfig(BaseUserDetailsService baseUserDetailsService, BaseAuthenticationEntryPoint baseAuthenticationEntryPoint, BaseAccessDeniedHandler baseAccessDeniedHandler) { |
||||||
|
super(baseUserDetailsService, baseAuthenticationEntryPoint, baseAccessDeniedHandler); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { |
||||||
|
// 기본 security 설정을 불러온다.
|
||||||
|
this.setDefaultHttpSecurity(http); |
||||||
|
// 여기서는 role별 허용 url 설정을 한다.
|
||||||
|
http |
||||||
|
.securityMatchers(matchers -> matchers.requestMatchers("/**")) |
||||||
|
.authorizeHttpRequests(authz -> |
||||||
|
authz |
||||||
|
.requestMatchers(USER_URL).hasRole("USER") |
||||||
|
.anyRequest().authenticated() |
||||||
|
) |
||||||
|
; |
||||||
|
|
||||||
|
return http.build(); |
||||||
|
} |
||||||
|
|
||||||
|
// security filter 제외 - permission all
|
||||||
|
@Override |
||||||
|
protected List<String> getExcludeURI() { |
||||||
|
return new ArrayList<>(Arrays.asList(IGNORE_URL)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,68 @@ |
|||||||
|
package kr.co.palnet.kac.app.core.web; |
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.context.i18n.LocaleContextHolder; |
||||||
|
import org.springframework.util.StringUtils; |
||||||
|
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Locale; |
||||||
|
|
||||||
|
@Slf4j |
||||||
|
public class BaseAcceptHeaderLocaleResolver extends AcceptHeaderLocaleResolver { |
||||||
|
private final List<Locale> LOCALES = Arrays.asList( |
||||||
|
new Locale("ko"), |
||||||
|
new Locale("ko", "KR"), |
||||||
|
new Locale("en"), |
||||||
|
new Locale("en", "US") |
||||||
|
); |
||||||
|
private final String LOCALE_HEADER_KEY = "Accept-Language"; |
||||||
|
|
||||||
|
/** |
||||||
|
* resolve locale 구성 |
||||||
|
* |
||||||
|
* @param request the request to resolve the locale for |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Locale resolveLocale(HttpServletRequest request) { |
||||||
|
if (!StringUtils.hasText(request.getHeader(LOCALE_HEADER_KEY))) { |
||||||
|
return this.getDefaultLocale(); |
||||||
|
} |
||||||
|
try { |
||||||
|
|
||||||
|
Locale locale = LOCALES.stream().filter(_locale -> { |
||||||
|
String defaultLocale = _locale.toString() |
||||||
|
.replaceAll("-", "") |
||||||
|
.replaceAll("_", "") |
||||||
|
.toLowerCase(); |
||||||
|
String headerLocale = request.getHeader(LOCALE_HEADER_KEY).toString() |
||||||
|
.replaceAll("-", "") |
||||||
|
.replaceAll("_", "") |
||||||
|
.toLowerCase(); |
||||||
|
return defaultLocale.equals(headerLocale); |
||||||
|
}).findFirst().orElse(null); |
||||||
|
|
||||||
|
if (locale == null) { |
||||||
|
locale = LOCALES.stream() |
||||||
|
.filter(_locale -> { |
||||||
|
String language = _locale.getLanguage(); |
||||||
|
return request.getHeader(LOCALE_HEADER_KEY).contains(language); |
||||||
|
}) |
||||||
|
.map(_locale -> { |
||||||
|
String language = _locale.getLanguage(); |
||||||
|
return new Locale(language); |
||||||
|
}) |
||||||
|
.distinct() |
||||||
|
.findFirst().orElse(Locale.KOREAN); |
||||||
|
} |
||||||
|
// log.debug("{}, {}", request.getHeader(LOCALE_HEADER_KEY), locale);
|
||||||
|
return locale; |
||||||
|
} catch (IllegalArgumentException e) { |
||||||
|
log.warn("{}", e.getMessage()); |
||||||
|
return this.getDefaultLocale(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,128 @@ |
|||||||
|
package kr.co.palnet.kac.app.ping.controller; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.core.exception.BaseErrorCode; |
||||||
|
import kr.co.palnet.kac.core.exception.BaseException; |
||||||
|
import kr.co.palnet.kac.util.EncryptUtil; |
||||||
|
import kr.co.palnet.kac.util.KisaEncryptUtil; |
||||||
|
import lombok.RequiredArgsConstructor; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.beans.factory.annotation.Qualifier; |
||||||
|
import org.springframework.context.MessageSource; |
||||||
|
import org.springframework.context.i18n.LocaleContextHolder; |
||||||
|
import org.springframework.context.support.MessageSourceAccessor; |
||||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||||
|
import org.springframework.web.bind.annotation.PathVariable; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.RestController; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Locale; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
@Slf4j |
||||||
|
@RequiredArgsConstructor |
||||||
|
@RequestMapping("/test") |
||||||
|
@RestController |
||||||
|
public class TestErrorContoller { |
||||||
|
|
||||||
|
@Qualifier("errorMessageSource") |
||||||
|
private final MessageSource errorMessageSource; |
||||||
|
|
||||||
|
@Qualifier("errorMessageSourceAccessor") |
||||||
|
private final MessageSourceAccessor errorMessageSourceAccessor; |
||||||
|
|
||||||
|
@GetMapping("/encrypt/{plainText}") |
||||||
|
public String ecrypt(@PathVariable String plainText) { |
||||||
|
String encrypt = KisaEncryptUtil.CbcEncrypt.encrypt(plainText); |
||||||
|
log.info("e : {}", encrypt); |
||||||
|
String decrypt = KisaEncryptUtil.CbcEncrypt.decrypt(encrypt); |
||||||
|
log.info("d : {}", decrypt); |
||||||
|
String encrypt1 = EncryptUtil.encrypt(plainText); |
||||||
|
log.info("e : {}", encrypt1); |
||||||
|
String decrypt1 = EncryptUtil.decrypt(encrypt1); |
||||||
|
log.info("d : {}", decrypt1); |
||||||
|
return decrypt; |
||||||
|
} |
||||||
|
|
||||||
|
@GetMapping("/error/{caseNumber}") |
||||||
|
public String errorTest(@PathVariable("caseNumber") Integer caseNumber) throws Exception { |
||||||
|
log.info("{}", caseNumber); |
||||||
|
return switch (caseNumber) { |
||||||
|
case 1 -> throw new BaseException(BaseErrorCode.IO_ERROR); |
||||||
|
case 2 -> throw new Exception("test"); |
||||||
|
default -> "success"; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
@GetMapping("/message/locale") |
||||||
|
public Map<String, String> locale() { |
||||||
|
Map<String, String> map = new HashMap<>(); |
||||||
|
map.put("message", errorMessageSourceAccessor.getMessage("TEST001")); |
||||||
|
map.put("locale", LocaleContextHolder.getLocale().toString()); |
||||||
|
return map; |
||||||
|
} |
||||||
|
|
||||||
|
@GetMapping("/message/error") |
||||||
|
public void messageSource() { |
||||||
|
Map<String, String> map = new HashMap<>(); |
||||||
|
try { |
||||||
|
String ko_KR = errorMessageSource.getMessage("TEST001", null, Locale.KOREA); |
||||||
|
map.put("ko_KR", ko_KR); |
||||||
|
} catch (Exception e) { |
||||||
|
log.error("{}", e.getMessage()); |
||||||
|
} |
||||||
|
try { |
||||||
|
String ko = errorMessageSource.getMessage("TEST001", null, Locale.KOREAN); |
||||||
|
map.put("ko", ko); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
log.error("{}", e.getMessage()); |
||||||
|
} |
||||||
|
try { |
||||||
|
String en = errorMessageSource.getMessage("TEST001", null, Locale.ENGLISH); |
||||||
|
map.put("en", en); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
log.error("{}", e.getMessage()); |
||||||
|
} |
||||||
|
try { |
||||||
|
String en_US = errorMessageSource.getMessage("TEST001", null, Locale.US); |
||||||
|
map.put("en_US", en_US); |
||||||
|
} catch (Exception e) { |
||||||
|
log.error("{}", e.getMessage()); |
||||||
|
} |
||||||
|
|
||||||
|
log.info("=========================================================================================="); |
||||||
|
try { |
||||||
|
String df = errorMessageSourceAccessor.getMessage("TEST001"); |
||||||
|
map.put("df", df); |
||||||
|
} catch (Exception e) { |
||||||
|
log.error("{}", e.getMessage()); |
||||||
|
} |
||||||
|
try { |
||||||
|
String str = errorMessageSourceAccessor.getMessage("TEST001", Locale.KOREAN); |
||||||
|
map.put("s_ko", str); |
||||||
|
} catch (Exception e) { |
||||||
|
log.error("{}", e.getMessage()); |
||||||
|
} |
||||||
|
try { |
||||||
|
String str = errorMessageSourceAccessor.getMessage("TEST001", Locale.KOREA); |
||||||
|
map.put("s_ko_kr", str); |
||||||
|
} catch (Exception e) { |
||||||
|
log.error("{}", e.getMessage()); |
||||||
|
} |
||||||
|
try { |
||||||
|
String str = errorMessageSourceAccessor.getMessage("TEST001", Locale.ENGLISH); |
||||||
|
map.put("s_en", str); |
||||||
|
} catch (Exception e) { |
||||||
|
log.error("{}", e.getMessage()); |
||||||
|
} |
||||||
|
try { |
||||||
|
String str = errorMessageSourceAccessor.getMessage("TEST001", Locale.US); |
||||||
|
map.put("s_en_us", str); |
||||||
|
} catch (Exception e) { |
||||||
|
log.error("{}", e.getMessage()); |
||||||
|
} |
||||||
|
log.info("{}", map); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
package kr.co.palnet.kac.app.ping.controller; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.config.security.model.BaseUserDetails; |
||||||
|
import kr.co.palnet.kac.config.security.util.SessionHelper; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.RestController; |
||||||
|
|
||||||
|
@Slf4j |
||||||
|
@RestController |
||||||
|
@RequestMapping("/test/session") |
||||||
|
public class TestSessionContrller { |
||||||
|
|
||||||
|
@GetMapping("/auth") |
||||||
|
public void test() { |
||||||
|
BaseUserDetails userInfo = SessionHelper.getUserInfo(); |
||||||
|
log.info("userInfo ::: {}", userInfo); |
||||||
|
Long userNo = SessionHelper.getCstmrSno(); |
||||||
|
log.info("userNo ::: {}", userNo); |
||||||
|
String userId = SessionHelper.getUserId(); |
||||||
|
log.info("userId ::: {}", userId); |
||||||
|
boolean isRole1 = SessionHelper.hasRole("USER"); |
||||||
|
log.info("isRole1 ::: {}", isRole1); |
||||||
|
boolean isRole2 = SessionHelper.hasRole("ADMIN"); |
||||||
|
log.info("isRole2 ::: {}", isRole2); |
||||||
|
boolean isRole3 = SessionHelper.hasRole("ADMINasdfasdf"); |
||||||
|
log.info("isRole3 ::: {}", isRole3); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,3 @@ |
|||||||
|
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier |
||||||
|
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Value |
||||||
|
lombok.anyConstructor.addConstructorProperties=true |
@ -0,0 +1,41 @@ |
|||||||
|
springdoc: |
||||||
|
api-docs: |
||||||
|
path: /api-docs |
||||||
|
groups: |
||||||
|
enabled: true |
||||||
|
# paths-to-exclude: |
||||||
|
# - /api/v1/utm |
||||||
|
# - /api/bas/flight/** |
||||||
|
# - /api/ctr/cntrl/contains |
||||||
|
# - /api/file/** |
||||||
|
swagger-ui: |
||||||
|
# 각 API의 그룹 표시 순서 |
||||||
|
# path, query, body, response 순으로 출력 |
||||||
|
path: /index.html |
||||||
|
display-request-duration: true |
||||||
|
|
||||||
|
groups-order: ASC |
||||||
|
|
||||||
|
# 태그 정렬 순서. |
||||||
|
# alpha: 알파벳 순 정렬 |
||||||
|
# method: OpenAPI specification file에 원하는 태그 정렬 방식 직접 기재 |
||||||
|
tags-sorter: alpha |
||||||
|
|
||||||
|
# 컨트롤러 정렬 순서. |
||||||
|
# method는 delete - get - patch - post - put 순으로 정렬된다. |
||||||
|
# alpha를 사용해 알파벳 순으로 정렬할 수 있다. |
||||||
|
operations-sorter: alpha |
||||||
|
|
||||||
|
# Spring Actuator의 endpoint까지 보여줄 것인지? |
||||||
|
show-actuator: false |
||||||
|
|
||||||
|
# request media type 의 기본 값 |
||||||
|
default-consumes-media-type: application/json |
||||||
|
|
||||||
|
# response media type 의 기본 값 |
||||||
|
default-produces-media-type: application/json |
||||||
|
|
||||||
|
# Swagger UI에서 기본적으로 펼쳐져 보이는 경로의 수 |
||||||
|
doc-expansion : none |
||||||
|
|
||||||
|
|
@ -0,0 +1,23 @@ |
|||||||
|
spring: |
||||||
|
profiles: |
||||||
|
include: |
||||||
|
- swagger |
||||||
|
- db |
||||||
|
threads: |
||||||
|
virtual: |
||||||
|
enabled: true |
||||||
|
|
||||||
|
logging: |
||||||
|
level: |
||||||
|
kr.co.palnet: DEBUG |
||||||
|
com.com.zaxxer.hikari: INFO |
||||||
|
jdbc: |
||||||
|
audit: OFF |
||||||
|
resultset: OFF |
||||||
|
resultsettable: INFO #SQL 결과 데이터 Table을 로그로 남긴다. |
||||||
|
sqlonly: OFF #SQL만 로그로 남긴다. |
||||||
|
sqltiming: INFO #SQL과 소요시간을 표기한다. |
||||||
|
connection : OFF # 커넥션 확인가능 |
||||||
|
org.hibernate: |
||||||
|
SQL: DEBUG |
||||||
|
type.descriptor.sql.BasicBinder: TRACE |
@ -0,0 +1,2 @@ |
|||||||
|
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator |
||||||
|
log4jdbc.dump.sql.maxlinelength=0 |
@ -0,0 +1,22 @@ |
|||||||
|
CM001=\uC131\uACF5\uC785\uB2C8\uB2E4. |
||||||
|
CM900=\uC54C \uC218 \uC5C6\uB294 \uC624\uB958\uC785\uB2C8\uB2E4. |
||||||
|
CM999=\uC2E4\uD328\uC785\uB2C8\uB2E4. |
||||||
|
CM002=\uC694\uCCAD\uD558\uC2E0 \uB0B4\uC6A9\uC774 \uCC98\uB9AC \uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. |
||||||
|
CM003=\uC785\uCD9C\uB825 \uC624\uB958\uC785\uB2C8\uB2E4. |
||||||
|
CM100=\uB85C\uADF8\uC778\uC744 \uB2E4\uC2DC \uD574\uC8FC\uC138\uC694. |
||||||
|
CM101=\uC774\uBBF8 \uB85C\uADF8\uC778\uD55C \uC0AC\uC6A9\uC790\uC785\uB2C8\uB2E4. |
||||||
|
CM102=\uB85C\uADF8\uC778 \uC2DC\uB3C4\uAC00 \uC815\uD574\uC9C4 \uD69F\uC218\uB97C \uCD08\uACFC\uD558\uC600\uC2B5\uB2C8\uB2E4. |
||||||
|
CM110=SNS \uB85C\uADF8\uC778\uC744 \uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. |
||||||
|
CM111=\uC774\uBBF8 \uAC00\uC785\uB41C SNS \uACC4\uC815\uC785\uB2C8\uB2E4. |
||||||
|
CM120=\uD1A0\uD070\uC774 \uB9CC\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. |
||||||
|
CM121=\uC798\uBABB\uB41C \uD1A0\uD070\uC785\uB2C8\uB2E4. |
||||||
|
CM130=\uC0AC\uC6A9\uC790\uC758 \uACC4\uC815\uC774 \uC815\uC9C0\uB418\uC5C8\uC2B5\uB2C8\uB2E4. |
||||||
|
CM131=\uC0AC\uC6A9\uC790\uC758 \uACC4\uC815\uC774 \uD734\uBA74\uC0C1\uD0DC\uC785\uB2C8\uB2E4. |
||||||
|
CM200=\uCE90\uC2DC \uB85C\uB529\uC5D0 \uC2E4\uD328\uD558\uC600\uC2B5\uB2C8\uB2E4. |
||||||
|
CM201=\uCE90\uC2DC \uB9AC\uB85C\uB529\uC5D0 \uC2E4\uD328\uD558\uC600\uC2B5\uB2C8\uB2E4. |
||||||
|
CM401=\uC0AC\uC6A9\uC790\uC758 \uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. |
||||||
|
WB400=\uD30C\uB77C\uBBF8\uD130\uB97C \uB2E4\uC2DC \uD655\uC778 \uD6C4 \uC694\uCCAD\uD574\uC8FC\uC138\uC694. |
||||||
|
WB500=\uC678\uBD80 \uC5F0\uB3D9 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD558\uC600\uC2B5\uB2C8\uB2E4. |
||||||
|
WB404=\uC694\uCCAD\uD558\uC2E0 URL\uC774 \uC874\uC7AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. |
||||||
|
DT001=\uC774\uBBF8 \uB4F1\uB85D\uB41C \uB370\uC774\uD130 \uC785\uB2C8\uB2E4. |
||||||
|
DT002=\uC694\uCCAD\uD55C \uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. |
@ -0,0 +1,22 @@ |
|||||||
|
CM001=It's a success. |
||||||
|
CM900=Unknown error. |
||||||
|
CM999=It's a failure. |
||||||
|
CM002=Your request has not been processed. |
||||||
|
CM003=Input/output error. |
||||||
|
CM100=Please log in again. |
||||||
|
CM101=This is a user who has already logged in. |
||||||
|
CM102=The login attempt exceeded the specified number of times. |
||||||
|
CM110=I can't log in to SNS. |
||||||
|
CM111=This is an SNS account that has already been subscribed. |
||||||
|
CM120=The token has expired. |
||||||
|
CM121=Invalid token. |
||||||
|
CM130=Your account has been suspended. |
||||||
|
CM131=Your account is dormant. |
||||||
|
CM200=Cache loading failed. |
||||||
|
CM201=Cache reloading failed. |
||||||
|
CM401=You do not have permissions. |
||||||
|
WB400=Please check the parameters again and request them. |
||||||
|
WB500=External interlocking error occurred. |
||||||
|
WB404=The URL you requested does not exist. |
||||||
|
DT001=Data already registered. |
||||||
|
DT002=No data requested. |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,119 @@ |
|||||||
|
package kr.co.palnet.kac; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||||
|
import jakarta.servlet.ServletException; |
||||||
|
import kr.co.palnet.kac.api.v1.user.account.model.detail.SearchUserRS; |
||||||
|
import kr.co.palnet.kac.api.v1.user.account.model.register.FormRegisterRQ; |
||||||
|
import kr.co.palnet.kac.api.v1.user.account.service.UserAccountService; |
||||||
|
import kr.co.palnet.kac.app.KacAppApplication; |
||||||
|
import kr.co.palnet.kac.config.security.model.BaseUserDetails; |
||||||
|
import kr.co.palnet.kac.config.security.service.BaseUserDetailsService; |
||||||
|
import kr.co.palnet.kac.config.security.util.JwtUtil; |
||||||
|
import kr.co.palnet.kac.util.ObjectMapperUtils; |
||||||
|
import org.junit.jupiter.api.BeforeEach; |
||||||
|
import org.junit.jupiter.api.extension.ExtendWith; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.boot.test.context.SpringBootTest; |
||||||
|
import org.springframework.mock.web.MockFilterConfig; |
||||||
|
import org.springframework.restdocs.RestDocumentationContextProvider; |
||||||
|
import org.springframework.restdocs.RestDocumentationExtension; |
||||||
|
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation; |
||||||
|
import org.springframework.security.config.BeanIds; |
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService; |
||||||
|
import org.springframework.test.web.servlet.MockMvc; |
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders; |
||||||
|
import org.springframework.web.context.WebApplicationContext; |
||||||
|
import org.springframework.web.filter.CharacterEncodingFilter; |
||||||
|
import org.springframework.web.filter.DelegatingFilterProxy; |
||||||
|
|
||||||
|
import java.time.LocalDate; |
||||||
|
import java.time.LocalDateTime; |
||||||
|
|
||||||
|
import static org.springframework.restdocs.operation.preprocess.Preprocessors.modifyUris; |
||||||
|
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; |
||||||
|
|
||||||
|
@SpringBootTest(classes = KacAppApplication.class) |
||||||
|
@ExtendWith({RestDocumentationExtension.class}) |
||||||
|
public class BaseTest { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
protected WebApplicationContext webApplicationContext; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
protected UserAccountService userAccountService; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
protected BaseUserDetailsService baseUserDetailsService; |
||||||
|
|
||||||
|
public MockMvc mockMvc; |
||||||
|
|
||||||
|
protected final String CREATE_PASSWORD = "palnet!234"; |
||||||
|
|
||||||
|
@BeforeEach |
||||||
|
public void setUpAll(RestDocumentationContextProvider restDocumentationContextProvider) throws ServletException { |
||||||
|
DelegatingFilterProxy delegateProxyFilter = new DelegatingFilterProxy(); |
||||||
|
delegateProxyFilter.init(new MockFilterConfig(webApplicationContext.getServletContext(), BeanIds.SPRING_SECURITY_FILTER_CHAIN)); |
||||||
|
|
||||||
|
|
||||||
|
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) // @Autowired로 빈주입 받은 context
|
||||||
|
.addFilters(new CharacterEncodingFilter("UTF-8", true), delegateProxyFilter) // UTF-8 인코딩 필터, SecurityFilter
|
||||||
|
.apply( |
||||||
|
MockMvcRestDocumentation.documentationConfiguration(restDocumentationContextProvider) |
||||||
|
.operationPreprocessors() |
||||||
|
.withRequestDefaults( |
||||||
|
modifyUris().scheme("http").host("localhost").port(8080), prettyPrint() // URL 정보를 넣어주시면 됩니다.
|
||||||
|
) |
||||||
|
.withResponseDefaults( |
||||||
|
prettyPrint() |
||||||
|
) |
||||||
|
) |
||||||
|
.build(); |
||||||
|
} |
||||||
|
|
||||||
|
protected String getUserToken(){ |
||||||
|
|
||||||
|
String username = "TEST_" + System.currentTimeMillis(); |
||||||
|
|
||||||
|
String jsonRQ = """ |
||||||
|
{ |
||||||
|
"cstrmDivCd" : "MEMBER", |
||||||
|
"cstrmStatusCd" : "ACTIVE", |
||||||
|
"userId" : "%s", |
||||||
|
"authId" : "USER", |
||||||
|
"siteCode" : "DRONE", |
||||||
|
"userPswd" : "%s", |
||||||
|
"joinCrtfyCd" : "HP_CRTFD", |
||||||
|
"memberName" : "이경도", |
||||||
|
"brthdyDate" : "1999-09-07", |
||||||
|
"email" : "lkd9125@naver.com", |
||||||
|
"hpno" : "01083703435", |
||||||
|
"clncd" : "+82" |
||||||
|
} |
||||||
|
""".formatted(username, this.CREATE_PASSWORD); |
||||||
|
|
||||||
|
FormRegisterRQ rq = new FormRegisterRQ(); |
||||||
|
rq.setCstrmDivCd("MEMBER"); |
||||||
|
rq.setCstrmStatusCd("ACTIVE"); |
||||||
|
rq.setUserId(username); |
||||||
|
rq.setAuthId("USER"); |
||||||
|
rq.setSiteCode("DRONE"); |
||||||
|
rq.setUserPswd("palnet!234"); |
||||||
|
rq.setJoinCrtfyCd("HP_CRTFD"); |
||||||
|
rq.setMemberName("이경도"); |
||||||
|
rq.setBrthdyDate(LocalDate.of(1999, 9, 7)); |
||||||
|
rq.setEmail("lkd9125@naver.com"); |
||||||
|
rq.setHpno("01083703435"); |
||||||
|
rq.setClncd("+82"); |
||||||
|
|
||||||
|
try{ |
||||||
|
userAccountService.createUser(rq); |
||||||
|
} catch (Exception e){ |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
|
||||||
|
BaseUserDetails userDetails = (BaseUserDetails) baseUserDetailsService.loadUserByUsername(username); |
||||||
|
|
||||||
|
return JwtUtil.makeAuthToken(userDetails); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,600 @@ |
|||||||
|
package kr.co.palnet.kac.com.code; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.BaseTest; |
||||||
|
import kr.co.palnet.kac.api.v1.common.code.model.FormCodeGroupRQ; |
||||||
|
import kr.co.palnet.kac.api.v1.common.code.model.FormCodeLangRQ; |
||||||
|
import kr.co.palnet.kac.api.v1.common.code.model.FormCodeRQ; |
||||||
|
import kr.co.palnet.kac.api.v1.common.code.service.ComCodeService; |
||||||
|
import org.junit.jupiter.api.DisplayName; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.http.MediaType; |
||||||
|
import org.springframework.restdocs.payload.JsonFieldType; |
||||||
|
import org.springframework.transaction.annotation.Propagation; |
||||||
|
import org.springframework.transaction.annotation.Transactional; |
||||||
|
|
||||||
|
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; |
||||||
|
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; |
||||||
|
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; |
||||||
|
import static org.springframework.restdocs.payload.PayloadDocumentation.*; |
||||||
|
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; |
||||||
|
import static org.springframework.restdocs.request.RequestDocumentation.queryParameters; |
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; |
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; |
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
||||||
|
|
||||||
|
|
||||||
|
public class ComnCodeControllerTest extends BaseTest { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private ComCodeService comCodeService; |
||||||
|
|
||||||
|
private final String BASE_URL = "/v1/com/code"; |
||||||
|
|
||||||
|
@DisplayName("언어코드 삭제") |
||||||
|
@Test |
||||||
|
public void deleteLang() throws Exception { |
||||||
|
String groupCd = "NEW_GROUP001"; |
||||||
|
String cdId = "NEW_CODE001"; |
||||||
|
String langDivCd = "ko_KR"; |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
delete(this.BASE_URL + "/lang?groupCd=" + groupCd + "&cdId=" + cdId + "&langDivCd=" + langDivCd) |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"com/code/lang/delete", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
queryParameters( |
||||||
|
parameterWithName("groupCd").description("그룹 아이디"), |
||||||
|
parameterWithName("cdId").description("코드 아이디"), |
||||||
|
parameterWithName("langDivCd").description("삭제할 언어코드") |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("코드 삭제") |
||||||
|
@Test |
||||||
|
public void deleteCode() throws Exception { |
||||||
|
String groupCd = "NEW_GROUP001"; |
||||||
|
String cdId = "NEW_CODE001"; |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
delete(this.BASE_URL + "/code?groupCd=" + groupCd + "&cdId=" + cdId) |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"com/code/code/delete", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
queryParameters( |
||||||
|
parameterWithName("groupCd").description("그룹 아이디"), |
||||||
|
parameterWithName("cdId").description("코드 아이디") |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("그룹 삭제") |
||||||
|
@Test |
||||||
|
public void deleteCodeGroup() throws Exception { |
||||||
|
|
||||||
|
String deleteGroupCd = "NEW_GROUP001"; |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
delete(this.BASE_URL + "/group?groupCd=" + deleteGroupCd) |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"com/code/group/delete", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
queryParameters( |
||||||
|
parameterWithName("groupCd").description("그룹 아이디") |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("코드의 언어코드 수정") |
||||||
|
@Test |
||||||
|
@Transactional |
||||||
|
public void updateCodeLang() throws Exception { |
||||||
|
|
||||||
|
String randomNm = "NEW_GROUP_" + System.currentTimeMillis(); |
||||||
|
randomNm = randomNm.substring(0, 20); |
||||||
|
|
||||||
|
FormCodeGroupRQ groupRq = FormCodeGroupRQ.builder().groupCd(randomNm).siteCd("KAC").groupCdNm("신규그룹001").rm("비고....").build(); |
||||||
|
comCodeService.createCodeGroup(groupRq); |
||||||
|
|
||||||
|
FormCodeRQ codeRq = FormCodeRQ.builder().groupCd(randomNm).cdId("NEW_CODE001").upperCd(null).sortOrdr(0).addInfoValue("추가!!").useYn("Y").build(); |
||||||
|
comCodeService.createCode(codeRq); |
||||||
|
|
||||||
|
FormCodeLangRQ langRq = FormCodeLangRQ.builder().groupCd(randomNm).cdId("NEW_CODE001").langDivCd("ko_KR").cdNm("신규코드001").rm("비고....").build(); |
||||||
|
comCodeService.createCodeLang(langRq); |
||||||
|
|
||||||
|
String jsonRQ = """ |
||||||
|
{ |
||||||
|
"groupCd": "%s", |
||||||
|
"cdId": "NEW_CODE001", |
||||||
|
"langDivCd": "ko_KR", |
||||||
|
"cdNm": "신규코드001", |
||||||
|
"rm": "수정..." |
||||||
|
} |
||||||
|
""".formatted(randomNm); |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
put(this.BASE_URL + "/lang") |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.content(jsonRQ) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"com/code/lang/update", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
requestFields( |
||||||
|
fieldWithPath("groupCd").type(JsonFieldType.STRING).description("그룹코드"), |
||||||
|
fieldWithPath("cdId").type(JsonFieldType.STRING).description("코드 아이디"), |
||||||
|
fieldWithPath("langDivCd").type(JsonFieldType.STRING).description("언어코드"), |
||||||
|
fieldWithPath("cdNm").type(JsonFieldType.STRING).description("코드이름[언어별]"), |
||||||
|
fieldWithPath("rm").type(JsonFieldType.STRING).description("비고") |
||||||
|
), |
||||||
|
responseFields( |
||||||
|
fieldWithPath("groupCd").type(JsonFieldType.STRING).description("그룹코드"), |
||||||
|
fieldWithPath("cdId").type(JsonFieldType.STRING).description("코드 아이디"), |
||||||
|
fieldWithPath("langDivCd").type(JsonFieldType.STRING).description("언어코드"), |
||||||
|
fieldWithPath("cdNm").type(JsonFieldType.STRING).description("코드이름[언어별]"), |
||||||
|
fieldWithPath("rm").type(JsonFieldType.STRING).description("비고"), |
||||||
|
fieldWithPath("createUserId").type(JsonFieldType.STRING).description("등록한 유저 아이디"), |
||||||
|
fieldWithPath("createDt").type(JsonFieldType.STRING).description("등록일시"), |
||||||
|
fieldWithPath("updateUserId").type(JsonFieldType.STRING).description("수정한 유저 아이디"), |
||||||
|
fieldWithPath("updateDt").type(JsonFieldType.STRING).description("수정일시") |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("코드 수정") |
||||||
|
@Test |
||||||
|
@Transactional |
||||||
|
public void updateCode() throws Exception { |
||||||
|
|
||||||
|
String randomNm = "NEW_GROUP_" + System.currentTimeMillis(); |
||||||
|
randomNm = randomNm.substring(0, 20); |
||||||
|
|
||||||
|
FormCodeGroupRQ groupRq = FormCodeGroupRQ.builder().groupCd(randomNm).siteCd("KAC").groupCdNm("신규그룹001").rm("비고....").build(); |
||||||
|
comCodeService.createCodeGroup(groupRq); |
||||||
|
|
||||||
|
FormCodeRQ codeRq = FormCodeRQ.builder().groupCd(randomNm).cdId("NEW_CODE001").upperCd(null).sortOrdr(0).addInfoValue("추가!!").useYn("Y").build(); |
||||||
|
comCodeService.createCode(codeRq); |
||||||
|
|
||||||
|
FormCodeLangRQ langRq = FormCodeLangRQ.builder().groupCd(randomNm).cdId("NEW_CODE001").langDivCd("ko_KR").cdNm("신규코드001").rm("비고....").build(); |
||||||
|
comCodeService.createCodeLang(langRq); |
||||||
|
|
||||||
|
String jsonRQ = """ |
||||||
|
{ |
||||||
|
"groupCd": "%s", |
||||||
|
"cdId": "NEW_CODE001", |
||||||
|
"sortOrdr": 0, |
||||||
|
"addInfoValue": "수정!!", |
||||||
|
"useYn": "Y" |
||||||
|
} |
||||||
|
""".formatted(randomNm); |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
put(this.BASE_URL + "/code") |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.content(jsonRQ) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"com/code/code/update", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
requestFields( |
||||||
|
fieldWithPath("groupCd").type(JsonFieldType.STRING).description("그룹코드"), |
||||||
|
fieldWithPath("cdId").type(JsonFieldType.STRING).description("코드 아이디"), |
||||||
|
fieldWithPath("sortOrdr").type(JsonFieldType.NUMBER).description("정렬순서"), |
||||||
|
fieldWithPath("addInfoValue").type(JsonFieldType.STRING).description("추가사항"), |
||||||
|
fieldWithPath("useYn").type(JsonFieldType.STRING).description("사용여부") |
||||||
|
), |
||||||
|
responseFields( |
||||||
|
fieldWithPath("groupCd").type(JsonFieldType.STRING).description("그룹코드"), |
||||||
|
fieldWithPath("cdId").type(JsonFieldType.STRING).description("코드 아이디"), |
||||||
|
fieldWithPath("upperCd").type(JsonFieldType.STRING).description("상위 아이디").optional(), |
||||||
|
fieldWithPath("sortOrdr").type(JsonFieldType.NUMBER).description("정렬순서"), |
||||||
|
fieldWithPath("addInfoValue").type(JsonFieldType.STRING).description("추가사항"), |
||||||
|
fieldWithPath("useYn").type(JsonFieldType.STRING).description("사용여부"), |
||||||
|
fieldWithPath("createUserId").type(JsonFieldType.STRING).description("등록한 유저 아이디"), |
||||||
|
fieldWithPath("createDt").type(JsonFieldType.STRING).description("등록일시"), |
||||||
|
fieldWithPath("updateUserId").type(JsonFieldType.STRING).description("수정한 유저 아이디"), |
||||||
|
fieldWithPath("updateDt").type(JsonFieldType.STRING).description("수정일시") |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("그룹 수정") |
||||||
|
@Test |
||||||
|
@Transactional |
||||||
|
public void updateCodeGroup() throws Exception { |
||||||
|
|
||||||
|
String randomNm = "NEW_GROUP_" + System.currentTimeMillis(); |
||||||
|
randomNm = randomNm.substring(0, 20); |
||||||
|
|
||||||
|
FormCodeGroupRQ groupRq = FormCodeGroupRQ.builder().groupCd(randomNm).siteCd("KAC").groupCdNm("신규그룹001").rm("비고....").build(); |
||||||
|
comCodeService.createCodeGroup(groupRq); |
||||||
|
|
||||||
|
|
||||||
|
String jsonRQ = """ |
||||||
|
{ |
||||||
|
"groupCd": "%s", |
||||||
|
"siteCd": "KAC", |
||||||
|
"groupCdNm": "신규그룹001", |
||||||
|
"rm": "비고...." |
||||||
|
} |
||||||
|
""".formatted(randomNm); |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
put(this.BASE_URL + "/group") |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.content(jsonRQ) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"com/code/group/update", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
requestFields( |
||||||
|
fieldWithPath("groupCd").type(JsonFieldType.STRING).description("그룹코드"), |
||||||
|
fieldWithPath("siteCd").type(JsonFieldType.STRING).description("사이트코드"), |
||||||
|
fieldWithPath("groupCdNm").type(JsonFieldType.STRING).description("그룹이름"), |
||||||
|
fieldWithPath("rm").type(JsonFieldType.STRING).description("비고") |
||||||
|
), |
||||||
|
responseFields( |
||||||
|
fieldWithPath("groupCd").type(JsonFieldType.STRING).description("그룹코드"), |
||||||
|
fieldWithPath("siteCd").type(JsonFieldType.STRING).description("사이트코드"), |
||||||
|
fieldWithPath("groupCdNm").type(JsonFieldType.STRING).description("그룹이름"), |
||||||
|
fieldWithPath("rm").type(JsonFieldType.STRING).description("비고"), |
||||||
|
fieldWithPath("createUserId").type(JsonFieldType.STRING).description("등록한 유저 아이디"), |
||||||
|
fieldWithPath("createDt").type(JsonFieldType.STRING).description("등록일시"), |
||||||
|
fieldWithPath("updateUserId").type(JsonFieldType.STRING).description("수정한 유저 아이디"), |
||||||
|
fieldWithPath("updateDt").type(JsonFieldType.STRING).description("수정일시") |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("코드의 언어코드 추가") |
||||||
|
@Test |
||||||
|
@Transactional |
||||||
|
public void createCodeLang() throws Exception { |
||||||
|
|
||||||
|
String langDivCd = "ko_KR"; |
||||||
|
|
||||||
|
String randomNm = "NEW_GROUP_" + System.currentTimeMillis(); |
||||||
|
randomNm = randomNm.substring(0, 20); |
||||||
|
|
||||||
|
FormCodeGroupRQ groupRq = FormCodeGroupRQ.builder().groupCd(randomNm).siteCd("KAC").groupCdNm("신규그룹001").rm("비고....").build(); |
||||||
|
comCodeService.createCodeGroup(groupRq); |
||||||
|
|
||||||
|
FormCodeRQ codeRq = FormCodeRQ.builder().groupCd(randomNm).cdId("NEW_CODE001").upperCd(null).sortOrdr(0).addInfoValue("추가!!").useYn("Y").build(); |
||||||
|
comCodeService.createCode(codeRq); |
||||||
|
|
||||||
|
String jsonRQ = """ |
||||||
|
{ |
||||||
|
"groupCd": "%s", |
||||||
|
"cdId": "NEW_CODE001", |
||||||
|
"langDivCd": "%s", |
||||||
|
"cdNm": "신규코드001", |
||||||
|
"rm": "비고...." |
||||||
|
} |
||||||
|
""".formatted(randomNm, langDivCd); |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
post(this.BASE_URL + "/lang") |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.content(jsonRQ) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"com/code/lang/create", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
requestFields( |
||||||
|
fieldWithPath("groupCd").type(JsonFieldType.STRING).description("그룹코드"), |
||||||
|
fieldWithPath("cdId").type(JsonFieldType.STRING).description("코드 아이디"), |
||||||
|
fieldWithPath("langDivCd").type(JsonFieldType.STRING).description("언어코드"), |
||||||
|
fieldWithPath("cdNm").type(JsonFieldType.STRING).description("코드이름[언어별]"), |
||||||
|
fieldWithPath("rm").type(JsonFieldType.STRING).description("비고") |
||||||
|
), |
||||||
|
responseFields( |
||||||
|
fieldWithPath("groupCd").type(JsonFieldType.STRING).description("그룹코드"), |
||||||
|
fieldWithPath("cdId").type(JsonFieldType.STRING).description("코드 아이디"), |
||||||
|
fieldWithPath("langDivCd").type(JsonFieldType.STRING).description("언어코드"), |
||||||
|
fieldWithPath("cdNm").type(JsonFieldType.STRING).description("코드이름[언어별]"), |
||||||
|
fieldWithPath("rm").type(JsonFieldType.STRING).description("비고"), |
||||||
|
fieldWithPath("createUserId").type(JsonFieldType.STRING).description("등록한 유저 아이디"), |
||||||
|
fieldWithPath("createDt").type(JsonFieldType.STRING).description("등록일시"), |
||||||
|
fieldWithPath("updateUserId").type(JsonFieldType.STRING).description("수정한 유저 아이디"), |
||||||
|
fieldWithPath("updateDt").type(JsonFieldType.STRING).description("수정일시") |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("코드 추가") |
||||||
|
@Test |
||||||
|
@Transactional |
||||||
|
public void createCode() throws Exception { |
||||||
|
String codeNm = "NEW_CODE001"; |
||||||
|
|
||||||
|
String randomNm = "NEW_GROUP_" + System.currentTimeMillis(); |
||||||
|
randomNm = randomNm.substring(0, 20); |
||||||
|
|
||||||
|
FormCodeGroupRQ groupRq = FormCodeGroupRQ.builder().groupCd(randomNm).siteCd("KAC").groupCdNm("신규그룹001").rm("비고....").build(); |
||||||
|
comCodeService.createCodeGroup(groupRq); |
||||||
|
|
||||||
|
String jsonRQ = """ |
||||||
|
{ |
||||||
|
"groupCd": "%s", |
||||||
|
"cdId": "%s", |
||||||
|
"sortOrdr": 0, |
||||||
|
"addInfoValue": "추가!!", |
||||||
|
"useYn": "Y" |
||||||
|
} |
||||||
|
""".formatted(randomNm, codeNm); |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
post(this.BASE_URL + "/code") |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.content(jsonRQ) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"com/code/code/create", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
requestFields( |
||||||
|
fieldWithPath("groupCd").type(JsonFieldType.STRING).description("그룹코드"), |
||||||
|
fieldWithPath("cdId").type(JsonFieldType.STRING).description("코드 아이디"), |
||||||
|
fieldWithPath("sortOrdr").type(JsonFieldType.NUMBER).description("정렬순서"), |
||||||
|
fieldWithPath("addInfoValue").type(JsonFieldType.STRING).description("추가사항"), |
||||||
|
fieldWithPath("useYn").type(JsonFieldType.STRING).description("사용여부") |
||||||
|
), |
||||||
|
responseFields( |
||||||
|
fieldWithPath("groupCd").type(JsonFieldType.STRING).description("그룹코드"), |
||||||
|
fieldWithPath("cdId").type(JsonFieldType.STRING).description("코드 아이디"), |
||||||
|
fieldWithPath("upperCd").type(JsonFieldType.STRING).description("상위 아이디").optional(), |
||||||
|
fieldWithPath("sortOrdr").type(JsonFieldType.NUMBER).description("정렬순서"), |
||||||
|
fieldWithPath("addInfoValue").type(JsonFieldType.STRING).description("추가사항"), |
||||||
|
fieldWithPath("useYn").type(JsonFieldType.STRING).description("사용여부"), |
||||||
|
fieldWithPath("createUserId").type(JsonFieldType.STRING).description("등록한 유저 아이디"), |
||||||
|
fieldWithPath("createDt").type(JsonFieldType.STRING).description("등록일시"), |
||||||
|
fieldWithPath("updateUserId").type(JsonFieldType.STRING).description("수정한 유저 아이디"), |
||||||
|
fieldWithPath("updateDt").type(JsonFieldType.STRING).description("수정일시") |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("코드그룹 추가") |
||||||
|
@Test |
||||||
|
@Transactional |
||||||
|
public void createCodeGroup() throws Exception { |
||||||
|
|
||||||
|
String randomNm = "NEW_GROUP_" + System.currentTimeMillis(); |
||||||
|
randomNm = randomNm.substring(0, 20); |
||||||
|
|
||||||
|
String jsonRQ = """ |
||||||
|
{ |
||||||
|
"groupCd": "%s", |
||||||
|
"siteCd": "KAC", |
||||||
|
"groupCdNm": "신규그룹001", |
||||||
|
"rm": "비고...." |
||||||
|
} |
||||||
|
""".formatted(randomNm); |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
post(this.BASE_URL + "/group") |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.content(jsonRQ) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"com/code/group/create", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
requestFields( |
||||||
|
fieldWithPath("groupCd").type(JsonFieldType.STRING).description("그룹코드"), |
||||||
|
fieldWithPath("siteCd").type(JsonFieldType.STRING).description("사이트코드"), |
||||||
|
fieldWithPath("groupCdNm").type(JsonFieldType.STRING).description("그룹이름"), |
||||||
|
fieldWithPath("rm").type(JsonFieldType.STRING).description("비고") |
||||||
|
), |
||||||
|
responseFields( |
||||||
|
fieldWithPath("groupCd").type(JsonFieldType.STRING).description("그룹코드"), |
||||||
|
fieldWithPath("siteCd").type(JsonFieldType.STRING).description("사이트코드"), |
||||||
|
fieldWithPath("groupCdNm").type(JsonFieldType.STRING).description("그룹이름"), |
||||||
|
fieldWithPath("rm").type(JsonFieldType.STRING).description("비고"), |
||||||
|
fieldWithPath("createUserId").type(JsonFieldType.STRING).description("등록한 유저 아이디"), |
||||||
|
fieldWithPath("createDt").type(JsonFieldType.STRING).description("등록일시"), |
||||||
|
fieldWithPath("updateUserId").type(JsonFieldType.STRING).description("수정한 유저 아이디"), |
||||||
|
fieldWithPath("updateDt").type(JsonFieldType.STRING).description("수정일시") |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("모든 코드 조회") |
||||||
|
@Test |
||||||
|
@Transactional(propagation = Propagation.SUPPORTS) |
||||||
|
public void getAllCodeByGroup() throws Exception { |
||||||
|
|
||||||
|
String randomNm = "NEW_GROUP_" + System.currentTimeMillis(); |
||||||
|
randomNm = randomNm.substring(0, 20); |
||||||
|
|
||||||
|
FormCodeGroupRQ groupRq = FormCodeGroupRQ.builder().groupCd(randomNm).siteCd("KAC").groupCdNm("신규그룹001").rm("비고....").build(); |
||||||
|
comCodeService.createCodeGroup(groupRq); |
||||||
|
|
||||||
|
FormCodeRQ codeRq = FormCodeRQ.builder().groupCd(randomNm).cdId("NEW_CODE001").upperCd(null).sortOrdr(0).addInfoValue("추가!!").useYn("Y").build(); |
||||||
|
comCodeService.createCode(codeRq); |
||||||
|
|
||||||
|
FormCodeLangRQ langRq = FormCodeLangRQ.builder().groupCd(randomNm).cdId("NEW_CODE001").langDivCd("ko_KR").cdNm("신규코드001").rm("비고....").build(); |
||||||
|
comCodeService.createCodeLang(langRq); |
||||||
|
|
||||||
|
String langDivCd = "ko_KR"; |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
get(this.BASE_URL + "/code") |
||||||
|
.param("groupCd", randomNm) |
||||||
|
.param("langDivCd", langDivCd) |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"com/code/code", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
queryParameters( |
||||||
|
parameterWithName("groupCd").description("그룹코드"), |
||||||
|
parameterWithName("langDivCd").description("언어코드") |
||||||
|
), |
||||||
|
responseFields( |
||||||
|
fieldWithPath("[].groupCd").type(JsonFieldType.STRING).description("코드의 그룹").optional(), |
||||||
|
fieldWithPath("[].cdId").type(JsonFieldType.STRING).description("코드의 ID").optional(), |
||||||
|
fieldWithPath("[].cdNm").type(JsonFieldType.STRING).description("코드의 이름").optional(), |
||||||
|
fieldWithPath("[].upperCd").type(JsonFieldType.STRING).description("상위 코드의 이름").optional(), |
||||||
|
fieldWithPath("[].sortOrdr").type(JsonFieldType.NUMBER).description("코드의 정렬순서").optional(), |
||||||
|
fieldWithPath("[].addInfoValue").type(JsonFieldType.STRING).description("코드의 추가 밸류").optional(), |
||||||
|
fieldWithPath("[].children").type(JsonFieldType.STRING).description("코드의 하위요소").optional() |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
|
||||||
|
// comCodeService.deleteLang(randomNm, "NEW_CODE001", "ko_KR");
|
||||||
|
// comCodeService.deleteCode(randomNm, "NEW_CODE001");
|
||||||
|
comCodeService.deleteCodeGroup(randomNm); |
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("모든 그룹과 코드 조회") |
||||||
|
@Test |
||||||
|
@Transactional |
||||||
|
public void getAllGroupCode() throws Exception { |
||||||
|
|
||||||
|
String randomNm = "NEW_GROUP_" + System.currentTimeMillis(); |
||||||
|
randomNm = randomNm.substring(0, 20); |
||||||
|
|
||||||
|
FormCodeGroupRQ groupRq = FormCodeGroupRQ.builder().groupCd(randomNm).siteCd("KAC").groupCdNm("신규그룹001").rm("비고....").build(); |
||||||
|
comCodeService.createCodeGroup(groupRq); |
||||||
|
|
||||||
|
FormCodeRQ codeRq = FormCodeRQ.builder().groupCd(randomNm).cdId("NEW_CODE001").upperCd(null).sortOrdr(0).addInfoValue("추가!!").useYn("Y").build(); |
||||||
|
comCodeService.createCode(codeRq); |
||||||
|
|
||||||
|
FormCodeLangRQ langRq = FormCodeLangRQ.builder().groupCd(randomNm).cdId("NEW_CODE001").langDivCd("ko_KR").cdNm("신규코드001").rm("비고....").build(); |
||||||
|
comCodeService.createCodeLang(langRq); |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
get(this.BASE_URL + "/group") |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"com/code/group", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
responseFields( |
||||||
|
fieldWithPath("[].groupCd").type(JsonFieldType.STRING).description("그룹 코드").optional(), |
||||||
|
fieldWithPath("[].siteCd").type(JsonFieldType.STRING).description("사이트 코드").optional(), |
||||||
|
fieldWithPath("[].groupCdNm").type(JsonFieldType.STRING).description("그룹 명").optional(), |
||||||
|
fieldWithPath("[].rm").type(JsonFieldType.STRING).description("비고").optional(), |
||||||
|
fieldWithPath("[].codeList").type(JsonFieldType.ARRAY).description("그룹에 포함된 코드 리스트").optional() |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("모든 그룹 조회") |
||||||
|
@Test |
||||||
|
@Transactional |
||||||
|
public void getAllGroup() throws Exception { |
||||||
|
|
||||||
|
String randomNm = "NEW_GROUP_" + System.currentTimeMillis(); |
||||||
|
randomNm = randomNm.substring(0, 20); |
||||||
|
|
||||||
|
FormCodeGroupRQ groupRq = FormCodeGroupRQ.builder().groupCd(randomNm).siteCd("KAC").groupCdNm("신규그룹001").rm("비고....").build(); |
||||||
|
comCodeService.createCodeGroup(groupRq); |
||||||
|
|
||||||
|
FormCodeRQ codeRq = FormCodeRQ.builder().groupCd(randomNm).cdId("NEW_CODE001").upperCd(null).sortOrdr(0).addInfoValue("추가!!").useYn("Y").build(); |
||||||
|
comCodeService.createCode(codeRq); |
||||||
|
|
||||||
|
FormCodeLangRQ langRq = FormCodeLangRQ.builder().groupCd(randomNm).cdId("NEW_CODE001").langDivCd("ko_KR").cdNm("신규코드001").rm("비고....").build(); |
||||||
|
comCodeService.createCodeLang(langRq); |
||||||
|
|
||||||
|
String siteCd = "KAC"; |
||||||
|
String langDivCd = "ko_KR"; |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
get(this.BASE_URL + "/all") |
||||||
|
.param("siteCd", siteCd) |
||||||
|
.param("langDivCd", langDivCd) |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"com/code/all", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
queryParameters( |
||||||
|
parameterWithName("siteCd").description("사이트코드"), |
||||||
|
parameterWithName("langDivCd").description("언어코드") |
||||||
|
), |
||||||
|
responseFields( |
||||||
|
fieldWithPath("[].groupCd").type(JsonFieldType.STRING).description("그룹 코드").optional(), |
||||||
|
fieldWithPath("[].siteCd").type(JsonFieldType.STRING).description("사이트 코드").optional(), |
||||||
|
fieldWithPath("[].groupCdNm").type(JsonFieldType.STRING).description("그룹 명").optional(), |
||||||
|
fieldWithPath("[].rm").type(JsonFieldType.STRING).description("비고").optional(), |
||||||
|
fieldWithPath("[].codeList").type(JsonFieldType.ARRAY).description("그룹에 포함된 코드 리스트").optional(), |
||||||
|
fieldWithPath("[].codeList[].groupCd").type(JsonFieldType.STRING).description("코드의 그룹").optional(), |
||||||
|
fieldWithPath("[].codeList[].cdId").type(JsonFieldType.STRING).description("코드의 ID").optional(), |
||||||
|
fieldWithPath("[].codeList[].cdNm").type(JsonFieldType.STRING).description("코드의 이름").optional(), |
||||||
|
fieldWithPath("[].codeList[].upperCd").type(JsonFieldType.STRING).description("상위 코드의 이름").optional(), |
||||||
|
fieldWithPath("[].codeList[].sortOrdr").type(JsonFieldType.NUMBER).description("코드의 정렬순서").optional(), |
||||||
|
fieldWithPath("[].codeList[].addInfoValue").type(JsonFieldType.STRING).description("코드의 추가 밸류").optional(), |
||||||
|
fieldWithPath("[].codeList[].children").type(JsonFieldType.STRING).description("코드의 하위요소").optional() |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,228 @@ |
|||||||
|
package kr.co.palnet.kac.user.account; |
||||||
|
|
||||||
|
|
||||||
|
import kr.co.palnet.kac.BaseTest; |
||||||
|
import kr.co.palnet.kac.api.v1.user.account.service.UserAccountService; |
||||||
|
import org.junit.jupiter.api.DisplayName; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.http.MediaType; |
||||||
|
import org.springframework.restdocs.headers.HeaderDocumentation; |
||||||
|
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; |
||||||
|
import org.springframework.restdocs.payload.JsonFieldType; |
||||||
|
import org.springframework.transaction.annotation.Transactional; |
||||||
|
|
||||||
|
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; |
||||||
|
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; |
||||||
|
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; |
||||||
|
import static org.springframework.restdocs.payload.PayloadDocumentation.*; |
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; |
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; |
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
||||||
|
|
||||||
|
public class UserAccountControllerTest extends BaseTest { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private UserAccountService userAccountService; |
||||||
|
|
||||||
|
private final String BASE_URL = "/v1/user/account"; |
||||||
|
|
||||||
|
private final String GRANT_TYPE = "Bearer"; |
||||||
|
|
||||||
|
@DisplayName("회원정보 변경") |
||||||
|
@Test |
||||||
|
@Transactional |
||||||
|
public void updateUser() throws Exception{ |
||||||
|
String jsonRQ = """ |
||||||
|
{ |
||||||
|
"email" : "lkd9125@naver.com", |
||||||
|
"hpno" : "01083703435" |
||||||
|
} |
||||||
|
"""; |
||||||
|
|
||||||
|
String token = this.getUserToken(); |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
put(this.BASE_URL + "/update") |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.content(jsonRQ) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.header("Authorization", GRANT_TYPE + " " + token) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"user/account/update", |
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
HeaderDocumentation.requestHeaders( |
||||||
|
HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]") |
||||||
|
), |
||||||
|
requestFields( |
||||||
|
fieldWithPath("email").type(JsonFieldType.STRING).description("바꿀 이메일").optional(), |
||||||
|
fieldWithPath("hpno").type(JsonFieldType.STRING).description("바꿀 전화번호").optional() |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("암호 변경") |
||||||
|
@Test |
||||||
|
@Transactional |
||||||
|
public void updatePassword() throws Exception{ |
||||||
|
|
||||||
|
String jsonRQ = """ |
||||||
|
{ |
||||||
|
"userPswd" : "%s", |
||||||
|
"newPswd" : "palnet!234", |
||||||
|
"newPswdConfirm" : "palnet!234" |
||||||
|
} |
||||||
|
""".formatted(this.CREATE_PASSWORD); |
||||||
|
|
||||||
|
String token = this.getUserToken(); |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
put(this.BASE_URL + "/update/pswd") |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.content(jsonRQ) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.header("Authorization", GRANT_TYPE + " " + token) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"user/account/update/pswd", |
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
HeaderDocumentation.requestHeaders( |
||||||
|
HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]") |
||||||
|
), |
||||||
|
requestFields( |
||||||
|
fieldWithPath("userPswd").type(JsonFieldType.STRING).description("현재 암호").optional(), |
||||||
|
fieldWithPath("newPswd").type(JsonFieldType.STRING).description("바뀔 암호"), |
||||||
|
fieldWithPath("newPswdConfirm").type(JsonFieldType.STRING).description("바뀔 암호 확인") |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("회원정보 조회") |
||||||
|
@Test |
||||||
|
@Transactional |
||||||
|
public void getUserInfo() throws Exception{ |
||||||
|
String token = this.getUserToken(); |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
get(this.BASE_URL + "/profile") |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.header("Authorization", GRANT_TYPE + " " + token) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"user/account/profile", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
HeaderDocumentation.requestHeaders( |
||||||
|
HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]") |
||||||
|
), |
||||||
|
responseFields( |
||||||
|
fieldWithPath("memberName").type(JsonFieldType.STRING).description("회원 이름"), |
||||||
|
fieldWithPath("brthdyDate").type(JsonFieldType.STRING).description("생년월일"), |
||||||
|
fieldWithPath("cntryCd").type(JsonFieldType.STRING).description("국적 구분코드"), |
||||||
|
fieldWithPath("email").type(JsonFieldType.STRING).description("이메일"), |
||||||
|
fieldWithPath("hpno").type(JsonFieldType.STRING).description("휴대폰 번호"), |
||||||
|
fieldWithPath("userId").type(JsonFieldType.STRING).description("아이디"), |
||||||
|
fieldWithPath("updateDt").type(JsonFieldType.STRING).description("수정일시"), |
||||||
|
fieldWithPath("updateuserId").type(JsonFieldType.STRING).description("수정자 아이디"), |
||||||
|
fieldWithPath("cptAuthCode").type(JsonFieldType.STRING).description("각 항청 구분코드") |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("회원탈퇴") |
||||||
|
@Test |
||||||
|
@Transactional |
||||||
|
public void deleteUser() throws Exception{ |
||||||
|
String token = this.getUserToken(); |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
RestDocumentationRequestBuilders.delete(this.BASE_URL + "/delete") |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.header("Authorization", GRANT_TYPE + " " + token) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"user/account/delete", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
HeaderDocumentation.requestHeaders( |
||||||
|
HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]") |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isOk()); |
||||||
|
} |
||||||
|
|
||||||
|
@DisplayName("회원가입") |
||||||
|
@Test |
||||||
|
@Transactional |
||||||
|
public void register() throws Exception{ |
||||||
|
|
||||||
|
String username = "TEST_" + System.currentTimeMillis(); |
||||||
|
|
||||||
|
String jsonRQ = """ |
||||||
|
{ |
||||||
|
"cstrmDivCd" : "MEMBER", |
||||||
|
"cstrmStatusCd" : "ACTIVE", |
||||||
|
"userId" : "%s", |
||||||
|
"authId" : "USER", |
||||||
|
"siteCode" : "DRONE", |
||||||
|
"userPswd" : "palnet!234", |
||||||
|
"joinCrtfyCd" : "HP_CRTFD", |
||||||
|
"memberName" : "이경도", |
||||||
|
"brthdyDate" : "1999-09-07", |
||||||
|
"email" : "lkd9125@naver.com", |
||||||
|
"hpno" : "01083703435", |
||||||
|
"clncd" : "+82" |
||||||
|
} |
||||||
|
""".formatted(username); |
||||||
|
|
||||||
|
this.mockMvc.perform( |
||||||
|
post(this.BASE_URL + "/register") |
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
.content(jsonRQ) |
||||||
|
.accept(MediaType.APPLICATION_JSON_VALUE) |
||||||
|
) |
||||||
|
.andDo(print()) |
||||||
|
.andDo( |
||||||
|
document( |
||||||
|
"user/account/register", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름
|
||||||
|
preprocessResponse(prettyPrint()), |
||||||
|
requestFields( |
||||||
|
fieldWithPath("cstrmDivCd").type(JsonFieldType.STRING).description("회원타입 코드"), |
||||||
|
fieldWithPath("cstrmStatusCd").type(JsonFieldType.STRING).description("회원 활성화 코드"), |
||||||
|
fieldWithPath("userId").type(JsonFieldType.STRING).description("아이디"), |
||||||
|
fieldWithPath("authId").type(JsonFieldType.STRING).description("권한 값"), |
||||||
|
fieldWithPath("siteCode").type(JsonFieldType.STRING).description("사이트 코드"), |
||||||
|
fieldWithPath("userPswd").type(JsonFieldType.STRING).description("암호"), |
||||||
|
fieldWithPath("joinCrtfyCd").type(JsonFieldType.STRING).description("가입인증 분류 코드"), |
||||||
|
fieldWithPath("memberName").type(JsonFieldType.STRING).description("이름"), |
||||||
|
fieldWithPath("brthdyDate").type(JsonFieldType.STRING).description("생년월일"), |
||||||
|
fieldWithPath("email").type(JsonFieldType.STRING).description("이메일"), |
||||||
|
fieldWithPath("hpno").type(JsonFieldType.STRING).description("휴대폰 번호"), |
||||||
|
fieldWithPath("clncd").type(JsonFieldType.STRING).description("휴대폰 국가번호"), |
||||||
|
fieldWithPath("terms").type(JsonFieldType.ARRAY).description("동의 약관 리스트").optional(), |
||||||
|
fieldWithPath("terms[].termsSno").type(JsonFieldType.NUMBER).description("약관 식별번호"), |
||||||
|
fieldWithPath("terms[].agreeYn").type(JsonFieldType.STRING).description("약관 동의여부") |
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
.andExpect(status().isCreated()); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
.+{{path}}+ |
||||||
|
|=== |
||||||
|
|파라미터|설명|필수 |
||||||
|
|
||||||
|
{{#parameters}} |
||||||
|
|{{#tableCellContent}}`+{{name}}+`{{/tableCellContent}} |
||||||
|
|{{#tableCellContent}}{{description}}{{/tableCellContent}} |
||||||
|
|{{#tableCellContent}}{{#optional}}false{{/optional}}{{^optional}}true{{/optional}}{{/tableCellContent}} |
||||||
|
|
||||||
|
{{/parameters}} |
||||||
|
|=== |
@ -0,0 +1,10 @@ |
|||||||
|
|=== |
||||||
|
|파라미터|설명|필수 |
||||||
|
|
||||||
|
{{#parameters}} |
||||||
|
|{{#tableCellContent}}`+{{name}}+`{{/tableCellContent}} |
||||||
|
|{{#tableCellContent}}{{description}}{{/tableCellContent}} |
||||||
|
|{{#tableCellContent}}{{#optional}}false{{/optional}}{{^optional}}true{{/optional}}{{/tableCellContent}} |
||||||
|
|
||||||
|
{{/parameters}} |
||||||
|
|=== |
@ -0,0 +1,12 @@ |
|||||||
|
|=== |
||||||
|
|파라미터|타입|설명|필수 |
||||||
|
|
||||||
|
{{#fields}} |
||||||
|
|
||||||
|
|{{#tableCellContent}}`+{{path}}+`{{/tableCellContent}} |
||||||
|
|{{#tableCellContent}}`+{{type}}+`{{/tableCellContent}} |
||||||
|
|{{#tableCellContent}}{{description}}{{/tableCellContent}} |
||||||
|
|{{#tableCellContent}}{{#optional}}false{{/optional}}{{^optional}}true{{/optional}}{{/tableCellContent}} |
||||||
|
|
||||||
|
{{/fields}} |
||||||
|
|=== |
@ -0,0 +1,10 @@ |
|||||||
|
|=== |
||||||
|
|파라미터|설명|필수 |
||||||
|
|
||||||
|
{{#headers}} |
||||||
|
|{{#tableCellContent}}`+{{name}}+`{{/tableCellContent}} |
||||||
|
|{{#tableCellContent}}{{description}}{{/tableCellContent}} |
||||||
|
|{{#tableCellContent}}{{#optional}}false{{/optional}}{{^optional}}true{{/optional}}{{/tableCellContent}} |
||||||
|
|
||||||
|
{{/headers}} |
||||||
|
|=== |
@ -0,0 +1,12 @@ |
|||||||
|
|=== |
||||||
|
|파라미터|타입|설명|필수 |
||||||
|
|
||||||
|
{{#fields}} |
||||||
|
|
||||||
|
|{{#tableCellContent}}`+{{path}}+`{{/tableCellContent}} |
||||||
|
|{{#tableCellContent}}`+{{type}}+`{{/tableCellContent}} |
||||||
|
|{{#tableCellContent}}{{description}}{{/tableCellContent}} |
||||||
|
|{{#tableCellContent}}{{#optional}}false{{/optional}}{{^optional}}true{{/optional}}{{/tableCellContent}} |
||||||
|
|
||||||
|
{{/fields}} |
||||||
|
|=== |
@ -0,0 +1,12 @@ |
|||||||
|
|
||||||
|
|
||||||
|
dependencies { |
||||||
|
// jpa |
||||||
|
implementation "$boot:spring-boot-starter-data-jpa" |
||||||
|
// querydsl |
||||||
|
implementation "com.querydsl:querydsl-jpa:5.0.0:jakarta" |
||||||
|
|
||||||
|
runtimeOnly "com.mysql:mysql-connector-j" |
||||||
|
implementation "org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4:1.16" |
||||||
|
} |
||||||
|
|
@ -0,0 +1,68 @@ |
|||||||
|
package kr.co.palnet.kac.config.db; |
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties; |
||||||
|
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings; |
||||||
|
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; |
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||||
|
import org.springframework.boot.jdbc.DataSourceBuilder; |
||||||
|
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.context.annotation.Primary; |
||||||
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; |
||||||
|
import org.springframework.orm.jpa.JpaTransactionManager; |
||||||
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; |
||||||
|
import org.springframework.transaction.PlatformTransactionManager; |
||||||
|
|
||||||
|
import javax.sql.DataSource; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Objects; |
||||||
|
|
||||||
|
@Configuration |
||||||
|
@EnableJpaRepositories( |
||||||
|
basePackages = "kr.co.palnet.kac.data.*.repository", |
||||||
|
entityManagerFactoryRef = "kacEntityManagerFactory", |
||||||
|
transactionManagerRef = "kacTransactionManager" |
||||||
|
) |
||||||
|
public class KacJpaConfig { |
||||||
|
|
||||||
|
private final JpaProperties jpaProperties; |
||||||
|
private final HibernateProperties hibernateProperties; |
||||||
|
|
||||||
|
public KacJpaConfig(JpaProperties jpaProperties, HibernateProperties hibernateProperties) { |
||||||
|
this.jpaProperties = jpaProperties; |
||||||
|
this.hibernateProperties = hibernateProperties; |
||||||
|
} |
||||||
|
|
||||||
|
@Bean(name = "kacDataSource") |
||||||
|
@Primary |
||||||
|
@ConfigurationProperties(prefix = "spring.datasource.pav-kac") |
||||||
|
public DataSource kacDataSource() { |
||||||
|
return DataSourceBuilder.create().build(); |
||||||
|
} |
||||||
|
|
||||||
|
@Bean(name = "kacEntityManagerFactory") |
||||||
|
@Primary |
||||||
|
public LocalContainerEntityManagerFactoryBean kacEntityManagerFactory(EntityManagerFactoryBuilder builder) { |
||||||
|
Map<String, Object> prop = hibernateProperties.determineHibernateProperties( |
||||||
|
jpaProperties.getProperties(), |
||||||
|
new HibernateSettings() |
||||||
|
); |
||||||
|
|
||||||
|
return builder.dataSource(kacDataSource()) |
||||||
|
.properties(prop) |
||||||
|
.packages( |
||||||
|
"kr.co.palnet.kac.data.**.model", |
||||||
|
"kr.co.palnet.kac.data.**.domain" |
||||||
|
) |
||||||
|
.persistenceUnit("kac") |
||||||
|
.build(); |
||||||
|
} |
||||||
|
|
||||||
|
@Bean(name = "kacTransactionManager") |
||||||
|
@Primary |
||||||
|
public PlatformTransactionManager kacTransactionManager(EntityManagerFactoryBuilder builder) { |
||||||
|
return new JpaTransactionManager(Objects.requireNonNull(kacEntityManagerFactory(builder).getObject())); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
package kr.co.palnet.kac.config.db; |
||||||
|
|
||||||
|
import com.querydsl.jpa.impl.JPAQueryFactory; |
||||||
|
import jakarta.persistence.EntityManager; |
||||||
|
import jakarta.persistence.PersistenceContext; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
|
||||||
|
@Configuration |
||||||
|
public class QueryDslConfig { |
||||||
|
|
||||||
|
@PersistenceContext |
||||||
|
private EntityManager entityManager; |
||||||
|
|
||||||
|
@Bean |
||||||
|
public JPAQueryFactory jpaQueryFactory() { |
||||||
|
return new JPAQueryFactory(entityManager); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
spring: |
||||||
|
jpa: |
||||||
|
hibernate: |
||||||
|
ddl-auto: none |
||||||
|
naming: |
||||||
|
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl |
||||||
|
datasource: |
||||||
|
pav-kac: |
||||||
|
driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy |
||||||
|
jdbc-url: jdbc:log4jdbc:mysql://localhost:13306/PAV_KAC?characterEncoding=UTF-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true |
||||||
|
username: kac |
||||||
|
password: palnet!234 |
@ -0,0 +1,6 @@ |
|||||||
|
|
||||||
|
dependencies { |
||||||
|
implementation "$boot:spring-boot-starter-web" |
||||||
|
implementation 'io.swagger.core.v3:swagger-annotations:2.2.20' |
||||||
|
} |
||||||
|
|
@ -0,0 +1,4 @@ |
|||||||
|
package kr.co.palnet.kac.core; |
||||||
|
|
||||||
|
public class Sample { |
||||||
|
} |
@ -0,0 +1,60 @@ |
|||||||
|
package kr.co.palnet.kac.core.code; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator; |
||||||
|
|
||||||
|
public enum ErrorCode { |
||||||
|
SUCCESS("1", "성공"), |
||||||
|
FAIL("-1", "실패"), |
||||||
|
NON_VALID_PARAMETER("VP001", "파라미터가 유효하지 않습니다."), |
||||||
|
INTERNAL_SERVER_ERROR("ER500", "내부 시스템 오류"), |
||||||
|
NOT_REGIST_ERROR_CODE("ER501", "등록되지 않은 오류 코드"), |
||||||
|
DATA_NOTFIND("DT001", "데이터 를 찾을수 없습니다."), |
||||||
|
DATA_DUPLICATE("DT002", "중복 데이터가 존재합니다."), |
||||||
|
DATA_NOT_CHANGE("DT003", "아직 갱신되지 않았습니다."), |
||||||
|
DATA_NO("DT003", "데이터 미존재"), |
||||||
|
DB_ERROR("DB001", "디비 처리중 오류"), |
||||||
|
PLAN_DATA_DUPLICATE("FT500", "이미 등록된 비행계획서의 비행구역과 비행시간이 일치합니다.\n비행시간 또는 비행구역을 수정하여 주십시오."), |
||||||
|
ARCRFT_DATA_DUPLICATE("FT501", "해당 기체는 다른 비행계획서에서 이미 등록된 기체입니다.\n비행시간 또는 기체 정보를 확인하여 주십시오."), |
||||||
|
PLAN_LAANC_NOT_VALID("FT502", "LAANC를 통과하지 못한 비행계획서입니다."), |
||||||
|
EXTERNAL_API_ERROR("EA500", "외부서버 호출에 실패하였습니다."), |
||||||
|
AUTH_NAUTHORIZED("AU001", "권한이 없습니다."), |
||||||
|
|
||||||
|
// TS 연동 ERROR CODE
|
||||||
|
TS_SUCCESS("TS200", "정상적으로 수신되었습니다."), |
||||||
|
TS_PARAM("TS300", "메시지 규격이 다릅니다."), // Json 포멧이 틀린 경우
|
||||||
|
TS_PARAM_REQUIRED("TS301", "필수 항목이 누락되었습니다."), // 필수 항목이 누락된 경우
|
||||||
|
TS_TYPE("TS302", "메시지 타입이 맞지 않습니다."), // 메시지내 파라미터의 타입이 잘못된 경우
|
||||||
|
TS_SERVER_ERROR("TS500", "서버 연결이 되지 않습니다."), // call측 network exception 처리
|
||||||
|
TS_NT_LAZY("TS501", "네트워크 연결이 지연 됩니다."), // call측 network exception 처리
|
||||||
|
TS_AUTH_KEY("TS600", "인증키가 유효하지 않습니다."), |
||||||
|
TS_ETC("TS700", "기타 오류"), // 기 정의된 내용이 아닌 기타 오류인 경우
|
||||||
|
|
||||||
|
// QR 관련 ERROR CODE
|
||||||
|
QR_EXPIRED("QR001", "QR코드 유효기간이 만료되었습니다"); |
||||||
|
private final String code; |
||||||
|
|
||||||
|
private final String message; |
||||||
|
|
||||||
|
private ErrorCode(String code, String message) { |
||||||
|
this.code = code; |
||||||
|
this.message = message; |
||||||
|
} |
||||||
|
|
||||||
|
public String code() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
public String message() { |
||||||
|
return message; |
||||||
|
} |
||||||
|
|
||||||
|
@JsonCreator |
||||||
|
public static ErrorCode fromCode(String code) { |
||||||
|
for (ErrorCode errorCode : ErrorCode.values()) { |
||||||
|
if (errorCode.code().equals(code)) { |
||||||
|
return errorCode; |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
package kr.co.palnet.kac.core.code; |
||||||
|
|
||||||
|
public enum Level { |
||||||
|
INFO(0), |
||||||
|
WARN(1), |
||||||
|
RETRY(2), |
||||||
|
DROP(3), |
||||||
|
RECYCLE(4), |
||||||
|
CRITICAL(5); |
||||||
|
|
||||||
|
private int code; |
||||||
|
|
||||||
|
Level(int code) { |
||||||
|
setLevel(code); |
||||||
|
} |
||||||
|
|
||||||
|
public int getLevel() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLevel(int code) { |
||||||
|
this.code = code; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
package kr.co.palnet.kac.core.code; |
||||||
|
|
||||||
|
public enum MessageType { |
||||||
|
OPENSKY, |
||||||
|
ADSB, |
||||||
|
LTEM, |
||||||
|
ETC, |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
package kr.co.palnet.kac.core.code; |
||||||
|
|
||||||
|
public enum ObjectType { |
||||||
|
DRON, |
||||||
|
AIRPLANE, |
||||||
|
CAR, |
||||||
|
BUS, |
||||||
|
PERSON |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package kr.co.palnet.kac.core.code; |
||||||
|
|
||||||
|
public enum RSErrorCode { |
||||||
|
SUCCESS("1", "Success"), |
||||||
|
FAIL("-1" , "Fail"), |
||||||
|
ER_PARAM("-100" , "Please parameter Check"), |
||||||
|
DATA_NOTFOUNT("-101" , "Data not found"), |
||||||
|
PSWD_NOTMATCH("-102" , "Password does not match"), |
||||||
|
ACNT_UNAVAIL("-103","Account is unavailable"), |
||||||
|
|
||||||
|
AUTH_ERROR("-401", "auth error"), |
||||||
|
INTERNAL_SERVER_ERROR("-500", "Internal system error"), |
||||||
|
DATA_DUPLICATE("-104","Duplicate data exists"); |
||||||
|
|
||||||
|
|
||||||
|
private final String code; |
||||||
|
|
||||||
|
private final String message; |
||||||
|
|
||||||
|
private RSErrorCode(String code, String message) { |
||||||
|
this.code = code; |
||||||
|
this.message = message; |
||||||
|
} |
||||||
|
|
||||||
|
public String code() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
public String message() { |
||||||
|
return message; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,6 @@ |
|||||||
|
package kr.co.palnet.kac.core.code; |
||||||
|
|
||||||
|
public enum Source { |
||||||
|
SERVER, |
||||||
|
INTERNAL |
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
package kr.co.palnet.kac.core.exception; |
||||||
|
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus; |
||||||
|
|
||||||
|
public enum BaseErrorCode { |
||||||
|
SUCCESS("CM001", HttpStatus.OK, "성공"), |
||||||
|
FAILED("CM900", HttpStatus.INTERNAL_SERVER_ERROR, "실패"), |
||||||
|
UNKNOWN("CM999", HttpStatus.INTERNAL_SERVER_ERROR, "실패(사용자 정의 없는 에러)"), |
||||||
|
NOT_PROCESS("CM002", HttpStatus.INTERNAL_SERVER_ERROR, "처리되지 않음"), |
||||||
|
IO_ERROR("CM003", HttpStatus.INTERNAL_SERVER_ERROR, "IO 에러"), |
||||||
|
LOGIN_FAILED("CM100", HttpStatus.INTERNAL_SERVER_ERROR, "로그인 실패"), |
||||||
|
LOGIN_DUPLICATED("CM101", HttpStatus.INTERNAL_SERVER_ERROR, "중복 로그인"), |
||||||
|
LOGIN_ATTEMPT_COUNT("CM102", HttpStatus.INTERNAL_SERVER_ERROR, "로그인 실패 횟수 초과"), |
||||||
|
LOGIN_SNS_FAILED("CM110", HttpStatus.INTERNAL_SERVER_ERROR, "SNS 로그인 실패"), |
||||||
|
LOGIN_SNS_DUPLICATED("CM111", HttpStatus.INTERNAL_SERVER_ERROR, "SNS 가입 중복"), |
||||||
|
TOKEN_EXPIRED("CM120", HttpStatus.INTERNAL_SERVER_ERROR, "토큰 만료"), |
||||||
|
TOKEN_INVALID("CM121", HttpStatus.INTERNAL_SERVER_ERROR, "잘못된 토큰"), |
||||||
|
ACCOUNT_LOCK("CM130", HttpStatus.INTERNAL_SERVER_ERROR, "계정 잠김"), |
||||||
|
ACCOUNT_DORMANT("CM131", HttpStatus.INTERNAL_SERVER_ERROR, "휴면 계정"), |
||||||
|
CACHE_LOAD_FAILED("CM200", HttpStatus.INTERNAL_SERVER_ERROR, "캐시 로딩 실패"), |
||||||
|
CACHE_RELOAD_FAILED("CM201", HttpStatus.INTERNAL_SERVER_ERROR, "캐시 리로딩 실패"), |
||||||
|
AUTH_EMPTY("CM401", HttpStatus.UNAUTHORIZED, "권한 없음"), |
||||||
|
WEB_PARAM_INVALID("WB400", HttpStatus.INTERNAL_SERVER_ERROR, "잘못된 파라미터"), |
||||||
|
WEB_NOT_FOUND("WB404", HttpStatus.INTERNAL_SERVER_ERROR, "찾을수 없는 페이지"), |
||||||
|
WEB_API_ERROR("WB500", HttpStatus.INTERNAL_SERVER_ERROR, "외부 연동 에러"), |
||||||
|
DATA_ALREADY_EXISTS("DT001", HttpStatus.INTERNAL_SERVER_ERROR, "이미 등록된 데이터"), |
||||||
|
DATA_EMPTY("DT002", HttpStatus.INTERNAL_SERVER_ERROR, "데이터 없음"); |
||||||
|
|
||||||
|
|
||||||
|
private final String code; |
||||||
|
|
||||||
|
private final HttpStatus status; |
||||||
|
|
||||||
|
private final String message; |
||||||
|
|
||||||
|
private BaseErrorCode(String code, HttpStatus status, String message) { |
||||||
|
this.code = code; |
||||||
|
this.status = status; |
||||||
|
this.message = message; |
||||||
|
} |
||||||
|
|
||||||
|
public String code() { |
||||||
|
return this.code; |
||||||
|
} |
||||||
|
|
||||||
|
public String message() { |
||||||
|
return this.message; |
||||||
|
} |
||||||
|
|
||||||
|
public HttpStatus status() { |
||||||
|
return this.status; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,132 @@ |
|||||||
|
package kr.co.palnet.kac.core.exception; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.context.MessageSource; |
||||||
|
|
||||||
|
import java.util.Locale; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public class BaseException extends RuntimeException { |
||||||
|
|
||||||
|
|
||||||
|
private final BaseErrorCode errorCode; |
||||||
|
|
||||||
|
private final String logMessage; |
||||||
|
|
||||||
|
private final Level level; |
||||||
|
|
||||||
|
private final Object[] paramArray; |
||||||
|
|
||||||
|
public BaseException() { |
||||||
|
this(BaseErrorCode.FAILED, null, Level.WARN, null); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(Object[] paramArray) { |
||||||
|
this(BaseErrorCode.FAILED, null, Level.WARN, paramArray); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(Level level) { |
||||||
|
this(BaseErrorCode.FAILED, null, level, null); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(Level level, Object[] paramArray) { |
||||||
|
this(BaseErrorCode.FAILED, null, level, paramArray); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(String logMessage) { |
||||||
|
this(BaseErrorCode.FAILED, logMessage, Level.WARN, null); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(String logMessage, Object[] paramArray) { |
||||||
|
this(BaseErrorCode.FAILED, logMessage, Level.WARN, paramArray); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(String logMessage, Level level) { |
||||||
|
this(BaseErrorCode.FAILED, logMessage, level, null); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(String logMessage, Level level, Object[] paramArray) { |
||||||
|
this(BaseErrorCode.FAILED, logMessage, level, paramArray); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(BaseErrorCode errorCode) { |
||||||
|
this(errorCode, null, Level.WARN, null); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(BaseErrorCode errorCode, Object[] paramArray) { |
||||||
|
this(errorCode, null, Level.WARN, paramArray); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(BaseErrorCode errorCode, Level level) { |
||||||
|
this(errorCode, null, level, null); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(BaseErrorCode errorCode, Level level, Object[] paramArray) { |
||||||
|
this(errorCode, null, level, paramArray); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(BaseErrorCode errorCode, String logMessage) { |
||||||
|
this(errorCode, logMessage, Level.WARN, null); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(BaseErrorCode errorCode, String logMessage, Object[] paramArray) { |
||||||
|
this(errorCode, logMessage, Level.WARN, paramArray); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(BaseErrorCode errorCode, String logMessage, Level level) { |
||||||
|
this(errorCode, logMessage, level, null); |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(BaseErrorCode errorCode, String logMessage, Level level, Object[] paramArray) { |
||||||
|
this.errorCode = errorCode; |
||||||
|
this.logMessage = logMessage; |
||||||
|
this.level = level; |
||||||
|
this.paramArray = paramArray; |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(String message, BaseErrorCode errorCode, String logMessage, Level level, Object[] paramArray) { |
||||||
|
super(message); |
||||||
|
this.errorCode = errorCode; |
||||||
|
this.logMessage = logMessage; |
||||||
|
this.level = level; |
||||||
|
this.paramArray = paramArray; |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(String message, Throwable cause, BaseErrorCode errorCode, String logMessage, Level level, Object[] paramArray) { |
||||||
|
super(message, cause); |
||||||
|
this.errorCode = errorCode; |
||||||
|
this.logMessage = logMessage; |
||||||
|
this.level = level; |
||||||
|
this.paramArray = paramArray; |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(Throwable cause, BaseErrorCode errorCode, String logMessage, Level level, Object[] paramArray) { |
||||||
|
super(cause); |
||||||
|
this.errorCode = errorCode; |
||||||
|
this.logMessage = logMessage; |
||||||
|
this.level = level; |
||||||
|
this.paramArray = paramArray; |
||||||
|
} |
||||||
|
|
||||||
|
public BaseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, BaseErrorCode errorCode, String logMessage, Level level, Object[] paramArray) { |
||||||
|
super(message, cause, enableSuppression, writableStackTrace); |
||||||
|
this.errorCode = errorCode; |
||||||
|
this.logMessage = logMessage; |
||||||
|
this.level = level; |
||||||
|
this.paramArray = paramArray; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCode() { |
||||||
|
return errorCode.code(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getErrorMessage(MessageSource ms) { |
||||||
|
if (ms == null) { |
||||||
|
return BaseErrorCode.UNKNOWN.message(); |
||||||
|
} |
||||||
|
return ms.getMessage(getCode(), getParamArray(), BaseErrorCode.UNKNOWN.message(), Locale.getDefault()); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
package kr.co.palnet.kac.core.exception; |
||||||
|
|
||||||
|
public enum Level { |
||||||
|
TRACE, |
||||||
|
DEBUG, |
||||||
|
INFO, |
||||||
|
WARN, |
||||||
|
ERROR |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
package kr.co.palnet.kac.core.exception.model; |
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
import java.time.Instant; |
||||||
|
|
||||||
|
@Data |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Builder |
||||||
|
public class BaseErrorModel { |
||||||
|
|
||||||
|
private Instant timestamp; |
||||||
|
|
||||||
|
private int status; |
||||||
|
|
||||||
|
private String error; |
||||||
|
|
||||||
|
private String path; |
||||||
|
|
||||||
|
private String message; |
||||||
|
|
||||||
|
private String code; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
package kr.co.palnet.kac.core.response; |
||||||
|
|
||||||
|
public abstract class BasicResponse { |
||||||
|
|
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
package kr.co.palnet.kac.core.response; |
||||||
|
|
||||||
|
|
||||||
|
import kr.co.palnet.kac.core.code.RSErrorCode; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.EqualsAndHashCode; |
||||||
|
|
||||||
|
@Data |
||||||
|
@EqualsAndHashCode(callSuper=false) |
||||||
|
public class ErrorResponse extends BasicResponse{ |
||||||
|
|
||||||
|
private String errorMessage; |
||||||
|
private String errorCode; |
||||||
|
|
||||||
|
public ErrorResponse(String errorMessage) { |
||||||
|
this.errorMessage = errorMessage; |
||||||
|
this.errorCode = "404"; |
||||||
|
} |
||||||
|
|
||||||
|
public ErrorResponse(RSErrorCode code) { |
||||||
|
this.errorMessage = code.message(); |
||||||
|
this.errorCode = code.code(); |
||||||
|
} |
||||||
|
public ErrorResponse(String errorMessage, String errorCode) { |
||||||
|
this.errorMessage = errorMessage; |
||||||
|
this.errorCode = errorCode; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
package kr.co.palnet.kac.core.response; |
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.EqualsAndHashCode; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
|
||||||
|
@Data |
||||||
|
@EqualsAndHashCode(callSuper=false) |
||||||
|
public class SuccessResponse<T> extends BasicResponse { |
||||||
|
|
||||||
|
@Schema(description = "응답 데이터 건수") |
||||||
|
private int count; |
||||||
|
|
||||||
|
@Schema(description = "응답 데이터") |
||||||
|
private T data; |
||||||
|
|
||||||
|
public SuccessResponse(T data) { |
||||||
|
this.data = data; |
||||||
|
if(data instanceof List) { |
||||||
|
this.count = ((List<?>)data).size(); |
||||||
|
} else { |
||||||
|
this.count = 1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
|
||||||
|
|
||||||
|
dependencies { |
||||||
|
implementation "$boot:spring-boot-starter-json" |
||||||
|
} |
@ -0,0 +1,100 @@ |
|||||||
|
package kr.co.palnet.kac.util; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.util.kisa.KISA_SHA256; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
|
||||||
|
import javax.crypto.Cipher; |
||||||
|
import javax.crypto.spec.IvParameterSpec; |
||||||
|
import javax.crypto.spec.SecretKeySpec; |
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
import java.util.Base64; |
||||||
|
|
||||||
|
@Slf4j |
||||||
|
public class EncryptUtil { |
||||||
|
|
||||||
|
// 16byte
|
||||||
|
private static String ENCRYPT_KEY = "__DEFAULT__KEY__"; |
||||||
|
private static String ENCRYPT_IV = "DEFAULT_IV_VALUE"; |
||||||
|
|
||||||
|
public static void setEncryptKey(String encryptKey) { |
||||||
|
ENCRYPT_KEY = encryptKey; |
||||||
|
} |
||||||
|
|
||||||
|
public static void setEncryptIv(String encryptIv) { |
||||||
|
ENCRYPT_IV = encryptIv; |
||||||
|
} |
||||||
|
|
||||||
|
public static String encrypt(String value) { |
||||||
|
return encrypt(ENCRYPT_KEY, ENCRYPT_IV, value); |
||||||
|
} |
||||||
|
|
||||||
|
public static String decrypt(String encrypted) { |
||||||
|
return decrypt(ENCRYPT_KEY, ENCRYPT_IV, encrypted); |
||||||
|
} |
||||||
|
|
||||||
|
// 암호화
|
||||||
|
public static String encrypt(String key, String initVector, String value) { |
||||||
|
// log.info("encrypt() key: {}, initVector: {}, value: {}", key, initVector, value);
|
||||||
|
try { |
||||||
|
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8)); |
||||||
|
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"); |
||||||
|
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); |
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); |
||||||
|
// cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
|
||||||
|
byte[] encrypted = cipher.doFinal(value.getBytes()); |
||||||
|
Base64.Encoder encoder = Base64.getEncoder(); |
||||||
|
String encodedString = encoder.encodeToString(encrypted); |
||||||
|
log.debug("encrypted string: {}", encodedString); |
||||||
|
return encodedString; |
||||||
|
} catch (Exception e) { |
||||||
|
log.error("encrypt() Exception: {}", e.getMessage()); |
||||||
|
} |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
// 복호화
|
||||||
|
public static String decrypt(String key, String initVector, String encrypted) { |
||||||
|
// log.info("decrypt() key: {}, initVector: {}, encrypted: {}", key, initVector, encrypted);
|
||||||
|
try { |
||||||
|
|
||||||
|
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8)); |
||||||
|
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"); |
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); |
||||||
|
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); |
||||||
|
//cipher.init(Cipher.DECRYPT_MODE, skeySpec);
|
||||||
|
Base64.Decoder decoder = Base64.getDecoder(); |
||||||
|
byte[] original = cipher.doFinal(decoder.decode(encrypted)); |
||||||
|
|
||||||
|
return new String(original); |
||||||
|
} catch (Exception e) { |
||||||
|
log.error("decrypt() Exception: {}", e.getMessage()); |
||||||
|
} |
||||||
|
return encrypted; |
||||||
|
} |
||||||
|
|
||||||
|
public static String sha256Encrypt(String str) { |
||||||
|
|
||||||
|
byte[] bytes = str.getBytes(); |
||||||
|
byte[] pszDigest = new byte[32]; |
||||||
|
KISA_SHA256.SHA256_Encrpyt(bytes, bytes.length, pszDigest); |
||||||
|
StringBuffer encrypted = new StringBuffer(); |
||||||
|
for (int i = 0; i < 32; i++) { |
||||||
|
encrypted.append(String.format("%02x", pszDigest[i])); |
||||||
|
} |
||||||
|
return encrypted.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
public static void main(String[] args) { |
||||||
|
String key = "1234567890123456"; |
||||||
|
String initVector = "1234567890123456"; |
||||||
|
String test = "test"; |
||||||
|
|
||||||
|
// WkaOhqSK03Z1pSuPOdc03w==
|
||||||
|
// WkaOhqSK03Z1pSuPOdc03w==
|
||||||
|
String encrypted = encrypt(test); |
||||||
|
log.info("encrypted: {}", encrypted); |
||||||
|
String decrypted = decrypt(encrypted); |
||||||
|
log.info("decrypted: {}", decrypted); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,128 @@ |
|||||||
|
package kr.co.palnet.kac.util; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.util.kisa.KISA_SEED_CBC; |
||||||
|
import kr.co.palnet.kac.util.kisa.KISA_SEED_CTR; |
||||||
|
import kr.co.palnet.kac.util.kisa.KISA_SEED_ECB; |
||||||
|
import kr.co.palnet.kac.util.kisa.KISA_SHA256; |
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
import java.util.Base64; |
||||||
|
|
||||||
|
public class KisaEncryptUtil { |
||||||
|
// 사용자가 지정하는 입력 키 (16 bytes)
|
||||||
|
private final static String PBSZ_USER_KEY = "PBSZ_USER_KEY___"; // 16 bytes
|
||||||
|
// 사용자가 지정하는 초기화 벡트 (16 bytes)
|
||||||
|
private final static String PBSZ_VECTOR = "PBSZ_INIT_VECTOR"; // 16 bytes
|
||||||
|
public static class EcbEncrypt { |
||||||
|
public static String encrypt(String value) { |
||||||
|
byte[] ecbEncBytes = KISA_SEED_ECB.SEED_ECB_Encrypt(PBSZ_USER_KEY.getBytes(StandardCharsets.UTF_8), value.getBytes(StandardCharsets.UTF_8), 0, value.getBytes(StandardCharsets.UTF_8).length); |
||||||
|
Base64.Encoder encoder = Base64.getEncoder(); |
||||||
|
byte[] ecbEncode = encoder.encode(ecbEncBytes); |
||||||
|
return new String(ecbEncode); |
||||||
|
} |
||||||
|
|
||||||
|
public static String decrypt(String value) { |
||||||
|
Base64.Decoder decoder = Base64.getDecoder(); |
||||||
|
byte[] ecbDecoder = decoder.decode(value.getBytes(StandardCharsets.UTF_8)); |
||||||
|
byte[] ecbDecBytes = KISA_SEED_ECB.SEED_ECB_Decrypt(PBSZ_USER_KEY.getBytes(StandardCharsets.UTF_8), ecbDecoder, 0, ecbDecoder.length); |
||||||
|
return new String(ecbDecBytes); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static class CbcEncrypt { |
||||||
|
public static String encrypt(String value) { |
||||||
|
byte[] ecbEncBytes = KISA_SEED_CBC.SEED_CBC_Encrypt( |
||||||
|
PBSZ_USER_KEY.getBytes(StandardCharsets.UTF_8), |
||||||
|
PBSZ_VECTOR.getBytes(StandardCharsets.UTF_8), |
||||||
|
value.getBytes(StandardCharsets.UTF_8), |
||||||
|
0, |
||||||
|
value.getBytes(StandardCharsets.UTF_8).length |
||||||
|
); |
||||||
|
Base64.Encoder encoder = Base64.getEncoder(); |
||||||
|
byte[] ecbEncode = encoder.encode(ecbEncBytes); |
||||||
|
return new String(ecbEncode); |
||||||
|
} |
||||||
|
|
||||||
|
public static String decrypt(String value) { |
||||||
|
Base64.Decoder decoder = Base64.getDecoder(); |
||||||
|
byte[] ecbDecoder = decoder.decode(value.getBytes(StandardCharsets.UTF_8)); |
||||||
|
byte[] ecbDecBytes = KISA_SEED_CBC.SEED_CBC_Decrypt( |
||||||
|
PBSZ_USER_KEY.getBytes(StandardCharsets.UTF_8), |
||||||
|
PBSZ_VECTOR.getBytes(StandardCharsets.UTF_8), |
||||||
|
ecbDecoder, |
||||||
|
0, |
||||||
|
ecbDecoder.length |
||||||
|
); |
||||||
|
return new String(ecbDecBytes); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static class CtrEncrypt { |
||||||
|
|
||||||
|
public static String encrypt(String value) { |
||||||
|
byte[] encBytes = KISA_SEED_CTR.SEED_CTR_Encrypt( |
||||||
|
PBSZ_USER_KEY.getBytes(StandardCharsets.UTF_8), |
||||||
|
PBSZ_VECTOR.getBytes(StandardCharsets.UTF_8), |
||||||
|
value.getBytes(StandardCharsets.UTF_8), |
||||||
|
0, |
||||||
|
value.getBytes(StandardCharsets.UTF_8).length |
||||||
|
); |
||||||
|
Base64.Encoder encoder = Base64.getEncoder(); |
||||||
|
byte[] encodeBytes = encoder.encode(encBytes); |
||||||
|
return new String(encodeBytes); |
||||||
|
} |
||||||
|
public static String decrypt(String value) { |
||||||
|
Base64.Decoder decoder = Base64.getDecoder(); |
||||||
|
byte[] decodeBytes = decoder.decode(value.getBytes(StandardCharsets.UTF_8)); |
||||||
|
|
||||||
|
byte[] decBytes = KISA_SEED_CTR.SEED_CTR_Decrypt( |
||||||
|
PBSZ_USER_KEY.getBytes(StandardCharsets.UTF_8), |
||||||
|
PBSZ_VECTOR.getBytes(StandardCharsets.UTF_8), |
||||||
|
decodeBytes, |
||||||
|
0, |
||||||
|
decodeBytes.length |
||||||
|
); |
||||||
|
return new String(decBytes); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static class ShaEncrypt { |
||||||
|
public static String encrypt(String value) { |
||||||
|
byte[] bytes = value.getBytes(StandardCharsets.UTF_8); |
||||||
|
byte[] pszDigest = new byte[32]; |
||||||
|
KISA_SHA256.SHA256_Encrpyt(bytes, bytes.length, pszDigest); |
||||||
|
StringBuffer encrypted = new StringBuffer(); |
||||||
|
for (int i = 0; i < 32; i++) { |
||||||
|
encrypted.append(String.format("%02x", pszDigest[i])); |
||||||
|
} |
||||||
|
return encrypted.toString(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) { |
||||||
|
String message = "this is message!!@#!$^#$%^&@#$~!@ 메시지 입니다.___+_+)(_)("; |
||||||
|
System.out.println("message = " + message); |
||||||
|
System.out.println("=============== ECB ================="); |
||||||
|
String ecbEncStr = EcbEncrypt.encrypt(message); |
||||||
|
System.out.println("ecbEncStr = " + ecbEncStr); |
||||||
|
String ecbDecStr = EcbEncrypt.decrypt(ecbEncStr); |
||||||
|
System.out.println("ecbDecStr = " + ecbDecStr); |
||||||
|
|
||||||
|
System.out.println("=============== CBC ================="); |
||||||
|
String cbcEncStr = CbcEncrypt.encrypt(message); |
||||||
|
System.out.println("cbcEncStr = " + cbcEncStr); |
||||||
|
String cbcDncStr = CbcEncrypt.decrypt(cbcEncStr); |
||||||
|
System.out.println("cbcDncStr = " + cbcDncStr); |
||||||
|
|
||||||
|
System.out.println("=============== CTR ================="); |
||||||
|
String ctrEncStr = CtrEncrypt.encrypt(message); |
||||||
|
System.out.println("ctrEncStr = " + ctrEncStr); |
||||||
|
String ctrDncStr = CtrEncrypt.decrypt(ctrEncStr); |
||||||
|
System.out.println("ctrDncStr = " + ctrDncStr); |
||||||
|
|
||||||
|
System.out.println("=============== SHA ================="); |
||||||
|
String shaEncStr = ShaEncrypt.encrypt(message); |
||||||
|
System.out.println("shaEncStr = " + shaEncStr); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,106 @@ |
|||||||
|
package kr.co.palnet.kac.util; |
||||||
|
|
||||||
|
import java.util.regex.Matcher; |
||||||
|
import java.util.regex.Pattern; |
||||||
|
|
||||||
|
public class MaskingUtil { |
||||||
|
|
||||||
|
public static String maskString(String originalString, int start, int end) { |
||||||
|
String mask = originalString.substring(start, end).replaceAll(".", "*"); |
||||||
|
return originalString.substring(0, start) + mask + originalString.substring(end); |
||||||
|
} |
||||||
|
|
||||||
|
public static String maskStringEndWith(String originalString, int end) { |
||||||
|
return maskString(originalString, 0, end); |
||||||
|
} |
||||||
|
|
||||||
|
public static String maskStringStartWith(String originalString, int start) { |
||||||
|
return maskString(originalString, start, originalString.length()); |
||||||
|
} |
||||||
|
|
||||||
|
public static String maskEmail(String email) { |
||||||
|
return email.replaceAll("(?<=.{3}).(?=[^@]*?@)", "*"); |
||||||
|
} |
||||||
|
|
||||||
|
public static String maskEmailAndDomain(String email) { |
||||||
|
String regex = "(.+)@(.+)"; |
||||||
|
|
||||||
|
Pattern pattern = Pattern.compile(regex); |
||||||
|
Matcher matcher = pattern.matcher(email); |
||||||
|
if (matcher.find()) { |
||||||
|
String localPart = matcher.group(1); |
||||||
|
String domain = matcher.group(2); |
||||||
|
|
||||||
|
localPart = maskString(localPart, 3, localPart.length()); |
||||||
|
domain = maskString(domain, 3, domain.length()); |
||||||
|
return localPart + "@" + domain; |
||||||
|
} |
||||||
|
return email; |
||||||
|
} |
||||||
|
|
||||||
|
public static String maskCardNumber(String cardNumber) { |
||||||
|
// return cardNumber.replaceAll("\\b(\\d{6})(\\d+)(\\d{4})\\b", "$1****$2");
|
||||||
|
// 하이픈 제거
|
||||||
|
String cardNumberWithoutHyphens = cardNumber.replace("-", ""); |
||||||
|
|
||||||
|
// 마스킹 적용
|
||||||
|
StringBuffer sb = new StringBuffer(); |
||||||
|
Pattern pattern = Pattern.compile("(\\d{6})(\\d+)(\\d{4})"); |
||||||
|
Matcher matcher = pattern.matcher(cardNumberWithoutHyphens); |
||||||
|
while (matcher.find()) { |
||||||
|
matcher.appendReplacement(sb, matcher.group(1) + "*".repeat(matcher.group(2).length()) + matcher.group(3)); |
||||||
|
} |
||||||
|
matcher.appendTail(sb); |
||||||
|
String maskedCardNumber = sb.toString(); |
||||||
|
|
||||||
|
// Return the card number in the original format
|
||||||
|
return cardNumber.contains("-") |
||||||
|
? maskedCardNumber.replaceAll("(\\d{4})(.{4})(.{4})(\\d{3,4})", "$1-$2-$3-$4") |
||||||
|
: maskedCardNumber; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static String maskName(String name) { |
||||||
|
if (name.length() == 1) { |
||||||
|
return "*"; |
||||||
|
} else if (name.length() == 2) { |
||||||
|
return name.replaceAll("(?<=.).", "*"); |
||||||
|
} else { |
||||||
|
return name.replaceAll("(?<=.).(?=.)", "*"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static String maskPhoneNumber(String phoneNumber) { |
||||||
|
// 하이픈 제거
|
||||||
|
String phoneNumberWithoutHyphens = phoneNumber.replace("-", ""); |
||||||
|
|
||||||
|
// 마스킹 적용
|
||||||
|
StringBuffer sb = new StringBuffer(); |
||||||
|
Pattern pattern = Pattern.compile("(02|0\\d{2})(\\d+)(\\d{4})"); |
||||||
|
Matcher matcher = pattern.matcher(phoneNumberWithoutHyphens); |
||||||
|
while (matcher.find()) { |
||||||
|
matcher.appendReplacement(sb, matcher.group(1) + "*".repeat(matcher.group(2).length()) + matcher.group(3)); |
||||||
|
} |
||||||
|
matcher.appendTail(sb); |
||||||
|
String maskedPhoneNumber = sb.toString(); |
||||||
|
return phoneNumber.contains("-") |
||||||
|
? maskedPhoneNumber.replaceAll("(\\d{2,3})(.{3,4})(\\d{4})", "$1-$2-$3") |
||||||
|
: maskedPhoneNumber; |
||||||
|
} |
||||||
|
|
||||||
|
public static String maskExpireDate(String expireDate) { |
||||||
|
return expireDate.replaceAll("(\\d{2})(\\d{2})", "$1/$2"); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static String maskResidentRegistrationNumber(String rrn) { |
||||||
|
return rrn.replaceAll("(\\d{6}-?\\d{1})(\\d{6})", "$1******"); |
||||||
|
} |
||||||
|
|
||||||
|
public static String maskIp(String ip) { |
||||||
|
return ip.replaceAll("^(\\d+)(\\.\\d+\\.\\d+\\.\\d+)$", "***$2"); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,52 @@ |
|||||||
|
package kr.co.palnet.kac.util; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude; |
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature; |
||||||
|
import com.fasterxml.jackson.databind.MapperFeature; |
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature; |
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; |
||||||
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; |
||||||
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; |
||||||
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; |
||||||
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; |
||||||
|
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; |
||||||
|
|
||||||
|
import java.time.format.DateTimeFormatter; |
||||||
|
import java.util.TimeZone; |
||||||
|
|
||||||
|
/** |
||||||
|
* packageName : com.sumair.common.core.utils |
||||||
|
* fileName : ObjectMapperUtils |
||||||
|
* author : dhji |
||||||
|
* date : 2023-05-17(017) |
||||||
|
* description : |
||||||
|
* =========================================================== |
||||||
|
* DATE AUTHOR NOTE |
||||||
|
* ----------------------------------------------------------- |
||||||
|
* 2023-05-17(017) dhji 최초 생성 |
||||||
|
*/ |
||||||
|
public class ObjectMapperUtils { |
||||||
|
public static ObjectMapper getObjectMapper() { |
||||||
|
return getObjectMapperBuilder().build(); |
||||||
|
} |
||||||
|
|
||||||
|
public static Jackson2ObjectMapperBuilder getObjectMapperBuilder() { |
||||||
|
Jackson2ObjectMapperBuilder jacksonBuilder = new Jackson2ObjectMapperBuilder(); |
||||||
|
jacksonBuilder.serializationInclusion(JsonInclude.Include.NON_NULL); |
||||||
|
jacksonBuilder.serializationInclusion(JsonInclude.Include.NON_EMPTY); |
||||||
|
// jacksonBuilder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||||
|
// jacksonBuilder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||||
|
// jacksonBuilder.featuresToDisable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
|
||||||
|
// jacksonBuilder.featuresToDisable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);
|
||||||
|
// jacksonBuilder.modulesToInstall(new JavaTimeModule());
|
||||||
|
// jacksonBuilder.timeZone(TimeZone.getTimeZone("UTC"));
|
||||||
|
// jacksonBuilder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
// jacksonBuilder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
||||||
|
// jacksonBuilder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||||
|
// jacksonBuilder.deserializers(new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
||||||
|
// jacksonBuilder.deserializers(new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||||
|
|
||||||
|
return jacksonBuilder; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
package kr.co.palnet.kac.util; |
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication; |
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||||
|
|
||||||
|
@SpringBootApplication |
||||||
|
public class UtilApplication { |
||||||
|
public static void main(String[] args) { |
||||||
|
SpringApplication.run(UtilApplication.class, args); |
||||||
|
} |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,453 @@ |
|||||||
|
package kr.co.palnet.kac.util.kisa; |
||||||
|
|
||||||
|
/** |
||||||
|
@file KISA_SHA256.java |
||||||
|
@brief SHA256 암호 알고리즘 |
||||||
|
@author Copyright (c) 2013 by KISA |
||||||
|
@remarks http://seed.kisa.or.kr/
|
||||||
|
*/ |
||||||
|
|
||||||
|
public class KISA_SHA256 { |
||||||
|
|
||||||
|
// DEFAULT : JAVA = BIG_ENDIAN
|
||||||
|
private static int ENDIAN = Common.BIG_ENDIAN; |
||||||
|
|
||||||
|
private static final int SHA256_DIGEST_BLOCKLEN = 64; |
||||||
|
private static final int SHA256_DIGEST_VALUELEN = 32; |
||||||
|
|
||||||
|
private static final int SHA256_K[] = |
||||||
|
{ |
||||||
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, |
||||||
|
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, |
||||||
|
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, |
||||||
|
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, |
||||||
|
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, |
||||||
|
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, |
||||||
|
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, |
||||||
|
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, |
||||||
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, |
||||||
|
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, |
||||||
|
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
private static final int ROTL_ULONG(int x, int n) { |
||||||
|
return (x << n) | Common.URShift(x, 32 - n); |
||||||
|
} |
||||||
|
|
||||||
|
private static final int ROTR_ULONG(int x, int n) { |
||||||
|
return Common.URShift(x, n) | (x << (32 - (n))); |
||||||
|
} |
||||||
|
|
||||||
|
private static final int ENDIAN_REVERSE_ULONG(int dwS) { |
||||||
|
return ( (ROTL_ULONG((dwS), 8) & 0x00ff00ff) | (ROTL_ULONG((dwS), 24) & 0xff00ff00) ); |
||||||
|
} |
||||||
|
|
||||||
|
private static final void BIG_D2B(int D, byte[] B, int B_offset) { |
||||||
|
Common.int_to_byte_unit(B, B_offset, D, ENDIAN); |
||||||
|
} |
||||||
|
|
||||||
|
private static final int RR(int x, int n) { return ROTR_ULONG(x, n); } |
||||||
|
private static final int SS(int x, int n) { return Common.URShift(x, n); } |
||||||
|
|
||||||
|
private static final int Ch(int x, int y, int z) { return ((x & y) ^ ((~x) & z)); } |
||||||
|
private static final int Maj(int x, int y, int z) { return ((x & y) ^ (x & z) ^ (y & z)); } |
||||||
|
private static final int Sigma0(int x) { return (RR(x, 2) ^ RR(x, 13) ^ RR(x, 22)); } |
||||||
|
private static final int Sigma1(int x) { return (RR(x, 6) ^ RR(x, 11) ^ RR(x, 25)); } |
||||||
|
|
||||||
|
private static final int RHO0(int x) { return (RR(x, 7) ^ RR(x, 18) ^ SS(x, 3)); } |
||||||
|
private static final int RHO1(int x) { return (RR(x, 17) ^ RR(x, 19) ^ SS(x, 10)); } |
||||||
|
|
||||||
|
private static final int abcdefgh_a = 0; |
||||||
|
private static final int abcdefgh_b = 1; |
||||||
|
private static final int abcdefgh_c = 2; |
||||||
|
private static final int abcdefgh_d = 3; |
||||||
|
private static final int abcdefgh_e = 4; |
||||||
|
private static final int abcdefgh_f = 5; |
||||||
|
private static final int abcdefgh_g = 6; |
||||||
|
private static final int abcdefgh_h = 7; |
||||||
|
|
||||||
|
private static final void FF(int[] abcdefgh, int a, int b, int c, int d, int e, int f, int g, int h, int[] X, int j) { |
||||||
|
long T1; |
||||||
|
|
||||||
|
T1 = Common.intToUnsigned(abcdefgh[h]) + Common.intToUnsigned(Sigma1(abcdefgh[e])) + Common.intToUnsigned(Ch(abcdefgh[e], abcdefgh[f], abcdefgh[g])) + Common.intToUnsigned(SHA256_K[j]) + Common.intToUnsigned(X[j]); |
||||||
|
abcdefgh[d] += T1; |
||||||
|
abcdefgh[h] = (int)(T1 + Common.intToUnsigned(Sigma0(abcdefgh[a])) + Common.intToUnsigned(Maj(abcdefgh[a], abcdefgh[b], abcdefgh[c]))); |
||||||
|
} |
||||||
|
|
||||||
|
private static final int GetData(byte[] x, int x_offset) { |
||||||
|
return Common.byte_to_int(x, x_offset, ENDIAN); |
||||||
|
} |
||||||
|
|
||||||
|
//*********************************************************************************************************************************
|
||||||
|
// o SHA256_Transform() : 512 비트 단위 블록의 메시지를 입력 받아 연쇄변수를 갱신하는 압축 함수로써
|
||||||
|
// 4 라운드(64 단계)로 구성되며 8개의 연쇄변수(a, b, c, d, e, f, g, h)를 사용
|
||||||
|
// o 입력 : Message - 입력 메시지의 포인터 변수
|
||||||
|
// ChainVar - 연쇄변수의 포인터 변수
|
||||||
|
// o 출력 :
|
||||||
|
//*********************************************************************************************************************************
|
||||||
|
private static void SHA256_Transform(byte[] Message, int[] ChainVar) { |
||||||
|
int abcdefgh[] = new int[8]; |
||||||
|
int T1[] = new int[1]; |
||||||
|
int X[] = new int[64]; |
||||||
|
int j; |
||||||
|
|
||||||
|
for (j = 0; j < 16; j++) |
||||||
|
X[j] = GetData(Message, j*4); |
||||||
|
|
||||||
|
for (j = 16; j < 64; j++) |
||||||
|
X[j] = (int)(Common.intToUnsigned(RHO1(X[j - 2])) + Common.intToUnsigned(X[j - 7]) + Common.intToUnsigned(RHO0(X[j - 15])) + Common.intToUnsigned(X[j - 16])); |
||||||
|
|
||||||
|
abcdefgh[abcdefgh_a] = ChainVar[0]; |
||||||
|
abcdefgh[abcdefgh_b] = ChainVar[1]; |
||||||
|
abcdefgh[abcdefgh_c] = ChainVar[2]; |
||||||
|
abcdefgh[abcdefgh_d] = ChainVar[3]; |
||||||
|
abcdefgh[abcdefgh_e] = ChainVar[4]; |
||||||
|
abcdefgh[abcdefgh_f] = ChainVar[5]; |
||||||
|
abcdefgh[abcdefgh_g] = ChainVar[6]; |
||||||
|
abcdefgh[abcdefgh_h] = ChainVar[7]; |
||||||
|
|
||||||
|
for (j = 0; j < 64; j += 8) |
||||||
|
{ |
||||||
|
FF(abcdefgh, abcdefgh_a, abcdefgh_b, abcdefgh_c, abcdefgh_d, abcdefgh_e, abcdefgh_f, abcdefgh_g, abcdefgh_h, X, j + 0); |
||||||
|
FF(abcdefgh, abcdefgh_h, abcdefgh_a, abcdefgh_b, abcdefgh_c, abcdefgh_d, abcdefgh_e, abcdefgh_f, abcdefgh_g, X, j + 1); |
||||||
|
FF(abcdefgh, abcdefgh_g, abcdefgh_h, abcdefgh_a, abcdefgh_b, abcdefgh_c, abcdefgh_d, abcdefgh_e, abcdefgh_f, X, j + 2); |
||||||
|
FF(abcdefgh, abcdefgh_f, abcdefgh_g, abcdefgh_h, abcdefgh_a, abcdefgh_b, abcdefgh_c, abcdefgh_d, abcdefgh_e, X, j + 3); |
||||||
|
FF(abcdefgh, abcdefgh_e, abcdefgh_f, abcdefgh_g, abcdefgh_h, abcdefgh_a, abcdefgh_b, abcdefgh_c, abcdefgh_d, X, j + 4); |
||||||
|
FF(abcdefgh, abcdefgh_d, abcdefgh_e, abcdefgh_f, abcdefgh_g, abcdefgh_h, abcdefgh_a, abcdefgh_b, abcdefgh_c, X, j + 5); |
||||||
|
FF(abcdefgh, abcdefgh_c, abcdefgh_d, abcdefgh_e, abcdefgh_f, abcdefgh_g, abcdefgh_h, abcdefgh_a, abcdefgh_b, X, j + 6); |
||||||
|
FF(abcdefgh, abcdefgh_b, abcdefgh_c, abcdefgh_d, abcdefgh_e, abcdefgh_f, abcdefgh_g, abcdefgh_h, abcdefgh_a, X, j + 7); |
||||||
|
} |
||||||
|
|
||||||
|
ChainVar[0] += abcdefgh[abcdefgh_a]; |
||||||
|
ChainVar[1] += abcdefgh[abcdefgh_b]; |
||||||
|
ChainVar[2] += abcdefgh[abcdefgh_c]; |
||||||
|
ChainVar[3] += abcdefgh[abcdefgh_d]; |
||||||
|
ChainVar[4] += abcdefgh[abcdefgh_e]; |
||||||
|
ChainVar[5] += abcdefgh[abcdefgh_f]; |
||||||
|
ChainVar[6] += abcdefgh[abcdefgh_g]; |
||||||
|
ChainVar[7] += abcdefgh[abcdefgh_h]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
@brief 연쇄변수와 길이변수를 초기화하는 함수 |
||||||
|
@param Info : SHA256_Process 호출 시 사용되는 구조체 |
||||||
|
*/ |
||||||
|
public static void SHA256_Init( SHA256_INFO Info ) { |
||||||
|
Info.uChainVar[0] = 0x6a09e667; |
||||||
|
Info.uChainVar[1] = 0xbb67ae85; |
||||||
|
Info.uChainVar[2] = 0x3c6ef372; |
||||||
|
Info.uChainVar[3] = 0xa54ff53a; |
||||||
|
Info.uChainVar[4] = 0x510e527f; |
||||||
|
Info.uChainVar[5] = 0x9b05688c; |
||||||
|
Info.uChainVar[6] = 0x1f83d9ab; |
||||||
|
Info.uChainVar[7] = 0x5be0cd19; |
||||||
|
|
||||||
|
Info.uHighLength = Info.uLowLength = Info.remainNum = 0; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
@brief 연쇄변수와 길이변수를 초기화하는 함수 |
||||||
|
@param Info : SHA256_Init 호출하여 초기화된 구조체(내부적으로 사용된다.) |
||||||
|
@param pszMessage : 사용자 입력 평문 |
||||||
|
@param inLen : 사용자 입력 평문 길이 |
||||||
|
*/ |
||||||
|
public static void SHA256_Process( SHA256_INFO Info, byte[] pszMessage, int uDataLen ) { |
||||||
|
/* |
||||||
|
int pszMessage_offset = Info.remainNum; |
||||||
|
|
||||||
|
if((Info.uLowLength += (uDataLen << 3)) < 0) { |
||||||
|
Info.uHighLength++; |
||||||
|
} |
||||||
|
|
||||||
|
Info.uHighLength += Common.URShift(uDataLen,29); |
||||||
|
|
||||||
|
while (uDataLen + pszMessage_offset >= SHA256_DIGEST_BLOCKLEN) { |
||||||
|
Common.arraycopy_offset(Info.szBuffer, pszMessage_offset, pszMessage, 0, SHA256_DIGEST_BLOCKLEN); |
||||||
|
SHA256_Transform(Info.szBuffer, Info.uChainVar); |
||||||
|
pszMessage_offset += SHA256_DIGEST_BLOCKLEN - pszMessage_offset; |
||||||
|
uDataLen -= SHA256_DIGEST_BLOCKLEN - pszMessage_offset; |
||||||
|
pszMessage_offset = 0; |
||||||
|
} |
||||||
|
|
||||||
|
Common.arraycopy_offset(Info.szBuffer, pszMessage_offset, pszMessage, 0, uDataLen); |
||||||
|
Info.remainNum = pszMessage_offset + uDataLen; |
||||||
|
|
||||||
|
*/ |
||||||
|
int pszMessage_offset; |
||||||
|
|
||||||
|
if((Info.uLowLength += (uDataLen << 3)) < 0) { |
||||||
|
Info.uHighLength++; |
||||||
|
} |
||||||
|
|
||||||
|
Info.uHighLength += Common.URShift(uDataLen,29); |
||||||
|
|
||||||
|
pszMessage_offset = 0; |
||||||
|
while (uDataLen >= SHA256_DIGEST_BLOCKLEN) { |
||||||
|
Common.arraycopy_offset(Info.szBuffer, 0, pszMessage, pszMessage_offset, SHA256_DIGEST_BLOCKLEN); |
||||||
|
SHA256_Transform(Info.szBuffer, Info.uChainVar); |
||||||
|
pszMessage_offset += SHA256_DIGEST_BLOCKLEN; |
||||||
|
uDataLen -= SHA256_DIGEST_BLOCKLEN; |
||||||
|
} |
||||||
|
|
||||||
|
Common.arraycopy_offset(Info.szBuffer, 0, pszMessage, pszMessage_offset, uDataLen); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
@brief 메시지 덧붙이기와 길이 덧붙이기를 수행한 후 마지막 메시지 블록을 가지고 압축함수를 호출하는 함수 |
||||||
|
@param Info : SHA256_Init 호출하여 초기화된 구조체(내부적으로 사용된다.) |
||||||
|
@param pszDigest : 암호문 |
||||||
|
*/ |
||||||
|
public static void SHA256_Close( SHA256_INFO Info, byte[] pszDigest ) { |
||||||
|
int i, Index; |
||||||
|
|
||||||
|
Index = Common.URShift(Info.uLowLength, 3) % SHA256_DIGEST_BLOCKLEN; |
||||||
|
Info.szBuffer[Index++] = (byte)0x80; |
||||||
|
|
||||||
|
if (Index > SHA256_DIGEST_BLOCKLEN - 8) { |
||||||
|
Common.arrayinit_offset(Info.szBuffer, Index, (byte)0, SHA256_DIGEST_BLOCKLEN - Index); |
||||||
|
SHA256_Transform(Info.szBuffer, Info.uChainVar); |
||||||
|
Common.arrayinit(Info.szBuffer, (byte)0, SHA256_DIGEST_BLOCKLEN - 8); |
||||||
|
} |
||||||
|
else { |
||||||
|
Common.arrayinit_offset(Info.szBuffer, Index, (byte)0, SHA256_DIGEST_BLOCKLEN - Index - 8); |
||||||
|
} |
||||||
|
|
||||||
|
if(ENDIAN == Common.LITTLE_ENDIAN) { |
||||||
|
Info.uLowLength = ENDIAN_REVERSE_ULONG(Info.uLowLength); |
||||||
|
Info.uHighLength = ENDIAN_REVERSE_ULONG(Info.uHighLength); |
||||||
|
} |
||||||
|
|
||||||
|
Common.int_to_byte_unit(Info.szBuffer, ((int)(SHA256_DIGEST_BLOCKLEN / 4 - 2))*4, Info.uHighLength, ENDIAN); |
||||||
|
Common.int_to_byte_unit(Info.szBuffer, ((int)(SHA256_DIGEST_BLOCKLEN / 4 - 1))*4, Info.uLowLength, ENDIAN); |
||||||
|
|
||||||
|
SHA256_Transform(Info.szBuffer, Info.uChainVar); |
||||||
|
|
||||||
|
for (i = 0; i < SHA256_DIGEST_VALUELEN; i += 4) |
||||||
|
BIG_D2B((Info.uChainVar)[i / 4], pszDigest, i); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
@brief 사용자 입력 평문을 한번에 처리 |
||||||
|
@param pszMessage : 사용자 입력 평문 |
||||||
|
@param pszDigest : 암호문 |
||||||
|
@remarks 내부적으로 SHA256_Init, SHA256_Process, SHA256_Close를 호출한다. |
||||||
|
*/ |
||||||
|
public static void SHA256_Encrpyt( byte[] pszMessage, int uPlainTextLen, byte[] pszDigest ) { |
||||||
|
SHA256_INFO info = new SHA256_INFO(); |
||||||
|
SHA256_Init( info ); |
||||||
|
SHA256_Process( info, pszMessage, uPlainTextLen ); |
||||||
|
SHA256_Close( info, pszDigest ); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static class SHA256_INFO { |
||||||
|
public int uChainVar[] = new int[SHA256_DIGEST_VALUELEN / 4]; |
||||||
|
public int uHighLength; |
||||||
|
public int uLowLength; |
||||||
|
public int remainNum; |
||||||
|
public byte szBuffer[] = new byte[SHA256_DIGEST_BLOCKLEN]; |
||||||
|
} |
||||||
|
|
||||||
|
public static class Common { |
||||||
|
|
||||||
|
public static final int BIG_ENDIAN = 0; |
||||||
|
public static final int LITTLE_ENDIAN = 1; |
||||||
|
|
||||||
|
public static void arraycopy(byte[] dst, byte[] src, int length) { |
||||||
|
for(int i=0; i<length; i++) { |
||||||
|
dst[i] = src[i]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void arraycopy_offset(byte[] dst, int dst_offset, byte[] src, int src_offset, int length) { |
||||||
|
for(int i=0; i<length; i++) { |
||||||
|
dst[dst_offset+i] = src[src_offset+i]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void arrayinit(byte[] dst, byte value, int length) { |
||||||
|
for(int i=0; i<length; i++) { |
||||||
|
dst[i] = value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void arrayinit_offset(byte[] dst, int dst_offset, byte value, int length) { |
||||||
|
for(int i=0; i<length; i++) { |
||||||
|
dst[dst_offset+i] = value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void memcpy(int[] dst, byte[] src, int length, int ENDIAN) { |
||||||
|
int iLen = length / 4; |
||||||
|
for(int i=0; i<iLen; i++) { |
||||||
|
byte_to_int(dst, i, src, i*4, ENDIAN); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void memcpy(int[] dst, int[] src, int src_offset, int length) { |
||||||
|
int iLen = length / 4 + ((length % 4 != 0)?1:0); |
||||||
|
for(int i=0; i<iLen; i++) { |
||||||
|
dst[i] = src[src_offset+i]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void set_byte_for_int(int[] dst, int b_offset, byte value, int ENDIAN) { |
||||||
|
if(ENDIAN == BIG_ENDIAN) { |
||||||
|
int shift_value = (3-b_offset%4)*8; |
||||||
|
int mask_value = 0x0ff << shift_value; |
||||||
|
int mask_value2 = ~mask_value; |
||||||
|
int value2 = (value&0x0ff) << shift_value; |
||||||
|
dst[b_offset/4] = (dst[b_offset/4] & mask_value2) | (value2 & mask_value); |
||||||
|
} else { |
||||||
|
int shift_value = (b_offset%4)*8; |
||||||
|
int mask_value = 0x0ff << shift_value; |
||||||
|
int mask_value2 = ~mask_value; |
||||||
|
int value2 = (value&0x0ff) << shift_value; |
||||||
|
dst[b_offset/4] = (dst[b_offset/4] & mask_value2) | (value2 & mask_value); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static byte get_byte_for_int(int[] src, int b_offset, int ENDIAN) { |
||||||
|
if(ENDIAN == BIG_ENDIAN) { |
||||||
|
int shift_value = (3-b_offset%4)*8; |
||||||
|
int mask_value = 0x0ff << shift_value; |
||||||
|
int value = (src[b_offset/4] & mask_value) >> shift_value; |
||||||
|
return (byte)value; |
||||||
|
} else { |
||||||
|
int shift_value = (b_offset%4)*8; |
||||||
|
int mask_value = 0x0ff << shift_value; |
||||||
|
int value = (src[b_offset/4] & mask_value) >> shift_value; |
||||||
|
return (byte)value; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static byte[] get_bytes_for_ints(int[] src, int offset, int ENDIAN) { |
||||||
|
int iLen = src.length-offset; |
||||||
|
byte[] result = new byte[(iLen)*4]; |
||||||
|
for(int i=0; i<iLen; i++) { |
||||||
|
int_to_byte(result, i*4, src, offset+i, ENDIAN); |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
public static void byte_to_int(int[] dst, int dst_offset, byte[] src, int src_offset, int ENDIAN) { |
||||||
|
if(ENDIAN == BIG_ENDIAN) { |
||||||
|
dst[dst_offset] = ((0x0ff&src[src_offset]) << 24) | ((0x0ff&src[src_offset+1]) << 16) | ((0x0ff&src[src_offset+2]) << 8) | ((0x0ff&src[src_offset+3])); |
||||||
|
} else { |
||||||
|
dst[dst_offset] = ((0x0ff&src[src_offset])) | ((0x0ff&src[src_offset+1]) << 8) | ((0x0ff&src[src_offset+2]) << 16) | ((0x0ff&src[src_offset+3]) << 24); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static int byte_to_int(byte[] src, int src_offset, int ENDIAN) { |
||||||
|
if(ENDIAN == BIG_ENDIAN) { |
||||||
|
return ((0x0ff&src[src_offset]) << 24) | ((0x0ff&src[src_offset+1]) << 16) | ((0x0ff&src[src_offset+2]) << 8) | ((0x0ff&src[src_offset+3])); |
||||||
|
} else { |
||||||
|
return ((0x0ff&src[src_offset])) | ((0x0ff&src[src_offset+1]) << 8) | ((0x0ff&src[src_offset+2]) << 16) | ((0x0ff&src[src_offset+3]) << 24); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static int byte_to_int_big_endian(byte[] src, int src_offset) { |
||||||
|
return ((0x0ff&src[src_offset]) << 24) | ((0x0ff&src[src_offset+1]) << 16) | ((0x0ff&src[src_offset+2]) << 8) | ((0x0ff&src[src_offset+3])); |
||||||
|
} |
||||||
|
|
||||||
|
public static void int_to_byte(byte[] dst, int dst_offset, int[] src, int src_offset, int ENDIAN) { |
||||||
|
int_to_byte_unit(dst, dst_offset, src[src_offset], ENDIAN); |
||||||
|
} |
||||||
|
|
||||||
|
public static void int_to_byte_unit(byte[] dst, int dst_offset, int src, int ENDIAN) { |
||||||
|
if(ENDIAN == BIG_ENDIAN) { |
||||||
|
dst[dst_offset] = (byte)((src>> 24) & 0x0ff); |
||||||
|
dst[dst_offset+1] = (byte)((src >> 16) & 0x0ff); |
||||||
|
dst[dst_offset+2] = (byte)((src >> 8) & 0x0ff); |
||||||
|
dst[dst_offset+3] = (byte)((src) & 0x0ff); |
||||||
|
} else { |
||||||
|
dst[dst_offset] = (byte)((src) & 0x0ff); |
||||||
|
dst[dst_offset+1] = (byte)((src >> 8) & 0x0ff); |
||||||
|
dst[dst_offset+2] = (byte)((src >> 16) & 0x0ff); |
||||||
|
dst[dst_offset+3] = (byte)((src >> 24) & 0x0ff); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static void int_to_byte_unit_big_endian(byte[] dst, int dst_offset, int src) { |
||||||
|
dst[dst_offset] = (byte)((src>> 24) & 0x0ff); |
||||||
|
dst[dst_offset+1] = (byte)((src >> 16) & 0x0ff); |
||||||
|
dst[dst_offset+2] = (byte)((src >> 8) & 0x0ff); |
||||||
|
dst[dst_offset+3] = (byte)((src) & 0x0ff); |
||||||
|
} |
||||||
|
|
||||||
|
public static int URShift(int x, int n) { |
||||||
|
if(n == 0) |
||||||
|
return x; |
||||||
|
if(n >= 32) |
||||||
|
return 0; |
||||||
|
int v = x >> n; |
||||||
|
int v_mask = ~(0x80000000 >> (n-1)); |
||||||
|
return v & v_mask; |
||||||
|
} |
||||||
|
|
||||||
|
public static final long INT_RANGE_MAX = (long)Math.pow(2, 32); |
||||||
|
|
||||||
|
public static long intToUnsigned(int x) { |
||||||
|
if(x >= 0) |
||||||
|
return x; |
||||||
|
return x + INT_RANGE_MAX; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void main(String[] args) |
||||||
|
{ |
||||||
|
byte pbData[] = {(byte)0x00, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, |
||||||
|
(byte)0x08, (byte)0x09, (byte)0x0A, (byte)0x0B, (byte)0x0C, (byte)0x0D, (byte)0x0E, (byte)0x0F, |
||||||
|
(byte)0x08, (byte)0x09, (byte)0x0A, (byte)0x0B, (byte)0x0C, (byte)0x0D, (byte)0x0E, (byte)0x0F, |
||||||
|
(byte)0x00, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, |
||||||
|
(byte)0x08, (byte)0x09, (byte)0x0A, (byte)0x0B, (byte)0x0C, (byte)0x0D, (byte)0x0E, (byte)0x0F, |
||||||
|
(byte)0x08, (byte)0x09, (byte)0x0A, (byte)0x0B, (byte)0x0C, (byte)0x0D, (byte)0x0E, (byte)0x0F}; |
||||||
|
byte pbData1[] = {(byte)0x61}; |
||||||
|
|
||||||
|
byte pbCipher[] = new byte[32]; |
||||||
|
byte pbPlain[] = new byte[16]; |
||||||
|
|
||||||
|
System.out.print("[ Test SHA256 reference code ]"+"\n"); |
||||||
|
System.out.print("\n\n"); |
||||||
|
System.out.print("[ Test HASH mode ]"+"\n"); |
||||||
|
System.out.print("\n"); |
||||||
|
|
||||||
|
int Plaintext_length = 1; |
||||||
|
|
||||||
|
for(int k=0; k<30; k++) |
||||||
|
{ |
||||||
|
|
||||||
|
System.out.print("Plaintext\t: "); |
||||||
|
for (int i=0; i<Plaintext_length; i++) System.out.print(Integer.toHexString(0xff&pbData[i])+" "); |
||||||
|
System.out.print("\n"); |
||||||
|
|
||||||
|
// Encryption
|
||||||
|
SHA256_Encrpyt( pbData, Plaintext_length, pbCipher ); |
||||||
|
|
||||||
|
System.out.print("Ciphertext\t: "); |
||||||
|
for (int i=0; i<32; i++) System.out.print(Integer.toHexString(0xff&pbCipher[i])+" "); |
||||||
|
System.out.print("\n\n"); |
||||||
|
|
||||||
|
Plaintext_length++; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
System.out.print("Plaintext\t: "); |
||||||
|
for (int i=0; i<1; i++) System.out.print(Integer.toHexString(0xff&pbData1[i])+" "); |
||||||
|
System.out.print("\n"); |
||||||
|
// Encryption
|
||||||
|
SHA256_Encrpyt( pbData1, 1, pbCipher ); |
||||||
|
System.out.print("Ciphertext\t: "); |
||||||
|
for (int i=0; i<32; i++) System.out.print(Integer.toHexString(0xff&pbCipher[i])+" "); |
||||||
|
System.out.print("\n\n"); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
|
||||||
|
dependencies { |
||||||
|
implementation "$boot:spring-boot-starter-data-jpa" |
||||||
|
|
||||||
|
implementation "com.querydsl:querydsl-jpa:5.0.0:jakarta" |
||||||
|
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" |
||||||
|
annotationProcessor "jakarta.annotation:jakarta.annotation-api" |
||||||
|
annotationProcessor "jakarta.persistence:jakarta.persistence-api" |
||||||
|
|
||||||
|
implementation project(":common:config-db") |
||||||
|
testRuntimeOnly "com.h2database:h2" |
||||||
|
} |
||||||
|
|
||||||
|
def querydslDir = layout.buildDirectory.dir("generated/querydsl").get().asFile |
||||||
|
|
||||||
|
sourceSets { |
||||||
|
main.java.srcDir(querydslDir) |
||||||
|
} |
||||||
|
|
||||||
|
tasks.withType(JavaCompile) { |
||||||
|
options.getGeneratedSourceOutputDirectory().set(file(querydslDir)) |
||||||
|
} |
||||||
|
|
||||||
|
clean { |
||||||
|
delete file(querydslDir) |
||||||
|
} |
@ -0,0 +1,78 @@ |
|||||||
|
package kr.co.palnet.kac.data.cns.model; |
||||||
|
|
||||||
|
import jakarta.persistence.*; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
import org.hibernate.annotations.ColumnDefault; |
||||||
|
import org.hibernate.annotations.CreationTimestamp; |
||||||
|
import org.hibernate.annotations.UpdateTimestamp; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
|
||||||
|
@Data |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor |
||||||
|
@Builder |
||||||
|
@TableGenerator( |
||||||
|
table = "COM_SEQ_BAS", |
||||||
|
name = "CNS_FAQ_BAS_SEQ", |
||||||
|
pkColumnValue = "FAQ_SNO", |
||||||
|
allocationSize = 1 |
||||||
|
) |
||||||
|
@Entity |
||||||
|
@Table(name = "CNS_FAQ_BAS") |
||||||
|
public class CnsFaqBas { |
||||||
|
|
||||||
|
// FAQ일련번호
|
||||||
|
@Id |
||||||
|
@GeneratedValue(strategy = GenerationType.TABLE, generator = "CNS_FAQ_BAS_SEQ") |
||||||
|
@Column(name = "FAQ_SNO") // mysql :: "int unsigned"
|
||||||
|
private Long faqSno; |
||||||
|
|
||||||
|
// 카테고리
|
||||||
|
@Column(name = "CATEGORY", length = 20) |
||||||
|
private String category; |
||||||
|
|
||||||
|
// 제목
|
||||||
|
@Column(name = "TITLE", nullable = false) |
||||||
|
private String title; |
||||||
|
|
||||||
|
// 내용
|
||||||
|
@Lob |
||||||
|
@Column(name = "CONTENT", columnDefinition = "text") |
||||||
|
private String content; |
||||||
|
|
||||||
|
// 조회수
|
||||||
|
@ColumnDefault("0") |
||||||
|
@Column(name = "VIEW_CNT", nullable = false) |
||||||
|
private Integer viewCnt; |
||||||
|
|
||||||
|
// 표출여부
|
||||||
|
@Column(name = "EXPSR_YN", columnDefinition = "char(1) default 'N'", nullable = false) |
||||||
|
private String expsrYn; |
||||||
|
|
||||||
|
// 삭제여부
|
||||||
|
@Column(name = "DEL_YN", columnDefinition = "char(1) default 'N'", nullable = false) |
||||||
|
private String delYn; |
||||||
|
|
||||||
|
// 등록사용자ID
|
||||||
|
@Column(name = "CREATE_USER_ID", length = 30, updatable = false, nullable = false) |
||||||
|
private String createUserId; |
||||||
|
|
||||||
|
// 등록일시
|
||||||
|
@CreationTimestamp |
||||||
|
@Column(name = "CREATE_DT", columnDefinition = "datetime", updatable = false, nullable = false) |
||||||
|
private LocalDateTime createDt; |
||||||
|
|
||||||
|
// 수정사용자ID
|
||||||
|
@Column(name = "UPDATE_USER_ID", length = 30, nullable = false) |
||||||
|
private String updateUserId; |
||||||
|
|
||||||
|
// 수정일시
|
||||||
|
@UpdateTimestamp |
||||||
|
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false) |
||||||
|
private LocalDateTime updateDt; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,104 @@ |
|||||||
|
package kr.co.palnet.kac.data.cns.model; |
||||||
|
|
||||||
|
import jakarta.persistence.*; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
import org.hibernate.annotations.ColumnDefault; |
||||||
|
|
||||||
|
import java.time.Instant; |
||||||
|
|
||||||
|
|
||||||
|
@Data |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor |
||||||
|
@Builder |
||||||
|
@TableGenerator( |
||||||
|
table = "COM_SEQ_BAS", |
||||||
|
name = "CNS_QNA_BAS_SEQ", |
||||||
|
pkColumnValue = "QNA_SNO", |
||||||
|
allocationSize = 1 |
||||||
|
) |
||||||
|
@Entity |
||||||
|
@Table(name = "CNS_QNA_BAS") |
||||||
|
public class CnsQnaBas { |
||||||
|
|
||||||
|
// QNA일련번호
|
||||||
|
@Id |
||||||
|
@GeneratedValue(strategy = GenerationType.TABLE, generator = "CNS_QNA_BAS_SEQ") |
||||||
|
@Column(name = "QNA_SNO") // mysql :: "int unsigned"
|
||||||
|
private Long qnaSno; |
||||||
|
|
||||||
|
// 상위QNA일련번호
|
||||||
|
@Column(name = "TARGET_SNO") // mysql :: "int unsigned"
|
||||||
|
private Long targetSno; |
||||||
|
|
||||||
|
// 카테고리
|
||||||
|
@Column(name = "CATEGORY", length = 20) |
||||||
|
private String category; |
||||||
|
|
||||||
|
// 제목
|
||||||
|
@Column(name = "TITLE", nullable = false) |
||||||
|
private String title; |
||||||
|
|
||||||
|
// 내용
|
||||||
|
@Lob |
||||||
|
@Column(name = "CONTENT", columnDefinition = "text") |
||||||
|
private String content; |
||||||
|
|
||||||
|
// 연락처
|
||||||
|
@Column(name = "CONTACT", length = 20) |
||||||
|
private String contact; |
||||||
|
|
||||||
|
// 답변내용
|
||||||
|
@Lob |
||||||
|
@Column(name = "ANSER_CONTENT", columnDefinition = "text") |
||||||
|
private String anserContent; |
||||||
|
|
||||||
|
// 답변자
|
||||||
|
@Column(name = "ANSER_USER_NM", length = 50) |
||||||
|
private String anserUserNm; |
||||||
|
|
||||||
|
// 답변처리일시
|
||||||
|
@Column(name = "ANSER_PROC_DT", columnDefinition = "datetime") |
||||||
|
private Instant anserProcDt; |
||||||
|
|
||||||
|
// 답변상태
|
||||||
|
@Column(name = "ANSER_STATUS", length = 10) |
||||||
|
private String anserStatus; // 질문, 답변중, 답변완료, 보류
|
||||||
|
|
||||||
|
// 파일그룹번호
|
||||||
|
@Column(name = "FILE_GROUP_NO") // mysql :: "int unsigned"
|
||||||
|
private Long fileGroupNo; |
||||||
|
|
||||||
|
// 표출여부
|
||||||
|
@Column(name = "EXPSR_YN", columnDefinition = "char(1) default 'N'", nullable = false) |
||||||
|
private String expsrYn; |
||||||
|
|
||||||
|
// 삭제여부
|
||||||
|
@Column(name = "DEL_YN", columnDefinition = "char(1) default 'N'", nullable = false) |
||||||
|
private String delYn; |
||||||
|
|
||||||
|
// 조회수
|
||||||
|
@ColumnDefault("0") |
||||||
|
@Column(name = "VIEW_CNT", nullable = false) |
||||||
|
private Integer viewCnt; |
||||||
|
|
||||||
|
// 등록사용자ID
|
||||||
|
@Column(name = "CREATE_USER_ID", length = 30, updatable = false, nullable = false) |
||||||
|
private String createUserId; |
||||||
|
|
||||||
|
// 등록일시
|
||||||
|
@Column(name = "CREATE_DT", columnDefinition = "datetime", updatable = false, nullable = false) |
||||||
|
private Instant createDt; |
||||||
|
|
||||||
|
// 수정사용자ID
|
||||||
|
@Column(name = "UPDATE_USER_ID", length = 30, nullable = false) |
||||||
|
private String updateUserId; |
||||||
|
|
||||||
|
// 수정일시
|
||||||
|
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false) |
||||||
|
private Instant updateDt; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
package kr.co.palnet.kac.data.cns.repository; |
||||||
|
|
||||||
|
|
||||||
|
import jakarta.transaction.Transactional; |
||||||
|
import kr.co.palnet.kac.data.cns.model.CnsFaqBas; |
||||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||||
|
import org.springframework.data.jpa.repository.Modifying; |
||||||
|
import org.springframework.data.jpa.repository.Query; |
||||||
|
import org.springframework.data.repository.query.Param; |
||||||
|
import org.springframework.stereotype.Repository; |
||||||
|
|
||||||
|
|
||||||
|
@Repository |
||||||
|
public interface CnsFaqBasRepository extends JpaRepository<CnsFaqBas, Integer> { |
||||||
|
|
||||||
|
@Modifying |
||||||
|
@Transactional |
||||||
|
@Query("update CnsFaqBas c set c.viewCnt = c.viewCnt + 1" + |
||||||
|
"where c.faqSno = :sno") |
||||||
|
int updateViewCnt(@Param("sno") int sno); |
||||||
|
|
||||||
|
@Modifying |
||||||
|
@Transactional |
||||||
|
@Query("update CnsFaqBas c set c.delYn = 'Y' " + |
||||||
|
"where c.faqSno = :sno") |
||||||
|
int deleteFaq(@Param("sno") int sno); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,165 @@ |
|||||||
|
package kr.co.palnet.kac.data.cns.repository; |
||||||
|
|
||||||
|
import com.querydsl.core.BooleanBuilder; |
||||||
|
import com.querydsl.core.types.Projections; |
||||||
|
import com.querydsl.jpa.impl.JPAQueryFactory; |
||||||
|
import kr.co.palnet.kac.data.cns.model.CnsFaqBas; |
||||||
|
import kr.co.palnet.kac.data.cns.model.QCnsFaqBas; |
||||||
|
import lombok.RequiredArgsConstructor; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.stereotype.Repository; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
@Slf4j |
||||||
|
@Repository |
||||||
|
@RequiredArgsConstructor |
||||||
|
public class CnsFaqQueryRepository { |
||||||
|
|
||||||
|
private final JPAQueryFactory query; |
||||||
|
/** |
||||||
|
* 조건값으로 FaQ리스트를 조회하는 SQL기능. |
||||||
|
* @param category |
||||||
|
* @param word |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public List<CnsFaqBas> getFaqList(String category, String word) { |
||||||
|
|
||||||
|
QCnsFaqBas bas = QCnsFaqBas.cnsFaqBas; |
||||||
|
|
||||||
|
BooleanBuilder builder = new BooleanBuilder(); |
||||||
|
builder.and(bas.delYn.eq("N")); |
||||||
|
builder.and(bas.expsrYn.eq("Y")); |
||||||
|
|
||||||
|
if (category != null) { |
||||||
|
builder.and(bas.category.eq(category)); |
||||||
|
} |
||||||
|
|
||||||
|
if (word != null) { |
||||||
|
builder.and(bas.title.contains(word)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 삭제여부[delYn]값이 'N' 조건, |
||||||
|
* 표출여부[expsrYn]값이 'Y' 조건, |
||||||
|
* 카테고리값[category]값 조건, |
||||||
|
* 제목[title] 값이 word와의 조건 값으로 조회하는 SQL 입니다. |
||||||
|
* |
||||||
|
* SELECT |
||||||
|
* CFB.FAQ_SNO , |
||||||
|
* CFB.CATEGORY , |
||||||
|
* CFB.TITLE , |
||||||
|
* CFB.CONTENT , |
||||||
|
* CFB.VIEW_CNT , |
||||||
|
* CFB.EXPSR_YN , |
||||||
|
* CFB.CREATE_USER_ID , |
||||||
|
* CFB.CREATE_DT , |
||||||
|
* CFB.UPDATE_USER_ID , |
||||||
|
* CFB.UPDATE_DT |
||||||
|
* FROM CNS_FAQ_BAS CFB |
||||||
|
* WHERE CFB.DEL_YN = 'N' |
||||||
|
* AND CFB.EXPSR_YN = 'Y' |
||||||
|
* AND CFB.CATEGORY = #{category} |
||||||
|
* AND CFB.TITLE = #{word} |
||||||
|
* ORDER BY CFB.CREATE_DT DESC |
||||||
|
*/ |
||||||
|
List<CnsFaqBas> r = query |
||||||
|
.select(Projections.bean( |
||||||
|
CnsFaqBas.class, |
||||||
|
bas.faqSno, |
||||||
|
bas.category, |
||||||
|
bas.title, |
||||||
|
bas.content, |
||||||
|
bas.viewCnt, |
||||||
|
bas.expsrYn, |
||||||
|
bas.createUserId, |
||||||
|
bas.createDt, |
||||||
|
bas.updateUserId, |
||||||
|
bas.updateDt |
||||||
|
)) |
||||||
|
.from(bas) |
||||||
|
.where(builder) |
||||||
|
.orderBy(bas.createDt.desc()) |
||||||
|
.fetch(); |
||||||
|
|
||||||
|
|
||||||
|
return r; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 일련번호[sno]로 상세정보를 조회하는 SQL 기능. |
||||||
|
* @param sno |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public CnsFaqBas getFaqDetail(int sno) { |
||||||
|
|
||||||
|
QCnsFaqBas bas = QCnsFaqBas.cnsFaqBas; |
||||||
|
|
||||||
|
BooleanBuilder builder = new BooleanBuilder(); |
||||||
|
builder.and(bas.faqSno.eq((long) sno)); |
||||||
|
builder.and(bas.expsrYn.eq("Y")); |
||||||
|
builder.and(bas.delYn.eq("N")); |
||||||
|
|
||||||
|
/** |
||||||
|
* 일련번호[faqSno] 조건, |
||||||
|
* 표출여부[expsrYn]가 'Y' 인지 조건, |
||||||
|
* 삭제여부[delYn]가 'N' 인지 조건으로 조회하는 SQL 입니다. |
||||||
|
* |
||||||
|
* SELECT |
||||||
|
* CFB.FAQ_SNO , |
||||||
|
* CFB.CATEGORY , |
||||||
|
* CFB.TITLE , |
||||||
|
* CFB.CONTENT , |
||||||
|
* CFB.VIEW_CNT , |
||||||
|
* CFB.EXPSR_YN , |
||||||
|
* CFB.CREATE_USER_ID , |
||||||
|
* CFB.CREATE_DT , |
||||||
|
* CFB.UPDATE_USER_ID , |
||||||
|
* CFB.UPDATE_DT |
||||||
|
* FROM CNS_FAQ_BAS CFB |
||||||
|
* WHERE CFB.FAQ_SNO = #{sno} |
||||||
|
* AND CFB.EXPSR_YN = 'Y' |
||||||
|
* AND CFB.DEL_YN = 'N' |
||||||
|
*/ |
||||||
|
CnsFaqBas r = query |
||||||
|
.select(Projections.bean( |
||||||
|
CnsFaqBas.class, |
||||||
|
bas.faqSno, |
||||||
|
bas.category, |
||||||
|
bas.title, |
||||||
|
bas.content, |
||||||
|
bas.viewCnt, |
||||||
|
bas.expsrYn, |
||||||
|
bas.createUserId, |
||||||
|
bas.createDt, |
||||||
|
bas.updateUserId, |
||||||
|
bas.updateDt |
||||||
|
)) |
||||||
|
.from(bas) |
||||||
|
.where(builder) |
||||||
|
.fetchOne(); |
||||||
|
|
||||||
|
|
||||||
|
return r; |
||||||
|
} |
||||||
|
|
||||||
|
public void updateFaq(CnsFaqBas model) { |
||||||
|
QCnsFaqBas bas = QCnsFaqBas.cnsFaqBas; |
||||||
|
|
||||||
|
BooleanBuilder builder = new BooleanBuilder(); |
||||||
|
builder.and(bas.faqSno.eq(model.getFaqSno())); |
||||||
|
|
||||||
|
query.update(bas) |
||||||
|
.set(bas.category, model.getCategory()) |
||||||
|
.set(bas.title, model.getTitle()) |
||||||
|
.set(bas.content, model.getContent()) |
||||||
|
.set(bas.viewCnt, model.getViewCnt()) |
||||||
|
.set(bas.expsrYn, model.getExpsrYn()) |
||||||
|
.set(bas.updateUserId, model.getUpdateUserId()) |
||||||
|
.set(bas.updateDt, model.getUpdateDt()) |
||||||
|
.where(builder) |
||||||
|
.execute(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
package kr.co.palnet.kac.data.cns.repository; |
||||||
|
|
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.cns.model.CnsQnaBas; |
||||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||||
|
import org.springframework.data.jpa.repository.Modifying; |
||||||
|
import org.springframework.data.jpa.repository.Query; |
||||||
|
import org.springframework.data.repository.query.Param; |
||||||
|
import org.springframework.stereotype.Repository; |
||||||
|
|
||||||
|
@Repository |
||||||
|
public interface CnsQnaBasRepository extends JpaRepository<CnsQnaBas, Integer> { |
||||||
|
|
||||||
|
CnsQnaBas findFirstByTargetSnoAndDelYnAndExpsrYn(int targetSno, String delYn, String expsrYn); |
||||||
|
|
||||||
|
CnsQnaBas findByQnaSnoAndDelYnAndExpsrYn(int qnaSno, String delYn, String expsrYn); |
||||||
|
|
||||||
|
CnsQnaBas findFirstByQnaSnoAndTargetSnoAndDelYnAndExpsrYn(int qnaSno, int targetSno, String delYn, String expsrYn); |
||||||
|
|
||||||
|
@Modifying |
||||||
|
@Query("UPDATE CnsQnaBas q SET q.viewCnt = q.viewCnt + 1 WHERE q.qnaSno = :qnaSno") |
||||||
|
void pulsViewCount(@Param("qnaSno")int qnaSno); |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
package kr.co.palnet.kac.data.cns.service; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.cns.model.CnsFaqBas; |
||||||
|
import kr.co.palnet.kac.data.cns.repository.CnsFaqBasRepository; |
||||||
|
import kr.co.palnet.kac.data.cns.repository.CnsFaqQueryRepository; |
||||||
|
import lombok.RequiredArgsConstructor; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.Optional; |
||||||
|
|
||||||
|
@Service |
||||||
|
@RequiredArgsConstructor |
||||||
|
public class CnsFaqDomainService { |
||||||
|
|
||||||
|
private final CnsFaqBasRepository cnsFaqBasRepository; |
||||||
|
private final CnsFaqQueryRepository query; |
||||||
|
|
||||||
|
public List<CnsFaqBas> getFaqList(String category, String word){ |
||||||
|
return query.getFaqList(category, word); |
||||||
|
} |
||||||
|
|
||||||
|
public void updateViewCnt(int sno){ |
||||||
|
cnsFaqBasRepository.updateViewCnt(sno); |
||||||
|
} |
||||||
|
|
||||||
|
public CnsFaqBas getFaqDetail(int sno){ |
||||||
|
return query.getFaqDetail(sno); |
||||||
|
} |
||||||
|
|
||||||
|
public CnsFaqBas saveFaqBas(CnsFaqBas cnsFaqBas){ |
||||||
|
return cnsFaqBasRepository.save(cnsFaqBas); |
||||||
|
} |
||||||
|
|
||||||
|
public Optional<CnsFaqBas> findById(int faqSno){ |
||||||
|
return cnsFaqBasRepository.findById(faqSno); |
||||||
|
} |
||||||
|
|
||||||
|
public int deleteFaq(int faqSno){ |
||||||
|
return cnsFaqBasRepository.deleteFaq(faqSno); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
|
||||||
|
dependencies { |
||||||
|
implementation "$boot:spring-boot-starter-data-jpa" |
||||||
|
|
||||||
|
implementation "com.querydsl:querydsl-jpa:5.0.0:jakarta" |
||||||
|
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" |
||||||
|
annotationProcessor "jakarta.annotation:jakarta.annotation-api" |
||||||
|
annotationProcessor "jakarta.persistence:jakarta.persistence-api" |
||||||
|
|
||||||
|
implementation project(":common:config-db") |
||||||
|
testRuntimeOnly "com.h2database:h2" |
||||||
|
} |
||||||
|
|
||||||
|
def querydslDir = layout.buildDirectory.dir("generated/querydsl").get().asFile |
||||||
|
|
||||||
|
sourceSets { |
||||||
|
main.java.srcDir(querydslDir) |
||||||
|
} |
||||||
|
|
||||||
|
tasks.withType(JavaCompile) { |
||||||
|
options.getGeneratedSourceOutputDirectory().set(file(querydslDir)) |
||||||
|
} |
||||||
|
|
||||||
|
clean { |
||||||
|
delete file(querydslDir) |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.domain; |
||||||
|
|
||||||
|
import jakarta.persistence.Column; |
||||||
|
import jakarta.persistence.Entity; |
||||||
|
import jakarta.persistence.Id; |
||||||
|
import jakarta.persistence.Table; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
|
||||||
|
@Data |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor |
||||||
|
@Builder |
||||||
|
@Entity |
||||||
|
@Table(name = "COM_ADM_DISTRICT_BAS") |
||||||
|
public class ComAdmDistrictBas { |
||||||
|
|
||||||
|
// 행정코드
|
||||||
|
@Id |
||||||
|
@Column(name = "ADM_CD", length = 10) |
||||||
|
private String admCd; |
||||||
|
// 행정구역명
|
||||||
|
@Column(name = "ADM_SECT_NM", length = 100) |
||||||
|
private String admSectNm; |
||||||
|
// 최하위행정구역명
|
||||||
|
@Column(name = "LOWEST_ADM_SECT_NM", length = 100) |
||||||
|
private String lowestAdmSectNm; |
||||||
|
// 레벨
|
||||||
|
@Column(name = "LEVEL") |
||||||
|
private Integer level; |
||||||
|
// 상위행정코드
|
||||||
|
@Column(name = "UP_ADM_CD", length = 10) |
||||||
|
private String upAdmCd; |
||||||
|
// 삭제일자
|
||||||
|
@Column(name = "DEL_YMD", length = 8) |
||||||
|
private String delYmd; |
||||||
|
// 변경전행정구역구분
|
||||||
|
@Column(name = "CHG_BEF_ADM_SECT_GBN", length = 1) |
||||||
|
private String chgBefAdmSectGbn; |
||||||
|
// 생성일자
|
||||||
|
@Column(name = "CRE_YMD", length = 8) |
||||||
|
private String creYmd; |
||||||
|
// 변경전행정구역코드
|
||||||
|
@Column(name = "CHG_BEF_ADM_SECT_CD", length = 10) |
||||||
|
private String chgBefAdmSectCd; |
||||||
|
// 원천시군구코드
|
||||||
|
@Column(name = "COL_ADM_SECT_CD", length = 5) |
||||||
|
private String colAdmSectCd; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,114 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.domain; |
||||||
|
|
||||||
|
import jakarta.persistence.*; |
||||||
|
import lombok.*; |
||||||
|
|
||||||
|
import java.time.Instant; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
|
||||||
|
@Data |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor |
||||||
|
@Builder |
||||||
|
@ToString(exclude = {"comIdntfBasList"}) |
||||||
|
@TableGenerator( |
||||||
|
table = "COM_SEQ_BAS", |
||||||
|
name = "COM_ARCRFT_BAS_SEQ", |
||||||
|
pkColumnValue = "ARCRFT_SNO", |
||||||
|
allocationSize = 1 |
||||||
|
) |
||||||
|
@Entity |
||||||
|
@Table(name = "COM_ARCRFT_BAS") |
||||||
|
public class ComArcrftBas { |
||||||
|
|
||||||
|
// 기체일련번호
|
||||||
|
@Id |
||||||
|
@GeneratedValue(strategy = GenerationType.TABLE, generator = "COM_ARCRFT_BAS_SEQ") |
||||||
|
@Column(name = "ARCRFT_SNO") // mysql :: "int unsigned"
|
||||||
|
private Long arcrftSno; |
||||||
|
|
||||||
|
// 그룹ID
|
||||||
|
@Column(name = "GROUP_ID", length = 50) |
||||||
|
private String groupId; |
||||||
|
|
||||||
|
// 제작번호
|
||||||
|
@Column(name = "PRDCT_NUM", length = 50, nullable = false) |
||||||
|
private String prdctNum; |
||||||
|
|
||||||
|
// 기체종류코드
|
||||||
|
@Column(name = "ARCRFT_TYPE_CD", length = 20, nullable = false) |
||||||
|
private String arcrftTypeCd; |
||||||
|
|
||||||
|
// 기체모델명
|
||||||
|
@Column(name = "ARCRFT_MODEL_NM", length = 50, nullable = false) |
||||||
|
private String arcrftModelNm; |
||||||
|
|
||||||
|
// 제작자
|
||||||
|
@Column(name = "PRDCT_CMPN_NM", length = 50) |
||||||
|
private String prdctCmpnNm; |
||||||
|
|
||||||
|
// 제작일자
|
||||||
|
@Column(name = "PRDCT_DATE", columnDefinition = "datetime") |
||||||
|
private Instant prdctDate; |
||||||
|
|
||||||
|
// 기체길이
|
||||||
|
@Column(name = "ARCRFT_LNGTH", columnDefinition = "double") |
||||||
|
private double arcrftLngth; |
||||||
|
|
||||||
|
// 기체폭
|
||||||
|
@Column(name = "ARCRFT_WDTH", columnDefinition = "double") |
||||||
|
private double arcrftWdth; |
||||||
|
|
||||||
|
// 기체높이
|
||||||
|
@Column(name = "ARCRFT_HGHT", columnDefinition = "double") |
||||||
|
private double arcrftHght; |
||||||
|
|
||||||
|
// 자체중량
|
||||||
|
@Column(name = "ARCRFT_WGHT", columnDefinition = "double") |
||||||
|
private double arcrftWght; |
||||||
|
|
||||||
|
// 중량구분코드
|
||||||
|
@Column(name = "WGHT_TYPE_CD", length = 20, nullable = false) |
||||||
|
private String wghtTypeCd; |
||||||
|
|
||||||
|
// 이미지URL
|
||||||
|
@Column(name = "IMAGE_URL", length = 200) |
||||||
|
private String imageUrl; |
||||||
|
|
||||||
|
// 최대이륙중량
|
||||||
|
@Column(name = "TAKEOFF_WGHT", columnDefinition = "double") |
||||||
|
private double takeoffWght; |
||||||
|
|
||||||
|
// 사용여부
|
||||||
|
@Column(name = "USE_YN", columnDefinition = "char(1) default 'N'", nullable = false) |
||||||
|
private String useYn; |
||||||
|
|
||||||
|
// 카메라탑재여부
|
||||||
|
@Column(name = "CAMERA_YN", columnDefinition = "char(1) default 'N'", nullable = false) |
||||||
|
private String cameraYn; |
||||||
|
|
||||||
|
// 보험가입여부
|
||||||
|
@Column(name = "INSRNC_YN", columnDefinition = "char(1) default 'N'", nullable = false) |
||||||
|
private String insrncYn; |
||||||
|
|
||||||
|
// 등록일자
|
||||||
|
@Column(name = "CREATE_DT", columnDefinition = "datetime", updatable = false, nullable = false) |
||||||
|
private Instant createDt; |
||||||
|
|
||||||
|
// 등록사용자ID
|
||||||
|
@Column(name = "CREATE_USER_ID", length = 30, updatable = false, nullable = false) |
||||||
|
private String createUserId; |
||||||
|
|
||||||
|
// 수정일자
|
||||||
|
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false) |
||||||
|
private Instant updateDt; |
||||||
|
|
||||||
|
// 수정사용자ID
|
||||||
|
@Column(name = "UPDATE_USER_ID", length = 30, nullable = false) |
||||||
|
private String updateUserId; |
||||||
|
|
||||||
|
@OneToMany(mappedBy = "comArcrftBas", fetch = FetchType.LAZY) |
||||||
|
private List<ComIdntfBas> comIdntfBasList; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.domain; |
||||||
|
|
||||||
|
import jakarta.persistence.*; |
||||||
|
import lombok.*; |
||||||
|
|
||||||
|
import java.time.Instant; |
||||||
|
|
||||||
|
|
||||||
|
@Data |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor |
||||||
|
@Builder |
||||||
|
@ToString(exclude = {"comSiteBas"}) |
||||||
|
@Entity |
||||||
|
@Table(name = "COM_AUTH_BAS") |
||||||
|
public class ComAuthBas { |
||||||
|
|
||||||
|
// 권한ID
|
||||||
|
@Id |
||||||
|
@Column(name = "AUTH_ID", length = 50) |
||||||
|
private String authId; |
||||||
|
|
||||||
|
// 사이트코드
|
||||||
|
@Column(name = "SITE_CD", length = 20, nullable = false) |
||||||
|
private String siteCd; |
||||||
|
|
||||||
|
// 권한명
|
||||||
|
@Column(name = "AUTH_NM", length = 100, nullable = false) |
||||||
|
private String authNm; |
||||||
|
|
||||||
|
// 사용여부
|
||||||
|
@Column(name = "USE_YN", columnDefinition = "char(1) default 'N'", nullable = false) |
||||||
|
private String useYn; |
||||||
|
|
||||||
|
// 비고
|
||||||
|
@Lob |
||||||
|
@Column(name = "RM", columnDefinition = "mediumtext") |
||||||
|
private String rm; |
||||||
|
|
||||||
|
// 생성사용자ID
|
||||||
|
@Column(name = "CREATE_USER_ID", length = 30, updatable = false, nullable = false) |
||||||
|
private String createUserId; |
||||||
|
|
||||||
|
// 생성일시
|
||||||
|
@Column(name = "CREATE_DT", columnDefinition = "datetime", updatable = false, nullable = false) |
||||||
|
private Instant createDt; |
||||||
|
|
||||||
|
// 수정사용자ID
|
||||||
|
@Column(name = "UPDATE_USER_ID", length = 30, nullable = false) |
||||||
|
private String updateUserId; |
||||||
|
|
||||||
|
// 수정일시
|
||||||
|
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false) |
||||||
|
private Instant updateDt; |
||||||
|
|
||||||
|
@JoinColumn( |
||||||
|
name = "SITE_CD", updatable = false, insertable = false, |
||||||
|
foreignKey = @ForeignKey(name = "FK_COM_AUTH_BAS_COM_SITE_BAS_SITE_CD") |
||||||
|
) |
||||||
|
@ManyToOne(fetch = FetchType.LAZY) |
||||||
|
private ComSiteBas comSiteBas; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,103 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.domain; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore; |
||||||
|
import jakarta.persistence.*; |
||||||
|
import lombok.*; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
|
||||||
|
@Data |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor |
||||||
|
@Builder |
||||||
|
@ToString(exclude = {"comCdGroupBas", "comCdLangCtgList"}) |
||||||
|
@IdClass(ComCdBas.ComCdBasId.class) |
||||||
|
@Entity |
||||||
|
@Table(name = "COM_CD_BAS") |
||||||
|
public class ComCdBas { |
||||||
|
|
||||||
|
|
||||||
|
@Data |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Builder |
||||||
|
public static class ComCdBasId implements Serializable { |
||||||
|
// 그룹코드
|
||||||
|
private String groupCd; |
||||||
|
// 코드ID
|
||||||
|
private String cdId; |
||||||
|
} |
||||||
|
|
||||||
|
// 그룹코드
|
||||||
|
@Id |
||||||
|
@Column(name = "GROUP_CD", length = 20) |
||||||
|
private String groupCd; |
||||||
|
|
||||||
|
// 코드ID
|
||||||
|
@Id |
||||||
|
@Column(name = "CD_ID", length = 30) |
||||||
|
private String cdId; |
||||||
|
|
||||||
|
// 상위코드
|
||||||
|
@Column(name = "UPPER_CD", length = 20) |
||||||
|
private String upperCd; |
||||||
|
|
||||||
|
// 정렬순서
|
||||||
|
@Column(name = "SORT_ORDR", columnDefinition = "tinyint default 0", nullable = false) |
||||||
|
private Integer sortOrdr; |
||||||
|
|
||||||
|
// 추가정보값
|
||||||
|
@Column(name = "ADD_INFO_VALUE", length = 100) |
||||||
|
private String addInfoValue; |
||||||
|
|
||||||
|
// 사용여부
|
||||||
|
@Column(name = "USE_YN", columnDefinition = "char(1) default 'Y'", nullable = false) |
||||||
|
private String useYn; |
||||||
|
|
||||||
|
// 생성사용자ID
|
||||||
|
@Column(name = "CREATE_USER_ID", length = 30, nullable = false, updatable = false) |
||||||
|
private String createUserId; |
||||||
|
|
||||||
|
// 생성일시
|
||||||
|
@Column(name = "CREATE_DT", columnDefinition = "datetime", nullable = false, updatable = false) |
||||||
|
private LocalDateTime createDt; |
||||||
|
|
||||||
|
// 수정사용자ID
|
||||||
|
@Column(name = "UPDATE_USER_ID", length = 30, nullable = false) |
||||||
|
private String updateUserId; |
||||||
|
|
||||||
|
// 수정일시
|
||||||
|
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false) |
||||||
|
private LocalDateTime updateDt; |
||||||
|
|
||||||
|
@JsonIgnore |
||||||
|
@ManyToOne(fetch = FetchType.LAZY) |
||||||
|
@JoinColumn( |
||||||
|
name = "GROUP_CD", updatable = false, insertable = false, |
||||||
|
foreignKey = @ForeignKey(name = "FK_COM_CD_BAS_TO_COM_CD_GROUP_BAS") |
||||||
|
) |
||||||
|
private ComCdGroupBas comCdGroupBas; |
||||||
|
|
||||||
|
@OneToMany(mappedBy = "comCdBas", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) |
||||||
|
private List<ComCdLangCtg> comCdLangCtgList; |
||||||
|
|
||||||
|
public void update(ComCdBas comCdBas) { |
||||||
|
if (comCdBas == null) return; |
||||||
|
|
||||||
|
if (comCdBas.getGroupCd() != null && !comCdBas.getGroupCd().isBlank()) this.groupCd = comCdBas.getGroupCd(); |
||||||
|
if (comCdBas.getCdId() != null && !comCdBas.getCdId().isBlank()) this.cdId = comCdBas.getCdId(); |
||||||
|
|
||||||
|
if (comCdBas.getUpperCd() != null && !comCdBas.getUpperCd().isBlank()) this.upperCd = comCdBas.getUpperCd(); |
||||||
|
if (comCdBas.getSortOrdr() != null) this.sortOrdr = comCdBas.getSortOrdr(); |
||||||
|
if (comCdBas.getAddInfoValue() != null && !comCdBas.getAddInfoValue().isBlank()) |
||||||
|
this.addInfoValue = comCdBas.getAddInfoValue(); |
||||||
|
if (comCdBas.getUseYn() != null && !comCdBas.getUseYn().isBlank()) this.useYn = comCdBas.getUseYn(); |
||||||
|
if (comCdBas.getUpdateUserId() != null && !comCdBas.getUpdateUserId().isBlank()) |
||||||
|
this.updateUserId = comCdBas.getUpdateUserId(); |
||||||
|
if (comCdBas.getUpdateDt() != null) this.updateDt = comCdBas.getUpdateDt(); |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,70 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.domain; |
||||||
|
|
||||||
|
import jakarta.persistence.*; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
|
||||||
|
@Data |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Builder |
||||||
|
@Entity |
||||||
|
@Table(name = "COM_CD_GROUP_BAS") |
||||||
|
public class ComCdGroupBas { |
||||||
|
|
||||||
|
// 그룹코드
|
||||||
|
@Id |
||||||
|
@Column(name = "GROUP_CD", length = 20) |
||||||
|
private String groupCd; |
||||||
|
|
||||||
|
// 사이트코드
|
||||||
|
@Column(name = "SITE_CD", length = 20, nullable = false) |
||||||
|
private String siteCd; |
||||||
|
|
||||||
|
// 그룹코드명
|
||||||
|
@Column(name = "GROUP_CD_NM", length = 100, nullable = false) |
||||||
|
private String groupCdNm; |
||||||
|
|
||||||
|
// 비고
|
||||||
|
@Lob |
||||||
|
@Column(name = "RM", columnDefinition = "mediumtext") |
||||||
|
private String rm; |
||||||
|
|
||||||
|
// 생성사용자ID
|
||||||
|
@Column(name = "CREATE_USER_ID", length = 30, nullable = false, updatable = false) |
||||||
|
private String createUserId; |
||||||
|
|
||||||
|
// 생성일시
|
||||||
|
@Column(name = "CREATE_DT", columnDefinition = "datetime", nullable = false, updatable = false) |
||||||
|
private LocalDateTime createDt; |
||||||
|
|
||||||
|
// 수정사용자ID
|
||||||
|
@Column(name = "UPDATE_USER_ID", length = 30, nullable = false) |
||||||
|
private String updateUserId; |
||||||
|
|
||||||
|
// 수정일시
|
||||||
|
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false) |
||||||
|
private LocalDateTime updateDt; |
||||||
|
|
||||||
|
@OneToMany(mappedBy = "comCdGroupBas", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) |
||||||
|
private List<ComCdBas> comCdBasList; |
||||||
|
|
||||||
|
public void update(ComCdGroupBas comCdGroupBas) { |
||||||
|
if(comCdGroupBas == null) return; |
||||||
|
// if(comCdGroupBas.getGroupCd() != null && this.groupCd != null && !this.groupCd.equals(comCdGroupBas.getGroupCd())) return;
|
||||||
|
|
||||||
|
if(comCdGroupBas.getGroupCd() != null && !comCdGroupBas.getGroupCd().isBlank()) this.groupCd = comCdGroupBas.getGroupCd(); |
||||||
|
if(comCdGroupBas.getSiteCd() != null && !comCdGroupBas.getSiteCd().isBlank()) this.siteCd = comCdGroupBas.getSiteCd(); |
||||||
|
if(comCdGroupBas.getGroupCdNm() != null && !comCdGroupBas.getGroupCdNm().isBlank()) this.groupCdNm = comCdGroupBas.getGroupCdNm(); |
||||||
|
if(comCdGroupBas.getRm() != null && !comCdGroupBas.getRm().isBlank()) this.rm = comCdGroupBas.getRm(); |
||||||
|
|
||||||
|
if(comCdGroupBas.getUpdateUserId() != null && !comCdGroupBas.getUpdateUserId().isBlank()) this.updateUserId = comCdGroupBas.getUpdateUserId(); |
||||||
|
if(comCdGroupBas.getUpdateDt() != null) this.updateDt = comCdGroupBas.getUpdateDt(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,106 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.domain; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore; |
||||||
|
import jakarta.persistence.*; |
||||||
|
import lombok.*; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.time.LocalDateTime; |
||||||
|
|
||||||
|
@Data |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Builder |
||||||
|
@ToString(exclude = {"comCdBas"}) |
||||||
|
@IdClass(ComCdLangCtg.ComCdLangCtgId.class) |
||||||
|
@Entity |
||||||
|
@Table(name = "COM_CD_LANG_CTG") |
||||||
|
public class ComCdLangCtg { |
||||||
|
|
||||||
|
@Data |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Builder |
||||||
|
public static class ComCdLangCtgId implements Serializable { |
||||||
|
// 그룹코드
|
||||||
|
private String groupCd; |
||||||
|
// 코드ID
|
||||||
|
private String cdId; |
||||||
|
// 언어구분코드
|
||||||
|
private String langDivCd; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// 그룹코드
|
||||||
|
@Id |
||||||
|
@Column(name = "GROUP_CD", length = 20) |
||||||
|
private String groupCd; |
||||||
|
|
||||||
|
// 코드ID
|
||||||
|
@Id |
||||||
|
@Column(name = "CD_ID", length = 30) |
||||||
|
private String cdId; |
||||||
|
|
||||||
|
// 언어구분코드
|
||||||
|
@Id |
||||||
|
@Column(name = "LANG_DIV_CD", length = 5) |
||||||
|
private String langDivCd; |
||||||
|
|
||||||
|
// 코드명
|
||||||
|
@Column(name = "CD_NM", length = 100, nullable = false) |
||||||
|
private String cdNm; |
||||||
|
|
||||||
|
// 비고
|
||||||
|
@Lob |
||||||
|
@Column(name = "RM", columnDefinition = "mediumtext") |
||||||
|
private String rm; |
||||||
|
|
||||||
|
// 생성사용자ID
|
||||||
|
@Column(name = "CREATE_USER_ID", length = 30, nullable = false, updatable = false) |
||||||
|
private String createUserId; |
||||||
|
|
||||||
|
// 생성일시
|
||||||
|
@Column(name = "CREATE_DT", columnDefinition = "datetime", nullable = false, updatable = false) |
||||||
|
private LocalDateTime createDt; |
||||||
|
|
||||||
|
// 수정사용자ID
|
||||||
|
@Column(name = "UPDATE_USER_ID", length = 30, nullable = false) |
||||||
|
private String updateUserId; |
||||||
|
|
||||||
|
// 수정일시
|
||||||
|
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false) |
||||||
|
private LocalDateTime updateDt; |
||||||
|
|
||||||
|
@JsonIgnore |
||||||
|
@ManyToOne(fetch = FetchType.LAZY) |
||||||
|
@JoinColumns( |
||||||
|
value = { |
||||||
|
@JoinColumn(name = "GROUP_CD", referencedColumnName = "GROUP_CD", insertable = false, updatable = false), |
||||||
|
@JoinColumn(name = "CD_ID", referencedColumnName = "CD_ID", insertable = false, updatable = false) |
||||||
|
}, |
||||||
|
foreignKey = @ForeignKey(name = "FK_COM_CD_LANG_CTG_COM_CD_BAS") |
||||||
|
) |
||||||
|
private ComCdBas comCdBas; |
||||||
|
|
||||||
|
public void update(ComCdLangCtg comCdLangCtg) { |
||||||
|
if (comCdLangCtg == null) return; |
||||||
|
// if(comCdLangCtg.getId() != null) {
|
||||||
|
// if(comCdLangCtg.getId().getComCdBasId() != null) {
|
||||||
|
// if(comCdLangCtg.getId().getComCdBasId().getGroupCd() != null && !comCdLangCtg.getId().getComCdBasId().getGroupCd().isBlank()) this.id.comCdBasId.setGroupCd(comCdLangCtg.getId().getComCdBasId().getGroupCd());
|
||||||
|
// if(comCdLangCtg.getId().getComCdBasId().getCdId() != null && !comCdLangCtg.getId().getComCdBasId().getCdId().isBlank()) this.id.comCdBasId.setCdId(comCdLangCtg.getId().getComCdBasId().getCdId());
|
||||||
|
// }
|
||||||
|
// if(comCdLangCtg.getId().getLangDivCd() != null && !comCdLangCtg.getId().getLangDivCd().isBlank()) this.id.langDivCd = comCdLangCtg.getId().getLangDivCd();
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (comCdLangCtg.getGroupCd() != null && !comCdLangCtg.getGroupCd().isBlank()) this.groupCd = comCdLangCtg.getGroupCd(); |
||||||
|
if (comCdLangCtg.getCdId() != null && !comCdLangCtg.getCdId().isBlank()) this.cdId = comCdLangCtg.getCdId(); |
||||||
|
if (comCdLangCtg.getLangDivCd() != null && !comCdLangCtg.getLangDivCd().isBlank()) |
||||||
|
this.langDivCd = comCdLangCtg.getLangDivCd(); |
||||||
|
|
||||||
|
if (comCdLangCtg.getCdNm() != null && !comCdLangCtg.getCdNm().isBlank()) this.cdNm = comCdLangCtg.getCdNm(); |
||||||
|
if (comCdLangCtg.getRm() != null && !comCdLangCtg.getRm().isBlank()) this.rm = comCdLangCtg.getRm(); |
||||||
|
if (comCdLangCtg.getUpdateUserId() != null && !comCdLangCtg.getUpdateUserId().isBlank()) |
||||||
|
this.updateUserId = comCdLangCtg.getUpdateUserId(); |
||||||
|
if (comCdLangCtg.getUpdateDt() != null) this.updateDt = comCdLangCtg.getUpdateDt(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,74 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.domain; |
||||||
|
|
||||||
|
import jakarta.persistence.*; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
import java.time.Instant; |
||||||
|
|
||||||
|
@Data |
||||||
|
@Builder |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@TableGenerator( |
||||||
|
table = "COM_SEQ_BAS", |
||||||
|
name = "COM_CONFIRM_BAS_SEQ", |
||||||
|
pkColumnValue = "CONFIRM_SNO", |
||||||
|
allocationSize = 1 |
||||||
|
) |
||||||
|
@Entity |
||||||
|
@Table(name = "COM_CONFIRM_BAS") |
||||||
|
public class ComConfirmBas { |
||||||
|
|
||||||
|
// 확인일련번호
|
||||||
|
@Id |
||||||
|
@GeneratedValue(strategy = GenerationType.TABLE, generator = "COM_CONFIRM_BAS_SEQ") |
||||||
|
@Column(name = "CONFIRM_SNO") // mysql :: "int unsigned"
|
||||||
|
private Long confirmSno; |
||||||
|
|
||||||
|
// 확인키
|
||||||
|
@Column(name = "CONFIRM_KEY", length = 50, nullable = false) |
||||||
|
private String confirmKey; |
||||||
|
|
||||||
|
// 상태
|
||||||
|
@Column(name = "STATUS", length = 20, nullable = false) |
||||||
|
private String status; // GENERATED, RECEIVED, CHECKED, FAILED, EXPIRED
|
||||||
|
|
||||||
|
// 대상구분
|
||||||
|
@Column(name = "TARGET_TYPE", length = 100) |
||||||
|
private String targetType; |
||||||
|
|
||||||
|
// RQ 데이터
|
||||||
|
@Lob |
||||||
|
@Column(name = "RQ_DATA", columnDefinition = "text") |
||||||
|
private String rqData; |
||||||
|
|
||||||
|
// RS 데이터
|
||||||
|
@Lob |
||||||
|
@Column(name = "RS_DATA", columnDefinition = "text") |
||||||
|
private String rsData; |
||||||
|
|
||||||
|
// 비고
|
||||||
|
@Lob |
||||||
|
@Column(name = "RM", columnDefinition = "text") |
||||||
|
private String rm; |
||||||
|
|
||||||
|
// 생성사용자ID
|
||||||
|
@Column(name = "CREATE_USER_ID", length = 30, updatable = false, nullable = false) |
||||||
|
private String createUserId; |
||||||
|
|
||||||
|
// 생성일시
|
||||||
|
@Column(name = "CREATE_DT", columnDefinition = "datetime", updatable = false, nullable = false) |
||||||
|
private Instant createDt; |
||||||
|
|
||||||
|
// 수정사용자ID
|
||||||
|
@Column(name = "UPDATE_USER_ID", length = 30, nullable = false) |
||||||
|
private String updateUserId; |
||||||
|
|
||||||
|
// 수정일시
|
||||||
|
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false) |
||||||
|
private Instant updateDt; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,85 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.domain; |
||||||
|
|
||||||
|
import jakarta.persistence.*; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
import java.time.Instant; |
||||||
|
|
||||||
|
|
||||||
|
@Data |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Builder |
||||||
|
@TableGenerator( |
||||||
|
table = "COM_SEQ_BAS", |
||||||
|
name = "COM_FILE_BAS_SEQ", |
||||||
|
pkColumnValue = "FILE_SNO", |
||||||
|
allocationSize = 1 |
||||||
|
) |
||||||
|
@Entity |
||||||
|
@Table(name = "COM_FILE_BAS") |
||||||
|
public class ComFileBas { |
||||||
|
// 파일일련번호
|
||||||
|
@Id |
||||||
|
@GeneratedValue(strategy = GenerationType.TABLE, generator = "COM_FILE_BAS_SEQ") |
||||||
|
@Column(name = "FILE_SNO") // mysql :: "int unsigned"
|
||||||
|
private Long fileSno; |
||||||
|
|
||||||
|
// 파일그룹번호
|
||||||
|
@Column(name = "FILE_GROUP_NO") // mysql :: "int unsigned"
|
||||||
|
private Long fileGroupNo; |
||||||
|
|
||||||
|
// 저장된파일명
|
||||||
|
@Column(name = "FILE_SAVE_NM", length = 200, nullable = false) |
||||||
|
private String fileSaveNm; |
||||||
|
|
||||||
|
// 실제파일명
|
||||||
|
@Column(name = "FILE_ORI_NM", length = 200) |
||||||
|
private String fileOriNm; |
||||||
|
|
||||||
|
// 파일저장경로
|
||||||
|
@Column(name = "FILE_PATH", length = 200) |
||||||
|
private String filePath; |
||||||
|
|
||||||
|
// 파일확장명
|
||||||
|
@Column(name = "FILE_EXT", length = 30) |
||||||
|
private String fileExt; |
||||||
|
|
||||||
|
// 파일크기
|
||||||
|
@Column(name = "FILE_SIZE", length = 30) |
||||||
|
private String fileSize; |
||||||
|
|
||||||
|
// 삭제여부
|
||||||
|
@Column(name = "DEL_YN", columnDefinition = "char(1) default 'N'", nullable = false) |
||||||
|
private String delYn; |
||||||
|
|
||||||
|
// 삭제사용자ID
|
||||||
|
@Column(name = "DEL_USER_ID", length = 30) |
||||||
|
private String delUserId; |
||||||
|
|
||||||
|
// 삭제일시
|
||||||
|
@Column(name = "DEL_DT", columnDefinition = "datetime") |
||||||
|
private Instant delDt; |
||||||
|
|
||||||
|
// 생성사용자ID
|
||||||
|
@Column(name = "CREATE_USER_ID", length = 30, updatable = false, nullable = false) |
||||||
|
private String createUserId; |
||||||
|
|
||||||
|
// 생성일시
|
||||||
|
@Column(name = "CREATE_DT", columnDefinition = "datetime", updatable = false, nullable = false) |
||||||
|
private Instant createDt; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,72 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.domain; |
||||||
|
|
||||||
|
import jakarta.persistence.*; |
||||||
|
import lombok.*; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.time.Instant; |
||||||
|
|
||||||
|
|
||||||
|
@Data |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Builder |
||||||
|
@ToString(exclude = {"comArcrftBas"}) |
||||||
|
@IdClass(ComIdntfBas.ComIdntfBasId.class) |
||||||
|
@Entity |
||||||
|
@Table(name = "COM_IDNTF_BAS") |
||||||
|
public class ComIdntfBas { |
||||||
|
|
||||||
|
@Data |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Builder |
||||||
|
public static class ComIdntfBasId implements Serializable { |
||||||
|
// 식별번호
|
||||||
|
private String idntfNum; |
||||||
|
// 기체일련번호
|
||||||
|
private Long arcrftSno; |
||||||
|
} |
||||||
|
|
||||||
|
// 식별번호
|
||||||
|
@Id |
||||||
|
@Column(name = "IDNTF_NUM", length = 30) |
||||||
|
private String idntfNum; |
||||||
|
|
||||||
|
// 기체일련번호
|
||||||
|
@Id |
||||||
|
@Column(name = "ARCRFT_SNO") // mysql :: "int unsigned"
|
||||||
|
private Long arcrftSno; |
||||||
|
|
||||||
|
// 식별장치종류코드
|
||||||
|
@Column(name = "IDNTF_TYPE_CD", length = 20, nullable = false) |
||||||
|
private String idntfTypeCd; |
||||||
|
|
||||||
|
// 소유자명
|
||||||
|
@Column(name = "OWNER_NM", length = 100, nullable = false) |
||||||
|
private String ownerNm; |
||||||
|
|
||||||
|
// 고객일련번호(소유자)
|
||||||
|
@Column(name = "CSTMR_SNO") // mysql :: "int unsigned"
|
||||||
|
private Long cstmrSno; |
||||||
|
|
||||||
|
// 휴대폰번호
|
||||||
|
@Column(name = "HPNO", length = 100, nullable = false) |
||||||
|
private String hpno; |
||||||
|
|
||||||
|
// 등록일자
|
||||||
|
@Column(name = "CREATE_DT", columnDefinition = "datetime", updatable = false, nullable = false) |
||||||
|
private Instant createDt; |
||||||
|
|
||||||
|
// 수정일자
|
||||||
|
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false) |
||||||
|
private Instant updateDt; |
||||||
|
|
||||||
|
@JoinColumn( |
||||||
|
name = "ARCRFT_SNO", updatable = false, insertable = false, |
||||||
|
foreignKey = @ForeignKey(name = "FK_COM_IDNTF_BAS_COM_ARCRFT_BAS_ARCRFT_SNO") |
||||||
|
) |
||||||
|
@ManyToOne(fetch = FetchType.LAZY) |
||||||
|
private ComArcrftBas comArcrftBas; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,111 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.domain; |
||||||
|
|
||||||
|
import jakarta.persistence.*; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
import org.hibernate.annotations.CreationTimestamp; |
||||||
|
import org.hibernate.annotations.UpdateTimestamp; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.time.Instant; |
||||||
|
|
||||||
|
@Data |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Builder |
||||||
|
@IdClass(ComRiseSetBas.ComRiseSetBasId.class) |
||||||
|
@Entity |
||||||
|
@Table(name = "COM_RISE_SET_BAS") |
||||||
|
public class ComRiseSetBas { |
||||||
|
|
||||||
|
@Data |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Builder |
||||||
|
public static class ComRiseSetBasId implements Serializable { |
||||||
|
|
||||||
|
// 날짜
|
||||||
|
private String locDate; |
||||||
|
// 지역
|
||||||
|
private String location; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// 날짜
|
||||||
|
@Id |
||||||
|
@Column(name = "LOC_DATE", length = 8) |
||||||
|
private String locDate; |
||||||
|
|
||||||
|
// 지역
|
||||||
|
@Id |
||||||
|
@Column(name = "LOCATION", length = 100) |
||||||
|
private String location; |
||||||
|
|
||||||
|
// 경도
|
||||||
|
@Column(name = "LON", columnDefinition = "double") |
||||||
|
private Double lon; |
||||||
|
|
||||||
|
// 위도
|
||||||
|
@Column(name = "LAT" , columnDefinition = "double") |
||||||
|
private Double lat; |
||||||
|
|
||||||
|
// 일출
|
||||||
|
@Column(name = "SUNRISE", length = 6) |
||||||
|
private String sunrise; |
||||||
|
|
||||||
|
// 일증
|
||||||
|
@Column(name = "SUNTRANSIT", length = 6) |
||||||
|
private String suntransit; |
||||||
|
|
||||||
|
// 일몰
|
||||||
|
@Column(name = "SUNSET", length = 6) |
||||||
|
private String sunset; |
||||||
|
|
||||||
|
// 월출
|
||||||
|
@Column(name = "MOONRISE", length = 6) |
||||||
|
private String moonrise; |
||||||
|
|
||||||
|
// 월중
|
||||||
|
@Column(name = "MOONTRANSIT", length = 6) |
||||||
|
private String moontransit; |
||||||
|
|
||||||
|
// 월몰
|
||||||
|
@Column(name = "MOONSET", length = 6) |
||||||
|
private String moonset; |
||||||
|
|
||||||
|
// 시민박명(아침)
|
||||||
|
@Column(name = "CIVILM", length = 6) |
||||||
|
private String civilm; |
||||||
|
|
||||||
|
// 시민박명(저녁)
|
||||||
|
@Column(name = "CIVILE", length = 6) |
||||||
|
private String civile; |
||||||
|
|
||||||
|
// 황해박명(아침)
|
||||||
|
@Column(name = "NAUTM", length = 6) |
||||||
|
private String nautm; |
||||||
|
|
||||||
|
// 황해박명(저녁)
|
||||||
|
@Column(name = "NAUTE", length = 6) |
||||||
|
private String naute; |
||||||
|
|
||||||
|
// 천문박명(아침)
|
||||||
|
@Column(name = "ASTM", length = 6) |
||||||
|
private String astm; |
||||||
|
|
||||||
|
// 춘문박명(저녁)
|
||||||
|
@Column(name = "ASTE", length = 6) |
||||||
|
private String aste; |
||||||
|
|
||||||
|
// 수정일시
|
||||||
|
@Column(name = "UPDATE_DT", columnDefinition = "datetime") |
||||||
|
private Instant updateDt; |
||||||
|
|
||||||
|
// 등록일시
|
||||||
|
@Column(name = "CREATE_DT", columnDefinition = "datetime", updatable = false) |
||||||
|
private Instant createDt; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.domain; |
||||||
|
|
||||||
|
import jakarta.persistence.*; |
||||||
|
import lombok.*; |
||||||
|
|
||||||
|
import java.time.Instant; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
|
||||||
|
@Data |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Builder |
||||||
|
@ToString(exclude = {"comAuthBasList"}) |
||||||
|
@Entity |
||||||
|
@Table(name = "COM_SITE_BAS") |
||||||
|
public class ComSiteBas { |
||||||
|
|
||||||
|
// 사이트코드
|
||||||
|
@Id |
||||||
|
@Column(name = "SITE_CD", length = 20) |
||||||
|
private String siteCd; |
||||||
|
|
||||||
|
// 사이트경로
|
||||||
|
@Column(name = "SITE_URL", length = 50, nullable = false) |
||||||
|
private String siteUrl; |
||||||
|
|
||||||
|
// 사이트명
|
||||||
|
@Column(name = "SITE_NM", length = 50, nullable = false) |
||||||
|
private String siteNm; |
||||||
|
|
||||||
|
// 사이트설명
|
||||||
|
@Lob |
||||||
|
@Column(name = "SITE_DESC", columnDefinition = "text") |
||||||
|
private String siteDesc; |
||||||
|
|
||||||
|
// 사용여부
|
||||||
|
@Column(name = "USE_YN", columnDefinition = "char(1) default 'N'", nullable = false) |
||||||
|
private String useYn; |
||||||
|
|
||||||
|
// 등록일자
|
||||||
|
@Column(name = "CREATE_DT", columnDefinition = "datetime", updatable = false, nullable = false) |
||||||
|
private Instant createDt; |
||||||
|
|
||||||
|
// 등록사용자
|
||||||
|
@Column(name = "CREATE_USER_ID", length = 30, updatable = false, nullable = false) |
||||||
|
private String createUserId; |
||||||
|
|
||||||
|
// 수정일자
|
||||||
|
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false) |
||||||
|
private Instant updateDt; |
||||||
|
|
||||||
|
// 수정사용자
|
||||||
|
@Column(name = "UPDATE_USER_ID", length = 30, nullable = false) |
||||||
|
private String updateUserId; |
||||||
|
|
||||||
|
@OneToMany(mappedBy = "comSiteBas", fetch = FetchType.LAZY) |
||||||
|
private List<ComAuthBas> comAuthBasList; |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.domain; |
||||||
|
|
||||||
|
import jakarta.persistence.Column; |
||||||
|
import jakarta.persistence.Entity; |
||||||
|
import jakarta.persistence.Id; |
||||||
|
import jakarta.persistence.Table; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
import java.time.Instant; |
||||||
|
|
||||||
|
@Data |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Builder |
||||||
|
@Entity |
||||||
|
@Table(name = "COM_TRMNL_BAS") |
||||||
|
public class ComTrmnlBas { |
||||||
|
|
||||||
|
// 터미널ID
|
||||||
|
@Id |
||||||
|
@Column(name = "TRMNL_ID", length = 20) |
||||||
|
private String trmnlId; |
||||||
|
|
||||||
|
// 터미널명
|
||||||
|
@Column(name = "TRMNL_NM", length = 100, nullable = false) |
||||||
|
private String trmnlNm; |
||||||
|
|
||||||
|
// 인증KEY
|
||||||
|
@Column(name = "AUTH_KEY", length = 100, nullable = false) |
||||||
|
private String authKey; |
||||||
|
|
||||||
|
// 터미널설명
|
||||||
|
@Column(name = "DESC_SN") |
||||||
|
private String descSn; |
||||||
|
|
||||||
|
// 사용여부
|
||||||
|
@Column(name = "USE_YN", columnDefinition = "char(1) default 'N'", nullable = false) |
||||||
|
private String useYn; |
||||||
|
// 등록일시
|
||||||
|
@Column(name = "CREATE_DT", columnDefinition = "datetime", updatable = false, nullable = false) |
||||||
|
private Instant createDt; |
||||||
|
|
||||||
|
// 등록사용자ID
|
||||||
|
@Column(name = "CREATE_USER_ID", length = 30, updatable = false, nullable = false) |
||||||
|
private String createUserId; |
||||||
|
|
||||||
|
// 수정일시
|
||||||
|
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false) |
||||||
|
private Instant updateDt; |
||||||
|
|
||||||
|
// 수정사용자ID
|
||||||
|
@Column(name = "UPDATE_USER_ID", length = 30, nullable = false) |
||||||
|
private String updateUserId; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.repository; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.com.domain.ComAdmDistrictBas; |
||||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||||
|
|
||||||
|
public interface ComAdmDistrictBasRepository extends JpaRepository<ComAdmDistrictBas, String> { |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.repository; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.com.domain.ComArcrftBas; |
||||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||||
|
|
||||||
|
public interface ComArcrftBasRepository extends JpaRepository<ComArcrftBas, Integer> { |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.repository; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.com.domain.ComAuthBas; |
||||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||||
|
|
||||||
|
public interface ComAuthBasRepository extends JpaRepository<ComAuthBas, String>{ |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.repository; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.com.domain.ComCdBas; |
||||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public interface ComCdBasRepository extends JpaRepository<ComCdBas, ComCdBas.ComCdBasId> { |
||||||
|
|
||||||
|
List<ComCdBas> findByGroupCdAndUseYnOrderBySortOrdrAsc(String groupCd, String y); |
||||||
|
|
||||||
|
ComCdBas findByGroupCdAndCdIdAndUseYn(String groupCd, String cdId, String useYn); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.repository; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.com.domain.ComCdGroupBas; |
||||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public interface ComCdGroupBasRepository extends JpaRepository<ComCdGroupBas, String> { |
||||||
|
List<ComCdGroupBas> findBySiteCd(String siteCd); |
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.repository; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.com.domain.ComCdLangCtg; |
||||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public interface ComCdLangCtgRepository extends JpaRepository<ComCdLangCtg, ComCdLangCtg.ComCdLangCtgId> { |
||||||
|
List<ComCdLangCtg> findByGroupCdAndCdId(String groupCd, String cdId); |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.repository; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.com.domain.ComConfirmBas; |
||||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||||
|
|
||||||
|
public interface ComConfirmBasRepository extends JpaRepository<ComConfirmBas, Integer> { |
||||||
|
|
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.repository; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.com.domain.ComFileBas; |
||||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||||
|
|
||||||
|
public interface ComFileBasRepository extends JpaRepository<ComFileBas, Integer> { |
||||||
|
|
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.repository; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.com.domain.ComIdntfBas; |
||||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||||
|
|
||||||
|
public interface ComIdntBasRepository extends JpaRepository<ComIdntfBas, String> { |
||||||
|
|
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.repository; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.com.domain.ComRiseSetBas; |
||||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||||
|
|
||||||
|
public interface ComRiseSetBasRepository extends JpaRepository<ComRiseSetBas, ComRiseSetBas.ComRiseSetBasId> { |
||||||
|
|
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.repository; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.com.domain.ComSiteBas; |
||||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||||
|
|
||||||
|
public interface ComSiteBasRepository extends JpaRepository<ComSiteBas, String>{ |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.repository; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.com.domain.ComTrmnlBas; |
||||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||||
|
|
||||||
|
public interface ComTrmnlBasRepository extends JpaRepository<ComTrmnlBas, String>{ |
||||||
|
} |
@ -0,0 +1,212 @@ |
|||||||
|
package kr.co.palnet.kac.data.com.service; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.data.com.domain.ComCdBas; |
||||||
|
import kr.co.palnet.kac.data.com.domain.ComCdGroupBas; |
||||||
|
import kr.co.palnet.kac.data.com.domain.ComCdLangCtg; |
||||||
|
import kr.co.palnet.kac.data.com.repository.ComCdBasRepository; |
||||||
|
import kr.co.palnet.kac.data.com.repository.ComCdGroupBasRepository; |
||||||
|
import kr.co.palnet.kac.data.com.repository.ComCdLangCtgRepository; |
||||||
|
import lombok.RequiredArgsConstructor; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
import org.springframework.transaction.annotation.Transactional; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
@Slf4j |
||||||
|
@Transactional |
||||||
|
@RequiredArgsConstructor |
||||||
|
@Service |
||||||
|
public class ComCodeDomainService { |
||||||
|
|
||||||
|
private final ComCdGroupBasRepository comCdGroupBasRepository; |
||||||
|
private final ComCdBasRepository comCdBasRepository; |
||||||
|
private final ComCdLangCtgRepository comCdLangCtgRepository; |
||||||
|
|
||||||
|
|
||||||
|
// 그룹 조회
|
||||||
|
@Transactional(readOnly = true) |
||||||
|
public List<ComCdGroupBas> getComCdGroupBasList() { |
||||||
|
return comCdGroupBasRepository.findAll(); |
||||||
|
} |
||||||
|
|
||||||
|
@Transactional(readOnly = true) |
||||||
|
public List<ComCdGroupBas> getComCdGroupBasList(String siteCd) { |
||||||
|
return comCdGroupBasRepository.findBySiteCd(siteCd); |
||||||
|
} |
||||||
|
|
||||||
|
@Transactional(readOnly = true) |
||||||
|
public ComCdGroupBas getComCdGroupBas(String groupCd) { |
||||||
|
return comCdGroupBasRepository.findById(groupCd).orElse(null); |
||||||
|
} |
||||||
|
|
||||||
|
// 코드 조회
|
||||||
|
@Transactional(readOnly = true) |
||||||
|
public List<ComCdBas> getComCdBasList(String groupCd) { |
||||||
|
return comCdBasRepository.findByGroupCdAndUseYnOrderBySortOrdrAsc(groupCd, "Y"); |
||||||
|
} |
||||||
|
|
||||||
|
@Transactional(readOnly = true) |
||||||
|
public ComCdBas getComCdBas(String groupCd, String cdId) { |
||||||
|
return comCdBasRepository.findByGroupCdAndCdIdAndUseYn(groupCd, cdId, "Y"); |
||||||
|
} |
||||||
|
|
||||||
|
// 언어 조회
|
||||||
|
@Transactional(readOnly = true) |
||||||
|
public List<ComCdLangCtg> getComCdLangCtgList(String groupCd, String cdId) { |
||||||
|
return comCdLangCtgRepository.findByGroupCdAndCdId(groupCd, cdId); |
||||||
|
} |
||||||
|
|
||||||
|
@Transactional(readOnly = true) |
||||||
|
public ComCdLangCtg getComCdLangCtg(String groupCd, String cdId, String langDivCd) { |
||||||
|
ComCdLangCtg.ComCdLangCtgId id = ComCdLangCtg.ComCdLangCtgId.builder() |
||||||
|
.groupCd(groupCd) |
||||||
|
.cdId(cdId) |
||||||
|
.langDivCd(langDivCd) |
||||||
|
.build(); |
||||||
|
return comCdLangCtgRepository.findById(id).orElse(null); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// TODO Exception 처리
|
||||||
|
// 그룹 등록
|
||||||
|
public ComCdGroupBas createComCdGroupBas(ComCdGroupBas comCdGroupBas) { |
||||||
|
comCdGroupBasRepository.findById(comCdGroupBas.getGroupCd()).ifPresent(bas -> { |
||||||
|
throw new RuntimeException("이미 존재하는 코드 그룹입니다."); |
||||||
|
}); |
||||||
|
|
||||||
|
// TODO 일자 및 사용자 넣기
|
||||||
|
comCdGroupBas.setCreateDt(LocalDateTime.now()); |
||||||
|
comCdGroupBas.setCreateUserId("CREATE_USER"); |
||||||
|
comCdGroupBas.setUpdateDt(LocalDateTime.now()); |
||||||
|
comCdGroupBas.setUpdateUserId("CREATE_USER"); |
||||||
|
|
||||||
|
return comCdGroupBasRepository.save(comCdGroupBas); |
||||||
|
} |
||||||
|
|
||||||
|
// TODO 일자 및 사용자 넣기
|
||||||
|
// TODO Exception 처리
|
||||||
|
// 코드 등록
|
||||||
|
public ComCdBas createComCdBas(ComCdBas comCdBas) { |
||||||
|
var id = ComCdBas.ComCdBasId.builder() |
||||||
|
.groupCd(comCdBas.getGroupCd()) |
||||||
|
.cdId(comCdBas.getCdId()) |
||||||
|
.build(); |
||||||
|
comCdBasRepository.findById(id).ifPresent(bas -> { |
||||||
|
throw new RuntimeException("이미 존재하는 코드입니다."); |
||||||
|
}); |
||||||
|
// TODO 일자 및 사용자 넣기
|
||||||
|
comCdBas.setCreateDt(LocalDateTime.now()); |
||||||
|
comCdBas.setCreateUserId("CREATE_USER"); |
||||||
|
comCdBas.setUpdateDt(LocalDateTime.now()); |
||||||
|
comCdBas.setUpdateUserId("CREATE_USER"); |
||||||
|
|
||||||
|
return comCdBasRepository.save(comCdBas); |
||||||
|
} |
||||||
|
|
||||||
|
// 언어 등록
|
||||||
|
public ComCdLangCtg createComCdLangCtg(ComCdLangCtg comCdLangCtg) { |
||||||
|
// comCdLangCtgRepository.findById(comCdLangCtg.getId()).ifPresent(bas -> {
|
||||||
|
// throw new RuntimeException("이미 존재하는 코드 언어입니다.");
|
||||||
|
// });
|
||||||
|
var id = ComCdLangCtg.ComCdLangCtgId.builder() |
||||||
|
.groupCd(comCdLangCtg.getGroupCd()) |
||||||
|
.cdId(comCdLangCtg.getCdId()) |
||||||
|
.langDivCd(comCdLangCtg.getLangDivCd()) |
||||||
|
.build(); |
||||||
|
comCdLangCtgRepository.findById(id).ifPresent(bas -> { |
||||||
|
throw new RuntimeException("이미 존재하는 코드 언어입니다."); |
||||||
|
}); |
||||||
|
|
||||||
|
// TODO 일자 및 사용자 넣기
|
||||||
|
comCdLangCtg.setCreateDt(LocalDateTime.now()); |
||||||
|
comCdLangCtg.setCreateUserId("CREATE_USER"); |
||||||
|
comCdLangCtg.setUpdateDt(LocalDateTime.now()); |
||||||
|
comCdLangCtg.setUpdateUserId("CREATE_USER"); |
||||||
|
|
||||||
|
return comCdLangCtgRepository.save(comCdLangCtg); |
||||||
|
} |
||||||
|
|
||||||
|
// TODO Exception 처리
|
||||||
|
// 그룹 수정
|
||||||
|
public ComCdGroupBas updateComCdGroupBas(ComCdGroupBas comCdGroupBas) { |
||||||
|
var bas = comCdGroupBasRepository.findById(comCdGroupBas.getGroupCd()).orElseThrow(() -> { |
||||||
|
throw new RuntimeException("존재하지 않는 코드 그룹입니다."); |
||||||
|
}); |
||||||
|
bas.update(comCdGroupBas); |
||||||
|
|
||||||
|
// TODO 일자 및 사용자 넣기
|
||||||
|
bas.setUpdateDt(LocalDateTime.now()); |
||||||
|
bas.setUpdateUserId("UPDATE_USER"); |
||||||
|
|
||||||
|
return comCdGroupBasRepository.save(bas); |
||||||
|
} |
||||||
|
|
||||||
|
// TODO 일자 및 사용자 넣기
|
||||||
|
// TODO Exception 처리
|
||||||
|
// 코드 수정
|
||||||
|
public ComCdBas updateComCdBas(ComCdBas comCdBas) { |
||||||
|
|
||||||
|
var id = ComCdBas.ComCdBasId.builder() |
||||||
|
.groupCd(comCdBas.getGroupCd()) |
||||||
|
.cdId(comCdBas.getCdId()) |
||||||
|
.build(); |
||||||
|
|
||||||
|
var bas = comCdBasRepository.findById(id).orElseThrow(() -> { |
||||||
|
throw new RuntimeException("존재하지 않는 코드입니다."); |
||||||
|
}); |
||||||
|
bas.update(comCdBas); |
||||||
|
|
||||||
|
// TODO 일자 및 사용자 넣기
|
||||||
|
bas.setUpdateDt(LocalDateTime.now()); |
||||||
|
bas.setUpdateUserId("UPDATE_USER"); |
||||||
|
|
||||||
|
return comCdBasRepository.save(bas); |
||||||
|
} |
||||||
|
|
||||||
|
// TODO 일자 및 사용자 넣기
|
||||||
|
// TODO Exception 처리
|
||||||
|
// 언어 수정
|
||||||
|
public ComCdLangCtg updateComCdLangCtg(ComCdLangCtg comCdLangCtg) { |
||||||
|
var id = ComCdLangCtg.ComCdLangCtgId.builder() |
||||||
|
.groupCd(comCdLangCtg.getGroupCd()) |
||||||
|
.cdId(comCdLangCtg.getCdId()) |
||||||
|
.langDivCd(comCdLangCtg.getLangDivCd()) |
||||||
|
.build(); |
||||||
|
var bas = comCdLangCtgRepository.findById(id).orElseThrow(() -> { |
||||||
|
throw new RuntimeException("존재하지 않는 코드 언어입니다."); |
||||||
|
}); |
||||||
|
bas.update(comCdLangCtg); |
||||||
|
|
||||||
|
// TODO 일자 및 사용자 넣기
|
||||||
|
bas.setUpdateDt(LocalDateTime.now()); |
||||||
|
bas.setUpdateUserId("UPDATE_USER"); |
||||||
|
|
||||||
|
return comCdLangCtgRepository.save(bas); |
||||||
|
} |
||||||
|
|
||||||
|
// 그룹 삭제
|
||||||
|
public void deleteComCdGroupBas(String groupCd) { |
||||||
|
comCdGroupBasRepository.deleteById(groupCd); |
||||||
|
} |
||||||
|
|
||||||
|
// 코드 삭제
|
||||||
|
public void deleteComCdBas(String groupCd, String cdId) { |
||||||
|
var id = ComCdBas.ComCdBasId.builder() |
||||||
|
.groupCd(groupCd) |
||||||
|
.cdId(cdId) |
||||||
|
.build(); |
||||||
|
comCdBasRepository.deleteById(id); |
||||||
|
} |
||||||
|
|
||||||
|
// 언어 삭제
|
||||||
|
public void deleteComCdLangCtg(String groupCd, String cdId, String langDivCd) { |
||||||
|
var id = ComCdLangCtg.ComCdLangCtgId.builder() |
||||||
|
.groupCd(groupCd) |
||||||
|
.cdId(cdId) |
||||||
|
.langDivCd(langDivCd) |
||||||
|
.build(); |
||||||
|
comCdLangCtgRepository.deleteById(id); |
||||||
|
} |
||||||
|
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue