Initial commit
This commit is contained in:
15
backend/reserve-item-service/Dockerfile
Normal file
15
backend/reserve-item-service/Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
||||
# openjdk8 base image
|
||||
FROM openjdk:8-jre-alpine
|
||||
|
||||
# config server uri: dockder run --e 로 변경 가능
|
||||
ENV SPRING_CLOUD_CONFIG_URI https://egov-config.paas-ta.org
|
||||
# jar 파일이 복사되는 위치
|
||||
ENV APP_HOME=/usr/app/
|
||||
# 작업 시작 위치
|
||||
WORKDIR $APP_HOME
|
||||
# jar 파일 복사
|
||||
COPY build/libs/*.jar app.jar
|
||||
# application port
|
||||
#EXPOSE 8000
|
||||
# 실행 (application-cf.yml 프로필이 기본값)
|
||||
CMD ["java", "-Dspring.profiles.active=${profile:cf}", "-jar", "app.jar"]
|
||||
84
backend/reserve-item-service/build.gradle
Normal file
84
backend/reserve-item-service/build.gradle
Normal file
@@ -0,0 +1,84 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '2.4.5'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'org.egovframe.cloud'
|
||||
version = '0.1'
|
||||
sourceCompatibility = '1.8'
|
||||
|
||||
configurations {
|
||||
compileOnly {
|
||||
extendsFrom annotationProcessor
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "https://maven.egovframe.go.kr/maven/" } // egovframe maven 원격 저장소
|
||||
}
|
||||
|
||||
ext {
|
||||
set('springCloudVersion', "2020.0.3")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// implementation files('../../module-common/build/libs/module-common-0.1.jar') // @ComponentScan(basePackages={"org.egovframe.cloud"}) 추가해야 적용된다
|
||||
implementation 'org.egovframe.cloud:module-common:0.1'
|
||||
implementation('org.egovframe.rte:org.egovframe.rte.fdl.cmmn:4.0.0') {
|
||||
exclude group: 'org.egovframe.rte', module: 'org.egovframe.rte.fdl.logging'
|
||||
}
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-webflux'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-validation'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-actuator'
|
||||
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
|
||||
implementation 'org.springframework.cloud:spring-cloud-starter-config' // config
|
||||
implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap' // config
|
||||
implementation 'org.springframework.cloud:spring-cloud-starter-bus-amqp' // bus
|
||||
implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j'
|
||||
implementation 'com.playtika.reactivefeign:feign-reactor-spring-cloud-starter:3.1.0'
|
||||
|
||||
implementation 'io.jsonwebtoken:jjwt:0.9.1'
|
||||
|
||||
implementation 'dev.miku:r2dbc-mysql:0.8.2.RELEASE'
|
||||
implementation 'mysql:mysql-connector-java'
|
||||
|
||||
// swagger api docs
|
||||
implementation 'org.springdoc:springdoc-openapi-webflux-ui:1.5.10'
|
||||
|
||||
// bolcking 호출 감지
|
||||
implementation 'io.projectreactor:reactor-tools:3.4.9'
|
||||
implementation 'io.projectreactor.tools:blockhound:1.0.6.RELEASE'
|
||||
|
||||
//messaging
|
||||
implementation 'org.springframework.cloud:spring-cloud-stream'
|
||||
implementation 'org.springframework.cloud:spring-cloud-stream-binder-rabbit'
|
||||
implementation 'net.java.dev.jna:jna:5.9.0' // byte-buddy (No compatible attachment provider is available.)
|
||||
|
||||
//lombok
|
||||
implementation 'org.projectlombok:lombok'
|
||||
annotationProcessor 'org.projectlombok:lombok'
|
||||
testImplementation 'org.projectlombok:lombok'
|
||||
testAnnotationProcessor 'org.projectlombok:lombok'
|
||||
|
||||
testImplementation 'com.h2database:h2'
|
||||
testImplementation 'io.r2dbc:r2dbc-h2'
|
||||
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
testImplementation 'io.projectreactor:reactor-test'
|
||||
testImplementation 'org.springframework.security:spring-security-test'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
|
||||
}
|
||||
}
|
||||
|
||||
185
backend/reserve-item-service/gradlew
vendored
Executable file
185
backend/reserve-item-service/gradlew
vendored
Executable file
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or 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 UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# 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"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 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
|
||||
;;
|
||||
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"
|
||||
which java >/dev/null 2>&1 || 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
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
89
backend/reserve-item-service/gradlew.bat
vendored
Normal file
89
backend/reserve-item-service/gradlew.bat
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
@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=.
|
||||
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%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
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%"=="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!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
16
backend/reserve-item-service/manifest.yml
Normal file
16
backend/reserve-item-service/manifest.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
applications:
|
||||
- name: egov-reserve-item-service # CF push 시 생성되는 이름
|
||||
# memory: 512M # 메모리
|
||||
instances: 1 # 인스턴스 수
|
||||
host: egov-reserve-item-service # host 명으로 유일해야 함
|
||||
path: build/libs/reserve-item-service-0.1.jar # build 후 생성된 jar 위치
|
||||
buildpack: java_buildpack # cf buildpacks 명령어로 java buildpack 이름 확인
|
||||
services:
|
||||
- egov-discovery-provided-service # discovery service binding
|
||||
env:
|
||||
spring_profiles_active: cf
|
||||
spring_cloud_config_uri: https://egov-config.paas-ta.org
|
||||
app_name: egov-reserve-item-service # logstash custom app name
|
||||
TZ: Asia/Seoul
|
||||
JAVA_OPTS: -Xss349k
|
||||
1
backend/reserve-item-service/settings.gradle
Normal file
1
backend/reserve-item-service/settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = 'reserve-item-service'
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.egovframe.cloud.reserveitemservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
import reactivefeign.spring.config.EnableReactiveFeignClients;
|
||||
import reactor.blockhound.BlockHound;
|
||||
|
||||
import java.security.Security;
|
||||
|
||||
@ComponentScan({"org.egovframe.cloud.common", "org.egovframe.cloud.reactive", "org.egovframe.cloud.reserveitemservice"}) // org.egovframe.cloud.common package 포함하기 위해
|
||||
@EnableDiscoveryClient
|
||||
@EnableReactiveFeignClients
|
||||
@SpringBootApplication
|
||||
public class ReserveItemServiceApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// TLSv1/v1.1 No longer works after upgrade, "No appropriate protocol" error
|
||||
String property = Security.getProperty("jdk.tls.disabledAlgorithms").replace(", TLSv1", "").replace(", TLSv1.1", "");
|
||||
Security.setProperty("jdk.tls.disabledAlgorithms", property);
|
||||
|
||||
//blocking 코드 감지
|
||||
BlockHound.builder()
|
||||
/**
|
||||
* mysql r2dbc 에서 호출되는 FileInputStream.readBytes() 가 블로킹코드인데 이를 허용해주도록 한다.
|
||||
* 해당 코드가 어디서 호출되는지 알지 못하는 상태에서 FileInputStream.readBytes() 자체를 허용해주는 것은 좋지 않다.
|
||||
* 누군가 무분별하게 사용하게 되면 검출해 낼 수 없어 시스템의 위험요소로 남게 된다.
|
||||
* r2dbc를 사용하기 위해 FileInputStream.readBytes()를 호출하는 부분만 허용하고 나머지는 여전히 검출대상으로 남기도록 한다.
|
||||
*/
|
||||
.allowBlockingCallsInside("dev.miku.r2dbc.mysql.client.ReactorNettyClient", "init")
|
||||
.install();
|
||||
|
||||
SpringApplication.run(ReserveItemServiceApplication.class, args);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.location;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.egovframe.cloud.common.dto.RequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.location.dto.LocationResponseDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.location.dto.LocationSaveRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.location.dto.LocationUpdateRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.service.location.LocationService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.api.location.LocationApiController
|
||||
* <p>
|
||||
* 예약 지역 api contoller class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/06
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/06 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
public class LocationApiController {
|
||||
|
||||
private final LocationService locationService;
|
||||
|
||||
/**
|
||||
* 목록 조회
|
||||
*
|
||||
* @param requestDto
|
||||
* @param page
|
||||
* @param size
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api/v1/locations")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
@Operation(summary = "page of location")
|
||||
public Mono<Page<LocationResponseDto>> search(RequestDto requestDto,
|
||||
@RequestParam(name = "page") int page,
|
||||
@RequestParam(name = "size") int size) {
|
||||
return locationService.search(requestDto, PageRequest.of(page, size));
|
||||
}
|
||||
|
||||
/**
|
||||
* 한건 조회
|
||||
*
|
||||
* @param locationId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api/v1/locations/{locationId}")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public Mono<LocationResponseDto> findById(@PathVariable Long locationId) {
|
||||
return locationService.findById(locationId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 지역 목록 조회 (사용여부 = true)
|
||||
* 예약 목록 등록 시
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api/v1/locations/combo")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public Flux<LocationResponseDto> findAll() {
|
||||
return locationService.findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* 지역 한건 저장
|
||||
*
|
||||
* @param saveRequestDto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/v1/locations")
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
public Mono<LocationResponseDto> save(@Valid @RequestBody LocationSaveRequestDto saveRequestDto) {
|
||||
return locationService.save(saveRequestDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 지역 한건 수정
|
||||
*
|
||||
* @param locationId
|
||||
* @param updateRequestDto
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/api/v1/locations/{locationId}")
|
||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||
public Mono<Void> update(@PathVariable Long locationId, @Valid @RequestBody LocationUpdateRequestDto updateRequestDto) {
|
||||
return locationService.update(locationId, updateRequestDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 지역 한건 삭제
|
||||
*
|
||||
* @param locationId
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping("/api/v1/locations/{locationId}")
|
||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||
public Mono<Void> delete(@PathVariable Long locationId) {
|
||||
return locationService.delete(locationId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 지역 사용여부 toggle
|
||||
*
|
||||
* @param locationId
|
||||
* @param isUse
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/api/v1/locations/{locationId}/{isUse}")
|
||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||
public Mono<Void> updateIsUse(@PathVariable Long locationId, @PathVariable Boolean isUse) {
|
||||
return locationService.updateIsUse(locationId, isUse);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.location.dto;
|
||||
|
||||
import lombok.*;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.api.location.dto.LocationResponseDto
|
||||
* <p>
|
||||
* 예약 지역 응답 dto class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/06
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/06 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
public class LocationResponseDto {
|
||||
private Long locationId;
|
||||
private String locationName;
|
||||
private Integer sortSeq;
|
||||
private Boolean isUse;
|
||||
private LocalDateTime createDate;
|
||||
|
||||
@Builder
|
||||
public LocationResponseDto(Location entity) {
|
||||
this.locationId = entity.getLocationId();
|
||||
this.locationName = entity.getLocationName();
|
||||
this.sortSeq = entity.getSortSeq();
|
||||
this.isUse = entity.getIsUse();
|
||||
this.createDate = entity.getCreateDate();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.location.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.api.location.dto.LocationSaveRequestDto
|
||||
* <p>
|
||||
* 예약 지역 저장 요청 dto class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/06
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/06 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
public class LocationSaveRequestDto {
|
||||
@NotNull
|
||||
private String locationName;
|
||||
private Integer sortSeq;
|
||||
private Boolean isUse;
|
||||
|
||||
@Builder
|
||||
public LocationSaveRequestDto(String locationName, Integer sortSeq, Boolean isUse) {
|
||||
this.locationName = locationName;
|
||||
this.sortSeq = sortSeq;
|
||||
this.isUse = isUse;
|
||||
}
|
||||
|
||||
/**
|
||||
* dto -> entity
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Location toEntity() {
|
||||
return Location.builder()
|
||||
.locationName(this.locationName)
|
||||
.sortSeq(this.sortSeq)
|
||||
.isUse(this.isUse)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.location.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.api.location.dto.LocationUpdateRequestDto
|
||||
* <p>
|
||||
* 예약 지역 수정 요청 dto class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/08
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/08 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
public class LocationUpdateRequestDto {
|
||||
@NotNull
|
||||
private String locationName;
|
||||
private Integer sortSeq;
|
||||
private Boolean isUse;
|
||||
|
||||
@Builder
|
||||
public LocationUpdateRequestDto(String locationName, Integer sortSeq, Boolean isUse) {
|
||||
this.locationName = locationName;
|
||||
this.sortSeq = sortSeq;
|
||||
this.isUse = isUse;
|
||||
}
|
||||
|
||||
/**
|
||||
* dto -> entity
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Location toEntity() {
|
||||
return Location.builder()
|
||||
.locationName(this.locationName)
|
||||
.sortSeq(this.sortSeq)
|
||||
.isUse(this.isUse)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.reserveItem;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemListResponseDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemMainResponseDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemRelationResponseDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemResponseDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemSaveRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemUpdateRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.service.reserveItem.ReserveItemService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.api.reserveItem.ReserveItemApiController
|
||||
* <p>
|
||||
* 예약 물품 api controller class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/13
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/13 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
public class ReserveItemApiController {
|
||||
|
||||
private final ReserveItemService reserveItemService;
|
||||
|
||||
/**
|
||||
* 목록 조회
|
||||
*
|
||||
* @param requestDto
|
||||
* @param page
|
||||
* @param size
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api/v1/reserve-items")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public Mono<Page<ReserveItemListResponseDto>> search(ReserveItemRequestDto requestDto,
|
||||
@RequestParam(name = "page") int page,
|
||||
@RequestParam(name = "size") int size) {
|
||||
return reserveItemService.search(requestDto, PageRequest.of(page, size));
|
||||
}
|
||||
|
||||
/**
|
||||
* 목록 조회 - 사용자 조회 시
|
||||
*
|
||||
* @param requestDto
|
||||
* @param page
|
||||
* @param size
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api/v1/{categoryId}/reserve-items")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public Mono<Page<ReserveItemListResponseDto>> searchForUser(@PathVariable String categoryId,
|
||||
ReserveItemRequestDto requestDto,
|
||||
@RequestParam(name = "page") int page,
|
||||
@RequestParam(name = "size") int size) {
|
||||
return reserveItemService.searchForUser(categoryId, requestDto, PageRequest.of(page, size));
|
||||
}
|
||||
|
||||
/**
|
||||
* 한건 조회
|
||||
*
|
||||
* @param reserveItemId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api/v1/reserve-items/{reserveItemId}")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public Mono<ReserveItemResponseDto> findById(@PathVariable Long reserveItemId) {
|
||||
System.out.println("findById : " + reserveItemId);
|
||||
return reserveItemService.findById(reserveItemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 한건 등록
|
||||
*
|
||||
* @param saveRequestDto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/v1/reserve-items")
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
public Mono<ReserveItemResponseDto> save(@Valid @RequestBody ReserveItemSaveRequestDto saveRequestDto) {
|
||||
return reserveItemService.save(saveRequestDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 한건 수정
|
||||
*
|
||||
* @param reserveItemId
|
||||
* @param updateRequestDto
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/api/v1/reserve-items/{reserveItemId}")
|
||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||
public Mono<Void> update(@PathVariable Long reserveItemId, @Valid @RequestBody ReserveItemUpdateRequestDto updateRequestDto) {
|
||||
return reserveItemService.update(reserveItemId, updateRequestDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 사용여부 업데이트
|
||||
*
|
||||
* @param reserveItemId
|
||||
* @param isUse
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/api/v1/reserve-items/{reserveItemId}/{isUse}")
|
||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||
public Mono<Void> updateIsUse(@PathVariable Long reserveItemId, @PathVariable Boolean isUse) {
|
||||
return reserveItemService.updateIsUse(reserveItemId, isUse);
|
||||
}
|
||||
|
||||
/**
|
||||
* 한건 조회 시 연관관계(지역, 공통코드) 데이터까지 모두 조회
|
||||
*
|
||||
* @param reserveItemId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api/v1/reserve-items/relations/{reserveItemId}")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public Mono<ReserveItemRelationResponseDto> findByIdWithRelations(@PathVariable Long reserveItemId) {
|
||||
return reserveItemService.findByIdWithRelations(reserveItemId).log();
|
||||
}
|
||||
|
||||
/**
|
||||
* 관리자가 예약 신청 시 이벤트 스트림 없이 바로 재고 변경
|
||||
*
|
||||
* @param reserveItemId
|
||||
* @param reserveQty
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/api/v1/reserve-items/{reserveItemId}/inventories")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public Mono<Boolean> updateInventory(@PathVariable Long reserveItemId, @RequestBody Integer reserveQty) {
|
||||
System.out.println("update inventories : " + reserveItemId+" : " + reserveQty);
|
||||
return reserveItemService.updateInventory(reserveItemId, reserveQty);
|
||||
}
|
||||
|
||||
/**
|
||||
* 각 카테고리별 최신 예약 물품 조회
|
||||
* 파라미터로 받는 갯수만큼 조회한다.
|
||||
*
|
||||
* @param count 조회할 갯수 0:전체
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api/v1/reserve-items/latest/{count}")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public Mono<Map<String, Collection<ReserveItemMainResponseDto>>> findLatest(@PathVariable Integer count) {
|
||||
return reserveItemService.findLatest(count);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
|
||||
import org.springframework.util.NumberUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemListResponseDto
|
||||
* <p>
|
||||
* 예약 물품 목록 응답 dto class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/13
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/13 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
public class ReserveItemListResponseDto {
|
||||
private Long reserveItemId; // 예약 물품 id
|
||||
private String reserveItemName; //예약 물품 명
|
||||
private Long locationId; //지역 id
|
||||
private String locationName;
|
||||
private String categoryId; //예약유형 - 공통코드 reserve-category
|
||||
private String categoryName;
|
||||
private Integer totalQty; //총 재고/수용인원 수
|
||||
private Integer inventoryQty; //총 재고/수용인원 수
|
||||
private Boolean isUse; //사용여부
|
||||
private LocalDateTime createDate; //등록일
|
||||
private Boolean isPossible; //예약 가능 여부
|
||||
|
||||
@Builder
|
||||
public ReserveItemListResponseDto(ReserveItem reserveItem) {
|
||||
this.reserveItemId = reserveItem.getReserveItemId();
|
||||
this.reserveItemName = reserveItem.getReserveItemName();
|
||||
this.locationId = reserveItem.getLocationId();
|
||||
this.locationName = reserveItem.getLocation().getLocationName();
|
||||
this.categoryId = reserveItem.getCategoryId();
|
||||
this.categoryName = reserveItem.getCategoryName();
|
||||
this.totalQty = reserveItem.getTotalQty();
|
||||
this.inventoryQty = reserveItem.getInventoryQty();
|
||||
this.isUse = reserveItem.getIsUse();
|
||||
this.createDate = reserveItem.getCreateDate();
|
||||
this.isPossible = isReservationPossible(reserveItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 가능 여부 체크
|
||||
*
|
||||
* @param reserveItem
|
||||
* @return
|
||||
*/
|
||||
private boolean isReservationPossible(ReserveItem reserveItem) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if (!reserveItem.getIsUse()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reserveItem.getInventoryQty() <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reserveItem.getIsPeriod()) {
|
||||
if (reserveItem.getRequestStartDate().isBefore(now) && reserveItem.getRequestEndDate().isAfter(now)) {
|
||||
return true;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (reserveItem.getOperationStartDate().isBefore(now) && reserveItem.getOperationEndDate().isAfter(now)) {
|
||||
return true;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
public class ReserveItemMainResponseDto {
|
||||
|
||||
private Long reserveItemId; // 예약 물품 id
|
||||
private String reserveItemName; //예약 물품 명
|
||||
private String categoryId; //예약유형 - 공통코드 reserve-category
|
||||
private String categoryName;
|
||||
private LocalDateTime startDate; //운영 시작 일 or 예약 신청 시작일
|
||||
private LocalDateTime endDate; //운영 종료 일 or 예약 신청 종료일
|
||||
private Boolean isPossible;
|
||||
|
||||
@Builder
|
||||
public ReserveItemMainResponseDto (ReserveItem entity) {
|
||||
this.reserveItemId = entity.getReserveItemId();
|
||||
this.reserveItemName = entity.getReserveItemName();
|
||||
this.categoryId = entity.getCategoryId();
|
||||
this.categoryName = entity.getCategoryName();
|
||||
this.startDate = entity.getOperationStartDate();
|
||||
this.endDate = entity.getOperationEndDate();
|
||||
if (entity.getReserveMethodId().equals("internet")) {
|
||||
if (entity.getReserveMeansId().equals("realtime")) {
|
||||
this.startDate = entity.getRequestStartDate();
|
||||
this.endDate = entity.getRequestEndDate();
|
||||
}
|
||||
}
|
||||
this.isPossible = isReservationPossible(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 가능 여부 체크
|
||||
*
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
private boolean isReservationPossible(ReserveItem entity) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if (!entity.getIsUse()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entity.getInventoryQty() <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entity.getIsPeriod()) {
|
||||
if (entity.getRequestStartDate().isBefore(now) && entity.getRequestEndDate().isAfter(now)) {
|
||||
return true;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (entity.getOperationStartDate().isBefore(now) && entity.getOperationEndDate().isAfter(now)) {
|
||||
return true;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemRelationResponseDto
|
||||
* <p>
|
||||
* 예약 물품 relation 응답 dto class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/27
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/27 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@ToString
|
||||
public class ReserveItemRelationResponseDto {
|
||||
private Long reserveItemId; // 예약 물품 id
|
||||
private String reserveItemName; //예약 물품 명
|
||||
private Long locationId;
|
||||
private Location location;
|
||||
private String categoryId; //예약유형 - 공통코드 reserve-category
|
||||
private String categoryName;
|
||||
private Integer totalQty; //총 재고/수용인원 수
|
||||
private Integer inventoryQty; // 재고/수용인원 수
|
||||
private LocalDateTime operationStartDate; //운영 시작 일
|
||||
private LocalDateTime operationEndDate; //운영 종료 일
|
||||
private String reserveMethodId; // 예약 방법 - 공통코드 reserve-method
|
||||
private String reserveMethodName;
|
||||
private String reserveMeansId; // 예약 구분 (인터넷 예약 시) - 공통코드 reserve-means
|
||||
private String reserveMeansName;
|
||||
private LocalDateTime requestStartDate; //예약 신청 시작 일시
|
||||
private LocalDateTime requestEndDate; //예약 신청 종료 일시
|
||||
private Boolean isPeriod; //기간 지정 가능 여부 - true: 지정 가능, false: 지정 불가
|
||||
private Integer periodMaxCount; // 최대 예약 가능 일 수
|
||||
private String externalUrl; //외부링크
|
||||
private String selectionMeansId; //선별 방법 - 공통코드 reserve-selection
|
||||
private String selectionMeansName;
|
||||
private Boolean isPaid; // 유/무료 - false: 무료, true: 유료
|
||||
private BigDecimal usageCost; //이용 요금
|
||||
private Boolean isUse; //사용여부
|
||||
private String purpose; //용도
|
||||
private String address; //주소
|
||||
private String targetId; //이용 대상 - 공통코드 reserve-target
|
||||
private String targetName;
|
||||
private String excluded; // 사용허가 제외대상
|
||||
private String homepage; //홈페이지 주소
|
||||
private String contact; //문의처
|
||||
private String managerDept; //담당자 소속
|
||||
private String managerName; //담당자 이름
|
||||
private String managerContact; //담당자 연락처
|
||||
|
||||
@Builder
|
||||
public ReserveItemRelationResponseDto(ReserveItem entity) {
|
||||
this.reserveItemId = entity.getReserveItemId();
|
||||
this.reserveItemName = entity.getReserveItemName();
|
||||
this.locationId = entity.getLocationId();
|
||||
this.location = entity.getLocation();
|
||||
this.categoryId = entity.getCategoryId();
|
||||
this.categoryName = entity.getCategoryName();
|
||||
this.totalQty = entity.getTotalQty();
|
||||
this.inventoryQty = entity.getInventoryQty();
|
||||
this.operationStartDate = entity.getOperationStartDate();
|
||||
this.operationEndDate = entity.getOperationEndDate();
|
||||
this.reserveMethodId = entity.getReserveMethodId();
|
||||
this.reserveMethodName = entity.getReserveMethodName();
|
||||
this.reserveMeansId = entity.getReserveMeansId();
|
||||
this.reserveMeansName = entity.getReserveMeansName();
|
||||
this.requestStartDate = entity.getRequestStartDate();
|
||||
this.requestEndDate = entity.getRequestEndDate();
|
||||
this.isPeriod = entity.getIsPeriod();
|
||||
this.periodMaxCount = entity.getPeriodMaxCount();
|
||||
this.externalUrl = entity.getExternalUrl();
|
||||
this.selectionMeansId = entity.getSelectionMeansId();
|
||||
this.selectionMeansName = entity.getSelectionMeansName();
|
||||
this.isPaid = entity.getIsPaid();
|
||||
this.usageCost = entity.getUsageCost();
|
||||
this.isUse = entity.getIsUse();
|
||||
this.purpose = entity.getPurpose();
|
||||
this.address = entity.getAddress();
|
||||
this.targetId = entity.getTargetId();
|
||||
this.targetName = entity.getTargetName();
|
||||
this.excluded = entity.getExcluded();
|
||||
this.homepage = entity.getHomepage();
|
||||
this.contact = entity.getContact();
|
||||
this.managerDept = entity.getManagerDept();
|
||||
this.managerName = entity.getManagerName();
|
||||
this.managerContact = entity.getManagerContact();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
|
||||
|
||||
import lombok.*;
|
||||
import org.egovframe.cloud.common.dto.RequestDto;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemRequestDto
|
||||
* <p>
|
||||
* 예약 목록 조회 요청 dto class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/27
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/27 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
public class ReserveItemRequestDto extends RequestDto {
|
||||
private Long locationId;
|
||||
private String categoryId;
|
||||
private Boolean isUse;
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
|
||||
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemResponseDto
|
||||
* <p>
|
||||
* 예약 물품 응답 dto class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/13
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/13 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
public class ReserveItemResponseDto {
|
||||
private Long reserveItemId; // 예약 물품 id
|
||||
private String reserveItemName; //예약 물품 명
|
||||
private Long locationId;
|
||||
private String categoryId; //예약유형 - 공통코드 reserve-category
|
||||
private Integer prevTotalQty; //총 재고/수용인원 수
|
||||
private Integer totalQty; //총 재고/수용인원 수
|
||||
private Integer inventoryQty; // 재고/수용인원 수
|
||||
private LocalDateTime operationStartDate; //운영 시작 일
|
||||
private LocalDateTime operationEndDate; //운영 종료 일
|
||||
private String reserveMethodId; // 예약 방법 - 공통코드 reserve-method
|
||||
private String reserveMeansId; // 예약 구분 (인터넷 예약 시) - 공통코드 reserve-means
|
||||
private LocalDateTime requestStartDate; //예약 신청 시작 일시
|
||||
private LocalDateTime requestEndDate; //예약 신청 종료 일시
|
||||
private Boolean isPeriod; //기간 지정 가능 여부 - true: 지정 가능, false: 지정 불가
|
||||
private Integer periodMaxCount; // 최대 예약 가능 일 수
|
||||
private String externalUrl; //외부링크
|
||||
private String selectionMeansId; //선별 방법 - 공통코드 reserve-selection
|
||||
private Boolean isPaid; // 유/무료 - false: 무료, true: 유료
|
||||
private BigDecimal usageCost; //이용 요금
|
||||
private Boolean isUse; //사용여부
|
||||
private String purpose; //용도
|
||||
private String address; //주소
|
||||
private String targetId; //이용 대상 - 공통코드 reserve-target
|
||||
private String excluded; // 사용허가 제외대상
|
||||
private String homepage; //홈페이지 주소
|
||||
private String contact; //문의처
|
||||
private String managerDept; //담당자 소속
|
||||
private String managerName; //담당자 이름
|
||||
private String managerContact; //담당자 연락처
|
||||
|
||||
@Builder
|
||||
public ReserveItemResponseDto(ReserveItem reserveItem) {
|
||||
this.reserveItemId = reserveItem.getReserveItemId();
|
||||
this.reserveItemName = reserveItem.getReserveItemName();
|
||||
this.locationId = reserveItem.getLocationId();
|
||||
this.categoryId = reserveItem.getCategoryId();
|
||||
this.prevTotalQty = reserveItem.getTotalQty();
|
||||
this.totalQty = reserveItem.getTotalQty();
|
||||
this.inventoryQty = reserveItem.getInventoryQty();
|
||||
this.operationStartDate = reserveItem.getOperationStartDate();
|
||||
this.operationEndDate = reserveItem.getOperationEndDate();
|
||||
this.reserveMethodId = reserveItem.getReserveMethodId();
|
||||
this.reserveMeansId = reserveItem.getReserveMeansId();
|
||||
this.requestStartDate = reserveItem.getRequestStartDate();
|
||||
this.requestEndDate = reserveItem.getRequestEndDate();
|
||||
this.isPeriod = reserveItem.getIsPeriod();
|
||||
this.periodMaxCount = reserveItem.getPeriodMaxCount();
|
||||
this.externalUrl = reserveItem.getExternalUrl();
|
||||
this.selectionMeansId = reserveItem.getSelectionMeansId();
|
||||
this.isPaid = reserveItem.getIsPaid();
|
||||
this.usageCost = reserveItem.getUsageCost();
|
||||
this.isUse = reserveItem.getIsUse();
|
||||
this.purpose = reserveItem.getPurpose();
|
||||
this.address = reserveItem.getAddress();
|
||||
this.targetId = reserveItem.getTargetId();
|
||||
this.excluded = reserveItem.getExcluded();
|
||||
this.homepage = reserveItem.getHomepage();
|
||||
this.contact = reserveItem.getContact();
|
||||
this.managerDept = reserveItem.getManagerDept();
|
||||
this.managerName = reserveItem.getManagerName();
|
||||
this.managerContact = reserveItem.getManagerContact();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
|
||||
import org.egovframe.cloud.reserveitemservice.validator.annotation.ReserveItemSaveValid;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemSaveRequestDto
|
||||
* <p>
|
||||
* 예약 물품 저장 요청 dto class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/13
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/13 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
@ReserveItemSaveValid
|
||||
public class ReserveItemSaveRequestDto {
|
||||
|
||||
@NotBlank
|
||||
@Size(max = 200)
|
||||
private String reserveItemName; //예약 물품 명
|
||||
@NotNull
|
||||
private Long locationId;
|
||||
@NotBlank
|
||||
private String categoryId; //예약유형 - 공통코드 reserve-category
|
||||
@NotNull
|
||||
@PositiveOrZero
|
||||
private Integer totalQty; //재고/수용인원 수
|
||||
@NotNull
|
||||
@PositiveOrZero
|
||||
private Integer inventoryQty; //재고/수용인원 수
|
||||
|
||||
@NotNull
|
||||
private LocalDateTime operationStartDate; //운영 시작 일
|
||||
@NotNull
|
||||
private LocalDateTime operationEndDate; //운영 종료 일
|
||||
@NotBlank
|
||||
private String reserveMethodId; // 예약 방법 - 공통코드 reserve-method
|
||||
private String reserveMeansId; // 예약 구분 (인터넷 예약 시) - 공통코드 reserve-means
|
||||
private LocalDateTime requestStartDate; //예약 신청 시작 일시
|
||||
private LocalDateTime requestEndDate; //예약 신청 종료 일시
|
||||
private Boolean isPeriod; //기간 지정 가능 여부 - true: 지정 가능, false: 지정 불가
|
||||
private Integer periodMaxCount; // 최대 예약 가능 일 수
|
||||
|
||||
@Size(max = 500)
|
||||
private String externalUrl; //외부링크
|
||||
@NotBlank
|
||||
private String selectionMeansId; //선별 방법 - 공통코드 reserve-selection
|
||||
private Boolean isPaid; // 유/무료 - false: 무료, true: 유료
|
||||
private BigDecimal usageCost; //이용 요금
|
||||
private Boolean isUse; //사용여부
|
||||
|
||||
@Size(max = 4000)
|
||||
private String purpose; //용도
|
||||
|
||||
@Size(max = 500)
|
||||
private String address; //주소
|
||||
private String targetId; //이용 대상 - 공통코드 reserve-target
|
||||
|
||||
@Size(max = 2000)
|
||||
private String excluded; // 사용허가 제외대상
|
||||
|
||||
@Size(max = 500)
|
||||
private String homepage; //홈페이지 주소
|
||||
|
||||
@Size(max = 50)
|
||||
private String contact; //문의처
|
||||
|
||||
@Size(max = 200)
|
||||
private String managerDept; //담당자 소속
|
||||
|
||||
@Size(max = 200)
|
||||
private String managerName; //담당자 이름
|
||||
|
||||
@Size(max = 50)
|
||||
private String managerContact; //담당자 연락처
|
||||
|
||||
public ReserveItem toEntity() {
|
||||
return ReserveItem.builder()
|
||||
.reserveItemName(this.reserveItemName)
|
||||
.locationId(this.locationId)
|
||||
.categoryId(this.categoryId)
|
||||
.totalQty(this.totalQty)
|
||||
.inventoryQty(this.inventoryQty)
|
||||
.operationStartDate(this.operationStartDate)
|
||||
.operationEndDate(this.operationEndDate)
|
||||
.reserveMethodId(this.reserveMethodId)
|
||||
.reserveMeansId(this.reserveMeansId)
|
||||
.requestStartDate(this.requestStartDate)
|
||||
.requestEndDate(this.requestEndDate)
|
||||
.isPeriod(this.isPeriod)
|
||||
.periodMaxCount(this.periodMaxCount)
|
||||
.externalUrl(this.externalUrl)
|
||||
.selectionMeansId(this.selectionMeansId)
|
||||
.isPaid(this.isPaid)
|
||||
.usageCost(this.usageCost)
|
||||
.isUse(this.isUse)
|
||||
.purpose(this.purpose)
|
||||
.address(this.address)
|
||||
.targetId(this.targetId)
|
||||
.excluded(this.excluded)
|
||||
.homepage(this.homepage)
|
||||
.contact(this.contact)
|
||||
.managerDept(this.managerDept)
|
||||
.managerName(this.managerName)
|
||||
.managerContact(this.managerContact)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
|
||||
import org.egovframe.cloud.reserveitemservice.validator.annotation.ReserveItemSaveValid;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemUpdateRequestDto
|
||||
* <p>
|
||||
* 예약 물품 수정 요청 dto class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/13
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/13 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
@ReserveItemSaveValid
|
||||
public class ReserveItemUpdateRequestDto {
|
||||
@NotBlank
|
||||
@Size(max = 200)
|
||||
private String reserveItemName; //예약 물품 명
|
||||
@NotNull
|
||||
private Long locationId;
|
||||
@NotBlank
|
||||
private String categoryId; //예약유형 - 공통코드 reserve-category
|
||||
@NotNull
|
||||
@PositiveOrZero
|
||||
private Integer totalQty; //총 재고/수용인원 수
|
||||
@NotNull
|
||||
@PositiveOrZero
|
||||
private Integer inventoryQty; //재고/수용인원 수
|
||||
@NotNull
|
||||
private LocalDateTime operationStartDate; //운영 시작 일
|
||||
@NotNull
|
||||
private LocalDateTime operationEndDate; //운영 종료 일
|
||||
@NotBlank
|
||||
private String reserveMethodId; // 예약 방법 - 공통코드 reserve-method
|
||||
private String reserveMeansId; // 예약 구분 (인터넷 예약 시) - 공통코드 reserve-means
|
||||
private LocalDateTime requestStartDate; //예약 신청 시작 일시
|
||||
private LocalDateTime requestEndDate; //예약 신청 종료 일시
|
||||
private Boolean isPeriod; //기간 지정 가능 여부 - true: 지정 가능, false: 지정 불가
|
||||
private Integer periodMaxCount; // 최대 예약 가능 일 수
|
||||
@Size(max = 500)
|
||||
private String externalUrl; //외부링크
|
||||
@NotBlank
|
||||
private String selectionMeansId; //선별 방법 - 공통코드 reserve-selection
|
||||
@NotNull
|
||||
private Boolean isPaid; // 유/무료 - false: 무료, true: 유료
|
||||
private BigDecimal usageCost; //이용 요금
|
||||
private Boolean isUse; //사용여부
|
||||
@Size(max = 4000)
|
||||
private String purpose; //용도
|
||||
@Size(max = 500)
|
||||
private String address; //주소
|
||||
private String targetId; //이용 대상 - 공통코드 reserve-target
|
||||
@Size(max = 2000)
|
||||
private String excluded; // 사용허가 제외대상
|
||||
@Size(max = 500)
|
||||
private String homepage; //홈페이지 주소
|
||||
@Size(max = 50)
|
||||
private String contact; //문의처
|
||||
@Size(max = 200)
|
||||
private String managerDept; //담당자 소속
|
||||
@Size(max = 200)
|
||||
private String managerName; //담당자 이름
|
||||
@Size(max = 50)
|
||||
private String managerContact; //담당자 연락처
|
||||
|
||||
public ReserveItem toEntity() {
|
||||
return ReserveItem.builder()
|
||||
.reserveItemName(this.reserveItemName)
|
||||
.locationId(this.locationId)
|
||||
.categoryId(this.categoryId)
|
||||
.totalQty(this.totalQty)
|
||||
.inventoryQty(this.inventoryQty)
|
||||
.operationStartDate(this.operationStartDate)
|
||||
.operationEndDate(this.operationEndDate)
|
||||
.reserveMethodId(this.reserveMethodId)
|
||||
.reserveMeansId(this.reserveMeansId)
|
||||
.requestStartDate(this.requestStartDate)
|
||||
.requestEndDate(this.requestEndDate)
|
||||
.isPeriod(this.isPeriod)
|
||||
.periodMaxCount(this.periodMaxCount)
|
||||
.externalUrl(this.externalUrl)
|
||||
.selectionMeansId(this.selectionMeansId)
|
||||
.isPaid(this.isPaid)
|
||||
.usageCost(this.usageCost)
|
||||
.isUse(this.isUse)
|
||||
.purpose(this.purpose)
|
||||
.address(this.address)
|
||||
.targetId(this.targetId)
|
||||
.excluded(this.excluded)
|
||||
.homepage(this.homepage)
|
||||
.contact(this.contact)
|
||||
.managerDept(this.managerDept)
|
||||
.managerName(this.managerName)
|
||||
.managerContact(this.managerContact)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserverequestservice.api.dto.ReserveSaveRequestDto
|
||||
* <p>
|
||||
* 예약 신청 저장 요청 dto class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/17
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/17 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
public class ReserveSaveRequestDto {
|
||||
|
||||
@Setter
|
||||
private String reserveId;
|
||||
@NotNull
|
||||
private Long reserveItemId;
|
||||
private Integer reserveQty; //예약 신청 인원/수량
|
||||
@NotNull
|
||||
private String reservePurposeContent; //예약 목적
|
||||
private String attachmentCode; //첨부파일 코드
|
||||
private LocalDateTime reserveStartDate; //예약 신청 시작일
|
||||
private LocalDateTime reserveEndDate; //예약 신청 종료일
|
||||
@Setter
|
||||
private String reserveStatusId; //예약상태 - 공통코드(reserve-status)
|
||||
@NotNull
|
||||
private String userId; //예약자
|
||||
@NotNull
|
||||
private String userContactNo; //예약자 연락처
|
||||
@NotNull
|
||||
private String userEmail; //예약자 이메일
|
||||
|
||||
@Builder
|
||||
public ReserveSaveRequestDto(Long reserveItemId, Integer reserveQty, String reservePurposeContent, String attachmentCode, LocalDateTime reserveStartDate, LocalDateTime reserveEndDate, String reserveStatusId, String userId, String userContactNo, String userEmail) {
|
||||
this.reserveItemId = reserveItemId;
|
||||
this.reserveQty = reserveQty;
|
||||
this.reservePurposeContent = reservePurposeContent;
|
||||
this.attachmentCode = attachmentCode;
|
||||
this.reserveStartDate = reserveStartDate;
|
||||
this.reserveEndDate = reserveEndDate;
|
||||
this.reserveStatusId = reserveStatusId;
|
||||
this.userId = userId;
|
||||
this.userContactNo = userContactNo;
|
||||
this.userEmail = userEmail;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.egovframe.cloud.reserveitemservice.config;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserverequestservice.config.RequestMessage
|
||||
*
|
||||
* 예약 신청 후 이벤트 스트림 message VO class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/16
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/16 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@ToString
|
||||
public class RequestMessage {
|
||||
private String reserveId;
|
||||
private Boolean isItemUpdated;
|
||||
private String uuid;
|
||||
|
||||
@Builder
|
||||
public RequestMessage(String reserveId, Boolean isItemUpdated, String uuid) {
|
||||
this.reserveId = reserveId;
|
||||
this.isItemUpdated = isItemUpdated;
|
||||
this.uuid = uuid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package org.egovframe.cloud.reserveitemservice.config;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveSaveRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.service.reserveItem.ReserveItemService;
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Scheduler;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserverequestservice.config.ReserveEventConfig
|
||||
*
|
||||
* event stream 설정 class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/16
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/16 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class ReserveEventConfig {
|
||||
|
||||
@Autowired
|
||||
private ReserveItemService reserveItemService;
|
||||
|
||||
/**
|
||||
* 예약 신청 후 재고 변경에 대한 consumer
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Consumer<ReserveSaveRequestDto> reserveRequest() {
|
||||
return reserveSaveRequestDto -> {
|
||||
log.info("receive data => {}", reserveSaveRequestDto);
|
||||
reserveItemService.updateInventoryThenSendMessage(
|
||||
reserveSaveRequestDto.getReserveItemId(),
|
||||
reserveSaveRequestDto.getReserveQty(),
|
||||
reserveSaveRequestDto.getReserveId())
|
||||
.subscribe();
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.egovframe.cloud.reserveitemservice.config;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
|
||||
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.portalservice.config.Resilience4JConfig
|
||||
* <p>
|
||||
* Resilience4J Configuration
|
||||
* 기본 설정값으로 운영되어도 무방하다. 이 클래스는 필수는 아니다.
|
||||
* retry 기본값은 최대 3회이고, fallback 이 없는 경우에만 동작하므로 설정하지 않았다.
|
||||
*
|
||||
* @author 표준프레임워크센터 jaeyeolkim
|
||||
* @version 1.0
|
||||
* @since 2021/08/31
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/08/31 jaeyeolkim 최초 생성
|
||||
* 2021/10/05 shinmj reactive로 변경
|
||||
* </pre>
|
||||
*/
|
||||
@Configuration
|
||||
public class Resilience4JConfig {
|
||||
|
||||
@Bean
|
||||
public CircuitBreakerRegistry circuitBreakerRegistry() {
|
||||
CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
|
||||
.failureRateThreshold(50) // Circuit 열지 말지 결정하는 실패 threshold 퍼센테이지
|
||||
.waitDurationInOpenState(Duration.ofSeconds(5)) // (half closed 전에) circuitBreaker가 open 되기 전에 기다리는 기간
|
||||
.slidingWindowType(CircuitBreakerConfig.SlidingWindowType.COUNT_BASED) // circuit breaker count 기반 처리
|
||||
.slidingWindowSize(10) // 통계 대상 건수 -> N건의 요청중..
|
||||
.build();
|
||||
return CircuitBreakerRegistry.of(circuitBreakerConfig);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.egovframe.cloud.reserveitemservice.domain.code;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.egovframe.cloud.reactive.domain.BaseEntity;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.relational.core.mapping.Column;
|
||||
import org.springframework.data.relational.core.mapping.Table;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.boardservice.domain.org.egovframe.cloud.reserveitemservice.domain.org.egovframe.cloud.reserveitemservice.domain.code.Code
|
||||
* <p>
|
||||
* 공통코드 엔티티
|
||||
*
|
||||
* @author 표준프레임워크센터 jaeyeolkim
|
||||
* @version 1.0
|
||||
* @since 2021/07/12
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/07/12 jaeyeolkim 최초 생성
|
||||
* 2021/09/15 shinmj r2dbc 변경
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
@Table("code")
|
||||
public class Code extends BaseEntity {
|
||||
@Id
|
||||
@Column
|
||||
private String codeId; // 코드ID
|
||||
|
||||
@Column
|
||||
private String parentCodeId; // 상위 코드ID
|
||||
|
||||
@Column
|
||||
private String codeName; // 코드 명
|
||||
|
||||
@Builder
|
||||
public Code(String codeId, String parentCodeId, String codeName) {
|
||||
this.codeId = codeId;
|
||||
this.parentCodeId = parentCodeId;
|
||||
this.codeName = codeName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package org.egovframe.cloud.reserveitemservice.domain.location;
|
||||
|
||||
import lombok.*;
|
||||
import org.egovframe.cloud.reactive.domain.BaseEntity;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.relational.core.mapping.Column;
|
||||
import org.springframework.data.relational.core.mapping.Table;
|
||||
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.domain.location.Location
|
||||
*
|
||||
* 예약 지역 도메인 클래스
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/06
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/06 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
@Table("location")
|
||||
public class Location extends BaseEntity {
|
||||
|
||||
@Id
|
||||
private Long locationId;
|
||||
|
||||
@Size(max = 200)
|
||||
@Column
|
||||
private String locationName;
|
||||
@Column
|
||||
private Integer sortSeq;
|
||||
|
||||
@Column("use_at")
|
||||
private Boolean isUse;
|
||||
|
||||
@Builder
|
||||
public Location(Long locationId, String locationName, Integer sortSeq, Boolean isUse) {
|
||||
this.locationId = locationId;
|
||||
this.locationName = locationName;
|
||||
this.sortSeq = sortSeq;
|
||||
this.isUse = isUse;
|
||||
}
|
||||
|
||||
public Location update(String locationName, Integer sortSeq, Boolean isUse) {
|
||||
this.locationName = locationName;
|
||||
this.sortSeq = sortSeq;
|
||||
this.isUse = isUse;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Location updateIsUse(Boolean isUse) {
|
||||
this.isUse = isUse;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package org.egovframe.cloud.reserveitemservice.domain.location;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.r2dbc.repository.R2dbcRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.domain.location.LocationRepository
|
||||
*
|
||||
* 예약 지역 R2dbc repository 클래스
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/06
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/06 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Repository
|
||||
public interface LocationRepository extends R2dbcRepository<Location, Long> {
|
||||
|
||||
/**
|
||||
* 검색조건(지역이름)을 포함한 목록조회
|
||||
*
|
||||
* @param locationName
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
Flux<Location> findAllByLocationNameContainingOrderBySortSeq(String locationName, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 검색조건(지역이름)을 포함한 count
|
||||
* paging 처리를 하기 위해서 조회
|
||||
*
|
||||
* @param locationName
|
||||
* @return
|
||||
*/
|
||||
Mono<Long> countAllByLocationNameContaining(String locationName);
|
||||
|
||||
/**
|
||||
* paging 처리를 하기 위한 목록 조회
|
||||
*
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
Flux<Location> findAllByOrderBySortSeq (Pageable pageable);
|
||||
|
||||
Flux<Location> findAllByIsUseTrueOrderBySortSeq();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.egovframe.cloud.reserveitemservice.domain.reserveItem;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum Category {
|
||||
EDUCATION("education", "교육"),
|
||||
EQUIPMENT("equipment", "장비"),
|
||||
SPACE("space", "공간");
|
||||
|
||||
private final String key;
|
||||
private final String title;
|
||||
|
||||
public boolean isEquals(String compare) {
|
||||
return this.getKey().equals(compare);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
package org.egovframe.cloud.reserveitemservice.domain.reserveItem;
|
||||
|
||||
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.egovframe.cloud.reactive.domain.BaseEntity;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemUpdateRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.data.relational.core.mapping.Column;
|
||||
import org.springframework.data.relational.core.mapping.Table;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem
|
||||
*
|
||||
* 예약 물품 도메인 클래스
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/09
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/09 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
@Table("reserve_item")
|
||||
public class ReserveItem extends BaseEntity {
|
||||
|
||||
@Id
|
||||
@Column("reserve_item_id")
|
||||
private Long reserveItemId; // 예약 물품 id
|
||||
|
||||
@Size(max = 200)
|
||||
@NotNull
|
||||
@Column("reserve_item_name")
|
||||
private String reserveItemName; //예약 물품 명
|
||||
|
||||
@Column
|
||||
private Long locationId;
|
||||
|
||||
@ToString.Exclude
|
||||
@Transient
|
||||
private Location location; //지역
|
||||
|
||||
@Size(max = 20)
|
||||
@NotNull
|
||||
@Column
|
||||
private String categoryId; //예약유형 - 공통코드 reserve-category
|
||||
|
||||
@Transient
|
||||
private String categoryName;
|
||||
|
||||
@Size(max = 5)
|
||||
@NotNull
|
||||
@Column
|
||||
private Integer totalQty; //총 재고/수용인원 수
|
||||
|
||||
@Size(max = 5)
|
||||
@Column
|
||||
private Integer inventoryQty; //현재 재고/수용인원 수
|
||||
|
||||
@Column
|
||||
private LocalDateTime operationStartDate; //운영 시작 일
|
||||
|
||||
@Column
|
||||
private LocalDateTime operationEndDate; //운영 종료 일
|
||||
|
||||
@Size(max = 20)
|
||||
@NotNull
|
||||
@Column
|
||||
private String reserveMethodId; // 예약 방법 - 공통코드 reserve-method
|
||||
|
||||
@Transient
|
||||
private String reserveMethodName;
|
||||
|
||||
@Size(max = 20)
|
||||
@Column
|
||||
private String reserveMeansId; // 예약 구분 (인터넷 예약 시) - 공통코드 reserve-means
|
||||
|
||||
@Transient
|
||||
private String reserveMeansName;
|
||||
|
||||
@Column
|
||||
private LocalDateTime requestStartDate; //예약 신청 시작 일시
|
||||
|
||||
@Column
|
||||
private LocalDateTime requestEndDate; //예약 신청 종료 일시
|
||||
|
||||
@Column("period_at")
|
||||
private Boolean isPeriod; //기간 지정 가능 여부 - true: 지정 가능, false: 지정 불가
|
||||
|
||||
@Size(max = 3)
|
||||
@Column
|
||||
private Integer periodMaxCount; // 최대 예약 가능 일 수
|
||||
|
||||
@Size(max = 500)
|
||||
@Column
|
||||
private String externalUrl; //외부링크
|
||||
|
||||
@Size(max = 20)
|
||||
@NotNull
|
||||
@Column
|
||||
private String selectionMeansId; //선별 방법 - 공통코드 reserve-selection
|
||||
|
||||
@Transient
|
||||
private String selectionMeansName;
|
||||
|
||||
@Column("paid_at")
|
||||
private Boolean isPaid; // 유/무료 - false: 무료, true: 유료
|
||||
|
||||
@Column
|
||||
private BigDecimal usageCost; //이용 요금
|
||||
|
||||
@Column("use_at")
|
||||
private Boolean isUse; //사용여부
|
||||
|
||||
@Size(max = 4000)
|
||||
@Column("purpose_content")
|
||||
private String purpose; //용도
|
||||
|
||||
@Size(max = 500)
|
||||
@Column("item_addr")
|
||||
private String address; //주소
|
||||
|
||||
@Size(max = 20)
|
||||
@Column
|
||||
private String targetId; //이용 대상 - 공통코드 reserve-target
|
||||
|
||||
@Transient
|
||||
private String targetName;
|
||||
|
||||
@Size(max = 2000)
|
||||
@Column("excluded_content")
|
||||
private String excluded; // 사용허가 제외대상
|
||||
|
||||
@Size(max = 500)
|
||||
@Column("homepage_url")
|
||||
private String homepage; //홈페이지 주소
|
||||
|
||||
@Size(max = 50)
|
||||
@Column("contact_no")
|
||||
private String contact; //문의처
|
||||
|
||||
@Size(max = 200)
|
||||
@Column("manager_dept_name")
|
||||
private String managerDept; //담당자 소속
|
||||
|
||||
@Size(max = 200)
|
||||
@Column("manager_name")
|
||||
private String managerName; //담당자 이름
|
||||
|
||||
@Size(max = 50)
|
||||
@Column("manager_contact_no")
|
||||
private String managerContact; //담당자 연락처
|
||||
|
||||
@Builder
|
||||
public ReserveItem(Long reserveItemId, String reserveItemName, Long locationId, Location location, String categoryId, String categoryName, Integer totalQty, Integer inventoryQty, LocalDateTime operationStartDate, LocalDateTime operationEndDate, String reserveMethodId, String reserveMethodName, String reserveMeansId, String reserveMeansName, LocalDateTime requestStartDate, LocalDateTime requestEndDate, Boolean isPeriod, Integer periodMaxCount, String externalUrl, String selectionMeansId, String selectionMeansName, Boolean isPaid, BigDecimal usageCost, Boolean isUse, String purpose, String address, String targetId, String targetName, String excluded, String homepage, String contact, String managerDept, String managerName, String managerContact) {
|
||||
this.reserveItemId = reserveItemId;
|
||||
this.reserveItemName = reserveItemName;
|
||||
this.locationId = locationId;
|
||||
this.location = location;
|
||||
this.categoryId = categoryId;
|
||||
this.categoryName = categoryName;
|
||||
this.totalQty = totalQty;
|
||||
this.inventoryQty = inventoryQty;
|
||||
this.operationStartDate = operationStartDate;
|
||||
this.operationEndDate = operationEndDate;
|
||||
this.reserveMethodId = reserveMethodId;
|
||||
this.reserveMethodName = reserveMethodName;
|
||||
this.reserveMeansId = reserveMeansId;
|
||||
this.reserveMeansName = reserveMeansName;
|
||||
this.requestStartDate = requestStartDate;
|
||||
this.requestEndDate = requestEndDate;
|
||||
this.isPeriod = isPeriod;
|
||||
this.periodMaxCount = periodMaxCount;
|
||||
this.externalUrl = externalUrl;
|
||||
this.selectionMeansId = selectionMeansId;
|
||||
this.selectionMeansName = selectionMeansName;
|
||||
this.isPaid = isPaid;
|
||||
this.usageCost = usageCost;
|
||||
this.isUse = isUse;
|
||||
this.purpose = purpose;
|
||||
this.address = address;
|
||||
this.targetId = targetId;
|
||||
this.targetName = targetName;
|
||||
this.excluded = excluded;
|
||||
this.homepage = homepage;
|
||||
this.contact = contact;
|
||||
this.managerDept = managerDept;
|
||||
this.managerName = managerName;
|
||||
this.managerContact = managerContact;
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 지역 정보 조회
|
||||
*
|
||||
* @param location
|
||||
* @return
|
||||
*/
|
||||
public ReserveItem setLocation(Location location) {
|
||||
this.location = location;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 유형 명칭 조회 세팅
|
||||
*
|
||||
* @param categoryName
|
||||
* @return
|
||||
*/
|
||||
public ReserveItem setCategoryName(String categoryName) {
|
||||
this.categoryName = categoryName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 방법 명칭
|
||||
*
|
||||
* @param reserveMethodName
|
||||
* @return
|
||||
*/
|
||||
public ReserveItem setReserveMethodName(String reserveMethodName) {
|
||||
this.reserveMethodName = reserveMethodName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 구분 명칭
|
||||
*
|
||||
* @param reserveMeansName
|
||||
* @return
|
||||
*/
|
||||
public ReserveItem setReserveMeansName(String reserveMeansName) {
|
||||
this.reserveMeansName = reserveMeansName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 선별 방법 명칭
|
||||
*
|
||||
* @param selectionMeansName
|
||||
* @return
|
||||
*/
|
||||
public ReserveItem setSelectionMeansName(String selectionMeansName) {
|
||||
this.selectionMeansName = selectionMeansName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 이용 대상 명칭
|
||||
*
|
||||
* @param targetName
|
||||
* @return
|
||||
*/
|
||||
public ReserveItem setTargetName(String targetName) {
|
||||
this.targetName = targetName;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 예약 물품 정보 업데이트
|
||||
*
|
||||
* @param updateRequestDto
|
||||
* @return
|
||||
*/
|
||||
public ReserveItem update(ReserveItemUpdateRequestDto updateRequestDto) {
|
||||
System.out.println("============ ?? : " + updateRequestDto.toString());
|
||||
this.reserveItemName = updateRequestDto.getReserveItemName();
|
||||
this.locationId = updateRequestDto.getLocationId();
|
||||
this.categoryId = updateRequestDto.getCategoryId();
|
||||
this.totalQty = updateRequestDto.getTotalQty();
|
||||
this.inventoryQty = updateRequestDto.getInventoryQty();
|
||||
this.operationStartDate = updateRequestDto.getOperationStartDate();
|
||||
this.operationEndDate = updateRequestDto.getOperationEndDate();
|
||||
this.reserveMethodId = updateRequestDto.getReserveMethodId();
|
||||
this.reserveMeansId = updateRequestDto.getReserveMeansId();
|
||||
this.requestStartDate = updateRequestDto.getRequestStartDate();
|
||||
this.requestEndDate = updateRequestDto.getRequestEndDate();
|
||||
this.isPeriod = updateRequestDto.getIsPeriod();
|
||||
this.periodMaxCount = updateRequestDto.getPeriodMaxCount();
|
||||
this.externalUrl = updateRequestDto.getExternalUrl();
|
||||
this.selectionMeansId = updateRequestDto.getSelectionMeansId();
|
||||
this.isPaid = updateRequestDto.getIsPaid();
|
||||
this.usageCost = updateRequestDto.getUsageCost();
|
||||
this.isUse = updateRequestDto.getIsUse();
|
||||
this.purpose = updateRequestDto.getPurpose();
|
||||
this.address = updateRequestDto.getAddress();
|
||||
this.targetId = updateRequestDto.getTargetId();
|
||||
this.excluded = updateRequestDto.getExcluded();
|
||||
this.homepage = updateRequestDto.getHomepage();
|
||||
this.contact = updateRequestDto.getContact();
|
||||
this.managerDept = updateRequestDto.getManagerDept();
|
||||
this.managerName = updateRequestDto.getManagerName();
|
||||
this.managerContact = updateRequestDto.getManagerContact();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 재고 변경
|
||||
*
|
||||
* @param inventoryQty
|
||||
* @return
|
||||
*/
|
||||
public ReserveItem updateInventoryQty(Integer inventoryQty) {
|
||||
this.inventoryQty = inventoryQty;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 사용여부 변경
|
||||
*
|
||||
* @param isUse
|
||||
* @return
|
||||
*/
|
||||
public ReserveItem updateIsUse(Boolean isUse) {
|
||||
this.isUse = isUse;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReserveItem setCreateDate(LocalDateTime createDate) {
|
||||
this.createDate = createDate;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.egovframe.cloud.reserveitemservice.domain.reserveItem;
|
||||
|
||||
import org.springframework.data.r2dbc.repository.R2dbcRepository;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItemRepository
|
||||
*
|
||||
* 예약 물품 도메인 repository interface
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/09
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/09 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
public interface ReserveItemRepository extends R2dbcRepository<ReserveItem, Long>, ReserveItemRepositoryCustom {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.egovframe.cloud.reserveitemservice.domain.reserveItem;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemMainResponseDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.code.Code;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItemRepositoryCustom
|
||||
*
|
||||
* 예약 물품 도메인 repository custom(query) interface
|
||||
* R2DBCEntityTemplate을 이용하여 쿼리하기 위한 Interface
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/13
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/13 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
public interface ReserveItemRepositoryCustom {
|
||||
|
||||
Flux<ReserveItem> search(ReserveItemRequestDto requestDto, Pageable pageable);
|
||||
Mono<Long> searchCount(ReserveItemRequestDto requestDto, Pageable pageable);
|
||||
|
||||
Flux<ReserveItem> searchForUser(String categoryId, ReserveItemRequestDto requestDto, Pageable pageable);
|
||||
Mono<Long> searchCountForUser(String categoryId, ReserveItemRequestDto requestDto, Pageable pageable);
|
||||
|
||||
Mono<ReserveItem> findWithRelation(Long reserveItemId);
|
||||
|
||||
Flux<ReserveItem> findLatestByCategory(Integer count, String categoryId);
|
||||
Flux<Code> findCodeDetail(String codeId);
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
package org.egovframe.cloud.reserveitemservice.domain.reserveItem;
|
||||
|
||||
import static org.springframework.data.relational.core.query.Criteria.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.code.Code;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
|
||||
import org.springframework.data.relational.core.query.Criteria;
|
||||
import org.springframework.data.relational.core.query.Query;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItemRepositoryImpl
|
||||
*
|
||||
* 예약 물품 도메인 repository custom(query) 구현체
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/13
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/13 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class ReserveItemRepositoryImpl implements ReserveItemRepositoryCustom{
|
||||
|
||||
private final R2dbcEntityTemplate entityTemplate;
|
||||
|
||||
/**
|
||||
* page 목록 조회
|
||||
*
|
||||
* @param requestDto
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Flux<ReserveItem> search(ReserveItemRequestDto requestDto, Pageable pageable) {
|
||||
return entityTemplate.select(ReserveItem.class)
|
||||
.matching(Query.query(Criteria.from(whereQuery(requestDto)))
|
||||
.sort(Sort.by(Sort.Direction.DESC, "create_date"))
|
||||
.with(pageable))
|
||||
.all()
|
||||
.flatMap(this::loadRelations)
|
||||
.switchIfEmpty(Flux.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* 목록 total count 조회
|
||||
*
|
||||
* @param requestDto
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Mono<Long> searchCount(ReserveItemRequestDto requestDto, Pageable pageable) {
|
||||
return entityTemplate.select(ReserveItem.class)
|
||||
.matching(Query.query(Criteria.from(whereQuery(requestDto)))
|
||||
.sort(Sort.by(Sort.Direction.DESC, "create_date"))
|
||||
.with(pageable))
|
||||
.count();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<ReserveItem> searchForUser(String categoryId, ReserveItemRequestDto requestDto, Pageable pageable) {
|
||||
Criteria where = Criteria.from(whereQuery(requestDto));
|
||||
|
||||
if (!"all".equals(categoryId)) {
|
||||
where = where.and(where("category_id").is(categoryId));
|
||||
}
|
||||
|
||||
Query query = Query.query(where("use_at").isTrue().and(where))
|
||||
.sort(Sort.by(Sort.Direction.DESC, "create_date"))
|
||||
.with(pageable);
|
||||
|
||||
return entityTemplate.select(ReserveItem.class)
|
||||
.matching(query)
|
||||
.all()
|
||||
.flatMap(this::loadRelations)
|
||||
.switchIfEmpty(Flux.empty());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Mono<Long> searchCountForUser(String categoryId, ReserveItemRequestDto requestDto, Pageable pageable) {
|
||||
Criteria where = Criteria.from(whereQuery(requestDto));
|
||||
|
||||
if (!"all".equals(categoryId)) {
|
||||
where = where.and(where("category_id").is(categoryId));
|
||||
}
|
||||
|
||||
Query query = Query.query(where("use_at").isTrue().and(where))
|
||||
.sort(Sort.by(Sort.Direction.DESC, "create_date"))
|
||||
.with(pageable);
|
||||
return entityTemplate.select(ReserveItem.class)
|
||||
.matching(query)
|
||||
.count();
|
||||
}
|
||||
|
||||
/**
|
||||
* relation 걸린 table 정보도 같이 조회
|
||||
* 공통코드, 지역
|
||||
*
|
||||
* @param reserveItemId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Mono<ReserveItem> findWithRelation(Long reserveItemId) {
|
||||
return entityTemplate.selectOne(Query.query(where("reserve_item_id").is(reserveItemId)), ReserveItem.class)
|
||||
.flatMap(this::loadRelationsAll)
|
||||
.switchIfEmpty(Mono.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* 카테고리별 예약 물품 최신 데이터 count 만큼 조회
|
||||
*
|
||||
* @param count 조회할 갯수 0:전체
|
||||
* @param categoryId 카테고리 아이디
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Flux<ReserveItem> findLatestByCategory(Integer count, String categoryId) {
|
||||
Query query =Query.query(where("category_id").is(categoryId)
|
||||
.and("use_at").isTrue()).sort(Sort.by(Sort.Order.desc("create_date")));
|
||||
|
||||
if (count > 0) {
|
||||
query.limit(count);
|
||||
}
|
||||
|
||||
return entityTemplate.select(ReserveItem.class)
|
||||
.matching(query)
|
||||
.all()
|
||||
.flatMap(this::loadRelations);
|
||||
}
|
||||
|
||||
/**
|
||||
* 공통코드 조회
|
||||
*
|
||||
* @param codeId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Flux<Code> findCodeDetail(String codeId) {
|
||||
return entityTemplate.select(Code.class)
|
||||
.matching(Query.query(where("parent_code_id").is(codeId).and("use_at").isTrue()))
|
||||
.all();
|
||||
}
|
||||
|
||||
/**
|
||||
* 유형만 공통코드 조회
|
||||
*
|
||||
* @param reserveItem
|
||||
* @return
|
||||
*/
|
||||
private Mono<ReserveItem> loadRelations(final ReserveItem reserveItem) {
|
||||
//load common code
|
||||
Mono<ReserveItem> mono = Mono.just(reserveItem)
|
||||
.zipWith(findCodeById(reserveItem.getCategoryId()))
|
||||
.map(tuple -> tuple.getT1().setCategoryName(tuple.getT2().getCodeName()))
|
||||
.switchIfEmpty(Mono.just(reserveItem));
|
||||
|
||||
// load location
|
||||
mono = mono.zipWith(findLocationById(reserveItem.getLocationId()))
|
||||
.map(tuple -> tuple.getT1().setLocation(tuple.getT2()))
|
||||
.switchIfEmpty(mono);
|
||||
|
||||
return mono;
|
||||
}
|
||||
|
||||
/**
|
||||
* 공통코드 이름 조회 (모든 공통코드에 대해 조회)
|
||||
*
|
||||
* @param reserveItem
|
||||
* @return
|
||||
*/
|
||||
private Mono<ReserveItem> loadRelationsAll(final ReserveItem reserveItem) {
|
||||
//load common code
|
||||
Mono<ReserveItem> mono = Mono.just(reserveItem)
|
||||
.zipWith(findCodeById(reserveItem.getCategoryId()))
|
||||
.map(tuple -> tuple.getT1().setCategoryName(tuple.getT2().getCodeName()))
|
||||
.zipWith(findCodeById(reserveItem.getReserveMethodId()))
|
||||
.map(tuple -> tuple.getT1().setReserveMethodName(tuple.getT2().getCodeName()))
|
||||
.zipWith(findCodeById(reserveItem.getReserveMeansId()))
|
||||
.map(tuple -> tuple.getT1().setReserveMeansName(tuple.getT2().getCodeName()))
|
||||
.zipWith(findCodeById(reserveItem.getSelectionMeansId()))
|
||||
.map(tuple -> tuple.getT1().setSelectionMeansName(tuple.getT2().getCodeName()))
|
||||
.zipWith(findCodeById(reserveItem.getTargetId()))
|
||||
.map(tuple -> tuple.getT1().setTargetName(tuple.getT2().getCodeName()))
|
||||
.switchIfEmpty(Mono.just(reserveItem));
|
||||
|
||||
// load location
|
||||
mono = mono.zipWith(findLocationById(reserveItem.getLocationId()))
|
||||
.map(tuple -> tuple.getT1().setLocation(tuple.getT2()))
|
||||
.switchIfEmpty(mono);
|
||||
|
||||
return mono;
|
||||
}
|
||||
|
||||
/**
|
||||
* 지역 조회
|
||||
*
|
||||
* @param locationId
|
||||
* @return
|
||||
*/
|
||||
private Mono<Location> findLocationById(Long locationId ) {
|
||||
return entityTemplate.select(Location.class)
|
||||
.matching(Query.query(where("location_id").is(locationId)))
|
||||
.one()
|
||||
.switchIfEmpty(Mono.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* 공통 코드 조회
|
||||
*
|
||||
* @param codeId
|
||||
* @return
|
||||
*/
|
||||
private Mono<Code> findCodeById(String codeId ) {
|
||||
return entityTemplate.select(Code.class)
|
||||
.matching(Query.query(where("code_id").is(codeId)))
|
||||
.one()
|
||||
.switchIfEmpty(Mono.empty());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 조회조건 쿼리
|
||||
*
|
||||
* @param requestDto
|
||||
* @return
|
||||
*/
|
||||
private List<Criteria> whereQuery(ReserveItemRequestDto requestDto) {
|
||||
String keywordType = requestDto.getKeywordType();
|
||||
String keyword = requestDto.getKeyword();
|
||||
|
||||
|
||||
List<Criteria> whereCriteria = new ArrayList<>();
|
||||
|
||||
if (StringUtils.hasText(keyword)) {
|
||||
if ("item".equals(keywordType)) {
|
||||
whereCriteria.add(where("reserve_item_name").like(likeText(keyword)));
|
||||
}
|
||||
}
|
||||
|
||||
if (requestDto.getLocationId() != null) {
|
||||
whereCriteria.add(where("location_id").in(requestDto.getLocationId()));
|
||||
}
|
||||
|
||||
if (requestDto.getCategoryId() != null ) {
|
||||
whereCriteria.add(where("category_id").in(requestDto.getCategoryId()));
|
||||
}
|
||||
|
||||
// 물품 팝업에서 조회하는 경우 인터넷 예약이 가능한 물품만 조회
|
||||
if (requestDto.getIsUse()) {
|
||||
whereCriteria.add(where("use_at").isTrue());
|
||||
whereCriteria.add(where("reserve_method_id").is("internet"));
|
||||
}
|
||||
|
||||
return whereCriteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* like 검색
|
||||
*
|
||||
* @param keyword
|
||||
* @return
|
||||
*/
|
||||
private String likeText(String keyword) {
|
||||
return "%" + keyword + "%";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package org.egovframe.cloud.reserveitemservice.service.location;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.egovframe.cloud.common.dto.RequestDto;
|
||||
import org.egovframe.cloud.common.exception.BusinessMessageException;
|
||||
import org.egovframe.cloud.common.exception.EntityNotFoundException;
|
||||
import org.egovframe.cloud.common.service.AbstractService;
|
||||
import org.egovframe.cloud.common.util.MessageUtil;
|
||||
import org.egovframe.cloud.reactive.service.ReactiveAbstractService;
|
||||
import org.egovframe.cloud.reserveitemservice.api.location.dto.LocationResponseDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.location.dto.LocationSaveRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.location.dto.LocationUpdateRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.location.LocationRepository;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.service.location.LocationService
|
||||
*
|
||||
* 예약 지역 service 클래스
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/06
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/06 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Transactional
|
||||
@Service
|
||||
public class LocationService extends ReactiveAbstractService {
|
||||
|
||||
private final LocationRepository locationRepository;
|
||||
|
||||
/**
|
||||
* 검색조건 없을 경우 전체 목록 조회
|
||||
*
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
private Mono<Page<LocationResponseDto>> findAll(Pageable pageable) {
|
||||
return locationRepository.findAllByOrderBySortSeq(pageable)
|
||||
.flatMap(this::convertLocationResponseDto)
|
||||
.collectList()
|
||||
.zipWith(locationRepository.count())
|
||||
.flatMap(tuple -> Mono.just(new PageImpl<>(tuple.getT1(), pageable, tuple.getT2())));
|
||||
}
|
||||
|
||||
/**
|
||||
* entity를 응답 dto 형태로 변환
|
||||
*
|
||||
* @param location
|
||||
* @return
|
||||
*/
|
||||
private Mono<LocationResponseDto> convertLocationResponseDto(Location location) {
|
||||
return Mono.just(LocationResponseDto.builder()
|
||||
.entity(location)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 지역 목록 조회
|
||||
*
|
||||
* @param requestDto
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public Mono<Page<LocationResponseDto>> search(RequestDto requestDto, Pageable pageable) {
|
||||
if (!StringUtils.hasText(requestDto.getKeywordType()) || !StringUtils.hasText(requestDto.getKeyword())) {
|
||||
return findAll(pageable);
|
||||
}
|
||||
|
||||
if ("locationName".equals(requestDto.getKeywordType())
|
||||
&& StringUtils.hasText(requestDto.getKeyword())
|
||||
) {
|
||||
return locationRepository.findAllByLocationNameContainingOrderBySortSeq(requestDto.getKeyword(), pageable)
|
||||
.flatMap(this::convertLocationResponseDto)
|
||||
.collectList()
|
||||
.zipWith(locationRepository.countAllByLocationNameContaining(requestDto.getKeyword()))
|
||||
.flatMap(tuple -> Mono.just(new PageImpl<>(tuple.getT1(), pageable, tuple.getT2())));
|
||||
}
|
||||
|
||||
return findAll(pageable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 지역 한건 조회
|
||||
*
|
||||
* @param locationId
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public Mono<LocationResponseDto> findById(Long locationId) {
|
||||
return locationRepository.findById(locationId)
|
||||
.switchIfEmpty(monoResponseStatusEntityNotFoundException(locationId))
|
||||
.flatMap(this::convertLocationResponseDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 지역 목록 조회 - 사용여부 = true
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public Flux<LocationResponseDto> findAll() {
|
||||
return locationRepository.findAllByIsUseTrueOrderBySortSeq()
|
||||
.flatMap(this::convertLocationResponseDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 지역 저장
|
||||
*
|
||||
* @param saveRequestDto
|
||||
* @return
|
||||
*/
|
||||
public Mono<LocationResponseDto> save(LocationSaveRequestDto saveRequestDto) {
|
||||
return locationRepository.save(saveRequestDto.toEntity())
|
||||
.flatMap(this::convertLocationResponseDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 지역 한건 저장
|
||||
*
|
||||
* @param locationId
|
||||
* @param updateRequestDto
|
||||
* @return
|
||||
*/
|
||||
public Mono<Void> update(Long locationId, LocationUpdateRequestDto updateRequestDto) {
|
||||
return locationRepository.findById(locationId)
|
||||
.switchIfEmpty(monoResponseStatusEntityNotFoundException(locationId))
|
||||
.map(location ->
|
||||
location.update(updateRequestDto.getLocationName(),
|
||||
updateRequestDto.getSortSeq(),
|
||||
updateRequestDto.getIsUse())
|
||||
)
|
||||
.flatMap(locationRepository::save)
|
||||
.then();
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 지역 한건 삭제
|
||||
*
|
||||
* @param locationId
|
||||
* @return
|
||||
*/
|
||||
public Mono<Void> delete(Long locationId) {
|
||||
return locationRepository.findById(locationId)
|
||||
.switchIfEmpty(monoResponseStatusEntityNotFoundException(locationId))
|
||||
.flatMap(locationRepository::delete)
|
||||
.onErrorResume(DataIntegrityViolationException.class,
|
||||
throwable -> Mono.error(new BusinessMessageException("참조하는 데이터가 있어 삭제할 수 없습니다.")));
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 지역 사용여부 토글
|
||||
*
|
||||
* @param locationId
|
||||
* @param isUse
|
||||
* @return
|
||||
*/
|
||||
public Mono<Void> updateIsUse(Long locationId, Boolean isUse) {
|
||||
return locationRepository.findById(locationId)
|
||||
.switchIfEmpty(monoResponseStatusEntityNotFoundException(locationId))
|
||||
.map(location -> location.updateIsUse(isUse))
|
||||
.flatMap(locationRepository::save)
|
||||
.then();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
package org.egovframe.cloud.reserveitemservice.service.reserveItem;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.egovframe.cloud.common.exception.BusinessMessageException;
|
||||
import org.egovframe.cloud.reactive.service.ReactiveAbstractService;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemListResponseDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemMainResponseDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemRelationResponseDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemResponseDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemSaveRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemUpdateRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.config.RequestMessage;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.Category;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItemRepository;
|
||||
import org.springframework.cloud.stream.function.StreamBridge;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.service.reserveItem.ReserveItemService
|
||||
*
|
||||
* 예약 물품 service class
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/13
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/13 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Transactional
|
||||
@Service
|
||||
public class ReserveItemService extends ReactiveAbstractService {
|
||||
|
||||
private static final String RESERVE_CATEGORY_CODE = "reserve-category";
|
||||
|
||||
private final ReserveItemRepository reserveItemRepository;
|
||||
private final StreamBridge streamBridge;
|
||||
|
||||
|
||||
/**
|
||||
* entity -> dto 변환
|
||||
*
|
||||
* @param reserveItem
|
||||
* @return
|
||||
*/
|
||||
private Mono<ReserveItemResponseDto> convertReserveItemResponseDto(ReserveItem reserveItem) {
|
||||
return Mono.just(ReserveItemResponseDto.builder().reserveItem(reserveItem).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* entity -> dto 변환
|
||||
*
|
||||
* @param reserveItem
|
||||
* @return
|
||||
*/
|
||||
private Mono<ReserveItemListResponseDto> convertReserveItemListResponseDto(ReserveItem reserveItem) {
|
||||
return Mono.just(ReserveItemListResponseDto.builder().reserveItem(reserveItem).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 목록 조회
|
||||
*
|
||||
* @param requestDto
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public Mono<Page<ReserveItemListResponseDto>> search(ReserveItemRequestDto requestDto, Pageable pageable) {
|
||||
return reserveItemRepository.search(requestDto, pageable)
|
||||
.flatMap(this::convertReserveItemListResponseDto)
|
||||
.collectList()
|
||||
.zipWith(reserveItemRepository.searchCount(requestDto, pageable))
|
||||
.flatMap(tuple -> Mono.just(new PageImpl<>(tuple.getT1(), pageable, tuple.getT2())));
|
||||
}
|
||||
|
||||
/**
|
||||
* 목록 조회 - 사용자가 조회 시
|
||||
*
|
||||
* @param categoryId
|
||||
* @param requestDto
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public Mono<Page<ReserveItemListResponseDto>> searchForUser(String categoryId, ReserveItemRequestDto requestDto, Pageable pageable) {
|
||||
return reserveItemRepository.searchForUser(categoryId, requestDto, pageable)
|
||||
.flatMap(this::convertReserveItemListResponseDto)
|
||||
.collectList()
|
||||
.zipWith(reserveItemRepository.searchCountForUser(categoryId, requestDto, pageable))
|
||||
.flatMap(tuple -> Mono.just(new PageImpl<>(tuple.getT1(), pageable, tuple.getT2())));
|
||||
}
|
||||
|
||||
/**
|
||||
* 한건 조회
|
||||
*
|
||||
* @param reserveItemId
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public Mono<ReserveItemResponseDto> findById(Long reserveItemId) {
|
||||
return reserveItemRepository.findById(reserveItemId)
|
||||
.switchIfEmpty(monoResponseStatusEntityNotFoundException(reserveItemId))
|
||||
.flatMap(this::convertReserveItemResponseDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 저장
|
||||
*
|
||||
* @param saveRequestDto
|
||||
* @return
|
||||
*/
|
||||
public Mono<ReserveItemResponseDto> save(ReserveItemSaveRequestDto saveRequestDto) {
|
||||
return reserveItemRepository.save(saveRequestDto.toEntity())
|
||||
.flatMap(this::convertReserveItemResponseDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 수정
|
||||
*
|
||||
* @param id
|
||||
* @param updateRequestDto
|
||||
* @return
|
||||
*/
|
||||
public Mono<Void> update(Long id, ReserveItemUpdateRequestDto updateRequestDto) {
|
||||
return reserveItemRepository.findById(id)
|
||||
.switchIfEmpty(monoResponseStatusEntityNotFoundException(id))
|
||||
.map(reserveItem -> reserveItem.update(updateRequestDto))
|
||||
.flatMap(reserveItemRepository::save)
|
||||
.then();
|
||||
}
|
||||
|
||||
/**
|
||||
* 사용여부 업데이트
|
||||
*
|
||||
* @param reserveItemId
|
||||
* @param isUse
|
||||
* @return
|
||||
*/
|
||||
public Mono<Void> updateIsUse(Long reserveItemId, Boolean isUse) {
|
||||
return reserveItemRepository.findById(reserveItemId)
|
||||
.switchIfEmpty(monoResponseStatusEntityNotFoundException(reserveItemId))
|
||||
.map(reserveItem -> reserveItem.updateIsUse(isUse))
|
||||
.flatMap(reserveItemRepository::save)
|
||||
.then();
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 신청(관리자) 시 재고 변경
|
||||
*
|
||||
* @param reserveItemId
|
||||
* @param reserveQty
|
||||
* @return
|
||||
*/
|
||||
public Mono<Boolean> updateInventory(Long reserveItemId, Integer reserveQty) {
|
||||
return reserveItemRepository.findById(reserveItemId)
|
||||
.switchIfEmpty(monoResponseStatusEntityNotFoundException(reserveItemId))
|
||||
.flatMap(reserveItem -> {
|
||||
int qty = reserveItem.getInventoryQty() - reserveQty;
|
||||
if (qty < 0) {
|
||||
return Mono.just(false);
|
||||
}
|
||||
return reserveItemRepository.save(reserveItem.updateInventoryQty(qty)).thenReturn(true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 신청(사용자) 시 재고 변경
|
||||
*
|
||||
* @param reserveItemId
|
||||
* @param reserveQty
|
||||
* @return
|
||||
*/
|
||||
public Mono<Void> updateInventoryThenSendMessage(Long reserveItemId, Integer reserveQty, String reserveId) {
|
||||
return reserveItemRepository.findById(reserveItemId)
|
||||
.switchIfEmpty(monoResponseStatusEntityNotFoundException(reserveItemId))
|
||||
.flatMap(reserveItem -> {
|
||||
if (!Category.EDUCATION.isEquals(reserveItem.getCategoryId())) {
|
||||
return Mono.error(new BusinessMessageException("저장할 수 없습니다."));
|
||||
}
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if (!(now.isAfter(reserveItem.getRequestStartDate()) && now.isBefore(reserveItem.getRequestEndDate()))) {
|
||||
return Mono.error(new BusinessMessageException("예약 가능 일자가 아닙니다."));
|
||||
}
|
||||
|
||||
int qty = reserveItem.getInventoryQty() - reserveQty;
|
||||
if (qty < 0) {
|
||||
return Mono.error(new BusinessMessageException("재고가 없습니다."));
|
||||
}
|
||||
|
||||
return Mono.just(reserveItem.updateInventoryQty(qty));
|
||||
})
|
||||
.flatMap(reserveItemRepository::save)
|
||||
.publishOn(Schedulers.boundedElastic())
|
||||
.doOnNext(reserveItem -> {
|
||||
log.info("reserve item inventory updated success");
|
||||
sendMessage(reserveId, true);
|
||||
})
|
||||
.doOnError(throwable -> {
|
||||
log.info("reserve item inventory updated fail = {}", throwable.getMessage());
|
||||
sendMessage(reserveId, false);
|
||||
}).then();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 재고 변경 성공 여부 이벤트 발생
|
||||
*
|
||||
* @param reserveId
|
||||
* @param isItemUpdated
|
||||
*/
|
||||
private void sendMessage(String reserveId, Boolean isItemUpdated) {
|
||||
streamBridge.send("inventoryUpdated-out-0",
|
||||
MessageBuilder.withPayload(
|
||||
RequestMessage.builder()
|
||||
.reserveId(reserveId)
|
||||
.isItemUpdated(isItemUpdated)
|
||||
.build())
|
||||
.setHeader("reserveUUID", reserveId).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 한건 조회 - 연관된 데이터도 같이 조회 (e.g. codename, location)
|
||||
*
|
||||
* @param reserveItemId
|
||||
* @return
|
||||
*/
|
||||
public Mono<ReserveItemRelationResponseDto> findByIdWithRelations(Long reserveItemId) {
|
||||
return reserveItemRepository.findWithRelation(reserveItemId)
|
||||
.switchIfEmpty(monoResponseStatusEntityNotFoundException(reserveItemId))
|
||||
.flatMap(reserveItem ->
|
||||
Mono.just(ReserveItemRelationResponseDto.builder().entity(reserveItem).build()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 각 카테고리별 최신 예약 물품 조회
|
||||
* 파라미터로 받는 갯수만큼 조회한다.
|
||||
*
|
||||
* @param count 조회할 갯수 0:전체
|
||||
* @return
|
||||
*/
|
||||
public Mono<Map<String, Collection<ReserveItemMainResponseDto>>> findLatest(Integer count) {
|
||||
return reserveItemRepository.findCodeDetail(
|
||||
RESERVE_CATEGORY_CODE)
|
||||
.flatMap(code -> reserveItemRepository.findLatestByCategory(count, code.getCodeId()))
|
||||
.map(reserveItem -> ReserveItemMainResponseDto.builder().entity(reserveItem).build())
|
||||
.collectMultimap(reserveItem -> reserveItem.getCategoryName());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
package org.egovframe.cloud.reserveitemservice.validator;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.egovframe.cloud.reserveitemservice.validator.annotation.ReserveItemSaveValid;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import java.lang.reflect.Field;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.validator.ReserveItemSaveValidator
|
||||
*
|
||||
* 예약 물품 저장 시 validation check를 하기 위한 custom validator
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/13
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/13 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
public class ReserveItemSaveValidator implements ConstraintValidator<ReserveItemSaveValid, Object> {
|
||||
|
||||
private String message;
|
||||
|
||||
@Override
|
||||
public void initialize(ReserveItemSaveValid constraintAnnotation) {
|
||||
message = constraintAnnotation.message();
|
||||
}
|
||||
|
||||
/**
|
||||
* 예약 물품 저장 시 비지니스 로직에 의한 validation check
|
||||
*
|
||||
* @param value
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public boolean isValid(Object value, ConstraintValidatorContext context) {
|
||||
boolean fieldValid = true;
|
||||
|
||||
// 운영 시작일, 종료일 체크
|
||||
LocalDateTime operationStartDate = (LocalDateTime) getFieldValue(value, "operationStartDate");
|
||||
LocalDateTime operationEndDate = (LocalDateTime) getFieldValue(value, "operationEndDate");
|
||||
if (operationStartDate.isAfter(operationEndDate)) {
|
||||
context.disableDefaultConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate("시작일이 종료일 보다 큽니다.")
|
||||
.addPropertyNode("operationStartDate")
|
||||
.addConstraintViolation();
|
||||
fieldValid = false;
|
||||
}
|
||||
|
||||
String reserveMethodId = String.valueOf(getFieldValue(value, "reserveMethodId"));
|
||||
//예약 방법이 '인터넷' 인경우
|
||||
if ("internet".equals(reserveMethodId)) {
|
||||
// 예약 구분 필수
|
||||
if (isNull(value, "reserveMeansId")) {
|
||||
context.disableDefaultConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate("인터넷 예약인 경우 예약 구분은 필수입니다.")
|
||||
.addPropertyNode("reserveMeansId")
|
||||
.addConstraintViolation();
|
||||
fieldValid = false;
|
||||
}else {
|
||||
String reserveMeansId = String.valueOf(getFieldValue(value, "reserveMeansId"));
|
||||
//예약 구분이 실시간 인 경우
|
||||
if ("realtime".equals(reserveMeansId)) {
|
||||
// 예약 신청 기간 필수
|
||||
if (isNull(value, "requestStartDate")) {
|
||||
context.disableDefaultConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate("인터넷 예약인 경우 예약 신청 시작 기간은 필수입니다.")
|
||||
.addPropertyNode("requestStartDate")
|
||||
.addConstraintViolation();
|
||||
fieldValid = false;
|
||||
} else if (isNull(value, "requestEndDate")) {
|
||||
context.disableDefaultConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate("인터넷 예약인 경우 예약 신청 종료 기간은 필수입니다.")
|
||||
.addPropertyNode("requestEndDate")
|
||||
.addConstraintViolation();
|
||||
fieldValid = false;
|
||||
}else {
|
||||
LocalDateTime requestStartDate = (LocalDateTime) getFieldValue(value, "requestStartDate");
|
||||
LocalDateTime requestEndDate = (LocalDateTime) getFieldValue(value, "requestEndDate");
|
||||
if (requestStartDate.isAfter(requestEndDate)) {
|
||||
context.disableDefaultConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate("시작일이 종료일 보다 큽니다.")
|
||||
.addPropertyNode("requestStartDate")
|
||||
.addConstraintViolation();
|
||||
fieldValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
//기간 지정 필수
|
||||
if (isNull(value, "isPeriod")) {
|
||||
context.disableDefaultConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate("인터넷 예약인 경우 기간 지정 여부는 필수입니다.")
|
||||
.addPropertyNode("requestEndDate")
|
||||
.addConstraintViolation();
|
||||
fieldValid = false;
|
||||
}else {
|
||||
Boolean isPeriod = Boolean.valueOf(String.valueOf(getFieldValue(value, "isPeriod")));
|
||||
// 기간 지정 가능인 경우 최대 얘약일 수 필수
|
||||
if (isPeriod && isNull(value, "periodMaxCount")) {
|
||||
context.disableDefaultConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate("기간 지정이 가능인 경우 최대 예약 일수는 필수입니다.")
|
||||
.addPropertyNode("periodMaxCount")
|
||||
.addConstraintViolation();
|
||||
fieldValid = false;
|
||||
}
|
||||
}
|
||||
}else if ("external".equals(reserveMeansId)) {
|
||||
//예약 구분이 외부 링크인 경우 외부 링크 url 필수
|
||||
if (isNull(value, "externalUrl")) {
|
||||
context.disableDefaultConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate("예약 구분이 외부링크인 경우 외부링크 url 값은 필수입니다.")
|
||||
.addPropertyNode("externalUrl")
|
||||
.addConstraintViolation();
|
||||
fieldValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ("telephone".equals(reserveMethodId)) {
|
||||
//예약 방법인 '전화'인 경우 contact 필수
|
||||
if (isNull(value, "contact")) {
|
||||
context.disableDefaultConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate("전화예약인 경우 문의처는 필수입니다.")
|
||||
.addPropertyNode("contact")
|
||||
.addConstraintViolation();
|
||||
fieldValid = false;
|
||||
}
|
||||
}else if ("visit".equals(reserveMethodId)) {
|
||||
//예약 방법인 '방문'인 경우 주소 필수
|
||||
if (isNull(value, "address")) {
|
||||
context.disableDefaultConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate("방문예약인 경우 주소는 필수입니다.")
|
||||
.addPropertyNode("address")
|
||||
.addConstraintViolation();
|
||||
fieldValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 유료인 경우 이용 요금 필수
|
||||
Boolean isPaid = Boolean.valueOf(String.valueOf(getFieldValue(value, "isPaid")));
|
||||
if (isPaid && isNull(value, "usageCost")) {
|
||||
context.disableDefaultConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate("유료인 경우 이용 요금은 필수입니다.")
|
||||
.addPropertyNode("usageCost")
|
||||
.addConstraintViolation();
|
||||
fieldValid = false;
|
||||
}
|
||||
|
||||
return fieldValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* 해당하는 field의 값 조회
|
||||
*
|
||||
* @param object
|
||||
* @param fieldName
|
||||
* @return
|
||||
* @throws NoSuchFieldException
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
private Object getFieldValue(Object object, String fieldName) throws NoSuchFieldException, IllegalAccessException {
|
||||
Class<?> clazz = object.getClass();
|
||||
Field field = clazz.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
return field.get(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* 해당하는 Field가 null인지 체크
|
||||
*
|
||||
* @param object
|
||||
* @param fieldName
|
||||
* @return
|
||||
* @throws NoSuchFieldException
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
private boolean isNull(Object object, String fieldName) throws NoSuchFieldException, IllegalAccessException {
|
||||
Class<?> clazz = object.getClass();
|
||||
Field field = clazz.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
return field.get(object) == null || !StringUtils.hasLength(String.valueOf(field.get(object)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.egovframe.cloud.reserveitemservice.validator.annotation;
|
||||
|
||||
import org.egovframe.cloud.reserveitemservice.validator.ReserveItemSaveValidator;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* org.egovframe.cloud.reserveitemservice.validator.annotation.ReserveItemSaveValid
|
||||
*
|
||||
* 예약 물품 저장 시 validation check를 하기 위한 custom annotation
|
||||
*
|
||||
* @author 표준프레임워크센터 shinmj
|
||||
* @version 1.0
|
||||
* @since 2021/09/13
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2021/09/13 shinmj 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Constraint(validatedBy = ReserveItemSaveValidator.class)
|
||||
public @interface ReserveItemSaveValid {
|
||||
|
||||
String message() default "저장할 수 없습니다.";
|
||||
Class<?>[] groups() default {};
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
spring:
|
||||
application:
|
||||
name: reserve-item-service
|
||||
|
||||
server:
|
||||
port: 0
|
||||
|
||||
# config server actuator
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: refresh, health, beans
|
||||
@@ -0,0 +1,5 @@
|
||||
spring:
|
||||
cloud:
|
||||
config:
|
||||
uri: http://localhost:8888
|
||||
name: reserve-item-service
|
||||
60
backend/reserve-item-service/src/main/resources/schema.sql
Normal file
60
backend/reserve-item-service/src/main/resources/schema.sql
Normal file
@@ -0,0 +1,60 @@
|
||||
-- location Table Create SQL
|
||||
CREATE TABLE IF NOT EXISTS location
|
||||
(
|
||||
location_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '지역 id',
|
||||
location_name VARCHAR(200) NULL COMMENT '지역 이름',
|
||||
sort_seq SMALLINT(3) NULL COMMENT '정렬 순서',
|
||||
use_at TINYINT(1) NULL DEFAULT 1 COMMENT '사용 여부',
|
||||
created_by VARCHAR(255) NULL COMMENT '생성자',
|
||||
create_date DATETIME NULL COMMENT '생성일',
|
||||
last_modified_by VARCHAR(255) NULL COMMENT '수정자',
|
||||
modified_date DATETIME NULL COMMENT '수정일',
|
||||
PRIMARY KEY (location_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
ALTER TABLE location COMMENT '예약 지역';
|
||||
|
||||
|
||||
-- reserve_item Table Create SQL
|
||||
CREATE TABLE IF NOT EXISTS reserve_item
|
||||
(
|
||||
reserve_item_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '예약 물품 id',
|
||||
reserve_item_name VARCHAR(200) NULL COMMENT '예약 물품 이름',
|
||||
location_id BIGINT NULL COMMENT '지역 id',
|
||||
category_id VARCHAR(20) NULL COMMENT '예약유형 - 공통코드 reserve-category',
|
||||
total_qty BIGINT(18) NULL COMMENT '총 재고/수용인원 수',
|
||||
inventory_qty BIGINT(18) NULL COMMENT '현재 남은 재고/수용인원 수',
|
||||
operation_start_date DATETIME NULL COMMENT '운영 시작 일',
|
||||
operation_end_date DATETIME NULL COMMENT '운영 종료 일',
|
||||
reserve_method_id VARCHAR(20) NULL COMMENT '예약 방법 - 공통코드 reserve-method',
|
||||
reserve_means_id VARCHAR(20) NULL COMMENT '예약 구분 (인터넷 예약 시) - 공통코드 reserve-means',
|
||||
request_start_date DATETIME NULL COMMENT '예약 신청 시작 일시',
|
||||
request_end_date DATETIME NULL COMMENT '예약 신청 종료 일시',
|
||||
period_at TINYINT(1) NULL DEFAULT 0 COMMENT '기간 지정 가능 여부 - true: 지정 가능, false: 지정 불가',
|
||||
period_max_count SMALLINT(3) NULL COMMENT '최대 예약 가능 일 수',
|
||||
external_url VARCHAR(500) NULL COMMENT '외부링크',
|
||||
selection_means_id VARCHAR(20) NULL COMMENT '선별 방법 - 공통코드 reserve-selection-means',
|
||||
paid_at TINYINT(1) NULL DEFAULT 0 COMMENT '유/무료 - false: 무료, true: 유료',
|
||||
usage_cost DECIMAL(18, 0) NULL COMMENT '이용 요금',
|
||||
use_at TINYINT(1) NULL DEFAULT 1 COMMENT '사용 여부',
|
||||
purpose_content VARCHAR(4000) NULL COMMENT '용도',
|
||||
item_addr VARCHAR(500) NULL COMMENT '주소',
|
||||
target_id VARCHAR(20) NULL COMMENT '이용 대상 - 공통코드 reserve-target',
|
||||
excluded_content VARCHAR(2000) NULL COMMENT '사용허가 제외대상',
|
||||
homepage_url VARCHAR(500) NULL COMMENT '홈페이지 url',
|
||||
contact_no VARCHAR(50) NULL COMMENT '문의처',
|
||||
manager_dept_name VARCHAR(200) NULL COMMENT '담당자 소속',
|
||||
manager_name VARCHAR(200) NULL COMMENT '담당자 이름',
|
||||
manager_contact_no VARCHAR(50) NULL COMMENT '담당자 연락처',
|
||||
create_date DATETIME NULL COMMENT '생성일',
|
||||
created_by VARCHAR(255) NULL COMMENT '생성자',
|
||||
modified_date DATETIME NULL COMMENT '수정일',
|
||||
last_modified_by VARCHAR(255) NULL COMMENT '수정자',
|
||||
PRIMARY KEY (reserve_item_id),
|
||||
CONSTRAINT FK_reserve_item_location_id FOREIGN KEY (location_id)
|
||||
REFERENCES location (location_id) ON DELETE RESTRICT ON UPDATE RESTRICT
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
ALTER TABLE reserve_item COMMENT '예약 물품';
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.egovframe.cloud.reserveitemservice;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class ReserveItemServiceApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.location;
|
||||
|
||||
import org.egovframe.cloud.reserveitemservice.api.location.dto.LocationSaveRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.api.location.dto.LocationUpdateRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.config.R2dbcConfig;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.location.LocationRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.BDDMockito;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@EnableConfigurationProperties
|
||||
@TestPropertySource(properties = {"spring.config.location=classpath:application-test.yml"})
|
||||
@ActiveProfiles("test")
|
||||
@Import({R2dbcConfig.class})
|
||||
class LocationApiControllerTest {
|
||||
|
||||
@MockBean
|
||||
private LocationRepository locationRepository;
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webTestClient;
|
||||
|
||||
private final static String API_URL = "/api/v1/locations";
|
||||
|
||||
private Location location = Location.builder()
|
||||
.locationId(1L)
|
||||
.locationName("location")
|
||||
.isUse(true)
|
||||
.sortSeq(1)
|
||||
.build();
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
BDDMockito.when(locationRepository.findById(ArgumentMatchers.anyLong()))
|
||||
.thenReturn(Mono.just(location));
|
||||
//조회조건 있는 경우
|
||||
BDDMockito.when(locationRepository.findAllByLocationNameContainingOrderBySortSeq(
|
||||
ArgumentMatchers.anyString(), ArgumentMatchers.any(Pageable.class)))
|
||||
.thenReturn(Flux.just(location));
|
||||
BDDMockito.when(locationRepository.countAllByLocationNameContaining(ArgumentMatchers.anyString()))
|
||||
.thenReturn(Mono.just(1L));
|
||||
//조회조건 없는 경우
|
||||
BDDMockito.when(locationRepository.findAllByOrderBySortSeq(ArgumentMatchers.any(Pageable.class)))
|
||||
.thenReturn(Flux.just(location));
|
||||
BDDMockito.when(locationRepository.count()).thenReturn(Mono.just(1L));
|
||||
|
||||
BDDMockito.when(locationRepository.save(ArgumentMatchers.any(Location.class)))
|
||||
.thenReturn(Mono.just(location));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void 한건조회_성공() throws Exception {
|
||||
webTestClient.get()
|
||||
.uri(API_URL+"/{locationId}", location.getLocationId())
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody()
|
||||
.jsonPath("$.locationName").isEqualTo(location.getLocationName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void 조회조건있는경우_페이지목록조회_성공() throws Exception {
|
||||
webTestClient.get()
|
||||
.uri(API_URL+"?keywordType=locationName&keyword=location&page=0&size=3")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody()
|
||||
.jsonPath("$.totalElements").isEqualTo(1)
|
||||
.jsonPath("$.content[0].locationName").isEqualTo(location.getLocationName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void 조회조건없는경우_페이지목록조회_성공() throws Exception {
|
||||
webTestClient.get()
|
||||
.uri(API_URL+"?page=0&size=3")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody()
|
||||
.jsonPath("$.totalElements").isEqualTo(1)
|
||||
.jsonPath("$.content[0].locationName").isEqualTo(location.getLocationName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void 한건저장_성공() throws Exception {
|
||||
webTestClient.post()
|
||||
.uri(API_URL)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.body(BodyInserters.fromValue(LocationSaveRequestDto.builder()
|
||||
.locationName(location.getLocationName())
|
||||
.isUse(location.getIsUse())
|
||||
.sortSeq(location.getSortSeq())
|
||||
.build()))
|
||||
.exchange()
|
||||
.expectStatus().isCreated()
|
||||
.expectBody().jsonPath("$.locationName").isEqualTo(location.getLocationName());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void 한건수정_성공() throws Exception {
|
||||
webTestClient.put()
|
||||
.uri(API_URL+"/{locationId}", location.getLocationId())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.body(BodyInserters.fromValue(LocationUpdateRequestDto.builder()
|
||||
.locationName("updateLocation")
|
||||
.isUse(location.getIsUse())
|
||||
.sortSeq(location.getSortSeq())
|
||||
.build()))
|
||||
.exchange()
|
||||
.expectStatus().isNoContent();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void 한건삭제_참조데이터존재_삭제실패() throws Exception {
|
||||
BDDMockito.when(locationRepository.delete(ArgumentMatchers.any(Location.class)))
|
||||
.thenReturn(Mono.error(new DataIntegrityViolationException("integrity test")));
|
||||
webTestClient.delete()
|
||||
.uri(API_URL+"/{locationId}", 1L)
|
||||
.exchange()
|
||||
.expectStatus().isBadRequest();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package org.egovframe.cloud.reserveitemservice.api.reserveItem;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemRequestDto;
|
||||
import org.egovframe.cloud.reserveitemservice.config.R2dbcConfig;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.code.Code;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
|
||||
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItemRepository;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.BDDMockito;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@EnableConfigurationProperties
|
||||
@TestPropertySource(properties = {"spring.config.location=classpath:application-test.yml"})
|
||||
@ActiveProfiles(profiles = "test")
|
||||
@Import({R2dbcConfig.class})
|
||||
class ReserveItemApiControllerTest {
|
||||
|
||||
|
||||
@MockBean
|
||||
ReserveItemRepository reserveItemRepository;
|
||||
|
||||
@Autowired
|
||||
WebTestClient webTestClient;
|
||||
|
||||
private final static String API_URL = "/api/v1/reserve-items";
|
||||
|
||||
|
||||
@Test
|
||||
public void 사용자별_검색_목록_조회_성공() throws Exception {
|
||||
LocalDateTime startDate = LocalDateTime.of(2021, 1, 28, 1,1);
|
||||
LocalDateTime endDate = LocalDateTime.of(2021, 12, 6, 1,1);
|
||||
|
||||
Location location = Location.builder()
|
||||
.locationId(1L)
|
||||
.locationName("location")
|
||||
.sortSeq(1)
|
||||
.isUse(true)
|
||||
.build();
|
||||
ReserveItem reserveItem = ReserveItem.builder()
|
||||
.reserveItemId(1L)
|
||||
.location(location)
|
||||
.locationId(location.getLocationId())
|
||||
.reserveItemName("test")
|
||||
.categoryId("education")
|
||||
.categoryName("교육")
|
||||
.totalQty(100)
|
||||
.inventoryQty(80)
|
||||
.operationEndDate(endDate)
|
||||
.operationStartDate(startDate)
|
||||
.isPeriod(false)
|
||||
.isUse(true)
|
||||
.build();
|
||||
|
||||
BDDMockito.when(reserveItemRepository.searchForUser(ArgumentMatchers.anyString(),
|
||||
ArgumentMatchers.any(ReserveItemRequestDto.class), ArgumentMatchers.any(Pageable.class)))
|
||||
.thenReturn(Flux.just(reserveItem));
|
||||
|
||||
BDDMockito.when(reserveItemRepository.searchCountForUser(ArgumentMatchers.anyString(),
|
||||
ArgumentMatchers.any(ReserveItemRequestDto.class), ArgumentMatchers.any(Pageable.class)))
|
||||
.thenReturn(Mono.just(1L));
|
||||
|
||||
webTestClient.get()
|
||||
.uri("/api/v1/{categoryId}/reserve-items?keywordType=locationName&keyword=location&page=0&size=3", "education")
|
||||
.exchange()
|
||||
.expectStatus().isOk();
|
||||
|
||||
}
|
||||
@Test
|
||||
public void main_예약물품조회_성공() throws Exception {
|
||||
BDDMockito.when(reserveItemRepository.findCodeDetail(ArgumentMatchers.anyString()))
|
||||
.thenReturn(Flux.fromIterable(Arrays.asList(Code.builder().codeId("education").codeName("교육").build(),
|
||||
Code.builder().codeId("equipment").codeName("장비").build(),
|
||||
Code.builder().codeId("space").codeName("장소").build())));
|
||||
|
||||
LocalDateTime startDate = LocalDateTime.of(2021, 1, 28, 1,1);
|
||||
LocalDateTime endDate = LocalDateTime.of(2021, 12, 6, 1,1);
|
||||
|
||||
Location location = Location.builder()
|
||||
.locationId(1L)
|
||||
.locationName("location")
|
||||
.sortSeq(1)
|
||||
.isUse(true)
|
||||
.build();
|
||||
ReserveItem reserveItem1 = ReserveItem.builder()
|
||||
.reserveItemId(1L)
|
||||
.location(location)
|
||||
.locationId(location.getLocationId())
|
||||
.reserveItemName("test")
|
||||
.categoryId("education")
|
||||
.categoryName("교육")
|
||||
.totalQty(100)
|
||||
.inventoryQty(80)
|
||||
.operationEndDate(endDate)
|
||||
.operationStartDate(startDate)
|
||||
.reserveMethodId("visit")
|
||||
.isPeriod(false)
|
||||
.isUse(true)
|
||||
.build();
|
||||
ReserveItem reserveItem2 = ReserveItem.builder()
|
||||
.reserveItemId(1L)
|
||||
.location(location)
|
||||
.locationId(location.getLocationId())
|
||||
.reserveItemName("test")
|
||||
.categoryId("education")
|
||||
.categoryName("장비")
|
||||
.totalQty(100)
|
||||
.inventoryQty(80)
|
||||
.operationEndDate(endDate)
|
||||
.operationStartDate(startDate)
|
||||
.reserveMethodId("visit")
|
||||
.isPeriod(false)
|
||||
.isUse(true)
|
||||
.build();
|
||||
|
||||
ReserveItem reserveItem3 = ReserveItem.builder()
|
||||
.reserveItemId(1L)
|
||||
.location(location)
|
||||
.locationId(location.getLocationId())
|
||||
.reserveItemName("test")
|
||||
.categoryId("education")
|
||||
.categoryName("공간")
|
||||
.totalQty(100)
|
||||
.inventoryQty(80)
|
||||
.operationEndDate(endDate)
|
||||
.operationStartDate(startDate)
|
||||
.reserveMethodId("visit")
|
||||
.isPeriod(false)
|
||||
.isUse(true)
|
||||
.build();
|
||||
reserveItem1.setCreateDate(LocalDateTime.now());
|
||||
reserveItem2.setCreateDate(LocalDateTime.now());
|
||||
reserveItem3.setCreateDate(LocalDateTime.now());
|
||||
|
||||
BDDMockito.when(reserveItemRepository.findLatestByCategory(ArgumentMatchers.anyInt(), ArgumentMatchers.anyString()))
|
||||
.thenReturn(Flux.fromIterable(Arrays.asList(reserveItem1, reserveItem2, reserveItem3)));
|
||||
|
||||
|
||||
webTestClient.get()
|
||||
.uri("/api/v1/reserve-items/latest/3")
|
||||
.exchange()
|
||||
.expectStatus().isOk();
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.egovframe.cloud.reserveitemservice.config;
|
||||
|
||||
import io.r2dbc.h2.H2ConnectionConfiguration;
|
||||
import io.r2dbc.h2.H2ConnectionFactory;
|
||||
import io.r2dbc.h2.H2ConnectionOption;
|
||||
import io.r2dbc.spi.ConnectionFactory;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.r2dbc.config.AbstractR2dbcConfiguration;
|
||||
import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
|
||||
import org.springframework.r2dbc.connection.init.CompositeDatabasePopulator;
|
||||
import org.springframework.r2dbc.connection.init.ConnectionFactoryInitializer;
|
||||
import org.springframework.r2dbc.connection.init.ResourceDatabasePopulator;
|
||||
|
||||
@Profile("test")
|
||||
@TestConfiguration
|
||||
@EnableR2dbcRepositories
|
||||
public class R2dbcConfig{
|
||||
@Bean
|
||||
public H2ConnectionFactory connectionFactory() {
|
||||
return new H2ConnectionFactory(H2ConnectionConfiguration.builder()
|
||||
.tcp("localhost", "~/querydsl")
|
||||
.property(H2ConnectionOption.DB_CLOSE_DELAY, "-1")
|
||||
.username("sa")
|
||||
.build());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ConnectionFactoryInitializer initializer(ConnectionFactory connectionFactory) {
|
||||
ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
|
||||
initializer.setConnectionFactory(connectionFactory);
|
||||
CompositeDatabasePopulator populator = new CompositeDatabasePopulator();
|
||||
populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("schema-h2.sql")));
|
||||
initializer.setDatabasePopulator(populator);
|
||||
|
||||
return initializer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
spring:
|
||||
application:
|
||||
name: reserve-item-service
|
||||
|
||||
datasource:
|
||||
url: jdbc:h2:mem:testdb;MODE=MYSQL;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false
|
||||
username: sa
|
||||
password:
|
||||
driver-class-name: org.h2.Driver
|
||||
jpa:
|
||||
hibernate:
|
||||
generate-ddl: true
|
||||
ddl-auto: create-drop
|
||||
properties:
|
||||
hibernate:
|
||||
format_sql: true
|
||||
default_batch_fetch_size: 1000
|
||||
show-sql: true
|
||||
h2:
|
||||
console:
|
||||
enabled: true
|
||||
path: /h2
|
||||
|
||||
logging.level:
|
||||
org.hibernate.SQL: debug
|
||||
|
||||
file:
|
||||
directory: ${user.home}/msa-attach-volume
|
||||
messages:
|
||||
directory: ${file.directory}/messages
|
||||
|
||||
# jwt token
|
||||
token:
|
||||
secret: egovframe_user_token
|
||||
|
||||
# ftp server
|
||||
ftp:
|
||||
enabled: false # ftp 사용 여부, FTP 서버에 최상위 디렉토리 자동 생성 및 구현체를 결정하게 된다.
|
||||
|
||||
# eureka 가 포함되면 eureka server 도 등록되므로 해제한다.
|
||||
eureka:
|
||||
client:
|
||||
register-with-eureka: false
|
||||
fetch-registry: false
|
||||
@@ -0,0 +1,19 @@
|
||||
spring:
|
||||
application:
|
||||
name: reserve-item-service
|
||||
|
||||
logging:
|
||||
level:
|
||||
org:
|
||||
springramework:
|
||||
data:
|
||||
r2dbc: DEBUG
|
||||
|
||||
|
||||
file:
|
||||
location: ${user.home}/msa-attach-volume
|
||||
|
||||
|
||||
# jwt token
|
||||
token:
|
||||
secret: egovframe_user_token
|
||||
@@ -0,0 +1,5 @@
|
||||
spring:
|
||||
cloud:
|
||||
config:
|
||||
uri: http://localhost:8888
|
||||
name: reserve-item-service
|
||||
@@ -0,0 +1,49 @@
|
||||
CREATE TABLE IF NOT EXISTS location(
|
||||
location_id BIGINT AUTO_INCREMENT,
|
||||
location_name VARCHAR(200),
|
||||
use_at tinyint(1) default 1 null,
|
||||
sort_seq smallint(3) null,
|
||||
create_date DATE null,
|
||||
modified_date DATE null,
|
||||
created_by VARCHAR(255) null,
|
||||
last_modified_by VARCHAR(255) null,
|
||||
CONSTRAINT PERSON_PK PRIMARY KEY (location_id)
|
||||
);
|
||||
|
||||
|
||||
-- reserve_item Table Create SQL
|
||||
CREATE TABLE IF NOT EXISTS reserve_item
|
||||
(
|
||||
reserve_item_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '예약 물품 id',
|
||||
reserve_item_name VARCHAR(200) NULL COMMENT '예약 물품 이름',
|
||||
location_id BIGINT NULL COMMENT '지역 id',
|
||||
category_id VARCHAR(20) NULL COMMENT '예약유형 - 공통코드 reserve-category',
|
||||
capacity_count MEDIUMINT(5) NULL COMMENT '재고/수용인원 수',
|
||||
operation_start_date DATETIME NULL COMMENT '운영 시작 일',
|
||||
operation_end_date DATETIME NULL COMMENT '운영 종료 일',
|
||||
reserve_method_id VARCHAR(20) NULL COMMENT '예약 방법 - 공통코드 reserve-method',
|
||||
reserve_means_id VARCHAR(20) NULL COMMENT '예약 구분 (인터넷 예약 시) - 공통코드 reserve-means',
|
||||
request_start_date DATETIME NULL COMMENT '예약 신청 시작 일시',
|
||||
request_end_date DATETIME NULL COMMENT '예약 신청 종료 일시',
|
||||
period_at TINYINT(1) NULL DEFAULT 0 COMMENT '기간 지정 가능 여부 - true: 지정 가능, false: 지정 불가',
|
||||
period_max_count SMALLINT(3) NULL COMMENT '최대 예약 가능 일 수',
|
||||
external_url VARCHAR(500) NULL COMMENT '외부링크',
|
||||
selection_means_id VARCHAR(20) NULL COMMENT '선별 방법 - 공통코드 reserve-selection-means',
|
||||
free_at TINYINT(1) NULL DEFAULT 1 COMMENT '유/무료 - true: 무료, false: 유료',
|
||||
usage_cost DECIMAL(18, 0) NULL COMMENT '이용 요금',
|
||||
use_at TINYINT(1) NULL DEFAULT 1 COMMENT '사용 여부',
|
||||
purpose_content VARCHAR(4000) NULL COMMENT '용도',
|
||||
item_addr VARCHAR(500) NULL COMMENT '주소',
|
||||
target_id VARCHAR(20) NULL COMMENT '이용 대상 - 공통코드 reserve-target',
|
||||
excluded_content VARCHAR(2000) NULL COMMENT '사용허가 제외대상',
|
||||
homepage_url VARCHAR(500) NULL COMMENT '홈페이지 url',
|
||||
contact_no VARCHAR(50) NULL COMMENT '문의처',
|
||||
manager_dept_name VARCHAR(200) NULL COMMENT '담당자 소속',
|
||||
manager_name VARCHAR(200) NULL COMMENT '담당자 이름',
|
||||
manager_contact_no VARCHAR(50) NULL COMMENT '담당자 연락처',
|
||||
create_date DATETIME NULL COMMENT '생성일',
|
||||
created_by VARCHAR(255) NULL COMMENT '생성자',
|
||||
modified_date DATETIME NULL COMMENT '수정일',
|
||||
last_modified_by VARCHAR(255) NULL COMMENT '수정자',
|
||||
PRIMARY KEY (reserve_item_id)
|
||||
);
|
||||
Reference in New Issue
Block a user