This commit is contained in:
2025-05-24 01:45:57 +09:00
commit 491c8be885
263 changed files with 14926 additions and 0 deletions

38
.gitignore vendored Normal file
View File

@@ -0,0 +1,38 @@
HELP.md
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
/logs/

View File

@@ -0,0 +1,6 @@
### GET request to example server
GET http://localhost:8010/api/itg/appr?page=1&row=10
sabun: psn14020
###

View File

@@ -0,0 +1,6 @@
### GET request to example server
GET http://localhost:8010/api/itg/appr/req?page=1&row=10
sabun: 17131303
###

View File

@@ -0,0 +1,16 @@
PUT http://localhost:8010//api/appr
sabun: 17131303
Content-Type: application/json
{
"apprNo": "APPR-0000000052",
"apprOrd": 2,
"sabun": "17131303",
"apprStatCd": "0200",
"reason": ""
}
###
#APPR-20250519017,20,17131303,김진형,0000,결재요청
#APPR-20250519017,30,17131304,손원장,0000,결재요청

View File

@@ -0,0 +1,12 @@
PUT http://localhost:8010//api/business/password
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6Ijk5OS05OS05OTk5OCIsImlwIjoiMTI3LjAuMC4xIiwic3ViIjoiOTk5LTk5LTk5OTk4IiwiaWF0IjoxNzQ2MDEyNjcyLCJleHAiOjE3NDYwMTI5NzJ9.RaT9wa3_8oPeL6nWv1_uM6QlY1mcHyCN2tC6sP_N03w
Content-Type: application/json
{
"bizNo": "999-99-99998",
"oldPwd": "kospo2025!",
"pwd": "kospo2024!",
"rePwd": "kospo2024!"
}
###

View File

@@ -0,0 +1,13 @@
POST http://localhost:8010//api/business
Content-Type: application/json
{
"bizNo": "999-99-99998",
"pwd": "kospo2025!",
"rePwd": "kospo2025!",
"compNm": "테스트2",
"repNm": "테스트2",
"email": "bangae1@gmail.com"
}
###

View File

@@ -0,0 +1,12 @@
PUT http://localhost:8010//api/business
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6Ijk5OS05OS05OTk5OCIsImlwIjoiMTI3LjAuMC4xIiwic3ViIjoiOTk5LTk5LTk5OTk4IiwiaWF0IjoxNzQ2MDEyNjcyLCJleHAiOjE3NDYwMTI5NzJ9.RaT9wa3_8oPeL6nWv1_uM6QlY1mcHyCN2tC6sP_N03w
Content-Type: application/json
{
"bizNo": "999-99-99998",
"compNm": "테스트3",
"repNm": "테스트3",
"email": "bangae3@gmail.com"
}
###

View File

@@ -0,0 +1,5 @@
DELETE http://localhost:8010//api/business/999-99-99998
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6Ijk5OS05OS05OTk5OCIsImlwIjoiMTI3LjAuMC4xIiwic3ViIjoiOTk5LTk5LTk5OTk4IiwiaWF0IjoxNzQ2MDEyNjcyLCJleHAiOjE3NDYwMTI5NzJ9.RaT9wa3_8oPeL6nWv1_uM6QlY1mcHyCN2tC6sP_N03w
Content-Type: application/json
###

View File

@@ -0,0 +1,4 @@
### GET request to example server
GET http://localhost:8010/api/cont/CONT-0000000005
###

View File

@@ -0,0 +1,5 @@
### GET request to example server
GET http://localhost:8010/api/cont/page
?cateStatCd=&signSdt=&signEdt=&page=1&row=10
###

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
DELETE http://localhost:8010/api/bid/BID-0000000009/1
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6Ijk5OS05OS05OTk5OSIsImlwIjoiMTI3LjAuMC4xIiwic3ViIjoiOTk5LTk5LTk5OTk5IiwiaWF0IjoxNzQ1NTkwNjQ3LCJleHAiOjE3NDU1OTA5NDd9.a9nwoQTDV702VbU0HnP1jS8SGhFi_3UjkjdBcjoDzCE
###

View File

@@ -0,0 +1,24 @@
PUT http://localhost:8010/api/estimate
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6Ijk5OS05OS05OTk5OSIsImlwIjoiMTI3LjAuMC4xIiwic3ViIjoiOTk5LTk5LTk5OTk5IiwiaWF0IjoxNzQ3MDQ4NDI5LCJleHAiOjE3NDcwNTAyMjl9.6SzI3eiNVmXOz1s1p8ab26fT80rbSJBfoDlKLQ4z5Sg
{
"estimates": [
{
"estNo": "EST-0000000003",
"mngNm": "조진우",
"unitPrc": 2,
"amt": 40000
},
{
"estNo": "EST-0000000004",
"mngNm": "조진우",
"unitPrc": 12,
"amt": 60000
}
],
"pbAtts": []
}
###

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
### GET request to example server
GET http://localhost:8010/api/estimate
?prcsNo=PRCS-0000000006
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6Ijk5OS05OS05OTk5OSIsImlwIjoiMTI3LjAuMC4xIiwic3ViIjoiOTk5LTk5LTk5OTk5IiwiaWF0IjoxNzQ3MDQ4NDI5LCJleHAiOjE3NDcwNTAyMjl9.6SzI3eiNVmXOz1s1p8ab26fT80rbSJBfoDlKLQ4z5Sg
###

View File

@@ -0,0 +1,10 @@
### GET request to example server
POST http://localhost:8010/api/login
Content-Type: application/json
{
"bizNo": "111-11-11111",
"pwd": "kospo2025!"
}
###

View File

@@ -0,0 +1,6 @@
### GET request to example server
GET http://localhost:8010/api/prcs/external/page
?cateCd=&stCd=&regNm=&regSdt=&regEdt=&page=1&row=10
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6Ijk5OS05OS05OTk5OSIsImlwIjoiMTI3LjAuMC4xIiwic3ViIjoiOTk5LTk5LTk5OTk5IiwiaWF0IjoxNzQ2MDEzMjAwLCJleHAiOjE3NDYwMTM1MDB9.2mSDvhpXtvkYHeRr_d1tiKvnSU0OGehBq0ce1AOvXnE
###

View File

@@ -0,0 +1,4 @@
### GET request to example server
GET http://localhost:8010/api/prcs/PRCS-20250523052
###

View File

@@ -0,0 +1,57 @@
PUT http://localhost:8010//api/prcs
Content-Type: application/json
{
"prcsNo": "PRCS-20250521019",
"cateCd": "0200",
"title": "5층 파티션 구매",
"content": "싼거 찾아요111",
"regSdat": "2025-04-01",
"regEdat": "2025-07-30",
"prvYn": false,
"prvRsn": "",
"prvPwd": "",
"aiYn": false,
"prcsAtts": [
],
"dtlSpecs": [
],
"apprReqs": [
{
"gubunCd": "",
"apprNo": "APPR-20250514013",
"apprOrd": 10,
"sabun": "psn14020",
"name": "조진우",
"attendCd": ""
},
{
"gubunCd": "0100",
"apprNo": "APPR-20250514013",
"apprOrd": 20,
"sabun": "17131303",
"name": "김진형1",
"attendCd": ""
},
{
"gubunCd": "0200",
"apprNo": "APPR-20250514013",
"apprOrd": 30,
"sabun": "17131304",
"name": "손원장1",
"attendCd": "01"
}
],
"prcsBizs": [
{
"bizNo": "999-99-99999",
"email": "bangae2@gmail.com"
},
{
"bizNo": "111-11-11111",
"email": "bangae1@gmail.com"
}
]
}
###

View File

@@ -0,0 +1,46 @@
PUT https://svcm.hmsn.ink//api/prcs
Content-Type: application/json
{
"prcsNo": "PRCS-20250521023",
"cateCd": "0000",
"title": "4층 파티션 구매123",
"content": "싼거 찾아요123",
"regSdat": "2025-05-01",
"regEdat": "2025-05-03",
"prvYn": true,
"prvRsn": "",
"prvPwd": "",
"aiYn": true,
"prcsBizs": [
{
"bizNo": "999-99-99999",
"email": "aa@gmail.com"
},
{
"bizNo": "111-11-11111",
"email": "bb@gmail.com"
}
],
"prcsAtts": [],
"apprReqs": [
{
"gubunCd": "0000",
"sabun": "psn14020",
"name": "조진우",
"apprNo": "APPR-0000000023",
"apprOrd": 1,
"attendCd": null
},
{
"gubunCd": "0100",
"sabun": "15000007",
"name": "조용식",
"apprNo": "APPR-0000000023",
"apprOrd": 2,
"attendCd": null
}
]
}
###

View File

@@ -0,0 +1,4 @@
PUT http://localhost:8010/api/prcs/survey/PRCS-20250522038
Content-Type: application/json
###

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
### GET request to example server
GET http://localhost:8010/api/prcs/page
?cateCd=&stCd=&regNm=&regSdt=&regEdt=&page=1&row=10
###

View File

@@ -0,0 +1,3 @@
PUT http://localhost:8010/api/prcs/ret/PRCS-20250522037
Content-Type: application/json
###

View File

@@ -0,0 +1,10 @@
PUT http://localhost:8010/api/sap/appr
sabun: 15000004
Content-Type: application/json
{
"wkfid": "FI2025900007",
"wkfsq": 3,
"bname": "15000004",
"wkfst": "A"
}

View File

@@ -0,0 +1,44 @@
POST http://localhost:8010/api/sap/appr
Content-Type: application/json
{
"belnr": "202500102045",
"wkftx": "자재유형:SILLING, 품질등급 E:, 자재내역 : SUS",
"apprs": [
{
"label": "결재",
"value": [
{
"lineclsf": "Q",
"bname": "15000037",
"abscd": ""
},
{
"lineclsf": "I",
"bname": "15000003",
"abscd": ""
},
{
"lineclsf": "I",
"bname": "15000004",
"abscd": "A"
},
{
"lineclsf": "E",
"bname": "15000037",
"abscd": ""
},
{
"lineclsf": "E",
"bname": "15000062",
"abscd": ""
},
{
"lineclsf": "A",
"bname": "15000005",
"abscd": ""
}
]
}
]
}

View File

@@ -0,0 +1,33 @@
POST http://localhost:8010/api/sap/appr
sabun: 15000062
Content-Type: application/json
{
"wkfid": "FI2025900004",
"apprs": [
{
"label": "협조",
"value": [
{
"lineclsf": "Q",
"bname": "15000062",
"abscd": "",
"grpid": 1
},
{
"lineclsf": "I",
"bname": "15000057",
"abscd": "",
"grpid": 1
},
{
"lineclsf": "A",
"bname": "15000056",
"abscd": "",
"grpid": 1
}
]
}
]
}

View File

@@ -0,0 +1,20 @@
POST http://localhost:8010/api/slip
Content-Type: application/json
{
"contNo": "CONT-0000000005",
"lifnr": "999-99-99999",
"gsber": "1000",
"wrbtrS": "1102",
"mwskz": "V4",
"waers": "KRW",
"bldat": "20250501",
"budat": "20250502",
"hkont": "5366010",
"kostl": "12330",
"projk": "",
"wrbtr": "1203",
"bvtyp": "3100",
"bankl": "012",
"bankn": "3510876657453"
}

90
build.gradle Normal file
View File

@@ -0,0 +1,90 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.2'
id 'io.spring.dependency-management' version '1.1.6'
}
group = 'com.kospo'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
ext['queryDslVersion'] = '5.0.0'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
implementation 'org.springframework.boot:spring-boot-starter-web-services'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-reactor-netty'
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.springframework.retry:spring-retry:2.0.8'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'
implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'
implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5'
implementation 'com.github.ulisesbocchio:jasypt-maven-plugin:3.0.5'
implementation 'org.jetbrains:annotations:24.0.0'
implementation "com.querydsl:querydsl-jpa:${queryDslVersion}:jakarta"
implementation 'org.springframework.boot:spring-boot-starter-actuator'
// annotationProcessor "com.querydsl:querydsl-apt:${queryDslVersion}"
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
implementation 'com.google.code.gson:gson:2.9.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.3'
implementation 'com.fasterxml.jackson.core:jackson-core:2.15.3'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.15.3'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.3'
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
implementation 'org.apache.poi:poi:5.4.1'
implementation 'org.apache.poi:poi-ooxml:5.4.1'
implementation 'javax.xml.bind:jaxb-api:2.3.1'
implementation 'org.modelmapper:modelmapper:3.2.0'
implementation 'org.apache.commons:commons-lang3:3.13.0'
implementation 'commons-codec:commons-codec:1.16.0'
implementation 'org.apache.commons:commons-dbcp2:2.10.0'
implementation 'org.apache.commons:commons-pool2:2.12.0'
implementation 'commons-logging:commons-logging:1.2'
implementation 'commons-io:commons-io:2.19.0'
implementation 'org.apache.commons:commons-email:1.5'
implementation 'org.postgresql:postgresql:42.7.3'
// sockjs
runtimeOnly group: 'io.netty', name: 'netty-resolver-dns-native-macos', version: '4.1.112.Final'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}

30
fileToByte.html Normal file

File diff suppressed because one or more lines are too long

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

249
gradlew vendored Normal file
View File

@@ -0,0 +1,249 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

92
gradlew.bat vendored Normal file
View File

@@ -0,0 +1,92 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

1
readme.md Normal file
View File

@@ -0,0 +1 @@
소액 계약 관리 플랫폼

1
settings.gradle Normal file
View File

@@ -0,0 +1 @@
rootProject.name = 'svcm'

View File

@@ -0,0 +1,21 @@
package com.kospo.svcm;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.servers.Server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@OpenAPIDefinition(servers = {
@Server(url = "http://localhost:8010", description = "로컬 api"),
@Server(url = "http://hmsn.ink:8010", description = "개발 api"),
@Server(url = "https://svcm.hmsn.ink", description = "외부 api"),
})
@EnableScheduling
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@@ -0,0 +1,19 @@
package com.kospo.svcm.config;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class CorsPreflightHandler {
@RequestMapping(method = RequestMethod.OPTIONS, path="/api/**")
public ResponseEntity options() {
return ResponseEntity.ok()
.header(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*")
.header(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE, OPTIONS")
.header(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*")
.build();
}
}

View File

@@ -0,0 +1,21 @@
package com.kospo.svcm.config.exception;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@Schema(name="errorResponse", description = "오류")
public class CustomErrorResponse {
@Schema(name="code", description = "오류 코드", example = "30000")
private String code;
@Schema(name="body", description = "오류 메시지", example = "오류 발생")
private String body;
@Schema(name="errTime", description = "오류 시간", example = "1761000247")
private long errTime;
}

View File

@@ -0,0 +1,132 @@
package com.kospo.svcm.config.exception;
import com.kospo.svcm.exception.CustomException;
import com.kospo.svcm.exception.CustomMessageException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import java.util.Date;
@Slf4j
@ControllerAdvice
@Controller
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {
public static final String ANSI_RESET = "\u001B[0m";
public static final String ANSI_YELLOW_COLOR = "\u001B[33m";
@ExceptionHandler(CustomException.class)
@ResponseBody
public ResponseEntity customException(CustomException e, HandlerMethod method, HttpServletRequest request, WebRequest webRequest) {
Date errorDate = new Date();
String exceptionName = e.getClass().getSimpleName();
String controllerName = method.getMethod().getDeclaringClass().getSimpleName();
String methodName = method.getMethod().getName();
int lineNumber = e.getStackTrace()[0].getLineNumber();
String detail = e.getMessage();
String requestURI = request.getRequestURI();
log.error(ANSI_YELLOW_COLOR + "[EVENT_TIME: {} | CONTROLLER_NAME : {} | METHOD_NAME : {} | EXCEPTION_LINE : {} | EXCEPTION_NAME : {} | DETAIL : {} | REQUEST_URI : {}]" + ANSI_RESET
, errorDate
, controllerName
, methodName
, lineNumber
, exceptionName
, detail
, requestURI);
HttpHeaders resHeaders = new HttpHeaders();
resHeaders.add("Content-Type", "application/json;charset=UTF-8");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).headers(resHeaders).body(
CustomErrorResponse.builder()
.code(e.getErrorCode().getCode())
.body(e.getErrorCode().getBody())
.errTime(System.currentTimeMillis()).build()
);
}
@ExceptionHandler(CustomMessageException.class)
@ResponseBody
public ResponseEntity customMessageException(CustomMessageException e, HandlerMethod method, HttpServletRequest request, WebRequest webRequest) {
Date errorDate = new Date();
String exceptionName = e.getClass().getSimpleName();
String controllerName = method.getMethod().getDeclaringClass().getSimpleName();
String methodName = method.getMethod().getName();
int lineNumber = e.getStackTrace()[0].getLineNumber();
String detail = e.getMessage();
String requestURI = request.getRequestURI();
log.error(ANSI_YELLOW_COLOR + "[EVENT_TIME: {} | CONTROLLER_NAME : {} | METHOD_NAME : {} | EXCEPTION_LINE : {} | EXCEPTION_NAME : {} | DETAIL : {} | REQUEST_URI : {}]" + ANSI_RESET
, errorDate
, controllerName
, methodName
, lineNumber
, exceptionName
, detail
, requestURI);
HttpHeaders resHeaders = new HttpHeaders();
resHeaders.add("Content-Type", "application/json;charset=UTF-8");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).headers(resHeaders).body(
CustomErrorResponse.builder()
.code(e.getCusMessage().getCode())
.body(e.getCusMessage().getMessage())
.errTime(System.currentTimeMillis()).build()
);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleException(Exception e, HandlerMethod method, HttpServletRequest request, WebRequest webRequest) {
// Date errorDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime());
Date errorDate = new Date();
String exceptionName = e.getClass().getSimpleName();
String controllerName = method.getMethod().getDeclaringClass().getSimpleName();
String methodName = method.getMethod().getName();
int lineNumber = e.getStackTrace()[0].getLineNumber();
String detail = e.getMessage();
String requestURI = request.getRequestURI();
log.error(ANSI_YELLOW_COLOR + "[EVENT_TIME: {} | CONTROLLER_NAME : {} | METHOD_NAME : {} | EXCEPTION_LINE : {} | EXCEPTION_NAME : {} | DETAIL : {} | REQUEST_URI : {}]" + ANSI_RESET
, errorDate
, controllerName
, methodName
, lineNumber
, exceptionName
, detail
, requestURI);
HttpHeaders resHeaders = new HttpHeaders();
resHeaders.add("Content-Type", "application/json;charset=UTF-8");
return ResponseEntity.status(500).headers(resHeaders).body(
CustomErrorResponse.builder()
.code(ErrorCode.INTERNAL_SERVER_ERROR.getCode())
.body(ErrorCode.INTERNAL_SERVER_ERROR.getBody())
.errTime(System.currentTimeMillis()).build()
);
}
}

View File

@@ -0,0 +1,65 @@
package com.kospo.svcm.config.exception;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum ErrorCode {
/*트랜잭션 관련*/
FIND_ERR("20000", "조회에 실패했습니다."),
SAVE_ERR("20001", "저장에 실패했습니다."),
UPD_ERR("20002", "수정에 실패했습니다."),
DEL_ERR("20003", "삭제에 실패했습니다."),
APPR_ERR("20004", "결재가 완료 되지 않았습니다.."),
APPR_LOCK("20005", "결재 진행중 이거나 완료 상태로 수정이 불가합니다."),
APPR_SVY_ERR("20006", "조사완료 되어 등록이 불가합니다."),
/*토큰 관련*/
EXPIRE_TOKEN("30000", "토큰이 만료 되었습니다."),
MALFORMED_JWT("30001", "JWT 문자열은 정확히 2개의 마침표 문자를 포함해야 합니다."),
/*bad request*/
BIND_ERROR("40001", "파라미터를 다시 확인해주세요."),
/*존재 하지 않음*/
NO_RESULT("44001", "존재하지 않는 데이터 입니다."),
NO_ACCOUNT("44011", "아이디 또는 비밀번호를 다시 확인해주세요."),
NO_MATCH_ACCOUNT("44012", "일치하는 사용자가 없습니다."),
NO_TOKEN("44021", "헤더에 토큰이 없습니다."),
NO_MATCH_TOKEN("44022", "일치 하지 않는 토큰입니다."),
NO_SAME_IP("44030", "등록된 아이피와 일치 하지 않습니다. 다시 로그인 해주세요"),
NO_SAME_DATA("44031", "사용자가 소유한 데이터가 아닙니다."),
No_SVY_NOT_EXECUTE("44032", "사전조사가 실행 되지 않았거나 등록 기간중 입니다."),
SAME_DATA("44020", "이미 등록된 데이터가 있습니다."),
/*권한 관련*/
AUTHENTICATION("43000", "사용자가 정보가 일치하지 않습니다."),
AUTHENTICATION_NOT_SUPPORT("43001", "허용되지 않은 사용자입니다."),
NO_REGISTER("43002", "사용자가 존재하지 않습니다."),
SLEEP_ACCOUNT("43003", "휴면 계정입니다. 개인정보에 약관에 동의해주세요."),
//500 INTERNAL SERVER ERROR
INTERNAL_SERVER_ERROR("50000", "서버 에러입니다. 유지보수관리자에게 연락주세요!"),
/*로그인 관련*/
LOGIN_ERR("60000", "사업자번호 또는 비밀번호가 일치 하지 않습니다."),
NOT_REGISTER("60001", "가입된 사업자가 아닙니다."),
ALREADY_REGISTER("60001", "이미 가입된 사업자 입니다."),
OLD_PWD_NOT_MATCH("60002", "현재 비밀번호가 일치 하지 않습니다."),
PWD_NOT_MATCH("60003", "비밀번호가 일치 하지 않습니다."),
EMAIL_VALIDATE_ERR("60004", "정상적인 이메일이 아닙니다."),
/*결재관련*/
PASS_APPR_TWO_PERSON("70001", "전결이 두명이상 될수 없습니다."),
PASS_APPR_MANIPULATE_DATA("70002", "변경 대상자 정보가 변조 되었습니다."),
/*파일 관련*/
FILE_NOT_FOUND_ERROR("80000", "파일이 존재 하지 않습니다."),
FILE_EXT_UPLOAD_ERROR("80001", "허용되지 않은 확장자 입니다."),
FILE_UPLOAD_ERROR("80002", "파일이 정상적이지 않습니다. 확인해주세요"),
FILE_DELETE_ERROR("80003", "파일 삭제중 오류가 발생했습니다. 확인해주세요"),
FILE_DOWNLOAD_ERROR("80004", "파일 다운로드에 실패 했습니다."),
FILE_REQUIRED("80005", "첨부파일은 필수 항목입니다."),
NO_SIGNAL("90000", "응답 코드가 없습니다.");
private final String code;
private final String body;
}

View File

@@ -0,0 +1,34 @@
package com.kospo.svcm.config.filter;
import com.kospo.svcm.service.UserService;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
@Configuration
@RequiredArgsConstructor
public class AuthenticationFilter extends OncePerRequestFilter {
private final UserService userService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
/*sso 로그인 추가*/
filterChain.doFilter(request, response);
}
private static String decodeCredentials(String credentials) {
return new String(java.util.Base64.getDecoder().decode(credentials.getBytes()));
}
}

View File

@@ -0,0 +1,174 @@
package com.kospo.svcm.config.filter;
import com.kospo.svcm.config.exception.ErrorCode;
import com.kospo.svcm.config.jwt.JwtUtil;
import com.kospo.svcm.exception.*;
import com.kospo.svcm.model.Business;
import com.kospo.svcm.model.User;
import com.kospo.svcm.repository.UserRepository;
import com.kospo.svcm.service.BusinessService;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.io.DecodingException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CustomBasicAuthenticationFilter extends BasicAuthenticationFilter {
private UserRepository userRepository;
private JwtUtil jwtUtil;
private BusinessService businessService;
public CustomBasicAuthenticationFilter(AuthenticationManager authenticationManager, UserRepository userRepository, JwtUtil jwtUtil, BusinessService businessService) {
super(authenticationManager);
this.jwtUtil = jwtUtil;
this.businessService = businessService;
this.userRepository = userRepository;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
final String requestTokenHeader = request.getHeader("Authorization");
boolean isAnonymous = false;
String sabun = null;
String jwtToken = null;
if (requestTokenHeader == null) {
jakarta.servlet.http.HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
String sso_sabun = "";
boolean isSso = true;
sso_sabun = request.getHeader("sabun");
try {
if (sso_sabun == null || sso_sabun.isEmpty()) {
sso_sabun = "psn14020";
// sso_sabun = request.getHeader("Authentication");
// if (sso_sabun != null) sso_sabun = CryptoUtil.decrypt(sso_sabun);
}
} catch (Exception e) {
new RuntimeException(e);
}
isSso = sso_sabun == null || sso_sabun.equals("");
if (!isSso) user = null;
/* SSO 인증 부분 */
if (user == null) {
/*sso 인증 개발시 header 정보에 사번 추가 하여 테스트*/
user = userRepository.findBySabun(sso_sabun);
Authentication authentication = null;
List<SimpleGrantedAuthority> mergedAuth = new ArrayList<>();
mergedAuth.addAll(Arrays.asList(new SimpleGrantedAuthority("ROLE_USER")));
if (user.getAuthorities().size() != 0 ) {
user.getAuthorities().stream().forEach(auth -> mergedAuth.add(new SimpleGrantedAuthority(auth.toString())));
}
authentication = new UsernamePasswordAuthenticationToken(user, null, mergedAuth);
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(authentication);
SecurityContextHolder.setContext(securityContext);
SecurityContextHolder.getContext().getAuthentication();
session.setAttribute("user", user);
} else {
Authentication getAuth = SecurityContextHolder.getContext().getAuthentication();
if (getAuth == null) {
Authentication authentication = null;
if (user.getAuthorities() == null) {
authentication = new UsernamePasswordAuthenticationToken(user, null, Arrays.asList(new SimpleGrantedAuthority("ROLE_DEFAULT")));
} else {
authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
}
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(authentication);
SecurityContextHolder.setContext(securityContext);
SecurityContextHolder.getContext().getAuthentication();
}
}
isAnonymous = true;
chain.doFilter(request, response);
SecurityContextHolder.clearContext();
} else if(requestTokenHeader != null && requestTokenHeader.startsWith("Bearer")) {
jwtToken = requestTokenHeader.substring(7);
try {
sabun = jwtUtil.extractUserName(jwtToken);
} catch(ExpiredJwtException e) {
System.out.println(e.getMessage());
throw new CustomExpireTokenException(e.getMessage());
} catch (DecodingException e) {
System.out.println(e.getMessage());
throw new CustomNoMatchTokenException(e.getMessage());
} catch(MalformedJwtException e) {
System.out.println(e.getMessage());
throw new CustomMalformedJwtException(e.getMessage());
}
if(!isAnonymous) {
Business business = null;
if(sabun != null) {
try {
business = businessService.findById(sabun);
} catch(UsernameNotFoundException e) {
throw new CustomNoResultException(ErrorCode.NO_RESULT.getBody());
}
if(jwtUtil.validateToken(jwtToken, business)) {
jwtUtil.extendAccessToken(jwtToken);
jwtUtil.extendRefreshToken(business.getRefreshToken());
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(business, null, business.getAuthorities());
usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(usernamePasswordAuthenticationToken);
SecurityContextHolder.setContext(securityContext);
SecurityContextHolder.getContext().getAuthentication();
chain.doFilter(request, response);
SecurityContextHolder.clearContext();
}
} else {
throw new CustomNoAccountException(ErrorCode.NO_ACCOUNT.getBody());
}
}
}
}
public CustomBasicAuthenticationFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
}
public CustomBasicAuthenticationFilter(AuthenticationManager authenticationManager, AuthenticationEntryPoint authenticationEntryPoint) {
super(authenticationManager, authenticationEntryPoint);
}
}

View File

@@ -0,0 +1,18 @@
package com.kospo.svcm.config.filter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;
public class LoggingFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent iLoggingEvent) {
if(iLoggingEvent.getMessage().contains("locale")) {
return FilterReply.DENY;
} else {
return FilterReply.ACCEPT;
}
}
}

View File

@@ -0,0 +1,104 @@
package com.kospo.svcm.config.filter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kospo.svcm.config.exception.CustomErrorResponse;
import com.kospo.svcm.config.exception.ErrorCode;
import com.kospo.svcm.exception.*;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
public class SecurityExceptionFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException {
ObjectMapper om = new ObjectMapper();
try {
filterChain.doFilter(request, response);
} catch (CustomExpireTokenException e) {
response.setStatus(500);
response.setContentType("application/json;charset=utf-8");
response.getWriter().println(
om.writeValueAsString(CustomErrorResponse.builder()
.code(ErrorCode.EXPIRE_TOKEN.getCode())
.body(ErrorCode.EXPIRE_TOKEN.getBody())
.errTime(System.currentTimeMillis()).build())
);
} catch (CustomNoAccountException e) {
response.setStatus(500);
response.setContentType("application/json;charset=utf-8");
response.getWriter().println(
om.writeValueAsString(CustomErrorResponse.builder()
.code(ErrorCode.NO_ACCOUNT.getCode())
.body(ErrorCode.NO_ACCOUNT.getBody())
.errTime(System.currentTimeMillis()).build())
);
} catch (CustomNoMatchTokenException e) {
response.setStatus(500);
response.setContentType("application/json;charset=utf-8");
response.getWriter().println(
om.writeValueAsString(CustomErrorResponse.builder()
.code(ErrorCode.NO_MATCH_TOKEN.getCode())
.body(ErrorCode.NO_MATCH_TOKEN.getBody())
.errTime(System.currentTimeMillis()).build())
);
} catch (CustomNoResultException e) {
response.setStatus(500);
response.setContentType("application/json;charset=utf-8");
response.getWriter().println(
om.writeValueAsString(CustomErrorResponse.builder()
.code(ErrorCode.NO_RESULT.getCode())
.body(ErrorCode.NO_RESULT.getBody())
.errTime(System.currentTimeMillis()).build())
);
} catch (CustomNoTokenException e) {
response.setStatus(500);
response.setContentType("application/json;charset=utf-8");
response.getWriter().println(
om.writeValueAsString(CustomErrorResponse.builder()
.code(ErrorCode.NO_TOKEN.getCode())
.body(ErrorCode.NO_TOKEN.getBody())
.errTime(System.currentTimeMillis()).build())
);
} catch (ServletException e) {
response.setStatus(500);
response.setContentType("application/json;charset=utf-8");
response.getWriter().println(
om.writeValueAsString(CustomErrorResponse.builder()
.code(ErrorCode.INTERNAL_SERVER_ERROR.getCode())
.body(ErrorCode.INTERNAL_SERVER_ERROR.getBody())
.errTime(System.currentTimeMillis()).build())
);
} catch (IOException e) {
response.setStatus(500);
response.setContentType("application/json;charset=utf-8");
response.getWriter().println(
om.writeValueAsString(CustomErrorResponse.builder()
.code(ErrorCode.INTERNAL_SERVER_ERROR.getCode())
.body(ErrorCode.INTERNAL_SERVER_ERROR.getBody())
.errTime(System.currentTimeMillis()).build())
);
} catch (CustomMalformedJwtException e) {
response.setStatus(500);
response.setContentType("application/json;charset=utf-8");
response.getWriter().println(
om.writeValueAsString(CustomErrorResponse.builder()
.code(ErrorCode.MALFORMED_JWT.getCode())
.body(ErrorCode.MALFORMED_JWT.getBody())
.errTime(System.currentTimeMillis()).build())
);
} catch (CustomNoSameIpException e) {
response.setStatus(500);
response.setContentType("application/json;charset=utf-8");
response.getWriter().println(
om.writeValueAsString(CustomErrorResponse.builder()
.code(ErrorCode.NO_SAME_IP.getCode())
.body(ErrorCode.NO_SAME_IP.getBody())
.errTime(System.currentTimeMillis()).build())
);
}
}
}

View File

@@ -0,0 +1,33 @@
package com.kospo.svcm.config.jasypt;
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableEncryptableProperties
public class JasyptConfigAES {
@Value("${jasypt.encryptor.key}")
private String key;
@Bean("jasyptEncryptorAES")
public StringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(key); // 암호화키
config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256"); // 알고리즘
config.setKeyObtentionIterations("1000"); // 반복할 해싱 회수
config.setPoolSize("1"); // 인스턴스 pool
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator"); // salt 생성 클래스
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
config.setStringOutputType("base64"); //인코딩 방식
encryptor.setConfig(config);
return encryptor;
}
}

View File

@@ -0,0 +1,84 @@
package com.kospo.svcm.config.jwt;
import com.kospo.svcm.config.exception.ErrorCode;
import com.kospo.svcm.exception.CustomExpireTokenException;
import com.kospo.svcm.exception.CustomMalformedJwtException;
import com.kospo.svcm.exception.CustomNoMatchTokenException;
import com.kospo.svcm.exception.CustomNoResultException;
import com.kospo.svcm.model.Business;
import com.kospo.svcm.service.BusinessService;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.io.DecodingException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
@RequiredArgsConstructor
public class JwtRequestFilter extends OncePerRequestFilter {
private final JwtUtil jwtUtil;
private final BusinessService businessService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
final String requestTokenHeader = request.getHeader("Authorization");
boolean isAnonymous = false;
String sabun = null;
String jwtToken = null;
if(requestTokenHeader != null && requestTokenHeader.startsWith("Bearer")) {
jwtToken = requestTokenHeader.substring(7);
try {
sabun = jwtUtil.extractUserName(jwtToken);
} catch(ExpiredJwtException e) {
System.out.println(e.getMessage());
throw new CustomExpireTokenException(e.getMessage());
} catch (DecodingException e) {
System.out.println(e.getMessage());
throw new CustomNoMatchTokenException(e.getMessage());
} catch(MalformedJwtException e) {
System.out.println(e.getMessage());
throw new CustomMalformedJwtException(e.getMessage());
}
} else {
System.out.println("noToken");
isAnonymous = true;
}
if(!isAnonymous) {
Business business = null;
if(sabun != null && SecurityContextHolder.getContext().getAuthentication() == null) {
try {
business = businessService.findById(sabun);
} catch(UsernameNotFoundException e) {
throw new CustomNoResultException(ErrorCode.NO_RESULT.getBody());
}
if(jwtUtil.validateToken(jwtToken, business)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(business, null, business.getAuthorities());
usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
} else {
// throw new CustomNoAccountException(ErrorCode.NO_ACCOUNT.getBody());
}
}
// String ip = jwtUtil.extractIp(jwtToken);
// if(!CommonUtils.getClientIp(request).equals(ip)) {
// throw new CustomNoSameIpException(ErrorCode.NO_SAME_IP.getBody());
// }
filterChain.doFilter(request, response);
}
}

View File

@@ -0,0 +1,166 @@
package com.kospo.svcm.config.jwt;
import com.kospo.svcm.config.exception.ErrorCode;
import com.kospo.svcm.config.utils.CommonUtils;
import com.kospo.svcm.exception.CustomException;
import com.kospo.svcm.model.Business;
import com.kospo.svcm.dto.res.TokenResponse;
import io.jsonwebtoken.*;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
@Component
public class JwtUtil {
@Value("${jwt.key}")
private String SECRET_KEY;
/* 토큰 사용자이름을 추출한다. */
public String extractUserName(String token) {
return extractClaim(token, Claims::getSubject);
}
/* 토큰 IP을 추출한다. */
public String extractIp(String token) {
return extractClaim(token, claims -> (String)claims.get("ip"));
}
/* 토큰 만료시간을 추출한다. */
public Date extractExpirationDate(String token) {
return extractClaim(token, Claims::getExpiration);
}
/* 토큰 정보를 추출한다. */
private <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
final Claims claims = extractAllClaims(token);
return claimsResolver.apply(claims);
}
/* 토큰 모든 정보를 추출한다. */
private Claims extractAllClaims(String token) {
return Jwts.parserBuilder().setSigningKey(SECRET_KEY).build().parseClaimsJws(token).getBody();
}
/* 토큰 만료여부 확인. */
private Boolean isTokenExpired(String token) {
return extractExpirationDate(token).before(new Date());
}
/* 토큰 엑서스 토큰을 생성한다. */
public String generateAccessToken(Business business, Date expired) {
RequestAttributes reqAttr = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes servlReqAttr = (ServletRequestAttributes)reqAttr;
HttpServletRequest req = servlReqAttr.getRequest();
Map<String, Object> claims = new HashMap<>();
claims.put("bizNo", business.getBizNo());
claims.put("ip", CommonUtils.getClientIp(req));
return createAccessToken(claims, business.getBizNo(), expired);
}
/* 토큰 엑서스 토큰을 생성한다. */
private String createAccessToken(Map<String, Object> claims, String subject, Date expired) {
return Jwts.builder().setClaims(claims).setSubject(subject)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(expired) // 5minutes
.signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();
}
/* 토큰 리플래쉬토큰을 생성한다. */
public String generateRefreshToken(Business business, Date expired) {
return createRefreshToken(business.getBizNo(), expired);
}
/* 토큰 리플래쉬토큰을 생성한다. */
private String createRefreshToken(String subject, Date expired) {
return Jwts.builder().setSubject(subject)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(expired) // 30minutes
.signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();
}
/* 토큰 생성(엑서스, 리플레시) 동시 생성. */
public TokenResponse generateToken(Business business) {
return TokenResponse.builder()
.accessToken(generateAccessToken(business, getAccessDate()))
.accessTokenExpired(getAccessDate().getTime())
.refreshToken(generateRefreshToken(business, getRefreshDate()))
.refreshTokenExpired(getRefreshDate().getTime())
.bid(business.getBizNo()).build();
}
/* 토큰 리플레쉬토큰으로 엑서스토큰을 재발급한다. */
public TokenResponse renewalToken(String accessToken, Business business) {
if(validateToken(accessToken, business)) {
Claims claims = extractAllClaims(accessToken);
return TokenResponse.builder()
.accessToken(generateAccessToken(business, getAccessDate()))
.accessTokenExpired(getAccessDate().getTime())
.refreshToken(accessToken)
.refreshTokenExpired(claims.getExpiration().getTime())
.bid(business.getBizNo()).build();
} else {
throw new CustomException(ErrorCode.EXPIRE_TOKEN);
}
}
/*토큰 정보로 jws 정보를 맵핑한다..*/
private Jws<Claims> parseToken(String token) {
return Jwts.parserBuilder().setSigningKey(SECRET_KEY).build().parseClaimsJws(token);
}
/* 토큰 리플레시토큰 만료기간을 연장한다. */
public TokenResponse extendRefreshToken(String refreshToken) {
Date refreshDate = getRefreshDate();
Jws<Claims> jws = parseToken(refreshToken);
jws.getBody().setExpiration(refreshDate).getSubject();
return TokenResponse.builder()
.refreshToken(refreshToken)
.refreshTokenExpired(refreshDate.getTime()).build();
}
/* 토큰 액세스토큰 만료기간을 연장한다. */
public TokenResponse extendAccessToken(String AccessToken) {
Date accessDate = getAccessDate();
Jws<Claims> jws = parseToken(AccessToken);
jws.getBody().setExpiration(accessDate).getSubject();
return TokenResponse.builder()
.accessToken(AccessToken)
.accessTokenExpired(accessDate.getTime()).build();
}
/* 토큰 만료 여부 확인. */
public Boolean validateToken(String token, Business business) {
try {
final String username = extractUserName(token);
return (username.equals(business.getBizNo()) && !isTokenExpired(token));
} catch(ExpiredJwtException e) {
return false;
}
}
/*리플레시토큰 만료기간 생성 30분*/
private Date getRefreshDate() {
return new Date(System.currentTimeMillis() + (1000 * 60 * 60 * 4));
}
/*엑서스토큰 만료기간 생성 5분*/
private Date getAccessDate() {
return new Date(System.currentTimeMillis() + (1000 * 60 * 30));
}
}

View File

@@ -0,0 +1,52 @@
package com.kospo.svcm.config.schedule;
import com.kospo.svcm.config.utils.CommonUtils;
import com.kospo.svcm.model.CodeId;
import com.kospo.svcm.repository.CodeRepository;
import com.kospo.svcm.repository.PrcsRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
@RequiredArgsConstructor
public class PrcsSchedule {
private final PrcsRepository prcsRepository;
private final CodeRepository codeRepository;
/*가격조사 등록기간 만료 자동 완료 처리 로직*/
@Scheduled(cron = "0 1 0 * * *")
public void SurveyAutoClose() {
System.out.println("come");
prcsRepository.findBySvyYn(false).stream().forEach(prc -> {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date endDt = sdf.parse(prc.getRegEdat());
Date nowDt = new Date();
if(endDt.getTime() < nowDt.getTime()) {
System.out.println("종료");
System.out.println(prc.getPrcsNo());
System.out.println(prc.getTitle());
System.out.println("***********************************");
prc.setSvyYn(true);
prc.setSvyDt(CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss"));
prc.setStCd("0200");
prc.setStNm(codeRepository.findById(CodeId.builder()
.cd("0200")
.id(1)
.build()).get().getNm());
prcsRepository.save(prc);
}
} catch (ParseException e) {
throw new RuntimeException(e);
}
});
}
}

View File

@@ -0,0 +1,40 @@
package com.kospo.svcm.config.security;
import org.postgresql.shaded.com.ongres.scram.common.bouncycastle.pbkdf2.SHA256Digest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.codec.Hex;
import org.springframework.security.crypto.password.*;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
public class PasswordEncoder {
public String sha256Encoding(String password) {
String encPassword = "";
MessageDigest digest = null;
try {
digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(password.getBytes(StandardCharsets.UTF_8));
encPassword = new String(Hex.encode(hash));
return encPassword;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public boolean matches(String passwd1, String passwd2) {
if(passwd2.equals(sha256Encoding(passwd1))) {
return true;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,117 @@
package com.kospo.svcm.config.security;
import com.kospo.svcm.config.filter.CustomBasicAuthenticationFilter;
import com.kospo.svcm.config.filter.SecurityExceptionFilter;
import com.kospo.svcm.config.jwt.JwtUtil;
import com.kospo.svcm.repository.UserRepository;
import com.kospo.svcm.service.BusinessService;
import com.kospo.svcm.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import java.util.List;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@RequiredArgsConstructor
public class SecurityConfig {
private final UserService userService;
private final JwtUtil jwtUtil;
private final BusinessService businessService;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http,
UserRepository userRepository) throws Exception {
http
.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry
.requestMatchers("/admin*").hasRole("ADMIN")
.anyRequest().authenticated()
)
.csrf(AbstractHttpConfigurer::disable)
.formLogin(httpSecurityFormLoginConfigurer -> httpSecurityFormLoginConfigurer.disable())
.addFilterBefore(new CustomBasicAuthenticationFilter(authenticationManager(), userRepository, jwtUtil, businessService), UsernamePasswordAuthenticationFilter.class)
// .addFilterBefore(new SecurityExceptionFilter(), JwtRequestFilter.class)
.addFilterBefore(new SecurityExceptionFilter(), CustomBasicAuthenticationFilter.class)
.headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer.frameOptions(frameOptionsConfig -> frameOptionsConfig.disable()))
.sessionManagement(httpSecuritySessionManagementConfigurer ->
httpSecuritySessionManagementConfigurer
.maximumSessions(1)
.sessionRegistry(sessionRegistry())
)
.cors(httpSecurityCorsConfigurer -> httpSecurityCorsConfigurer.configurationSource(new CorsConfigurationSource() {
@Override
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
CorsConfiguration config = new CorsConfiguration();
// String origin = request.getHeader("Origin");
config.setAllowCredentials(true);
config.setAllowedOrigins(List.of("http://localhost:3000", "http://hmsn.ink:3000", "http://hmsn.ink:8010", "http://hmsn.ink", "https://svcm.hmsn.ink", "http://182.227.15.92:3000"));
config.setAllowedMethods(List.of("POST","GET","DELETE","PUT","OPTIONS"));
config.setAllowedHeaders(List.of("*"));
config.setExposedHeaders(List.of("*"));
return config;
}
}));
return http.build();
}
private String getEncoding (String str) {
BCryptPasswordEncoder b = new BCryptPasswordEncoder();
return b.encode(str);
}
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
@Bean
public AuthenticationManager authenticationManager() {
AuthenticationManager manager = new AuthenticationManager() {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
return authentication;
}
};
return manager;
}
/*특정 url 필터 제외 처리*/
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().requestMatchers(
"/api/login", "/api/register", "/api/token/valid", "/css/**", "/images/**", "/js/**", "/pages/**"
// -- Swagger UI v2
, "/v2/api-docs/**", "/swagger-resources/**", "/v3/api-docs/**"
, "/swagger-ui/**", "/swagger/**", "/api-docs/**"
);
}
@Bean
public SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(sessionRegistry());
}
}

View File

@@ -0,0 +1,6 @@
package com.kospo.svcm.config.security;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer {
}

View File

@@ -0,0 +1,49 @@
package com.kospo.svcm.config.swagger;
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 org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SwaggerConfig {
private final String JWTSCHEMENAME = "jwtAuth";
private SecurityRequirement securityRequirement = new SecurityRequirement().addList(JWTSCHEMENAME);
@Bean
public OpenAPI openAPI() {
// return new OpenAPI()
// .info(apiInfo())
// .components(new Components().addSecuritySchemes("basicScheme", new SecurityScheme()
// .type(SecurityScheme.Type.HTTP).scheme("basic")));
// }
return new OpenAPI()
.info(apiInfo())
.addSecurityItem(securityRequirement)
.components(new Components()
.addSecuritySchemes(JWTSCHEMENAME, new SecurityScheme()
.name(JWTSCHEMENAME)
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")
.name("Authentication"))
.addSecuritySchemes("custom-header", new SecurityScheme()
.type(SecurityScheme.Type.APIKEY)
.in(SecurityScheme.In.HEADER)
.name("sabun")))
.addSecurityItem(new SecurityRequirement().addList("custom-header"));
}
private Info apiInfo() {
return new Info()
.title("소액계약거래")
.description("소액계약거래 api")
.version("1.0.0");
}
}

View File

@@ -0,0 +1,177 @@
package com.kospo.svcm.config.utils;
import com.kospo.svcm.model.Code;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import javax.xml.bind.DatatypeConverter;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@Slf4j
public class CommonUtils {
private static HashMap<String, Set<HashMap<String, Integer>>> listenings;
public CommonUtils() {
}
public static String getClientIp(HttpServletRequest request) {
String ip = "";
ip = request.getHeader("X-FORWARDED-FOR");
if (ip == null) {
ip = request.getHeader("Proxy-Client-IP");
log.info("Proxy-Client-IP : " + ip);
}
if (ip == null) {
ip = request.getHeader("WL-Proxy-Client-IP");
log.info("WL-Proxy-Client-IP : " + ip);
}
if (ip == null) {
ip = request.getHeader("HTTP_CLIENT_IP");
log.info("HTTP_CLIENT_IP : " + ip);
}
if (ip == null) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
log.info("HTTP_X_FORWARDED_FOR : " + ip);
}
if (ip == null) {
ip = request.getRemoteAddr();
log.info("getRemoteAddr : "+ip);
}
log.info("Result : IP Address : "+ip);
return ip;
}
public static Sort convertSort(String field) {
String[] propertyAndDirection = field.split(",");
if(propertyAndDirection.length == 1) propertyAndDirection = field.split(" ");
String property = propertyAndDirection[0];
Sort.Direction direction = Sort.DEFAULT_DIRECTION;
if(propertyAndDirection.length > 1) {
String directionString = propertyAndDirection[1];
direction = Sort.Direction.fromOptionalString(directionString)
.orElse(Sort.DEFAULT_DIRECTION);
}
Sort.Order order = new Sort.Order(direction, property);
return Sort.by(order);
}
public static String dateFormat(Date setDate, String pattern) {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.format(setDate);
}
public static String dateFormat(String pattern) {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.format(new Date());
}
public static Date plusDays(Date dt, int day) {
Calendar cal = Calendar.getInstance();
cal.setTime(dt);
cal.add(Calendar.DAY_OF_MONTH, day);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(sdf.format(cal.getTime()));
return cal.getTime();
}
public static String stringToPlusYear(String str, int year) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dt = null;
try {
dt = sdf.parse(str);
} catch (ParseException e) {
throw new RuntimeException(e);
}
Calendar cal = Calendar.getInstance();
cal.setTime(dt);
cal.add(Calendar.YEAR, year);
SimpleDateFormat result = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return result.format(cal.getTime());
}
public static Date stringToDate(String dd) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Date result = null;
try {
result = sdf.parse(dd);
System.out.println(sdf.format(result));
} catch (ParseException e) {
throw new RuntimeException(e);
}
return result;
}
public static String generateFileName() {
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSSSSSS");
String datePart = now.format(formatter);
String uniquePart = UUID.randomUUID().toString().substring(0, 8);
return datePart + "_" + uniquePart;
}
public static boolean checkAllowExt(String fileNm) {
String fileExtNm = "";
List<String> allowList = Arrays.asList("pdf");
fileExtNm = fileNm.toLowerCase().substring(fileNm.toLowerCase().lastIndexOf(".") + 1);
fileExtNm = fileExtNm.toLowerCase();
String allows = allowList.stream().map((str) -> str).collect(Collectors.joining(","));
return allows.contains(fileExtNm);
}
public static Date epochToDate(long epoch) {
return new Date(epoch);
}
public static String epochToString(long epoch, String pattern) {
Date expiry = new Date(epoch);
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.format(expiry);
}
public static String getNo(String prefix, int seq) {
return prefix+String.format("%010d", seq);
}
public static String getSapNo(int seq) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
String year = sdf.format(new Date());
return "FI"+ year +"9" + String.format("%05d", seq);
}
public static String getEstNo(String estNo) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
String year = sdf.format(new Date());
return estNo+year+"1000";
}
public static String getDateNo(String prefix, int seq) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
return prefix+ sdf.format(new Date()) +String.format("%03d", seq);
}
public static String getCodeNm(List<Code> list, String cd) {
Optional<Code> optionalCode = list.stream().filter(c -> c.getId().getCd().equals(cd)).findFirst();
if(optionalCode.isEmpty()) {
return "";
} else {
return optionalCode.get().getNm();
}
}
}

View File

@@ -0,0 +1,89 @@
package com.kospo.svcm.config.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.FileCopyUtils;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAKeyGenParameterSpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class CryptoUtil {
public static String encrypt(String plainText) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, loadPublicKey());
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
}
public static String decrypt(String encryptText) throws Exception {
encryptText = encryptText.replaceAll(" ", "+");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, loadPrivateKey());
byte[] decryptBytes = cipher.doFinal(Base64.getDecoder().decode(encryptText));
return new String(decryptBytes);
}
private static PublicKey loadPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
ClassPathResource resource = new ClassPathResource("public.key");
byte[] keyBytes = FileCopyUtils.copyToByteArray(resource.getInputStream());
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(spec);
}
private static PrivateKey loadPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
ClassPathResource resource = new ClassPathResource("private.key");
byte[] keyBytes = FileCopyUtils.copyToByteArray(resource.getInputStream());
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(spec);
}
private static byte[] readKeyFromFile(String fileName) {
File file = new File(fileName);
byte[] keyBytes = new byte[(int) file.length()];
try(FileInputStream fis = new FileInputStream(file)) {
fis.read(keyBytes);
} catch (IOException e) {
throw new RuntimeException(e);
}
return keyBytes;
}
private static void saveKeyToFile(String fileName, byte[] keyBytes) {
File file = new File(fileName);
try(FileOutputStream fos = new FileOutputStream(file)) {
fos.write(keyBytes);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
// System.out.println(encrypt("psn14020"));
// KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
// keygen.initialize(new RSAKeyGenParameterSpec(2048, RSAKeyGenParameterSpec.F4));
// KeyPair pair = keygen.generateKeyPair();
//
// saveKeyToFile("C:\\Users\\psn14020\\IdeaProjects\\talk\\src\\main\\resources\\private.key", pair.getPrivate().getEncoded());
// saveKeyToFile("C:\\Users\\psn14020\\IdeaProjects\\talk\\src\\main\\resources\\public.key", pair.getPublic().getEncoded());
}
}

View File

@@ -0,0 +1,58 @@
package com.kospo.svcm.config.utils;
import com.kospo.svcm.dto.res.DtlSpecExcelResponse;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.*;
import org.springframework.stereotype.Component;
import javax.xml.bind.DatatypeConverter;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@Component
@RequiredArgsConstructor
public class ExcelUtils {
public List<DtlSpecExcelResponse> dtlSpecExcel(String base64) {
ByteArrayInputStream bias = null;
try {
List<DtlSpecExcelResponse> DtlSpecExcelResponses = new ArrayList<>();
byte[] data = DatatypeConverter.parseBase64Binary(base64);
bias = new ByteArrayInputStream(data);
Workbook workbook = WorkbookFactory.create(bias);
Sheet sheet = workbook.getSheetAt(0);
for(Row row : sheet) {
if(row.getRowNum() != 0) {
AtomicInteger cellCount = new AtomicInteger(0);
DtlSpecExcelResponse DtlSpecExcelResponse = new DtlSpecExcelResponse();
for(Cell cell : row) {
if(cellCount.get() == 0) {
DtlSpecExcelResponse.setItemNm(cell.getStringCellValue());
} else if(cellCount.get() == 1) {
DtlSpecExcelResponse.setSpec(cell.getStringCellValue());
} else if(cellCount.get() == 2) {
DtlSpecExcelResponse.setUnit(cell.getStringCellValue());
} else if(cellCount.get() == 3) {
DtlSpecExcelResponse.setQty((int) cell.getNumericCellValue());
}
cellCount.incrementAndGet();
}
DtlSpecExcelResponses.add(DtlSpecExcelResponse);
}
}
return DtlSpecExcelResponses;
} catch(Exception e) {
throw new RuntimeException(e);
} finally {
try {
bias.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}

View File

@@ -0,0 +1,70 @@
package com.kospo.svcm.config.utils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import javax.xml.bind.DatatypeConverter;
import java.awt.image.BufferedImage;
import java.io.*;
@Component
public class FileUtils {
public synchronized boolean fileUpload(String full, String base64) {
boolean result = false;
File file = new File(full);
BufferedOutputStream bos = null;
try {
byte[] data = DatatypeConverter.parseBase64Binary(base64);
bos = new BufferedOutputStream(new FileOutputStream(file));
bos.write(data);
bos.flush();
result = true;
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
return result;
}
public synchronized boolean fileDelete(String full) {
File file = new File(full);
if(!file.exists()) {
return false;
} else {
file.delete();
return true;
}
}
public synchronized byte[] fileRead(String full) {
File file = new File(full);
if(file.exists()) {
BufferedImage originalImage = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
return fis.readAllBytes();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return null;
}
}

View File

@@ -0,0 +1,32 @@
package com.kospo.svcm.config.utils;
import jakarta.mail.internet.MimeMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import javax.mail.MessagingException;
@Component
@RequiredArgsConstructor
public class MailUtils {
// private final JavaMailSender mailSender;
public Boolean sendMail(String from, String to, String subject, String text) {
JavaMailSender mailSender = new JavaMailSenderImpl();
MimeMessage mimeMessage = mailSender.createMimeMessage();
try {
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false, "UTF-8");
mimeMessageHelper.setTo(to);
mimeMessageHelper.setFrom(from);
mimeMessageHelper.setSubject(subject);
mimeMessageHelper.setText(text);
mailSender.send(mimeMessage);
return true;
} catch (Exception e) {
return false;
}
}
}

View File

@@ -0,0 +1,20 @@
package com.kospo.svcm.config.utils;
import com.kospo.svcm.model.Sequence;
import com.kospo.svcm.repository.SequenceRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
@Configuration
@RequiredArgsConstructor
public class SequenceUtils {
private final SequenceRepository sequenceRepository;
public Integer findSeqAfterUpdate(String seqNm) {
Sequence sequence = sequenceRepository.findById(seqNm).get();
long nextVal = sequence.getNextVal() + 1;
sequence.setNextVal(nextVal);
sequenceRepository.save(sequence);
return Math.toIntExact(nextVal);
}
}

View File

@@ -0,0 +1,42 @@
package com.kospo.svcm.config.utils;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;
import org.springframework.context.annotation.Configuration;
import javax.xml.bind.DatatypeConverter;
import java.awt.image.BufferedImage;
import java.io.*;
@Configuration
public class XmlUtils {
public Object xmlToModel(String xml , Class cla) throws JAXBException, IOException, NoSuchMethodException {
ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes());
JAXBContext jaxbContext = JAXBContext.newInstance(cla);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Object obj = unmarshaller.unmarshal(bais);
bais.close();
return obj;
}
public String modelToXml(Object obj) throws JAXBException, IOException {
JAXBContext jaxbContext = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = jaxbContext.createMarshaller();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(obj, baos);
String list = baos.toString();
baos.close();
return list;
}
}

View File

@@ -0,0 +1,101 @@
package com.kospo.svcm.controller;
import com.kospo.svcm.config.exception.CustomErrorResponse;
import com.kospo.svcm.dto.req.ApprReqRequest;
import com.kospo.svcm.dto.res.ApprMstResponse;
import com.kospo.svcm.dto.res.ApprReqResponse;
import com.kospo.svcm.dto.res.PageResponse;
import com.kospo.svcm.dto.res.PrcsResponse;
import com.kospo.svcm.repository.ApprReqRepository;
import com.kospo.svcm.service.ApprService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
import java.util.List;
@Tag(name = "Approval Api", description = "결재 관리")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class ApprController {
private final ApprService apprService;
@Operation(summary = "가격조사 결재 상세 조회", description = "가격조사 결재 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{ApprMstResponse.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/appr/{prcsNo}")
public ResponseEntity findSearch(
@Parameter(description = "가격조사번호") @PathVariable(required = false) String prcsNo
) {
return ResponseEntity.ok(apprService.findByPrcsNo(prcsNo));
}
// @Operation(summary = "본인 결재목록 조회", description = "가격조사 결재 조회")
// @ApiResponses({
// @ApiResponse(description = "Success", responseCode = "200",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {PageResponse.class})
// )),
// @ApiResponse(description = "Not found", responseCode = "404",
// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
// {String.class}))),
// @ApiResponse(description = "Internal Error", responseCode = "500",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {CustomErrorResponse.class })))
// })
// @GetMapping("/appr/req")
// public ResponseEntity findReq(
// @Parameter(description = "page") @RequestParam("page") int page,
// @Parameter(description = "row") @RequestParam("row") int row,
// Principal principal
// ) {
// Pageable pageable = PageRequest.of(page -1, row);
// return ResponseEntity.ok(apprService.findByApprBySabun(principal.getName(), pageable));
// }
@Operation(summary = "가격조사 결재 상태변경", description = "결재 상태변경 (결재승인 0200 결재반려 0400)")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{ApprMstResponse.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PutMapping("/appr")
public ResponseEntity save(
@RequestBody ApprReqRequest apprReqRequest,
Principal principal
) {
return ResponseEntity.ok(apprService.stateUpdate(principal.getName(), apprReqRequest));
}
}

View File

@@ -0,0 +1,176 @@
package com.kospo.svcm.controller;
import com.kospo.svcm.config.exception.CustomErrorResponse;
import com.kospo.svcm.config.exception.ErrorCode;
import com.kospo.svcm.dto.req.BusinessRePasswdRequest;
import com.kospo.svcm.dto.req.BusinessUpdateRequest;
import com.kospo.svcm.dto.req.RegisterRequest;
import com.kospo.svcm.dto.res.BusinessResponse;
import com.kospo.svcm.exception.CustomException;
import com.kospo.svcm.service.BusinessService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
@Tag(name = "Business Api", description = "사업자 관리")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class BusinessController {
private final BusinessService businessService;
@Operation(summary = "사업자 조회", description = "전체 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", array = @ArraySchema(
schema = @Schema(oneOf =
{BusinessResponse.class})
))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/business")
public ResponseEntity findAll() {
return ResponseEntity.ok(businessService.findAll());
}
@Operation(summary = "사업자 개인 조회", description = "개인 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", array = @ArraySchema(
schema = @Schema(oneOf =
{BusinessResponse.class})
))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/business/me")
public ResponseEntity findById(
Principal principal
) {
return ResponseEntity.ok(businessService.findMe(principal.getName()));
}
@Operation(summary = "회원가입", description = "사업자 회원가입 한다.")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{BusinessResponse.class }))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PostMapping("/business")
public ResponseEntity register(@RequestBody RegisterRequest registerRequest) {
return ResponseEntity.ok(businessService.register(registerRequest));
}
@Operation(summary = "회원정보 수정", description = "사업자 정보 수정")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{BusinessResponse.class }))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PutMapping("/business")
public ResponseEntity update(
@RequestBody BusinessUpdateRequest businessUpdateRequest,
Principal principal
) {
return ResponseEntity.ok(businessService.update(principal.getName(), businessUpdateRequest));
}
@Operation(summary = "비밀번호 변경", description = "사업자 비밀번호 변경")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{BusinessResponse.class }))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PutMapping("/business/password")
public ResponseEntity rePassword(
@RequestBody BusinessRePasswdRequest businessRePasswdRequest,
Principal principal
) {
return ResponseEntity.ok(businessService.rePassword(principal.getName(), businessRePasswdRequest));
}
@Operation(summary = "회원탈퇴", description = "사업자 회원 탈퇴")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{String.class }))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@DeleteMapping("/business/{bizNo}")
public ResponseEntity delete(
@Parameter(description = "사업자번호") @PathVariable String bizNo,
Principal principal
) {
if(principal.getName().equals(bizNo)) {
businessService.delete(principal.getName(), bizNo);
return ResponseEntity.ok("삭제 되었습니다.");
} else {
throw new CustomException(ErrorCode.AUTHENTICATION);
}
}
@Operation(summary = "개인정보 만료 체크", description = "보유기간 만료된 사용자 휴면 계정으로 전환")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{String.class }))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/business/privary")
public ResponseEntity privacy(
Principal principal
) {
businessService.privacy();
return ResponseEntity.ok("");
}
}

View File

@@ -0,0 +1,260 @@
package com.kospo.svcm.controller;
import com.kospo.svcm.config.exception.CustomErrorResponse;
import com.kospo.svcm.dto.req.CodeRequest;
import com.kospo.svcm.dto.req.GrpCodeSaveRequest;
import com.kospo.svcm.dto.req.GrpCodeUpdateRequest;
import com.kospo.svcm.dto.res.CodeResponse;
import com.kospo.svcm.dto.res.GrpCodeResponse;
import com.kospo.svcm.dto.res.PageResponse;
import com.kospo.svcm.service.CodeService;
import com.kospo.svcm.service.GrpCodeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
@Tag(name = "Code Api", description = "코드 관리")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class CodeController {
private final CodeService codeService;
private final GrpCodeService grpCodeService;
@Operation(summary = "그룹코드 조회 (페이징)", description = "전체 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{PageResponse.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/grpCode/page")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity findGrpCodePage(
@Parameter(description = "nm") @RequestParam(value = "nm", required = false, defaultValue = "") String nm,
@Parameter(description = "useYn") @RequestParam(value = "useYn", required = false) boolean useYn,
@Parameter(description = "page") @RequestParam("page") int page,
@Parameter(description = "row") @RequestParam("row") int row
) {
Pageable pageable = PageRequest.of(page -1, row);
return ResponseEntity.ok(grpCodeService.findSearch(nm, useYn, pageable));
}
@Operation(summary = "그룹코드 조회", description = "전체 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", array = @ArraySchema(
schema = @Schema(oneOf =
{GrpCodeResponse.class})
))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/grpCode")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity findGrpCode(
@Parameter(description = "nm") @RequestParam(value = "nm", required = false, defaultValue = "") String nm,
@Parameter(description = "useYn") @RequestParam(value = "useYn", required = false) boolean useYn
) {
return ResponseEntity.ok(grpCodeService.findSearch(nm, useYn));
}
@Operation(summary = "그룹코드 저장", description = "그룹코드 저장")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{GrpCodeResponse.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PostMapping("/grpCode")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity saveRole(
@RequestBody GrpCodeSaveRequest grpCodeDto
) {
;
return ResponseEntity.ok(grpCodeService.save(grpCodeDto));
}
@Operation(summary = "그룹코드 수정", description = "그룹코드 수정")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{GrpCodeResponse.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PutMapping("/grpCode")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity updRole(
@RequestBody GrpCodeUpdateRequest grpCodeRequest
) {
return ResponseEntity.ok(grpCodeService.update(grpCodeRequest));
}
@Operation(summary = "그룹코드 삭제", description = "그룹코드 삭제")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{String.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@DeleteMapping("/grpCode/{id}")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity delRole(
@Parameter(description = "아이디") @PathVariable("id") Integer id
) {
grpCodeService.delete(id);
return ResponseEntity.ok("삭제 되었습니다.");
}
@Operation(summary = "특정 코드 조회", description = "코드 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", array = @ArraySchema(
schema = @Schema(oneOf =
{CodeResponse.class})
))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/code/{id}")
public ResponseEntity findSpecificCode(
@Parameter(description = "그룹 아이디") @PathVariable int id
) {
return ResponseEntity.ok(codeService.findSpecificCode(id));
}
@Operation(summary = "코드 조회", description = "코드 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", array = @ArraySchema(
schema = @Schema(oneOf =
{CodeResponse.class})
))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/code")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity findCode(
@Parameter(description = "useYn") @RequestParam(value = "useYn", required = false) boolean useYn,
@Parameter(description = "page") @RequestParam("page") int page,
@Parameter(description = "row") @RequestParam("row") int row
) {
Pageable pageable = PageRequest.of(page -1, row);
return ResponseEntity.ok(codeService.findSearch(useYn, pageable));
}
@Operation(summary = "코드 추가", description = "코드 저장")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CodeResponse.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PostMapping("/code")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity saveCode(
@RequestBody CodeRequest codeRequest
) {
;
return ResponseEntity.ok(codeService.save(codeRequest));
}
@Operation(summary = "코드 수정", description = "코드 수정")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CodeResponse.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PutMapping("/code")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity updCode(
@RequestBody CodeRequest codeRequest
) {
return ResponseEntity.ok(codeService.update(codeRequest));
}
@Operation(summary = "코드 삭제", description = "코드 삭제")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{String.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@DeleteMapping("/code")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity delCode(
@RequestBody CodeRequest codeRequest
) {
codeService.delete(codeRequest.getId(), codeRequest.getCd());
return ResponseEntity.ok("삭제 되었습니다.");
}
}

View File

@@ -0,0 +1,140 @@
package com.kospo.svcm.controller;
import com.kospo.svcm.config.exception.CustomErrorResponse;
import com.kospo.svcm.dto.req.ContSaveRequest;
import com.kospo.svcm.dto.res.ContListResponse;
import com.kospo.svcm.dto.res.ContSaveResponse;
import com.kospo.svcm.dto.res.PrcsResponse;
import com.kospo.svcm.service.ContService;
import com.kospo.svcm.service.PrcsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
@Tag(name = "Contract Api", description = "계약 관리")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class ContController {
private final ContService contService;
private final PrcsService prcsService;
@Operation(summary = "계약관리 - 가격조사 가져오기", description = "계약관리 등록 가격조사 가져오기")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", array = @ArraySchema(
schema = @Schema(oneOf =
{PrcsResponse.class})
))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/cont/prcs")
public ResponseEntity findContTarget(
) {
return ResponseEntity.ok(prcsService.findContTarget());
}
@Operation(summary = "계약관리 조회 (페이징)", description = "전체 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", array = @ArraySchema(
schema = @Schema(oneOf =
{ContListResponse.class})
))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/cont/page")
public ResponseEntity findCode(
@Parameter(description = "등록상태") @RequestParam(required = false) String contStatCd,
@Parameter(description = "계약체결시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String signSdt,
@Parameter(description = "계약체결종료일") @RequestParam(required = false, defaultValue = "2070-01-01") String signEdt,
@Parameter(description = "페이지") @RequestParam("page") int page,
@Parameter(description = "아이템갯수") @RequestParam("row") int row,
Principal principal
) {
Pageable pageable = PageRequest.of(page -1, row);
return ResponseEntity.ok(contService.findPage(principal.getName(), contStatCd, signSdt, signEdt, pageable));
}
@Operation(summary = "계약관리 상세조회", description = "계약번호로 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{ContListResponse.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/cont/{contNo}")
public ResponseEntity findCode(
@Parameter(description = "계약번호") @PathVariable String contNo,
Principal principal
) {
return ResponseEntity.ok(contService.findDetail(contNo));
}
@Operation(summary = "계약관리 저장", description = "계약관리, 첨부파일, 전자결재 통합저장")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{ContSaveResponse.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PostMapping("/cont")
public ResponseEntity save(
@RequestBody ContSaveRequest contSaveRequest
) {
return ResponseEntity.ok(contService.save(contSaveRequest));
}
@Operation(summary = "계약관리 회수 처리", description = "결재진행중인건에 대한 회수 처리")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{PrcsResponse.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PutMapping("/cont/ret/{contNo}")
public ResponseEntity retrieve(
@Parameter(description = "계약번호") @PathVariable String contNo,
Principal principal
) {
return ResponseEntity.ok(contService.retrieve(contNo));
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,293 @@
package com.kospo.svcm.controller;
import com.kospo.svcm.config.exception.CustomErrorResponse;
import com.kospo.svcm.config.utils.FileUtils;
import com.kospo.svcm.dto.req.EstimateListSaveRequest;
import com.kospo.svcm.dto.req.EstimateListUpdateRequest;
import com.kospo.svcm.dto.res.EstimateListResponse;
import com.kospo.svcm.dto.res.EstimateResponse;
import com.kospo.svcm.model.PbAtt;
import com.kospo.svcm.service.EstimateService;
import com.kospo.svcm.service.PrcsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.UrlResource;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.yaml.snakeyaml.util.UriEncoder;
import java.io.IOException;
import java.net.MalformedURLException;
import java.security.Principal;
@Tag(name = "Estimate Api", description = "견적 관리")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class EstimateController {
private final EstimateService estimateService;
private final PrcsService prcsService;
private final FileUtils fileUtils;
@Operation(summary = "가격조사 조회", description = "전체 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", array = @ArraySchema(
schema = @Schema(oneOf =
{EstimateResponse.class})
))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class})))
})
@GetMapping("/estimate")
public ResponseEntity findByBizNoAndPrcsNo(
@Parameter(description = "가격조사번호") @RequestParam(required = false) String prcsNo,
Principal principal
) {
return ResponseEntity.ok(estimateService.findByBizNoAndPrcsNo(principal.getName(), prcsNo));
}
@Operation(summary = "가격조사_견적관리 조회 (페이징)", description = "전체 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json",
schema = @Schema(oneOf =
{Pageable.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/estimate/external/page")
@PreAuthorize("hasRole('EXTERNAL')")
public ResponseEntity findExternalEstimateSearchPage(
@Parameter(description = "담당자") @RequestParam(required = false) String mngNm,
@Parameter(description = "제목") @RequestParam(required = false) String title,
@Parameter(description = "견적상태코드") @RequestParam(required = false) String estStatCd,
@Parameter(description = "페이지") @RequestParam("page") int page,
@Parameter(description = "아이템갯수") @RequestParam("row") int row,
Principal principal
) {
Pageable pageable = PageRequest.of(page -1, row);
return ResponseEntity.ok(prcsService.findExternalEstSearch(principal.getName(), title, estStatCd, mngNm, pageable));
}
//
// @Operation(summary = "가격조사 조회 (페이징)", description = "전체 조회")
// @ApiResponses({
// @ApiResponse(description = "Success", responseCode = "200",
// content = @Content(mediaType = "application/json", array = @ArraySchema(
// schema = @Schema(oneOf =
// {PrcsResponse.class})
// ))),
// @ApiResponse(description = "Not found", responseCode = "404",
// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
// {String.class}))),
// @ApiResponse(description = "Internal Error", responseCode = "500",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {CustomErrorResponse.class })))
// })
// @GetMapping("/prcs/page")
// public ResponseEntity findCode(
// @Parameter(description = "분야코드") @RequestParam(required = false) String cateCd,
// @Parameter(description = "등록상태") @RequestParam(required = false) String stCd,
// @Parameter(description = "담당자") @RequestParam(required = false) String regNm,
// @Parameter(description = "등록시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String regSdt,
// @Parameter(description = "등록종료일") @RequestParam(required = false, defaultValue = "2070-01-01") String regEdt,
// @Parameter(description = "페이지") @RequestParam("page") int page,
// @Parameter(description = "아이템갯수") @RequestParam("row") int row
// ) {
// Pageable pageable = PageRequest.of(page -1, row);
// return ResponseEntity.ok(
// MsgResponse.builder()
// .code("10000")
// .body(prcsService.findSearch(cateCd, stCd, regNm, regSdt, regEdt, pageable))
// .build()
// );
// }
@Operation(summary = "견적 관리 저장", description = "견적, 견적서(첨부파일) 저장")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", array = @ArraySchema(
schema = @Schema(oneOf =
{EstimateListResponse.class})
))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class})))
})
@PostMapping("/estimate")
public ResponseEntity save(
@RequestBody EstimateListSaveRequest estimateListSaveRequest
) {
return ResponseEntity.ok(estimateService.save(estimateListSaveRequest));
}
@Operation(summary = "견적 관리 수정", description = "견적, 견적서(첨부파일) 수정")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{EstimateListResponse.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class})))
})
@PutMapping("/estimate")
public ResponseEntity update(
@RequestBody EstimateListUpdateRequest estimateListUpdateRequest,
Principal principal
) {
return ResponseEntity.ok(estimateService.update(principal.getName(), estimateListUpdateRequest));
}
@Operation(summary = "견적서 삭제", description = "견적서(첨부파일) 삭제")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class})))
})
@DeleteMapping("/pbAtt/{prcsNo}/{bizNo}/{fileOrd}")
public ResponseEntity delete(
@Parameter(description = "가격조사번호") @PathVariable String prcsNo,
@Parameter(description = "견적관리번호") @PathVariable String bizNo,
@Parameter(description = "파일순서") @PathVariable Integer fileOrd,
Principal principal
) {
estimateService.pbAttFileDelete(prcsNo, bizNo, fileOrd);
return ResponseEntity.ok("삭제 되었습니다.");
}
@Operation(summary = "견적서 다운로드", description = "견적서(첨부파일) 다운로드")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{byte[].class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class})))
})
@GetMapping("/pbAtt/{prcsNo}/{bizNo}/{fileOrd}")
public ResponseEntity download(
@Parameter(description = "가격조사번호") @PathVariable String prcsNo,
@Parameter(description = "견적관리번호") @PathVariable String bizNo,
@Parameter(description = "파일순서") @PathVariable Integer fileOrd,
Principal principal
) {
PbAtt pbAtt = estimateService.getPbAtt(prcsNo, bizNo, fileOrd, principal.getName());
UrlResource resource = null;
HttpHeaders headers = new HttpHeaders();
try {
resource = new UrlResource("file:"+pbAtt.getPath());
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + UriEncoder.encode(pbAtt.getLogiFnm()).replace("+", " "));
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentLength(resource.contentLength());
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
// HTTP 헤더 설정
return ResponseEntity.ok()
.headers(headers)
.body(resource);
}
// @Operation(summary = "견적서 삭제", description = "견적서(첨부파일) 삭제")
// @ApiResponses({
// @ApiResponse(description = "Success", responseCode = "200",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {String.class}))),
// @ApiResponse(description = "Not found", responseCode = "404",
// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
// {String.class}))),
// @ApiResponse(description = "Internal Error", responseCode = "500",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {CustomErrorResponse.class})))
// })
// @DeleteMapping("/estimate/{bidNo}/{fileOrd}")
// public ResponseEntity delete(
// @Parameter(description = "견적관리번호") @PathVariable String bidNo,
// @Parameter(description = "파일순서") @PathVariable Integer fileOrd,
// Principal principal
// ) {
// estimateService.bidFileDelete(bidNo, fileOrd);
// return ResponseEntity.ok("삭제 되었습니다.");
// }
//
// @Operation(summary = "견적서 다운로드", description = "견적서(첨부파일) 다운로드")
// @ApiResponses({
// @ApiResponse(description = "Success", responseCode = "200",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {byte[].class}))),
// @ApiResponse(description = "Not found", responseCode = "404",
// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
// {String.class}))),
// @ApiResponse(description = "Internal Error", responseCode = "500",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {CustomErrorResponse.class})))
// })
// @GetMapping("/estimate/{bidNo}/{fileOrd}")
// public ResponseEntity download(
// @Parameter(description = "견적관리번호") @PathVariable String bidNo,
// @Parameter(description = "파일순서") @PathVariable Integer fileOrd,
// Principal principal
// ) {
// BidDoc bidDoc = estimateService.getBidDoc(bidNo, fileOrd);
// UrlResource resource = null;
// HttpHeaders headers = new HttpHeaders();
// try {
// resource = new UrlResource("file:"+bidDoc.getPath());
// headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + UriEncoder.encode(bidDoc.getLogiFnm()).replace("+", " "));
// headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
// headers.setContentLength(resource.contentLength());
// } catch (MalformedURLException e) {
// throw new RuntimeException(e);
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
//
// // HTTP 헤더 설정
//
//
// return ResponseEntity.ok()
// .headers(headers)
// .body(resource);
// }
}

View File

@@ -0,0 +1,80 @@
package com.kospo.svcm.controller;
import com.kospo.svcm.config.exception.CustomErrorResponse;
import com.kospo.svcm.dto.req.ApprReqRequest;
import com.kospo.svcm.dto.res.ApprMstResponse;
import com.kospo.svcm.dto.res.ApprReqResponse;
import com.kospo.svcm.dto.res.PageResponse;
import com.kospo.svcm.repository.ApprReqRepository;
import com.kospo.svcm.service.ApprService;
import com.kospo.svcm.service.IntegratedApprService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
@Tag(name = "Integrated Approval Api", description = "통합 결재 관리")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class IntegratedApprController {
private final IntegratedApprService integratedApprService;
@Operation(summary = "통합 결재 승인 목록(개인) 조회", description = "통합 결재 승인 목록 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{PageResponse.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/itg/appr/req")
public ResponseEntity findReq(
@Parameter(description = "결재제목") @RequestParam(value="title", required = false) String title,
@Parameter(description = "결재상태") @RequestParam(value="apprStat", required = false) String apprStat,
@Parameter(description = "페이지") @RequestParam("page") int page,
@Parameter(description = "아이템갯수") @RequestParam("row") int row
) {
Pageable pageable = PageRequest.of(page -1, row);
return ResponseEntity.ok(integratedApprService.searchBySabun(title, apprStat, pageable));
}
@Operation(summary = "통합 결재 목록(부서) 조회", description = "통합 결재 목록 조회 (관리자 :전체, 일반사용자 :부서)")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{PageResponse.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/itg/appr")
public ResponseEntity findAll(
@Parameter(description = "결재제목") @RequestParam(value="title", required = false) String title,
@Parameter(description = "페이지") @RequestParam("page") int page,
@Parameter(description = "아이템갯수") @RequestParam("row") int row
) {
Pageable pageable = PageRequest.of(page -1, row);
return ResponseEntity.ok(integratedApprService.searchList(title, pageable));
}
}

View File

@@ -0,0 +1,73 @@
package com.kospo.svcm.controller;
import com.kospo.svcm.config.exception.CustomErrorResponse;
import com.kospo.svcm.config.utils.CommonUtils;
import com.kospo.svcm.dto.req.LoginRequest;
import com.kospo.svcm.dto.res.LoginResponse;
import com.kospo.svcm.service.BusinessService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
@Tag(name = "Login Api", description = "로그인 관리")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class LoginController {
private final BusinessService businessService;
@Operation(summary = "로그인", description = "토큰을 생성한다.")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{LoginResponse.class }))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PostMapping("/login")
public ResponseEntity login(
@RequestBody LoginRequest loginRequest,
HttpServletRequest request
) {
return ResponseEntity.ok(businessService.login(loginRequest, CommonUtils.getClientIp(request)));
}
@Operation(summary = "토큰 유효성 검증", description = "토큰 만료 여부 확인")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{LoginResponse.class }))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/token/valid")
public ResponseEntity tokenValidate(
@RequestHeader("Authentication") String accessToken,
Principal principal
) {
if(accessToken == null || accessToken.isEmpty()) {
return ResponseEntity.ok(false);
} else {
return ResponseEntity.ok(businessService.tokenValidate(principal.getName(), accessToken));
}
}
}

View File

@@ -0,0 +1,355 @@
package com.kospo.svcm.controller;
import com.kospo.svcm.config.exception.CustomErrorResponse;
import com.kospo.svcm.dto.req.PrcsSaveRequest;
import com.kospo.svcm.dto.req.PrcsUpdateRequest;
import com.kospo.svcm.dto.res.PrcsResponse;
import com.kospo.svcm.model.PrcsAtt;
import com.kospo.svcm.service.PrcsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.UrlResource;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.yaml.snakeyaml.util.UriEncoder;
import java.io.IOException;
import java.net.MalformedURLException;
import java.security.Principal;
@Tag(name = "PriceSurvey Api", description = "가격조사 관리")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class PrcsController {
private final PrcsService prcsService;
@Operation(summary = "가격조사 상세조회", description = "가격조사번로 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json",
schema = @Schema(oneOf =
{PrcsResponse.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/prcs/{prcsNo}")
public ResponseEntity findSearchPage(
@Parameter(description = "가격조사번호") @PathVariable(required = false) String prcsNo
) {
return ResponseEntity.ok(prcsService.findDetail(prcsNo));
}
@Operation(summary = "가격조사 조회 (페이징)", description = "전체 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json",
schema = @Schema(oneOf =
{Pageable.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/prcs/page")
public ResponseEntity findSearchPage(
@Parameter(description = "분야코드") @RequestParam(required = false) String cateCd,
@Parameter(description = "등록상태") @RequestParam(required = false) String stCd,
@Parameter(description = "담당자") @RequestParam(required = false) String regNm,
@Parameter(description = "등록시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String regSdt,
@Parameter(description = "등록종료일") @RequestParam(required = false, defaultValue = "2070-01-01") String regEdt,
@Parameter(description = "페이지") @RequestParam("page") int page,
@Parameter(description = "아이템갯수") @RequestParam("row") int row
) {
Pageable pageable = PageRequest.of(page -1, row);
return ResponseEntity.ok(prcsService.findSearch(cateCd, stCd, regNm, regSdt, regEdt, pageable));
}
@Operation(summary = "가격조사_견적관리 조회", description = "단일 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json",
schema = @Schema(oneOf =
{Pageable.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/prcs/external/{prcsNo}")
@PreAuthorize("hasRole('EXTERNAL')")
public ResponseEntity findExternalPrcs(
@Parameter(description = "가격조사번호") @PathVariable String prcsNo,
Principal principal
) {
return ResponseEntity.ok(prcsService.findOne(principal.getName(), prcsNo));
}
@Operation(summary = "가격조사_견적관리 조회 (페이징)", description = "전체 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json",
schema = @Schema(oneOf =
{Pageable.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/prcs/external/page")
@PreAuthorize("hasRole('EXTERNAL')")
public ResponseEntity findExternalSearchPage(
@Parameter(description = "분야코드") @RequestParam(required = false) String cateCd,
@Parameter(description = "담당자") @RequestParam(required = false) String regNm,
@Parameter(description = "제목") @RequestParam(required = false) String title,
@Parameter(description = "등록시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String regSdt,
@Parameter(description = "등록종료일") @RequestParam(required = false, defaultValue = "9999-12-31") String regEdt,
@Parameter(description = "페이지") @RequestParam("page") int page,
@Parameter(description = "아이템갯수") @RequestParam("row") int row,
Principal principal
) {
Pageable pageable = PageRequest.of(page -1, row);
return ResponseEntity.ok(prcsService.findExternalSearch(principal.getName(), cateCd, title, regNm, regSdt, regEdt, pageable));
}
@Operation(summary = "가격조사_견적관리 조회 (페이징)", description = "전체 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json",
schema = @Schema(oneOf =
{Pageable.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/prcs/external/count")
@PreAuthorize("hasRole('EXTERNAL')")
public ResponseEntity findExternalSearchPage(
Principal principal
) {
return ResponseEntity.ok(prcsService.countReqByBizNo(principal.getName()));
}
@Operation(summary = "가격조사_계약관리 조회 (페이징)", description = "전체 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json",
schema = @Schema(oneOf =
{Pageable.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/prcs/contract/page")
public ResponseEntity findContractSearchPage(
@Parameter(description = "분야코드") @RequestParam(required = false) String cateCd,
@Parameter(description = "담당자") @RequestParam(required = false) String regNm,
@Parameter(description = "등록시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String regSdt,
@Parameter(description = "등록종료일") @RequestParam(required = false, defaultValue = "2070-01-01") String regEdt,
@Parameter(description = "페이지") @RequestParam("page") int page,
@Parameter(description = "아이템갯수") @RequestParam("row") int row
) {
Pageable pageable = PageRequest.of(page -1, row);
return ResponseEntity.ok(prcsService.findContractSearch(cateCd, regNm, regSdt, regEdt, pageable));
}
@Operation(summary = "가격조사_결재관리 조회 (페이징)", description = "전체 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json",
schema = @Schema(oneOf =
{Pageable.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/prcs/approval/page")
public ResponseEntity findApprSearchPage(
@Parameter(description = "분야코드") @RequestParam(required = false) String cateCd,
@Parameter(description = "담당자") @RequestParam(required = false) String regNm,
@Parameter(description = "등록시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String regSdt,
@Parameter(description = "등록종료일") @RequestParam(required = false, defaultValue = "2070-01-01") String regEdt,
@Parameter(description = "페이지") @RequestParam("page") int page,
@Parameter(description = "아이템갯수") @RequestParam("row") int row,
Principal principal
) {
Pageable pageable = PageRequest.of(page -1, row);
return ResponseEntity.ok(prcsService.findApprovalSearch(principal.getName(), cateCd, regNm, regSdt, regEdt, pageable));
}
@Operation(summary = "가격조사 저장", description = "가격조사, 규격, 첨부파일, 결재 통합저장")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{PrcsResponse.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PostMapping("/prcs")
public ResponseEntity save(
@RequestBody PrcsSaveRequest prcsRequest
) {
return ResponseEntity.ok(prcsService.save(prcsRequest));
}
@Operation(summary = "가격조사 수정", description = "가격조사, 규격, 첨부파일, 결재 통합 수정")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{PrcsResponse.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PutMapping("/prcs")
public ResponseEntity update(
@RequestBody PrcsUpdateRequest prcsRequest,
Principal principal
) {
return ResponseEntity.ok(prcsService.update(principal.getName(), prcsRequest));
}
@Operation(summary = "가격조사 회수 처리", description = "결재진행중인건에 대한 회수 처리")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{PrcsResponse.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PutMapping("/prcs/ret/{prcsNo}")
public ResponseEntity retrieve(
@Parameter(description = "가격조사번호") @PathVariable String prcsNo,
Principal principal
) {
return ResponseEntity.ok(prcsService.retrieve(prcsNo));
}
@Operation(summary = "가격조사 첨부파일 삭제", description = "가격조사 문서(첨부파일) 삭제")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@DeleteMapping("/prcs/{prcsNo}/{fileOrd}")
public ResponseEntity fileDelete(
@Parameter(description = "가격조사번호") @PathVariable String prcsNo,
@Parameter(description = "파일순서") @PathVariable Integer fileOrd,
Principal principal
) {
prcsService.prcsAttFileDelete(prcsNo, fileOrd);
return ResponseEntity.ok("삭제 되었습니다.");
}
@Operation(summary = "가격조사 완료 처리", description = "가격조사 완료 처리(사전 처리 및 자동 완료 처리)")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{PrcsResponse.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PutMapping("/prcs/survey/{prcsNo}")
public ResponseEntity surveyUpdate(
@Parameter(description = "가겨조사 번호") @PathVariable String prcsNo,
Principal principal
) {
return ResponseEntity.ok(prcsService.surveyUpdate(principal.getName(), prcsNo));
}
@Operation(summary = "가격조사서 다운로드", description = "가격조사서(첨부파일) 다운로드")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{byte[].class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class})))
})
@GetMapping("/prcs/{prcsNo}/{fileOrd}")
public ResponseEntity download(
@Parameter(description = "가격조사번호") @PathVariable String prcsNo,
@Parameter(description = "파일순서") @PathVariable Integer fileOrd,
Principal principal
) {
PrcsAtt prcsAtt = prcsService.getPrcsAtt(prcsNo, fileOrd, principal.getName());
UrlResource resource = null;
HttpHeaders headers = new HttpHeaders();
try {
resource = new UrlResource("file:"+prcsAtt.getPath());
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + UriEncoder.encode(prcsAtt.getLogiFnm()).replace("+", " "));
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentLength(resource.contentLength());
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
// HTTP 헤더 설정
return ResponseEntity.ok()
.headers(headers)
.body(resource);
}
}

View File

@@ -0,0 +1,115 @@
package com.kospo.svcm.controller;
import com.kospo.svcm.config.exception.CustomErrorResponse;
import com.kospo.svcm.dto.req.RoleRequest;
import com.kospo.svcm.dto.res.RoleResponse;
import com.kospo.svcm.dto.res.UserResponse;
import com.kospo.svcm.service.RoleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
@RestController
@Tag(name = "Role Api", description = "권한 관리")
@RequestMapping("/api")
@RequiredArgsConstructor
public class RoleController {
private final RoleService roleService;
@Operation(summary = "권한 조회", description = "전체 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", array = @ArraySchema(
schema = @Schema(oneOf =
{UserResponse.class})
))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/role")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity findRole(
@Parameter(description = "권한아이디") @RequestParam("roleId") String roleId
) {
return ResponseEntity.ok(roleService.findByRoleId(roleId));
}
@Operation(summary = "권한 추가", description = "관리자 권한부여")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{RoleResponse.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PostMapping("/role")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity saveRole(
@RequestBody RoleRequest roleRequest
) {
;
return ResponseEntity.ok(roleService.save(roleRequest));
}
@Operation(summary = "권한 수정", description = "관리자 아이피 수정")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{RoleResponse.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PutMapping("/role")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity updRole(
@RequestBody RoleRequest roleRequest
) {
return ResponseEntity.ok(roleService.update(roleRequest));
}
@Operation(summary = "권한 삭제", description = "특정 사용자 권한삭제")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{String.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@DeleteMapping("/role")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity delRole(
@RequestBody RoleRequest roleRequest
) {
roleService.delete(roleRequest);
return ResponseEntity.ok("삭제 되었습니다.");
}
}

View File

@@ -0,0 +1,187 @@
package com.kospo.svcm.controller;
import com.kospo.svcm.config.exception.CustomErrorResponse;
import com.kospo.svcm.dto.req.Zwf0011tSaveRequest;
import com.kospo.svcm.dto.req.ZwfApprUpdateRequest;
import com.kospo.svcm.dto.res.PageResponse;
import com.kospo.svcm.dto.res.Zwf0011tResponse;
import com.kospo.svcm.service.ApprService;
import com.kospo.svcm.service.SapService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
@Tag(name = "Sap Approval Api", description = "Sap 결재 관리")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class SapApprController {
private final SapService sapService;
// @Operation(summary = "SAP 결재 전체 조회", description = "임시전표 -> 확정전표 결재 조회")
// @ApiResponses({
// @ApiResponse(description = "Success", responseCode = "200",
// content = @Content(mediaType = "application/json", array = @ArraySchema(
// schema = @Schema(oneOf = {Zwf0011tResponse.class})
// ))),
// @ApiResponse(description = "Not found", responseCode = "404",
// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
// {String.class}))),
// @ApiResponse(description = "Internal Error", responseCode = "500",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {CustomErrorResponse.class })))
// })
// @GetMapping("/sap/appr")
// public ResponseEntity findSearch(
// @Parameter(description = "결재상태") @RequestParam(required = false) String wkfst,
// @Parameter(description = "요청자") @RequestParam(required = false) String ernam,
// @Parameter(description = "등록시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String erSdat,
// @Parameter(description = "등록종료일") @RequestParam(required = false, defaultValue = "2070-01-01") String erEdat,
// @Parameter(description = "페이지") @RequestParam("page") int page,
// @Parameter(description = "아이템갯수") @RequestParam("row") int row
// ) {
// Pageable pageable = PageRequest.of(page-1, row);
// return ResponseEntity.ok(sapService.findSearch(wkfst, ernam, erSdat, erEdat, pageable));
// }
// @Operation(summary = "SAP 결재 본인 승인 목록 조회", description = "결재시행 목록 조회")
// @ApiResponses({
// @ApiResponse(description = "Success", responseCode = "200",
// content = @Content(mediaType = "application/json", array = @ArraySchema(
// schema = @Schema(oneOf = {Zwf0011tResponse.class})
// ))),
// @ApiResponse(description = "Not found", responseCode = "404",
// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
// {String.class}))),
// @ApiResponse(description = "Internal Error", responseCode = "500",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {CustomErrorResponse.class })))
// })
// @GetMapping("/sap/appr")
// public ResponseEntity findSearchBySabun(
// @Parameter(description = "결재상태") @RequestParam(required = false) String wkfst,
// @Parameter(description = "등록시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String erSdat,
// @Parameter(description = "등록종료일") @RequestParam(required = false, defaultValue = "2070-01-01") String erEdat,
// @Parameter(description = "페이지") @RequestParam("page") int page,
// @Parameter(description = "아이템갯수") @RequestParam("row") int row
// ) {
// Pageable pageable = PageRequest.of(page-1, row);
// return ResponseEntity.ok(sapService.findSearchBySabun(wkfst, erSdat, erEdat, pageable));
// }
// @Operation(summary = "SAP 결재 상세 조회", description = "임시전표 -> 확정전표 결재 상세 조회")
// @ApiResponses({
// @ApiResponse(description = "Success", responseCode = "200",
// content = @Content(mediaType = "application/json",
// schema = @Schema(oneOf = {PageResponse.class})
// )),
// @ApiResponse(description = "Not found", responseCode = "404",
// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
// {String.class}))),
// @ApiResponse(description = "Internal Error", responseCode = "500",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {CustomErrorResponse.class })))
// })
// @GetMapping("/sap/appr/{wkfid}")
// public ResponseEntity findDetail(
// @Parameter(description = "요청번호") String wfkid
// ) {
//
// return ResponseEntity.ok(sapService.getDetail(wfkid));
// }
@Operation(summary = "SAP 결재 저장", description = "임시전표 + sap 결재 저장")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json",
schema = @Schema(oneOf = {PageResponse.class})
)),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PostMapping("/sap/appr")
public ResponseEntity save(
@RequestBody Zwf0011tSaveRequest zwf0011tSaveRequest
) {
return ResponseEntity.ok(sapService.save(zwf0011tSaveRequest));
}
@Operation(summary = "SAP 결재상태 변경", description = "sap 결재상태 변경(결재승인 A, 결재반려 S")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", array = @ArraySchema(
schema = @Schema(oneOf = {Zwf0011tResponse.class})
))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PutMapping("/sap/appr")
public ResponseEntity approve(
@RequestBody ZwfApprUpdateRequest zwfApprUpdateRequest
) {
return ResponseEntity.ok(sapService.approve(zwfApprUpdateRequest));
}
// @Operation(summary = "본인 결재목록 조회", description = "가격조사 결재 조회")
// @ApiResponses({
// @ApiResponse(description = "Success", responseCode = "200",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {PageResponse.class})
// )),
// @ApiResponse(description = "Not found", responseCode = "404",
// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
// {String.class}))),
// @ApiResponse(description = "Internal Error", responseCode = "500",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {CustomErrorResponse.class })))
// })
// @GetMapping("/appr/req")
// public ResponseEntity findReq(
// @Parameter(description = "page") @RequestParam("page") int page,
// @Parameter(description = "row") @RequestParam("row") int row,
// Principal principal
// ) {
// Pageable pageable = PageRequest.of(page -1, row);
// return ResponseEntity.ok(apprService.findByApprBySabun(principal.getName(), pageable));
// }
//
// @Operation(summary = "결재 갱신", description = "결재 상태 갱신")
// @ApiResponses({
// @ApiResponse(description = "Success", responseCode = "200",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {ApprReqResponse.class}))),
// @ApiResponse(description = "Not found", responseCode = "404",
// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
// {String.class}))),
// @ApiResponse(description = "Internal Error", responseCode = "500",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {CustomErrorResponse.class })))
// })
// @PutMapping("/appr")
// public ResponseEntity save(
// @RequestBody ApprReqRequest apprReqRequest,
// Principal principal
// ) {
// return ResponseEntity.ok(apprService.stateUpdate(principal.getName(), apprReqRequest));
// }
}

View File

@@ -0,0 +1,122 @@
package com.kospo.svcm.controller;
import com.kospo.svcm.config.exception.CustomErrorResponse;
import com.kospo.svcm.config.utils.FileUtils;
import com.kospo.svcm.dto.req.SlipSaveRequest;
import com.kospo.svcm.dto.res.EstimateListResponse;
import com.kospo.svcm.service.EstimateService;
import com.kospo.svcm.service.PrcsService;
import com.kospo.svcm.service.SlipService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
@Tag(name = "slip Api", description = "전표 관리")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class SlipController {
private final EstimateService estimateService;
private final PrcsService prcsService;
private final FileUtils fileUtils;
private final SlipService slipService;
// @Operation(summary = "전표 목록 조회", description = "임시, 확정 전표 조회")
// @ApiResponses({
// @ApiResponse(description = "Success", responseCode = "200",
// content = @Content(mediaType = "application/json",
// schema = @Schema(oneOf =
// {Pageable.class}))),
// @ApiResponse(description = "Not found", responseCode = "404",
// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
// {String.class}))),
// @ApiResponse(description = "Internal Error", responseCode = "500",
// content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
// {CustomErrorResponse.class })))
// })
// @GetMapping("/slip/page")
// public ResponseEntity findExternalEstimateSearchPage(
// @Parameter(description = "페이지") @RequestParam("page") int page,
// @Parameter(description = "아이템갯수") @RequestParam("row") int row,
// Principal principal
// ) {
// Pageable pageable = PageRequest.of(page -1, row);
// return null;
// }
@Operation(summary = "전표 상세 조회", description = "임시, 확정 전표 상세 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json",
schema = @Schema(oneOf =
{Pageable.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/slip/page/{contNo}")
public ResponseEntity findByContNo(
@Parameter(description = "계약번호") @PathVariable("contNo") String contNo,
Principal principal
) {
return ResponseEntity.ok(slipService.findByContNo(contNo));
}
@Operation(summary = "임시전표 저장", description = "임시전표 (계약중 대상자) 저장")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", array = @ArraySchema(
schema = @Schema(oneOf =
{EstimateListResponse.class})
))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class})))
})
@PostMapping("/slip")
public ResponseEntity save(
@RequestBody SlipSaveRequest slipSaveRequest
) {
return ResponseEntity.ok(slipService.save(slipSaveRequest));
}
@Operation(summary = "임시전표삭제 삭제", description = "임시전표삭제 삭제")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class})))
})
@DeleteMapping("/slip/{contNo}")
public ResponseEntity delete(
@Parameter(description = "계약번호") @PathVariable String contNo,
Principal principal
) {
slipService.delete(contNo);
return ResponseEntity.ok("삭제 되었습니다.");
}
}

View File

@@ -0,0 +1,65 @@
package com.kospo.svcm.controller;
import com.kospo.svcm.config.exception.CustomErrorResponse;
import com.kospo.svcm.model.User;
import com.kospo.svcm.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
@RestController
@Tag(name = "User Api", description = "사용자 관리")
@RequestMapping("/api")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@Operation(summary = "현재 사용자 정보 조회", description = "현재 사용자의 인사정보를 조회")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @io.swagger.v3.oas.annotations.media.Content(mediaType = "application/json", schema = @Schema(oneOf =
{User.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @io.swagger.v3.oas.annotations.media.Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @io.swagger.v3.oas.annotations.media.Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/user/info")
public ResponseEntity userInfo(
Principal principal) {
System.out.println(principal.getName());
return ResponseEntity.ok(userService.findOne(principal.getName()));
}
@Operation(summary = "직원검색", description = "이름 또는 사번으로 직원검색")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @io.swagger.v3.oas.annotations.media.Content(mediaType = "application/json", schema = @Schema(oneOf =
{User.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @io.swagger.v3.oas.annotations.media.Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @io.swagger.v3.oas.annotations.media.Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@GetMapping("/user")
// @PreAuthorize("hasRole('USER')")
public ResponseEntity findByName(
@Parameter(description = "이름") @RequestParam String name,
Principal principal) {
return ResponseEntity.ok(userService.findByNameContaining(name));
}
}

View File

@@ -0,0 +1,31 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.ApprReq;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
/**
* DTO for {@link ApprReq}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "ApprReqRequest", description = "현재 결재자")
public class ApprReqRequest implements Serializable {
@Schema(name = "apprNo", description = "결재번호")
String apprNo;
@Schema(name = "apprOrd", description = "결재순서")
Integer apprOrd;
@Schema(name = "sabun", description = "사번")
String sabun;
@Schema(name = "apprStatCd", description = "결재상태코드")
String apprStatCd;
@Schema(name = "reason", description = "사유 (반려일시 상태코드 0400)")
String reason;
}

View File

@@ -0,0 +1,32 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Business;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* DTO for {@link Business}
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "BusinessRePasswdRequest", description = "사업자 비밀번호 변경")
public class BusinessRePasswdRequest implements Serializable {
@Schema(name = "bizNo", description = "사업자번호")
String bizNo;
@Schema(name = "oldPwd", description = "이전비밀번호(비밀번호 변경시)")
String oldPwd;
@Schema(name = "pwd", description = "비밀번호 (삭제시 비밀번호 확인용으로도 사용됨)")
String pwd;
@Schema(name = "rePwd", description = "비밀번호 재확인")
String rePwd;
}

View File

@@ -0,0 +1,38 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Business;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* DTO for {@link Business}
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "BusinessRequest", description = "사업자")
public class BusinessRequest implements Serializable {
@Schema(name = "bizNo", description = "사업자번호")
String bizNo;
@Schema(name = "oldPwd", description = "이전비밀번호(비밀번호 변경시)")
String oldPwd;
@Schema(name = "pwd", description = "비밀번호 (삭제시 비밀번호 확인용으로도 사용됨)")
String pwd;
@Schema(name = "rePwd", description = "비밀번호 재확인")
String rePwd;
@Schema(name = "compNm", description = "업체명")
String compNm;
@Schema(name = "repNm", description = "대표자명")
String repNm;
@Schema(name = "email", description = "이메일")
String email;
}

View File

@@ -0,0 +1,32 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Business;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* DTO for {@link Business}
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "BusinessUpdateRequest", description = "사업자")
public class BusinessUpdateRequest implements Serializable {
@Schema(name = "bizNo", description = "사업자번호")
String bizNo;
@Schema(name = "compNm", description = "업체명")
String compNm;
@Schema(name = "repNm", description = "대표자명")
String repNm;
@Schema(name = "email", description = "이메일")
String email;
}

View File

@@ -0,0 +1,28 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "CodeDto", description = "코드")
public class CodeRequest {
@Schema(name = "id", description = "아이디")
private Integer id;
@Schema(name = "cd", description = "코드")
private String cd;
@Schema(name = "nm", description = "코드명")
private String nm;
@Schema(name = "desc", description = "설명")
private String desc;
@Schema(name = "useYn", description = "사용여부")
private Boolean useYn;
}

View File

@@ -0,0 +1,53 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Cont;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
import java.util.List;
/**
* DTO for {@link Cont}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "ContSaveRequest", description = "계약관리 저장")
public class ContSaveRequest implements Serializable {
@Schema(name = "bizNo", description = "사업자번호")
String bizNo;
@Schema(name = "prcsNo", description = "가겨조사 번호")
String prcsNo;
@Schema(name = "title", description = "계약명")
String title;
@Schema(name = "compNm", description = "업체명")
String compNm;
@Schema(name = "contSdat", description = "계약시작일")
String contSdat;
@Schema(name = "contEdat", description = "계약종료일")
String contEdat;
@Schema(name = "excYn", description = "가격조사 예외")
boolean excYn;
@Schema(name = "reason", description = "가격조사 예외사유")
String reason;
List<ContAttSaveRequest> contAtts;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "ContAttSaveRequest", description = "계약 문서")
public static class ContAttSaveRequest implements Serializable {
@Schema(name = "logiFnm", description = "논리파일명")
String logiFnm;
@Schema(name = "data", description = "base64")
String data;
}
}

View File

@@ -0,0 +1,56 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Cont;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
import java.util.List;
/**
* DTO for {@link Cont}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "ContUpdateRequest", description = "계약관리 수정")
public class ContUpdateRequest implements Serializable {
@Schema(name = "contNo", description = "계약번호")
String contNo;
@Schema(name = "bizNo", description = "사업자번호")
String bizNo;
@Schema(name = "compNm", description = "업체명")
String compNm;
@Schema(name = "signDt", description = "계약체결일")
String signDt;
@Schema(name = "contAmt", description = "계약금액")
Integer contAmt;
@Schema(name = "contSdat", description = "계약시작일")
String contSdat;
@Schema(name = "contEdat", description = "계약종료일")
String contEdat;
List<ContAttUpdateResponse> contAtts;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "ContAttUpdateResponse", description = "계약 문서")
public static class ContAttUpdateResponse implements Serializable {
@Schema(name = "contNo", description = "계약번호")
String contNo;
@Schema(name = "fileOrd", description = "파일순서")
Integer fileOrd;
@Schema(name = "logiFnm", description = "논리파일명")
String logiFnm;
@Schema(name = "data", description = "base64")
String data;
}
}

View File

@@ -0,0 +1,19 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "DtlSpecExcelRequest", description = "엑셀 업로드")
public class DtlSpecExcelRequest implements Serializable {
@Schema(name = "data", description = "엑셀 파일 base64")
String data;
}

View File

@@ -0,0 +1,40 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Estimate;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
import java.util.List;
/**
* DTO for {@link Estimate}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "EstimateListSaveRequest", description = "견적 저장")
public class EstimateListSaveRequest implements Serializable {
List<EstimateSaveRequest> estimates;
List<PbAttSaveRequest> pbAtts;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "PbAttSaveRequest", description = "견적서 저장")
public static class PbAttSaveRequest implements Serializable {
@Schema(name = "logiFnm", description = "논리파일명")
String logiFnm;
@Schema(name = "physFnm", description = "물리파일명")
String physFnm;
@Schema(name = "data", description = "base64")
String data;
}
}

View File

@@ -0,0 +1,46 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Estimate;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
import java.util.List;
/**
* DTO for {@link Estimate}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "EstimateListUpdateRequest", description = "견적 수정")
public class EstimateListUpdateRequest implements Serializable {
List<EstimateUpdateRequest> estimates;
List<PbAttUpdateRequest> pbAtts;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "PbAttUpdateRequest", description = "견적서 수정")
public static class PbAttUpdateRequest implements Serializable {
@Schema(name = "prcsNo", description = "가격조사번호")
String prcsNo;
@Schema(name = "bizNo", description = "사업자번호")
String bizNo;
@Schema(name = "fileOrd", description = "파일순서")
Integer fileOrd;
@Schema(name = "logiFnm", description = "논리파일명")
String logiFnm;
@Schema(name = "physFnm", description = "물리파일명")
String physFnm;
@Schema(name = "data", description = "base64")
String data;
}
}

View File

@@ -0,0 +1,35 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Estimate;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
/**
* DTO for {@link Estimate}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "EstimateSaveRequest", description = "견적 저장")
public class EstimateSaveRequest implements Serializable {
@Schema(name = "bizNo", description = "사업자번호")
String bizNo;
@Schema(name = "prcsNo", description = "가격조사번호")
String prcsNo;
@Schema(name = "dtlSpNo", description = "견적번호")
String dtlSpNo;
@Schema(name = "mngNm", description = "담당자명")
String mngNm;
@Schema(name = "unitPrc", description = "단가")
Integer unitPrc;
@Schema(name = "amt", description = "금액")
Integer amt;
@Schema(name = "regDt", description = "등록일시")
String regDt;
}

View File

@@ -0,0 +1,39 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Estimate;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
import java.util.List;
/**
* DTO for {@link Estimate}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "EstimateUpdateRequest", description = "견적 수정")
public class EstimateUpdateRequest implements Serializable {
@Schema(name = "estNo", description = "견적관리번호")
String estNo;
@Schema(name = "bizNo", description = "사업자번호")
String bizNo;
@Schema(name = "prcsNo", description = "가격조사번호")
String prcsNo;
@Schema(name = "dtlSpNo", description = "견적번호")
String dtlSpNo;
@Schema(name = "mngNm", description = "담당자명")
String mngNm;
@Schema(name = "unitPrc", description = "단가")
Integer unitPrc;
@Schema(name = "amt", description = "금액")
Integer amt;
@Schema(name = "regDt", description = "등록일시")
String regDt;
}

View File

@@ -0,0 +1,27 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.GrpCode;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
/**
* DTO for {@link GrpCode}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "GrpCodeDto", description = "그룹코드 요청")
public class GrpCodeSaveRequest implements Serializable {
@Schema(name = "nm", description = "코드명")
String nm;
@Schema(name = "desc", description = "설명")
String desc;
@Schema(name = "useYn", description = "사용여부(수정)")
Boolean useYn;
}

View File

@@ -0,0 +1,29 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.GrpCode;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
/**
* DTO for {@link GrpCode}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "GrpCodeDto", description = "그룹코드 요청")
public class GrpCodeUpdateRequest implements Serializable {
@Schema(name = "id", description = "코드 그룹 아이디(수정)")
Integer id;
@Schema(name = "nm", description = "코드명")
String nm;
@Schema(name = "desc", description = "설명")
String desc;
@Schema(name = "useYn", description = "사용여부(수정)")
Boolean useYn;
}

View File

@@ -0,0 +1,27 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Business;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* DTO for {@link Business}
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "LoginRequest", description = "로그인")
public class LoginRequest implements Serializable {
@Schema(name = "bizNo", description = "사업자번호")
private String bizNo;
@Schema(name = "pwd", description = "비밀번호")
private String pwd;
}

View File

@@ -0,0 +1,109 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Prcs;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
import java.util.List;
/**
* DTO for {@link Prcs}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "PrcsSaveRequest", description = "가격조사 저장")
public class PrcsSaveRequest implements Serializable {
@Schema(name = "cateCd", description = "분야")
String cateCd;
@Schema(name = "title", description = "제목")
String title;
@Schema(name = "content", description = "내용")
String content;
@Schema(name = "regSdat", description = "등록시작일")
String regSdat;
@Schema(name = "regEdat", description = "등록종료일")
String regEdat;
@Schema(name = "prvYn", description = "비공개여부")
Boolean prvYn;
@Schema(name = "prvRsn", description = "비공개사유")
String prvRsn;
@Schema(name = "prvPwd", description = "비공개비밀번호")
String prvPwd;
@Schema(name = "aiYn", description = "ai검증여부")
Boolean aiYn;
List<PrcsAttSaveRequest> prcsAtts;
List<DtlSpecSaveRequest> dtlSpecs;
List<ApprReqSaveRequest> apprReqs;
List<PrcsBizSaveRequest> prcsBizs;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "PrcsAttSaveRequest", description = "가격조사 첨부파일")
public static class PrcsAttSaveRequest implements Serializable {
String logiFnm;
@Schema(name = "data", description = "base64")
String data;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "DtlSpecSaveRequest", description = "상세규격")
public static class DtlSpecSaveRequest implements Serializable {
@Schema(name = "itemNm", description = "품명")
String itemNm;
@Schema(name = "spec", description = "규격")
String spec;
@Schema(name = "unit", description = "단위")
String unit;
@Schema(name = "qty", description = "수량")
Integer qty;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "ApprReqSaveRequest", description = "결재요청")
public static class ApprReqSaveRequest implements Serializable {
@Schema(name = "gubunCd", description = "구분코드")
String gubunCd;
@Schema(name = "sabun", description = "사번")
String sabun;
@Schema(name = "name", description = "이름")
String name;
@Schema(name = "attendCd", description = "근태코드")
String attendCd;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "PrcsBizSaveRequest", description = "입찰사업자")
public static class PrcsBizSaveRequest implements Serializable {
@Schema(name = "bizNo", description = "사업자번호")
String bizNo;
@Schema(name = "email", description = "이름")
String email;
}
}

View File

@@ -0,0 +1,125 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Prcs;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
import java.util.List;
/**
* DTO for {@link Prcs}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "PrcsUpdateRequest", description = "가격조사 수정")
public class PrcsUpdateRequest implements Serializable {
@Schema(name = "prcsNo", description = "가격조사 번호")
String prcsNo;
@Schema(name = "cateCd", description = "분야")
String cateCd;
@Schema(name = "title", description = "제목")
String title;
@Schema(name = "content", description = "내용")
String content;
@Schema(name = "regSdat", description = "등록시작일")
String regSdat;
@Schema(name = "regEdat", description = "등록종료일")
String regEdat;
@Schema(name = "prvYn", description = "비공개여부")
Boolean prvYn;
@Schema(name = "prvRsn", description = "비공개사유")
String prvRsn;
@Schema(name = "prvPwd", description = "비공개비밀번호")
String prvPwd;
@Schema(name = "aiYn", description = "ai검증여부")
Boolean aiYn;
List<PrcsAttUpdateRequest> prcsAtts;
List<DtlSpecUpdateRequest> dtlSpecs;
List<ApprReqUpdateRequest> apprReqs;
List<PrcsBizUpdateRequest> prcsBizs;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "PrcsAttRequest", description = "가격조사 첨부파일")
public static class PrcsAttUpdateRequest implements Serializable {
@Schema(name = "prcsNo", description = "가격조사 번호")
String prcsNo;
@Schema(name = "fileOrd", description = "파일순서")
Integer fileOrd;
@Schema(name = "logiFnm", description = "논리파일명")
String logiFnm;
@Schema(name = "data", description = "base64")
String data;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "DtlSpecUpdateRequest", description = "상세규격")
public static class DtlSpecUpdateRequest implements Serializable {
@Schema(name = "prcsNo", description = "가격조사 번호")
String prcsNo;
@Schema(name = "dtlSpNo", description = "상세규격 번호")
String dtlSpNo;
@Schema(name = "itemNm", description = "품명")
String itemNm;
@Schema(name = "spec", description = "규격")
String spec;
@Schema(name = "unit", description = "단위")
String unit;
@Schema(name = "qty", description = "수량")
Integer qty;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "ApprReqUpdateRequest", description = "결재요청")
public static class ApprReqUpdateRequest implements Serializable {
@Schema(name = "apprNO", description = "결재번호")
String apprNo;
@Schema(name = "apprOrd", description = "결재순번")
Integer apprOrd;
@Schema(name = "gubunCd", description = "구분코드")
String gubunCd;
@Schema(name = "sabun", description = "사번")
String sabun;
@Schema(name = "name", description = "이름")
String name;
@Schema(name = "attendCd", description = "근태코드")
String attendCd;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "PrcsBizUpdateRequest", description = "입찰사업자")
public static class PrcsBizUpdateRequest implements Serializable {
@Schema(name = "bizNo", description = "사업자번호")
String bizNo;
@Schema(name = "email", description = "이름")
String email;
}
}

View File

@@ -0,0 +1,35 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Business;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* DTO for {@link Business}
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "RegisterRequest", description = "회원가입")
public class RegisterRequest implements Serializable {
@Schema(name = "bizNo", description = "사업자번호")
private String bizNo;
@Schema(name = "pwd", description = "비밀번호")
private String pwd;
@Schema(name = "rePwd", description = "비밀번호")
private String rePwd;
@Schema(name = "compNm", description = "업체명")
private String compNm;
@Schema(name = "repNm", description = "대표자명")
String repNm;
@Schema(name = "email", description = "이메일")
String email;
}

View File

@@ -0,0 +1,21 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "RoleDto", description = "권한부여 요청")
public class RoleRequest {
@Schema(name = "sabun", description = "사번")
private String sabun;
@Schema(name = "roleId", description = "권한명")
private String roleId;
@Schema(name = "ip", description = "아이피")
private String ip;
}

View File

@@ -0,0 +1,61 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
import java.util.List;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "SlipSaveRequest", description = "임시전표 생성")
public class SlipSaveRequest implements Serializable {
@Schema(name = "contNo", description = "계약번호")
String contNo;
@Schema(name = "lifnr", description = "계약대상자")
String lifnr;
@Schema(name = "gsber", description = "사업영역코드")
String gsber;
@Schema(name = "wrbtrS", description = "전기금액(공급가액)")
String wrbtrS;
@Schema(name = "mwskz", description = "세금코드")
String mwskz;
@Schema(name = "waers", description = "통화코드")
String waers;
@Schema(name = "bldat", description = "증빙일")
String bldat;
@Schema(name = "budat", description = "전기일")
String budat;
@Schema(name = "hkont", description = "계정과목코드")
String hkont;
@Schema(name = "kostl", description = "코스트센터코드")
String kostl;
@Schema(name = "projk", description = "wbs요소코드")
String projk;
@Schema(name = "wrbtr", description = "전기금액(공급가액+세액")
String wrbtr;
@Schema(name = "bankl", description = "은행코드")
String bankl;
@Schema(name = "bankn", description = "계좌번호")
String bankn;
List<SlipAttSaveRequest> slipAtts;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "SlipAttSaveRequest", description = "가격조사 첨부파일")
public static class SlipAttSaveRequest implements Serializable {
String logiFnm;
@Schema(name = "data", description = "base64")
String data;
}
}

View File

@@ -0,0 +1,30 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Zwf0011t;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
import java.util.List;
/**
* DTO for {@link Zwf0011t}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "Zwf0011tSaveRequest", description = "SAP 결재 마스터")
public class Zwf0011tSaveRequest implements Serializable {
@Schema(name = "belnr", description = "전표번호")
String belnr;
@Schema(name = "wkfid", description = "요청번호 (협조용)")
String wkfid;
@Schema(name = "wkftx", description = "결재제목")
String wkftx;
List<ZwfApprGrpSaveRequest> apprs;
}

View File

@@ -0,0 +1,27 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Zwf0011t;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
import java.util.List;
/**
* DTO for {@link Zwf0011t}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "ZwfApprRequest", description = "SAP 결재 마스터")
public class ZwfApprGrpSaveRequest implements Serializable {
@Schema(name = "label", description = "명칭")
String label;
@Schema(name = "value", description = "결재선")
List<ZwfApprSaveRequest> value;
}

View File

@@ -0,0 +1,32 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Zwf0012t;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
/**
* DTO for {@link Zwf0012t}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "ZwfApprSaveRequest", description = "SAP 결재선")
public class ZwfApprSaveRequest implements Serializable {
@Schema(name = "lineclsf", description = "결재구분")
String lineclsf;
@Schema(name = "bname", description = "사번")
String bname;
@Schema(name = "gubun", description = "결재선 구분")
String gubun;
@Schema(name = "abscd", description = "사유코드(근태)")
String abscd;
@Schema(name = "grpid", description = "그룹번호")
Integer grpid;
}

View File

@@ -0,0 +1,32 @@
package com.kospo.svcm.dto.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Zwf0012t;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
/**
* DTO for {@link Zwf0012t}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "ZwfApprUpdateRequest", description = "SAP 결재 승인")
public class ZwfApprUpdateRequest implements Serializable {
@Schema(name = "wkfid", description = "요청번호")
String wkfid;
@Schema(name = "wkfsq", description = "결재순번")
Integer wkfsq;
@Schema(name = "bname", description = "사번")
String bname;
@Schema(name = "wkfst", description = "결재상태")
String wkfst;
@Schema(name = "reason", description = "(반려)사유")
String reason;
}

View File

@@ -0,0 +1,51 @@
package com.kospo.svcm.dto.res;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.ApprMst;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;
/**
* DTO for {@link ApprMst}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "ApprMstResponse", description = "결재 마스터")
public class ApprMstResponse implements Serializable {
@Schema(name = "apprNo", description = "결재번호")
String apprNo;
@Schema(name = "apprStatCd", description = "결재상태코드")
String apprStatCd;
@Schema(name = "apprStat", description = "결재상태")
String apprStat;
@Schema(name = "reason", description = "반려사유")
String reason;
@Schema(name = "compDt", description = "승인완료 일시")
String compDt;
@Schema(name = "regDt", description = "등록일시")
String regDt;
@Schema(name = "regSabun", description = "등록자")
String regSabun;
List<ApprReqResponse> apprReqs;
public static ApprMstResponse from(ApprMst apprMst) {
return ApprMstResponse.builder()
.apprNo(apprMst.getApprNo())
.apprStat(apprMst.getApprStat())
.apprStatCd(apprMst.getApprStatCd())
.compDt(apprMst.getCompDt())
.regDt(apprMst.getRegDt())
.regSabun(apprMst.getRegSabun())
.apprReqs(apprMst.getApprReqs().stream().map(ApprReqResponse::from).collect(Collectors.toList()))
.build();
}
}

View File

@@ -0,0 +1,67 @@
package com.kospo.svcm.dto.res;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.ApprReq;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
/**
* DTO for {@link ApprReq}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "ApprReqResponse", description = "결재요청")
public class ApprReqResponse implements Serializable {
@Schema(name = "apprNo", description = "결재번호")
String apprNo;
@Schema(name = "apprOrd", description = "결재순서")
Integer apprOrd;
@Schema(name = "sabun", description = "사번")
String sabun;
@Schema(name = "name", description = "이름")
String name;
@Schema(name = "apprStatCd", description = "결재상태코드")
String apprStatCd;
@Schema(name = "apprStat", description = "결재상태")
String apprStat;
@Schema(name = "apprDt", description = "결재시행일시")
String apprDt;
@Schema(name = "attendCd", description = "근태상태코드")
String attendCd;
@Schema(name = "attendNm", description = "근태상태")
String attendNm;
@Schema(name = "attendStaYmd", description = "근태시작일")
String attendStaYmd;
@Schema(name = "attendEndYmd", description = "근태종료일")
String attendEndYmd;
@Schema(name = "gubunCd", description = "구분코드")
String gubunCd;
@Schema(name = "gubunNm", description = "구분")
String gubunNm;
@Schema(name = "deptCd", description = "부서코드")
String deptCd;
@Schema(name = "gubunNm", description = "부서명")
String deptNm;
public static ApprReqResponse from(ApprReq apprReq) {
return ApprReqResponse.builder()
.apprNo(apprReq.getId().getApprNo())
.apprOrd(apprReq.getId().getApprOrd())
.sabun(apprReq.getSabun())
.name(apprReq.getName())
.apprStatCd(apprReq.getApprStatCd())
.apprStat(apprReq.getApprStat())
.apprDt(apprReq.getApprDt())
.gubunCd(apprReq.getGubunCd())
.gubunNm(apprReq.getGubunNm())
.deptCd(apprReq.getDeptCd())
.deptNm(apprReq.getDeptNm())
.build();
}
}

Some files were not shown because too many files have changed in this diff Show More