diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/Spring-B.iml b/.idea/Spring-B.iml new file mode 100644 index 0000000..7f098fc --- /dev/null +++ b/.idea/Spring-B.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..9c42d73 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..c4e283f --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/umc.mission/.gitignore b/umc.mission/.gitignore new file mode 100644 index 0000000..9903923 --- /dev/null +++ b/umc.mission/.gitignore @@ -0,0 +1,40 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### UserSpecific Stuffs ### +resources/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/umc.mission/build.gradle b/umc.mission/build.gradle new file mode 100644 index 0000000..66bac50 --- /dev/null +++ b/umc.mission/build.gradle @@ -0,0 +1,41 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '3.2.7' + id 'io.spring.dependency-management' version '1.1.5' +} + +group = 'com.example' +version = '0.0.1-SNAPSHOT' + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(17) + } +} + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2' + implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' + compileOnly 'org.projectlombok:lombok' + runtimeOnly 'com.mysql:mysql-connector-j' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' +} + +tasks.named('test') { + useJUnitPlatform() +} diff --git a/umc.mission/gradle/wrapper/gradle-wrapper.jar b/umc.mission/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e644113 Binary files /dev/null and b/umc.mission/gradle/wrapper/gradle-wrapper.jar differ diff --git a/umc.mission/gradle/wrapper/gradle-wrapper.properties b/umc.mission/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..a441313 --- /dev/null +++ b/umc.mission/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/umc.mission/gradlew b/umc.mission/gradlew new file mode 100644 index 0000000..b740cf1 --- /dev/null +++ b/umc.mission/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/umc.mission/gradlew.bat b/umc.mission/gradlew.bat new file mode 100644 index 0000000..25da30d --- /dev/null +++ b/umc.mission/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/umc.mission/settings.gradle b/umc.mission/settings.gradle new file mode 100644 index 0000000..d21fe13 --- /dev/null +++ b/umc.mission/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'umc.mission' diff --git a/umc.mission/src/main/java/com/example/umc/mission/Application.java b/umc.mission/src/main/java/com/example/umc/mission/Application.java new file mode 100644 index 0000000..6f06d43 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/Application.java @@ -0,0 +1,13 @@ +package com.example.umc.mission; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/ApiResponse.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/ApiResponse.java new file mode 100644 index 0000000..cf9f1a0 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/ApiResponse.java @@ -0,0 +1,35 @@ +package com.example.umc.mission.apiPayload; + +import com.example.umc.mission.apiPayload.code.BaseCode; +import com.example.umc.mission.apiPayload.code.status.SuccessStatus; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +@JsonPropertyOrder({"isSuccess", "code", "message", "result"}) +public class ApiResponse { + + @JsonProperty("isSuccess") + private final Boolean isSuccess; + private final String code; + private final String message; + @JsonInclude(JsonInclude.Include.NON_NULL) + private T result; + + public static ApiResponse onSucccess(T result){ + return new ApiResponse<>(true, SuccessStatus._OK.getCode(), SuccessStatus._OK.getMessage(), result); + } + + public static ApiResponse of(BaseCode code, T result){ + return new ApiResponse<>(true, code.getReasonHttpStatus().getCode(), code.getReasonHttpStatus().getMessage(), result); + } + + //실패한 경우 응답 생성 + public static ApiResponse onFailure(String code, String message, T data) { + return new ApiResponse<>(true, code, message, data); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/BaseCode.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/BaseCode.java new file mode 100644 index 0000000..56a8ad9 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/BaseCode.java @@ -0,0 +1,8 @@ +package com.example.umc.mission.apiPayload.code; + +public interface BaseCode { + + public ReasonDTO getReason(); + + public ReasonDTO getReasonHttpStatus(); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/BaseErrorCode.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/BaseErrorCode.java new file mode 100644 index 0000000..bf0b7cf --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/BaseErrorCode.java @@ -0,0 +1,8 @@ +package com.example.umc.mission.apiPayload.code; + +public interface BaseErrorCode { + + public ErrorReasonDTO getReason(); + + public ErrorReasonDTO getReasonHttpStatus(); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/ErrorReasonDTO.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/ErrorReasonDTO.java new file mode 100644 index 0000000..05127c3 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/ErrorReasonDTO.java @@ -0,0 +1,19 @@ +package com.example.umc.mission.apiPayload.code; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.http.HttpStatus; + +@Builder +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class ErrorReasonDTO { + + private String message; + private String code; + private Boolean isSuccess; + private HttpStatus httpStatus; +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/ReasonDTO.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/ReasonDTO.java new file mode 100644 index 0000000..9a5d221 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/ReasonDTO.java @@ -0,0 +1,19 @@ +package com.example.umc.mission.apiPayload.code; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.http.HttpStatus; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ReasonDTO { + + private String message; + private String code; + private Boolean isSuccess; + private HttpStatus httpStatus; +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/status/ErrorStatus.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/status/ErrorStatus.java new file mode 100644 index 0000000..a4ad0cc --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/status/ErrorStatus.java @@ -0,0 +1,67 @@ +package com.example.umc.mission.apiPayload.code.status; + +import com.example.umc.mission.apiPayload.code.BaseErrorCode; +import com.example.umc.mission.apiPayload.code.ErrorReasonDTO; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum ErrorStatus implements BaseErrorCode { + + //가장 일반적인 응답 + _INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "COMMON500", "서버 에러, 관리자에게 문의바랍니다."), + _BAD_REQUEST(HttpStatus.BAD_REQUEST, "COMMON400", "잘못된 요청입니다."), + _UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "COMMON401", "인증이 필요합니다."), + _FORBIDDEN(HttpStatus.FORBIDDEN, "COMMON403", "금지된 요청입니다."), + + //페이지 에러 + PAGE_FORBIDDEN(HttpStatus.BAD_REQUEST,"PAGE4001", "페이지 값이 음수입니다."), + + //멤버 에러 + MEMBER_NOT_FOUND(HttpStatus.BAD_REQUEST, "MEMBER4001", "사용자가 존재하지 않습니다."), + NICKNAME_NOT_EXIST(HttpStatus.BAD_REQUEST, "MEMBER4002", "닉네임은 필수입니다."), + + //음식 선호도 에러 + FOOD_CATEGORY_NOT_FOUND(HttpStatus.BAD_REQUEST, "FOODCATEGORY4001", "해당하는 음식 카테코리가 존재하지 않습니다."), + + //지역 에러 + REGION_NOT_FOUND(HttpStatus.BAD_REQUEST, "REGION4001" ,"입력한 이름을 가진 지역이 존재하지 않습니다."), + + //가게 에러 + STORE_NOT_FOUND(HttpStatus.BAD_REQUEST, "STORE4001", "해당하는 가게가 존재하지 않습니다."), + REVIEW_NOT_FOUND(HttpStatus.BAD_REQUEST, "REVIEW4001", "해당하는 리뷰가 존재하지 않습니다."), + + //미션 에러 + MISSION_NOT_FOUND(HttpStatus.BAD_REQUEST, "MISSION4001", "미션이 존재하지 않습니다."), + MISSION_IS_CHALLENGING(HttpStatus.BAD_REQUEST, "MISSION4002", "미션이 이미 도전 중입니다."), + + //Test + TEMP_EXCEPTION(HttpStatus.BAD_REQUEST, "TEMP4001", "FOR TEST"); + + private final HttpStatus httpStatus; + private final String code; + private final String message; + + @Override + public ErrorReasonDTO getReason(){ + return ErrorReasonDTO.builder() + .message(message) + .code(code) + .isSuccess(false) + .build() + ; + } + + @Override + public ErrorReasonDTO getReasonHttpStatus(){ + return ErrorReasonDTO.builder() + .message(message) + .code(code) + .isSuccess(false) + .httpStatus(httpStatus) + .build() + ; + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/status/SuccessStatus.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/status/SuccessStatus.java new file mode 100644 index 0000000..5b54f20 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/code/status/SuccessStatus.java @@ -0,0 +1,39 @@ +package com.example.umc.mission.apiPayload.code.status; + +import com.example.umc.mission.apiPayload.code.BaseCode; +import com.example.umc.mission.apiPayload.code.ReasonDTO; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum SuccessStatus implements BaseCode { + //가장 일반적인 응답 + _OK(HttpStatus.OK, "COMMON200", "성공입니다."); + + private final HttpStatus httpStatus; + private final String code; + private final String message; + + @Override + public ReasonDTO getReason(){ + return ReasonDTO.builder() + .message(message) + .code(code) + .isSuccess(true) + .build() + ; + } + + @Override + public ReasonDTO getReasonHttpStatus(){ + return ReasonDTO.builder() + .message(message) + .code(code) + .isSuccess(true) + .httpStatus(httpStatus) + .build() + ; + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/ExceptionAdvice.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/ExceptionAdvice.java new file mode 100644 index 0000000..8b5194b --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/ExceptionAdvice.java @@ -0,0 +1,121 @@ +package com.example.umc.mission.apiPayload.exception; + +import com.example.umc.mission.apiPayload.ApiResponse; +import com.example.umc.mission.apiPayload.code.ErrorReasonDTO; +import com.example.umc.mission.apiPayload.code.status.ErrorStatus; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.ConstraintViolationException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.context.request.ServletWebRequest; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Optional; + +@Slf4j +@RestControllerAdvice(annotations = {RestController.class}) +public class ExceptionAdvice extends ResponseEntityExceptionHandler { + + + @org.springframework.web.bind.annotation.ExceptionHandler + public ResponseEntity validation(ConstraintViolationException e, WebRequest request) { + String errorMessage = e.getConstraintViolations().stream() + .map(constraintViolation -> constraintViolation.getMessage()) + .findFirst() + .orElseThrow(() -> new RuntimeException("ConstraintViolationException 추출 도중 에러 발생")); + + return handleExceptionInternalConstraint(e, ErrorStatus.valueOf(errorMessage), HttpHeaders.EMPTY,request); + } + + + @Override + public ResponseEntity handleMethodArgumentNotValid( + MethodArgumentNotValidException e, HttpHeaders headers, HttpStatusCode status, WebRequest request) { + + Map errors = new LinkedHashMap<>(); + + e.getBindingResult().getFieldErrors().stream() + .forEach(fieldError -> { + String fieldName = fieldError.getField(); + String errorMessage = Optional.ofNullable(fieldError.getDefaultMessage()).orElse(""); + errors.merge(fieldName, errorMessage, (existingErrorMessage, newErrorMessage) -> existingErrorMessage + ", " + newErrorMessage); + }); + + return handleExceptionInternalArgs(e,HttpHeaders.EMPTY,ErrorStatus.valueOf("_BAD_REQUEST"),request,errors); + } + + @org.springframework.web.bind.annotation.ExceptionHandler + public ResponseEntity exception(Exception e, WebRequest request) { + e.printStackTrace(); + + return handleExceptionInternalFalse(e, ErrorStatus._INTERNAL_SERVER_ERROR, HttpHeaders.EMPTY, ErrorStatus._INTERNAL_SERVER_ERROR.getHttpStatus(),request, e.getMessage()); + } + + @ExceptionHandler(value = GeneralException.class) + public ResponseEntity onThrowException(GeneralException generalException, HttpServletRequest request) { + ErrorReasonDTO errorReasonHttpStatus = generalException.getErrorReasonHttpStatus(); + return handleExceptionInternal(generalException,errorReasonHttpStatus,null,request); + } + + private ResponseEntity handleExceptionInternal(Exception e, ErrorReasonDTO reason, + HttpHeaders headers, HttpServletRequest request) { + + ApiResponse body = ApiResponse.onFailure(reason.getCode(),reason.getMessage(),null); +// e.printStackTrace(); + + WebRequest webRequest = new ServletWebRequest(request); + return super.handleExceptionInternal( + e, + body, + headers, + reason.getHttpStatus(), + webRequest + ); + } + + private ResponseEntity handleExceptionInternalFalse(Exception e, ErrorStatus errorCommonStatus, + HttpHeaders headers, HttpStatus status, WebRequest request, String errorPoint) { + ApiResponse body = ApiResponse.onFailure(errorCommonStatus.getCode(),errorCommonStatus.getMessage(),errorPoint); + return super.handleExceptionInternal( + e, + body, + headers, + status, + request + ); + } + + private ResponseEntity handleExceptionInternalArgs(Exception e, HttpHeaders headers, ErrorStatus errorCommonStatus, + WebRequest request, Map errorArgs) { + ApiResponse body = ApiResponse.onFailure(errorCommonStatus.getCode(),errorCommonStatus.getMessage(),errorArgs); + return super.handleExceptionInternal( + e, + body, + headers, + errorCommonStatus.getHttpStatus(), + request + ); + } + + private ResponseEntity handleExceptionInternalConstraint(Exception e, ErrorStatus errorCommonStatus, + HttpHeaders headers, WebRequest request) { + ApiResponse body = ApiResponse.onFailure(errorCommonStatus.getCode(), errorCommonStatus.getMessage(), null); + return super.handleExceptionInternal( + e, + body, + headers, + errorCommonStatus.getHttpStatus(), + request + ); + } +} \ No newline at end of file diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/GeneralException.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/GeneralException.java new file mode 100644 index 0000000..d91f314 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/GeneralException.java @@ -0,0 +1,21 @@ +package com.example.umc.mission.apiPayload.exception; + +import com.example.umc.mission.apiPayload.code.BaseErrorCode; +import com.example.umc.mission.apiPayload.code.ErrorReasonDTO; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class GeneralException extends RuntimeException { + + private BaseErrorCode code; + + public ErrorReasonDTO getErrorReason() { + return this.code.getReason(); + } + + public ErrorReasonDTO getErrorReasonHttpStatus(){ + return this.code.getReasonHttpStatus(); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/FoodCategoryHandler.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/FoodCategoryHandler.java new file mode 100644 index 0000000..7eef720 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/FoodCategoryHandler.java @@ -0,0 +1,11 @@ +package com.example.umc.mission.apiPayload.exception.handler; + +import com.example.umc.mission.apiPayload.code.BaseErrorCode; +import com.example.umc.mission.apiPayload.exception.GeneralException; + +public class FoodCategoryHandler extends GeneralException { + + public FoodCategoryHandler(BaseErrorCode errorCode) { + super(errorCode); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/MemberHandler.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/MemberHandler.java new file mode 100644 index 0000000..f27975d --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/MemberHandler.java @@ -0,0 +1,11 @@ +package com.example.umc.mission.apiPayload.exception.handler; + +import com.example.umc.mission.apiPayload.code.BaseErrorCode; +import com.example.umc.mission.apiPayload.exception.GeneralException; + +public class MemberHandler extends GeneralException { + + public MemberHandler(BaseErrorCode errorCode) { + super(errorCode); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/MissionHandler.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/MissionHandler.java new file mode 100644 index 0000000..ebe1868 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/MissionHandler.java @@ -0,0 +1,11 @@ +package com.example.umc.mission.apiPayload.exception.handler; + +import com.example.umc.mission.apiPayload.code.BaseErrorCode; +import com.example.umc.mission.apiPayload.exception.GeneralException; + +public class MissionHandler extends GeneralException { + + public MissionHandler(BaseErrorCode errorCode) { + super(errorCode); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/RegionHandler.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/RegionHandler.java new file mode 100644 index 0000000..a197b1b --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/RegionHandler.java @@ -0,0 +1,11 @@ +package com.example.umc.mission.apiPayload.exception.handler; + +import com.example.umc.mission.apiPayload.code.BaseErrorCode; +import com.example.umc.mission.apiPayload.exception.GeneralException; + +public class RegionHandler extends GeneralException { + + public RegionHandler(BaseErrorCode errorCode) { + super(errorCode); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/StoreHandler.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/StoreHandler.java new file mode 100644 index 0000000..58976a4 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/StoreHandler.java @@ -0,0 +1,11 @@ +package com.example.umc.mission.apiPayload.exception.handler; + +import com.example.umc.mission.apiPayload.code.BaseErrorCode; +import com.example.umc.mission.apiPayload.exception.GeneralException; + +public class StoreHandler extends GeneralException { + + public StoreHandler(BaseErrorCode errorCode) { + super(errorCode); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/TempHandler.java b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/TempHandler.java new file mode 100644 index 0000000..ba8cf26 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/apiPayload/exception/handler/TempHandler.java @@ -0,0 +1,11 @@ +package com.example.umc.mission.apiPayload.exception.handler; + +import com.example.umc.mission.apiPayload.code.BaseErrorCode; +import com.example.umc.mission.apiPayload.exception.GeneralException; + +public class TempHandler extends GeneralException { + + public TempHandler(BaseErrorCode errorCode){ + super(errorCode); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/aws/s3/AmazonS3Manager.java b/umc.mission/src/main/java/com/example/umc/mission/aws/s3/AmazonS3Manager.java new file mode 100644 index 0000000..5b77937 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/aws/s3/AmazonS3Manager.java @@ -0,0 +1,56 @@ +package com.example.umc.mission.aws.s3; + +import com.amazonaws.SdkClientException; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.model.DeleteObjectRequest; +import com.amazonaws.services.s3.model.ObjectMetadata; +import com.amazonaws.services.s3.model.PutObjectRequest; +import com.example.umc.mission.config.AmazonConfig; +import com.example.umc.mission.domain.Uuid; +import com.example.umc.mission.repository.UuidRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +@Slf4j +@Component +@RequiredArgsConstructor +public class AmazonS3Manager { + + private final AmazonS3 amazonS3; + + private final AmazonConfig amazonConfig; + + private final UuidRepository uuidRepository; + + public String generateReviewKeyName(Uuid uuid){ + return amazonConfig.getReviewPath() + '/' + uuid.getUuid(); + } + + public String uploadFile(String keyName, MultipartFile file){ + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentType(file.getContentType()); + metadata.setContentLength(file.getSize()); + try{ + amazonS3.putObject(new PutObjectRequest(amazonConfig.getBucket(),keyName,file.getInputStream(), metadata)); + }catch (IOException e){ + log.error("error at AmazonS3Manager uploadFile : {}",(Object) e.getStackTrace()); + } + return amazonS3.getUrl(amazonConfig.getBucket(), keyName).toString(); + } + + public void deleteImage(String fileUrl){ + try{ + String splitStr = ".com/"; + String fileName = fileUrl.substring(fileUrl.lastIndexOf(splitStr) + splitStr.length()); + amazonS3.deleteObject(new DeleteObjectRequest(amazonConfig.getBucket(), fileName)); + } + catch(SdkClientException e){ + log.error("Error deleting file from s3"); + } + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/config/AmazonConfig.java b/umc.mission/src/main/java/com/example/umc/mission/config/AmazonConfig.java new file mode 100644 index 0000000..c2b5bfa --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/config/AmazonConfig.java @@ -0,0 +1,50 @@ +package com.example.umc.mission.config; + +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.AWSCredentialsProvider; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import jakarta.annotation.PostConstruct; +import lombok.Getter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@Getter +public class AmazonConfig { + + private AWSCredentials awsCredentials; + + @Value("${cloud.aws.credentials.accessKey}") + private String accesskey; + + @Value("${cloud.aws.credentials.secretKey}") + private String secretkey; + + @Value("${cloud.aws.region.static}") + private String region; + + @Value("${cloud.aws.s3.bucket}") + private String bucket; + + @Value("${cloud.aws.s3.path.review}") + private String reviewPath; + + @PostConstruct + public void init() { this.awsCredentials = new BasicAWSCredentials(accesskey, secretkey); } + + @Bean + public AmazonS3 s3Client() { + AWSCredentials awsCredentials1 = new BasicAWSCredentials(accesskey,secretkey); + return AmazonS3ClientBuilder.standard() + .withRegion(region) + .withCredentials(new AWSStaticCredentialsProvider(awsCredentials1)) + .build(); + } + + @Bean + public AWSCredentialsProvider awsCredentialsProvider(){ return new AWSStaticCredentialsProvider(awsCredentials); } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/config/SwaggerConfig.java b/umc.mission/src/main/java/com/example/umc/mission/config/SwaggerConfig.java new file mode 100644 index 0000000..e66ff54 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/config/SwaggerConfig.java @@ -0,0 +1,39 @@ +package com.example.umc.mission.config; + +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.oas.models.servers.Server; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SwaggerConfig { + + @Bean + public OpenAPI UMCstudyAPI() { + Info info = new Info() + .title("UMC Server WorkBook API") + .description("UMC Server WorkBook API 명세서") + .version("1.0.0"); + + String jwtSchemeName = "JWT TOKEN"; + // API 요청헤더에 인증정보 포함 + SecurityRequirement securityRequirement = new SecurityRequirement().addList(jwtSchemeName); + // SecuritySchemes 등록 + Components components = new Components() + .addSecuritySchemes(jwtSchemeName, new SecurityScheme() + .name(jwtSchemeName) + .type(SecurityScheme.Type.HTTP) // HTTP 방식 + .scheme("bearer") + .bearerFormat("JWT")); + + return new OpenAPI() + .addServersItem(new Server().url("/")) + .info(info) + .addSecurityItem(securityRequirement) + .components(components); + } +} \ No newline at end of file diff --git a/umc.mission/src/main/java/com/example/umc/mission/converter/MemberConverter.java b/umc.mission/src/main/java/com/example/umc/mission/converter/MemberConverter.java new file mode 100644 index 0000000..b274889 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/converter/MemberConverter.java @@ -0,0 +1,67 @@ +package com.example.umc.mission.converter; + +import com.example.umc.mission.domain.Member; +import com.example.umc.mission.domain.Mission; +import com.example.umc.mission.domain.enums.Gender; +import com.example.umc.mission.domain.mapping.MembersMission; +import com.example.umc.mission.web.dto.request.MemberRequestDTO; +import com.example.umc.mission.web.dto.response.MemberResponseDTO; +import com.example.umc.mission.web.dto.response.StoreResponseDTO; +import org.springframework.data.domain.Page; + +import java.util.ArrayList; +import java.util.List; + +public class MemberConverter { + + public static MemberResponseDTO.MissionPreViewListDTO toMissionPreReviewListDTO(Page missionList) { + List missionPreViewDTOList = missionList.stream() + .map(MemberConverter::toMissionPreReviewDTO).toList(); + + return MemberResponseDTO.MissionPreViewListDTO.builder() + .isFirst(missionList.isFirst()) + .isLast(missionList.isLast()) + .totalElements(missionList.getTotalElements()) + .totalPage(missionList.getTotalPages()) + .listSize(missionPreViewDTOList.size()) + .missionList(missionPreViewDTOList) + .build(); + } + + public static MemberResponseDTO.MissionPreViewDTO toMissionPreReviewDTO(MembersMission membersMission) { + return MemberResponseDTO.MissionPreViewDTO.builder() + .storeName(membersMission.getMission().getStore().getName()) + .cond(membersMission.getMission().getCond()) + .reward(membersMission.getMission().getReward()) + .status(membersMission.getStatus()) + .build(); + } + + + public static MemberResponseDTO.JoinResultDTO toJoinResultDTO(Member member){ + return MemberResponseDTO.JoinResultDTO.builder() + .memberId(member.getId()) + .build(); + } + + public static Member toMember(MemberRequestDTO.JoinDTO request){ + + Gender gender=null; + + switch (request.getGender()) { + case 1: + gender = Gender.MALE; + break; + case 2: + gender = Gender.FEMALE; + break; + } + + return Member.builder() + .address(request.getAddress()) + .gender(gender) + .name(request.getName()) + .preferrenceofFoodList(new ArrayList<>()) + .build(); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/converter/MissionConverter.java b/umc.mission/src/main/java/com/example/umc/mission/converter/MissionConverter.java new file mode 100644 index 0000000..d3fcd8d --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/converter/MissionConverter.java @@ -0,0 +1,54 @@ +package com.example.umc.mission.converter; + +import com.example.umc.mission.domain.Mission; +import com.example.umc.mission.domain.Review; +import com.example.umc.mission.domain.Store; +import com.example.umc.mission.web.dto.request.MissionRequestDTO; +import com.example.umc.mission.web.dto.response.MemberResponseDTO; +import com.example.umc.mission.web.dto.response.MissionResponseDTO; +import com.example.umc.mission.web.dto.response.StoreResponseDTO; +import org.springframework.data.domain.Page; + +import java.util.ArrayList; +import java.util.List; + +public class MissionConverter { + + public static StoreResponseDTO.MissionPreViewListDTO toMissionPreReviewListDTO(Page missionList) { + List missionPreViewDTOList = missionList.stream() + .map(MissionConverter::toMissionPreReviewDTO).toList(); + + return StoreResponseDTO.MissionPreViewListDTO.builder() + .isLast(missionList.isLast()) + .isFirst(missionList.isFirst()) + .totalPage(missionList.getTotalPages()) + .totalElements(missionList.getTotalElements()) + .listSize(missionPreViewDTOList.size()) + .missionList(missionPreViewDTOList) + .build(); + } + + public static StoreResponseDTO.MissionPreViewDTO toMissionPreReviewDTO(Mission mission) { + return StoreResponseDTO.MissionPreViewDTO.builder() + .storeName(mission.getStore().getName()) + .reward(mission.getReward()) + .cond(mission.getCond()) + .build(); + } + + public static MissionResponseDTO.addMissionResponseDTO toAddMissionResponseDTO(Mission mission) { + return MissionResponseDTO.addMissionResponseDTO.builder() + .mission_id(mission.getId()) + .store_id(mission.getStore().getId()) + .build(); + } + + public static Mission toMission(MissionRequestDTO.addMissionDTO request, Store store) { + return Mission.builder() + .store(store) + .name(request.getName()) + .cond(request.getCond()) + .reward(request.getReward()) + .build(); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/converter/PreferenceofFoodConverter.java b/umc.mission/src/main/java/com/example/umc/mission/converter/PreferenceofFoodConverter.java new file mode 100644 index 0000000..3f5180e --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/converter/PreferenceofFoodConverter.java @@ -0,0 +1,20 @@ +package com.example.umc.mission.converter; + +import com.example.umc.mission.domain.FoodCategory; +import com.example.umc.mission.domain.mapping.PreferrenceofFood; + +import java.util.List; +import java.util.stream.Collectors; + +public class PreferenceofFoodConverter { + + public static List toPreferList(List foodCategoryList){ + + return foodCategoryList.stream() + .map(foodCategory -> + PreferrenceofFood.builder() + .foodCategory(foodCategory) + .build() + ).collect(Collectors.toList()); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/converter/ReviewConverter.java b/umc.mission/src/main/java/com/example/umc/mission/converter/ReviewConverter.java new file mode 100644 index 0000000..a4fd398 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/converter/ReviewConverter.java @@ -0,0 +1,95 @@ +package com.example.umc.mission.converter; + +import com.example.umc.mission.domain.Member; +import com.example.umc.mission.domain.Review; +import com.example.umc.mission.domain.ReviewImage; +import com.example.umc.mission.domain.Store; +import com.example.umc.mission.web.dto.request.StoreRequestDTO; +import com.example.umc.mission.web.dto.response.MemberResponseDTO; +import com.example.umc.mission.web.dto.response.StoreResponseDTO; +import org.springframework.data.domain.Page; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class ReviewConverter { + + public static MemberResponseDTO.ReviewPreViewListDTO toMemberReviewListDTO(Page reviewList) { + + List reviewPreViewDTOList = reviewList.stream() + .map(ReviewConverter::toMemberReviewDTO).toList(); + + return MemberResponseDTO.ReviewPreViewListDTO.builder() + .isLast(reviewList.isLast()) + .isFirst(reviewList.isFirst()) + .totalPage(reviewList.getTotalPages()) + .totalElements(reviewList.getTotalElements()) + .listSize(reviewPreViewDTOList.size()) + .reviewList(reviewPreViewDTOList) + .build(); + } + + public static MemberResponseDTO.ReviewPreViewDTO toMemberReviewDTO(Review review) { + return MemberResponseDTO.ReviewPreViewDTO.builder() + .storeName(review.getStore().getName()) + .starPoint(review.getStarPoint()) + .content(review.getContent()) + .build(); + } + + public static StoreResponseDTO.ReviewPreViewListDTO toReviewPreViewListDTO(Page reviewList) { + + List reviewPreViewDTOList = reviewList.stream() + .map(ReviewConverter::toReviewPreViewDTO).collect(Collectors.toList()); + + return StoreResponseDTO.ReviewPreViewListDTO.builder() + .isLast(reviewList.isLast()) + .isFirst(reviewList.isFirst()) + .totalPage(reviewList.getTotalPages()) + .totalElements(reviewList.getTotalElements()) + .listSize(reviewPreViewDTOList.size()) + .reviewList(reviewPreViewDTOList) + .build(); + } + + public static StoreResponseDTO.ReviewPreViewDTO toReviewPreViewDTO(Review review){ + return StoreResponseDTO.ReviewPreViewDTO.builder() + .ownerNickname(review.getMember().getName()) + .starPoint(review.getStarPoint()) + .content(review.getContent()) + .build(); + } + + public static StoreResponseDTO.reviewResponseDTO toReviewResponseDTO(Review review) { + return StoreResponseDTO.reviewResponseDTO.builder() + .review_id(review.getId()) + .store_id(review.getStore().getId()) + .member_id(review.getMember().getId()) + .build(); + } + + public static Review toReivew(StoreRequestDTO.postReviewDTO request, Store store, Member member){ + return Review.builder() + .title(request.getTitle()) + .content(request.getContent()) + .starPoint(request.getStarPoint()) + .store(store) + .member(member) + .build(); + } + + public static ReviewImage toReviewImage(String pictureUrl, Review review){ + return ReviewImage.builder() + .review(review) + .pictureUrl(pictureUrl) + .build(); + } + + public static StoreResponseDTO.DeleteReviewDTO toDeleteReviewDTO(Long storeId){ + return StoreResponseDTO.DeleteReviewDTO.builder() + .storeId(storeId) + .text("해당 리뷰가 삭제되었습니다.") + .build(); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/converter/StoreConverter.java b/umc.mission/src/main/java/com/example/umc/mission/converter/StoreConverter.java new file mode 100644 index 0000000..bb78d38 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/converter/StoreConverter.java @@ -0,0 +1,43 @@ +package com.example.umc.mission.converter; + +import com.example.umc.mission.domain.*; +import com.example.umc.mission.domain.enums.MissionStatus; +import com.example.umc.mission.domain.mapping.MembersMission; +import com.example.umc.mission.web.dto.request.StoreRequestDTO; +import com.example.umc.mission.web.dto.response.StoreResponseDTO; + +public class StoreConverter { + + public static StoreResponseDTO.addStoreResponseDTO toAddStoreResponseDTO(Store store) { + return StoreResponseDTO.addStoreResponseDTO.builder() + .store_id(store.getId()) + .store_name(store.getName()) + .build(); + } + + public static Store toStore(StoreRequestDTO.addStoreDTO request, Region region){ + return Store.builder() + .name(request.getName()) + .address(request.getAddress()) + .phone(request.getPhone()) + .region(region) + .build(); + + } + + public static MembersMission toMembersMission(Member member, Mission mission){ + return MembersMission.builder() + .member(member) + .mission(mission) + .status(MissionStatus.CHALLENGING) + .build(); + } + + public static StoreResponseDTO.ChallengeResponseDTO toChallengeResponseDTO(MembersMission challenge) { + return StoreResponseDTO.ChallengeResponseDTO.builder() + .challengeId(challenge.getId()) + .missionId(challenge.getMission().getId()) + .memberId(challenge.getMember().getId()) + .build(); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/converter/TempConverter.java b/umc.mission/src/main/java/com/example/umc/mission/converter/TempConverter.java new file mode 100644 index 0000000..78522a1 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/converter/TempConverter.java @@ -0,0 +1,18 @@ +package com.example.umc.mission.converter; + +import com.example.umc.mission.web.dto.response.TempResponse; + +public class TempConverter { + + public static TempResponse.TempTestDTO toTempTestDTO() { + return TempResponse.TempTestDTO.builder() + .testString("This is Test!") + .build(); + } + + public static TempResponse.TempExceptionDTO toTempExceptionDTO(Integer flag) { + return TempResponse.TempExceptionDTO.builder() + .flag(flag) + .build(); + } +} \ No newline at end of file diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/AgreeService.java b/umc.mission/src/main/java/com/example/umc/mission/domain/AgreeService.java new file mode 100644 index 0000000..6d0d551 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/AgreeService.java @@ -0,0 +1,29 @@ +package com.example.umc.mission.domain; + +import com.example.umc.mission.domain.mapping.Agreement; +import jakarta.persistence.*; +import lombok.*; + +import javax.swing.table.TableCellEditor; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class AgreeService { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, length = 20, unique = true) + private String name; + + @OneToMany(mappedBy = "agreeService", cascade = CascadeType.ALL) + private List agreementList = new ArrayList<>(); + + +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/FoodCategory.java b/umc.mission/src/main/java/com/example/umc/mission/domain/FoodCategory.java new file mode 100644 index 0000000..aa3ee75 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/FoodCategory.java @@ -0,0 +1,27 @@ +package com.example.umc.mission.domain; + +import com.example.umc.mission.domain.mapping.PreferrenceofFood; +import jakarta.persistence.*; +import lombok.*; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class FoodCategory { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, length = 20, unique = true) + private String name; + + @OneToMany(mappedBy = "foodCategory", cascade = CascadeType.ALL) + private List preferrenceofFoodList = new ArrayList<>(); + +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/Member.java b/umc.mission/src/main/java/com/example/umc/mission/domain/Member.java new file mode 100644 index 0000000..6cd5a10 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/Member.java @@ -0,0 +1,68 @@ +package com.example.umc.mission.domain; + +import com.example.umc.mission.domain.enums.Gender; +import com.example.umc.mission.domain.enums.MemberStatus; +import com.example.umc.mission.domain.enums.SocialType; +import com.example.umc.mission.domain.mapping.Agreement; +import com.example.umc.mission.domain.mapping.MembersMission; +import com.example.umc.mission.domain.mapping.PreferrenceofFood; +import jakarta.persistence.*; +import lombok.*; +import org.hibernate.annotations.ColumnDefault; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@DynamicUpdate +@DynamicInsert +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class Member { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, length = 20, unique = true) + private String name; + + @Column(nullable = false, length = 50) + private String address; + + @Enumerated(EnumType.STRING) + @Column(columnDefinition = "VARCHAR(10)") + private Gender gender; + + @Enumerated(EnumType.STRING) + private SocialType socialType; + + private LocalDate birthDate; + + @Enumerated(EnumType.STRING) + @Column(columnDefinition = "VARCHAR(15) DEFAULT 'ACTIVE'") + private MemberStatus status; + + private LocalDate inactiveDate; + + @ColumnDefault("0") + private Integer point; + + @OneToMany(mappedBy = "member", cascade = CascadeType.ALL) + private List agreementList = new ArrayList<>(); + + @OneToMany(mappedBy = "member",cascade = CascadeType.ALL) + private List preferrenceofFoodList = new ArrayList<>(); + + @OneToMany(mappedBy = "member",cascade = CascadeType.ALL) + private List membersMissionList = new ArrayList<>(); + + @OneToMany(mappedBy = "member",cascade = CascadeType.ALL) + private List reviewList = new ArrayList<>(); + +} \ No newline at end of file diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/Mission.java b/umc.mission/src/main/java/com/example/umc/mission/domain/Mission.java new file mode 100644 index 0000000..3b987f1 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/Mission.java @@ -0,0 +1,42 @@ +package com.example.umc.mission.domain; + +import com.example.umc.mission.domain.enums.MissionStatus; +import com.example.umc.mission.domain.mapping.MembersMission; +import jakarta.persistence.*; +import lombok.*; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@DynamicUpdate +@DynamicInsert +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class Mission { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String name; + + @Column(nullable = false, length = 50) + private String cond; + + @Column(nullable = false) + private Integer reward; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "store_id") + private Store store; + + @OneToMany(mappedBy = "mission") + private List membersMissionList = new ArrayList<>(); + +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/Region.java b/umc.mission/src/main/java/com/example/umc/mission/domain/Region.java new file mode 100644 index 0000000..82cd2eb --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/Region.java @@ -0,0 +1,25 @@ +package com.example.umc.mission.domain; + +import jakarta.persistence.*; +import lombok.*; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class Region { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, length = 20, unique = true) + private String name; + + @OneToMany(mappedBy = "region", cascade = CascadeType.ALL) + private List StoreList = new ArrayList<>(); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/Review.java b/umc.mission/src/main/java/com/example/umc/mission/domain/Review.java new file mode 100644 index 0000000..82a1d58 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/Review.java @@ -0,0 +1,44 @@ +package com.example.umc.mission.domain; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import lombok.*; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Review { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, length = 20) + private String title; + + @Column(nullable = false, length = 200) + private String content; + + @Column(nullable = false) + @Min(0) + @Max(5) + private Integer starPoint; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "store_id") + private Store store; + + @OneToOne(mappedBy = "review",fetch = FetchType.LAZY,cascade = CascadeType.ALL) + private ReviewImage reviewImage; + +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/ReviewImage.java b/umc.mission/src/main/java/com/example/umc/mission/domain/ReviewImage.java new file mode 100644 index 0000000..240e366 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/ReviewImage.java @@ -0,0 +1,22 @@ +package com.example.umc.mission.domain; + +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ReviewImage { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String pictureUrl; + + @OneToOne + @JoinColumn(name = "review_id") + private Review review; +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/Store.java b/umc.mission/src/main/java/com/example/umc/mission/domain/Store.java new file mode 100644 index 0000000..310fd08 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/Store.java @@ -0,0 +1,40 @@ +package com.example.umc.mission.domain; + +import jakarta.persistence.*; +import lombok.*; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class Store { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, length = 20) + private String name; + + @Column(nullable = false, length = 50) + private String address; + + @Column(nullable = false, length = 15) + private String phone; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "region_id") + private Region region; + + //review 리스트 + @OneToMany(mappedBy = "store", cascade = CascadeType.ALL) + private List reviewList = new ArrayList<>(); + + //mission 리스트 + @OneToMany(mappedBy = "store", cascade = CascadeType.ALL) + private List missionList = new ArrayList<>(); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/Uuid.java b/umc.mission/src/main/java/com/example/umc/mission/domain/Uuid.java new file mode 100644 index 0000000..141b4ff --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/Uuid.java @@ -0,0 +1,19 @@ +package com.example.umc.mission.domain; + +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Builder +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Uuid{ + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(unique = true) + private String uuid; +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/enums/Gender.java b/umc.mission/src/main/java/com/example/umc/mission/domain/enums/Gender.java new file mode 100644 index 0000000..b0e4470 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/enums/Gender.java @@ -0,0 +1,5 @@ +package com.example.umc.mission.domain.enums; + +public enum Gender { + MALE, FEMALE +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/enums/MemberStatus.java b/umc.mission/src/main/java/com/example/umc/mission/domain/enums/MemberStatus.java new file mode 100644 index 0000000..a51e6b5 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/enums/MemberStatus.java @@ -0,0 +1,5 @@ +package com.example.umc.mission.domain.enums; + +public enum MemberStatus { + ACTIVE, INACTIVE +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/enums/MissionStatus.java b/umc.mission/src/main/java/com/example/umc/mission/domain/enums/MissionStatus.java new file mode 100644 index 0000000..2e4c61b --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/enums/MissionStatus.java @@ -0,0 +1,5 @@ +package com.example.umc.mission.domain.enums; + +public enum MissionStatus { + COMPLETE, CHALLENGING, INCOMPLETE +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/enums/SocialType.java b/umc.mission/src/main/java/com/example/umc/mission/domain/enums/SocialType.java new file mode 100644 index 0000000..96e416b --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/enums/SocialType.java @@ -0,0 +1,5 @@ +package com.example.umc.mission.domain.enums; + +public enum SocialType { + KAKAO, NAVER, GOOGLE, APPLE +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/mapping/Agreement.java b/umc.mission/src/main/java/com/example/umc/mission/domain/mapping/Agreement.java new file mode 100644 index 0000000..296d58e --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/mapping/Agreement.java @@ -0,0 +1,26 @@ +package com.example.umc.mission.domain.mapping; + +import com.example.umc.mission.domain.AgreeService; +import com.example.umc.mission.domain.Member; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class Agreement { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "agreeService_id") + private AgreeService agreeService; +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/mapping/MembersMission.java b/umc.mission/src/main/java/com/example/umc/mission/domain/mapping/MembersMission.java new file mode 100644 index 0000000..805f958 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/mapping/MembersMission.java @@ -0,0 +1,31 @@ +package com.example.umc.mission.domain.mapping; + +import com.example.umc.mission.domain.Member; +import com.example.umc.mission.domain.Mission; +import com.example.umc.mission.domain.enums.MissionStatus; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class MembersMission { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Enumerated(EnumType.STRING) + @Column(columnDefinition = "VARCHAR(15) DEFAULT 'CHALLENGING'") + private MissionStatus status; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "mission_id") + private Mission mission; +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/domain/mapping/PreferrenceofFood.java b/umc.mission/src/main/java/com/example/umc/mission/domain/mapping/PreferrenceofFood.java new file mode 100644 index 0000000..076f50e --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/domain/mapping/PreferrenceofFood.java @@ -0,0 +1,38 @@ +package com.example.umc.mission.domain.mapping; + +import com.example.umc.mission.domain.FoodCategory; +import com.example.umc.mission.domain.Member; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Builder +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class PreferrenceofFood { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "foodCategory_id") + private FoodCategory foodCategory; + + public void setMember(Member member){ + if(this.member != null) + member.getPreferrenceofFoodList().remove(this); + this.member = member; + member.getPreferrenceofFoodList().add(this); + } + + public void setFoodCategory(FoodCategory foodCategory){ + this.foodCategory = foodCategory; + } + +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/repository/FoodCategoryRepository.java b/umc.mission/src/main/java/com/example/umc/mission/repository/FoodCategoryRepository.java new file mode 100644 index 0000000..49964d6 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/repository/FoodCategoryRepository.java @@ -0,0 +1,7 @@ +package com.example.umc.mission.repository; + +import com.example.umc.mission.domain.FoodCategory; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface FoodCategoryRepository extends JpaRepository { +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/repository/MemberRepository.java b/umc.mission/src/main/java/com/example/umc/mission/repository/MemberRepository.java new file mode 100644 index 0000000..6ec9335 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/repository/MemberRepository.java @@ -0,0 +1,7 @@ +package com.example.umc.mission.repository; + +import com.example.umc.mission.domain.Member; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MemberRepository extends JpaRepository { +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/repository/MembersMissionRepository.java b/umc.mission/src/main/java/com/example/umc/mission/repository/MembersMissionRepository.java new file mode 100644 index 0000000..13b156f --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/repository/MembersMissionRepository.java @@ -0,0 +1,14 @@ +package com.example.umc.mission.repository; + +import com.example.umc.mission.domain.Member; +import com.example.umc.mission.domain.Mission; +import com.example.umc.mission.domain.mapping.MembersMission; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MembersMissionRepository extends JpaRepository { + boolean existsByMissionAndMember(Mission mission, Member member); + MembersMission findByMissionAndMember(Mission mission, Member member); + Page findAllByMember(Member member, PageRequest pageRequest); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/repository/MissionRepository.java b/umc.mission/src/main/java/com/example/umc/mission/repository/MissionRepository.java new file mode 100644 index 0000000..90ee9d9 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/repository/MissionRepository.java @@ -0,0 +1,12 @@ +package com.example.umc.mission.repository; + +import com.example.umc.mission.domain.Mission; +import com.example.umc.mission.domain.Store; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MissionRepository extends JpaRepository { + + Page findAllByStore(Store store, PageRequest pageRequest); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/repository/RegionRepository.java b/umc.mission/src/main/java/com/example/umc/mission/repository/RegionRepository.java new file mode 100644 index 0000000..30e22a5 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/repository/RegionRepository.java @@ -0,0 +1,11 @@ +package com.example.umc.mission.repository; + +import com.example.umc.mission.domain.Region; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface RegionRepository extends JpaRepository { + + Optional findByName(String name); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/repository/ReviewImageRepository.java b/umc.mission/src/main/java/com/example/umc/mission/repository/ReviewImageRepository.java new file mode 100644 index 0000000..243dfd2 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/repository/ReviewImageRepository.java @@ -0,0 +1,7 @@ +package com.example.umc.mission.repository; + +import com.example.umc.mission.domain.ReviewImage; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ReviewImageRepository extends JpaRepository { +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/repository/ReviewRepository.java b/umc.mission/src/main/java/com/example/umc/mission/repository/ReviewRepository.java new file mode 100644 index 0000000..990cf5d --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/repository/ReviewRepository.java @@ -0,0 +1,15 @@ +package com.example.umc.mission.repository; + +import com.example.umc.mission.domain.Member; +import com.example.umc.mission.domain.Review; +import com.example.umc.mission.domain.Store; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ReviewRepository extends JpaRepository { + + Page findAllByStore(Store store, PageRequest pageRequest); + + Page findAllByMember(Member member, PageRequest pageRequest); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/repository/StoreRepository.java b/umc.mission/src/main/java/com/example/umc/mission/repository/StoreRepository.java new file mode 100644 index 0000000..457bfe1 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/repository/StoreRepository.java @@ -0,0 +1,7 @@ +package com.example.umc.mission.repository; + +import com.example.umc.mission.domain.Store; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface StoreRepository extends JpaRepository { +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/repository/UuidRepository.java b/umc.mission/src/main/java/com/example/umc/mission/repository/UuidRepository.java new file mode 100644 index 0000000..a5433f4 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/repository/UuidRepository.java @@ -0,0 +1,7 @@ +package com.example.umc.mission.repository; + +import com.example.umc.mission.domain.Uuid; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UuidRepository extends JpaRepository { +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/MemberService/MemberCommandService.java b/umc.mission/src/main/java/com/example/umc/mission/service/MemberService/MemberCommandService.java new file mode 100644 index 0000000..f344fb8 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/MemberService/MemberCommandService.java @@ -0,0 +1,9 @@ +package com.example.umc.mission.service.MemberService; + +import com.example.umc.mission.domain.Member; +import com.example.umc.mission.web.dto.request.MemberRequestDTO; + +public interface MemberCommandService { + + public Member joinMember(MemberRequestDTO.JoinDTO request); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/MemberService/MemberCommandsServiceImpl.java b/umc.mission/src/main/java/com/example/umc/mission/service/MemberService/MemberCommandsServiceImpl.java new file mode 100644 index 0000000..9e28e10 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/MemberService/MemberCommandsServiceImpl.java @@ -0,0 +1,45 @@ +package com.example.umc.mission.service.MemberService; + +import com.example.umc.mission.apiPayload.code.status.ErrorStatus; +import com.example.umc.mission.apiPayload.exception.handler.FoodCategoryHandler; +import com.example.umc.mission.converter.MemberConverter; +import com.example.umc.mission.converter.PreferenceofFoodConverter; +import com.example.umc.mission.domain.FoodCategory; +import com.example.umc.mission.domain.Member; +import com.example.umc.mission.domain.mapping.PreferrenceofFood; +import com.example.umc.mission.repository.FoodCategoryRepository; +import com.example.umc.mission.repository.MemberRepository; +import com.example.umc.mission.web.dto.request.MemberRequestDTO; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class MemberCommandsServiceImpl implements MemberCommandService{ + + private final MemberRepository memberRepository; + + private final FoodCategoryRepository foodCategoryRepository; + + @Override + @Transactional + public Member joinMember(MemberRequestDTO.JoinDTO request){ + + Member newMember = MemberConverter.toMember(request); + List foodCategoryList = request.getPreferCategory().stream() + .map(category -> { + return foodCategoryRepository.findById(category).orElseThrow(() -> new FoodCategoryHandler(ErrorStatus.FOOD_CATEGORY_NOT_FOUND)); + }).collect(Collectors.toList()); + + List preferrenceofFoodList = PreferenceofFoodConverter.toPreferList(foodCategoryList); + + preferrenceofFoodList.forEach(preferrenceofFood -> {preferrenceofFood.setMember(newMember);}); + + return memberRepository.save(newMember); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/MemberService/MemberQueryService.java b/umc.mission/src/main/java/com/example/umc/mission/service/MemberService/MemberQueryService.java new file mode 100644 index 0000000..7287266 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/MemberService/MemberQueryService.java @@ -0,0 +1,12 @@ +package com.example.umc.mission.service.MemberService; + +import com.example.umc.mission.domain.Review; +import com.example.umc.mission.domain.mapping.MembersMission; +import org.springframework.data.domain.Page; + +public interface MemberQueryService { + + Page getChallengingMissionList(Long memberId, Integer page); + + Page getReviewList(Long MemberId, Integer page); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/MemberService/MemberQueryServiceImpl.java b/umc.mission/src/main/java/com/example/umc/mission/service/MemberService/MemberQueryServiceImpl.java new file mode 100644 index 0000000..cf4c8a5 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/MemberService/MemberQueryServiceImpl.java @@ -0,0 +1,42 @@ +package com.example.umc.mission.service.MemberService; + +import com.example.umc.mission.apiPayload.code.status.ErrorStatus; +import com.example.umc.mission.apiPayload.exception.handler.MemberHandler; +import com.example.umc.mission.domain.Member; +import com.example.umc.mission.domain.Review; +import com.example.umc.mission.domain.mapping.MembersMission; +import com.example.umc.mission.repository.MemberRepository; +import com.example.umc.mission.repository.MembersMissionRepository; +import com.example.umc.mission.repository.ReviewRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class MemberQueryServiceImpl implements MemberQueryService{ + + private final MemberRepository memberRepository; + + private final ReviewRepository reviewRepository; + + private final MembersMissionRepository membersMissionRepository; + + @Override + public Page getReviewList(Long MemberId, Integer page){ + Member member = memberRepository.findById(MemberId).get(); + + Page MemberPage = reviewRepository.findAllByMember(member, PageRequest.of(page, 10)); + return MemberPage; + } + + @Override + public Page getChallengingMissionList(Long memberId, Integer page){ + Member member = memberRepository.findById(memberId) + .orElseThrow(()->new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND)); + Page missionPage = membersMissionRepository.findAllByMember(member, PageRequest.of(page, 10)); + return missionPage; + } + +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/MissionService/MissionCommandService.java b/umc.mission/src/main/java/com/example/umc/mission/service/MissionService/MissionCommandService.java new file mode 100644 index 0000000..5d8a13f --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/MissionService/MissionCommandService.java @@ -0,0 +1,16 @@ +package com.example.umc.mission.service.MissionService; + +import com.example.umc.mission.domain.Mission; +import com.example.umc.mission.domain.enums.MissionStatus; +import com.example.umc.mission.domain.mapping.MembersMission; +import com.example.umc.mission.web.dto.request.MissionRequestDTO; +import com.example.umc.mission.web.dto.request.StoreRequestDTO; + +public interface MissionCommandService { + + public Mission saveMission(MissionRequestDTO.addMissionDTO request); + + public MembersMission saveChallenge(StoreRequestDTO.postChallengeDTO request); + + public boolean existOfMission(Long missionId); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/MissionService/MissionCommandServiceImpl.java b/umc.mission/src/main/java/com/example/umc/mission/service/MissionService/MissionCommandServiceImpl.java new file mode 100644 index 0000000..408ec82 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/MissionService/MissionCommandServiceImpl.java @@ -0,0 +1,54 @@ +package com.example.umc.mission.service.MissionService; + +import com.example.umc.mission.apiPayload.code.status.ErrorStatus; +import com.example.umc.mission.apiPayload.exception.handler.MemberHandler; +import com.example.umc.mission.apiPayload.exception.handler.MissionHandler; +import com.example.umc.mission.apiPayload.exception.handler.StoreHandler; +import com.example.umc.mission.converter.MissionConverter; +import com.example.umc.mission.converter.StoreConverter; +import com.example.umc.mission.domain.Member; +import com.example.umc.mission.domain.Mission; +import com.example.umc.mission.domain.Store; +import com.example.umc.mission.domain.enums.MissionStatus; +import com.example.umc.mission.domain.mapping.MembersMission; +import com.example.umc.mission.repository.MemberRepository; +import com.example.umc.mission.repository.MembersMissionRepository; +import com.example.umc.mission.repository.MissionRepository; +import com.example.umc.mission.repository.StoreRepository; +import com.example.umc.mission.web.dto.request.MissionRequestDTO; +import com.example.umc.mission.web.dto.request.StoreRequestDTO; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class MissionCommandServiceImpl implements MissionCommandService { + + private final MissionRepository missionRepository; + + private final StoreRepository storeRepository; + + private final MemberRepository memberRepository; + + private final MembersMissionRepository membersMissionRepository; + + public Mission saveMission(MissionRequestDTO.addMissionDTO request){ + Store store = storeRepository.findById(request.getStoreId()).orElseThrow(()->new StoreHandler(ErrorStatus.STORE_NOT_FOUND)); + Mission newmission = MissionConverter.toMission(request, store); + + return missionRepository.save(newmission); + } + + public MembersMission saveChallenge(StoreRequestDTO.postChallengeDTO request){ + Member member = memberRepository.findById(request.getMemberId()) + .orElseThrow(()-> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND)); + Mission mission = missionRepository.findById(request.getMissionId()) + .orElseThrow(()-> new MissionHandler(ErrorStatus.MISSION_NOT_FOUND)); + + return membersMissionRepository.save(StoreConverter.toMembersMission(member,mission)); + } + + public boolean existOfMission(Long missionId){ + return missionRepository.existsById(missionId); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/MissionService/MissionQueryService.java b/umc.mission/src/main/java/com/example/umc/mission/service/MissionService/MissionQueryService.java new file mode 100644 index 0000000..90b9c19 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/MissionService/MissionQueryService.java @@ -0,0 +1,14 @@ +package com.example.umc.mission.service.MissionService; + +import com.example.umc.mission.domain.Mission; +import com.example.umc.mission.domain.mapping.MembersMission; +import org.springframework.data.domain.Page; + +public interface MissionQueryService { + + MembersMission getMembersMission(Long missionId, Long memberId); + + boolean checkMembersMission(Long missionId, Long memberId); + + Page getMissions(Long StoreId, Integer page); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/MissionService/MissionQueryServiceImpl.java b/umc.mission/src/main/java/com/example/umc/mission/service/MissionService/MissionQueryServiceImpl.java new file mode 100644 index 0000000..378fdcb --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/MissionService/MissionQueryServiceImpl.java @@ -0,0 +1,58 @@ +package com.example.umc.mission.service.MissionService; + +import com.example.umc.mission.apiPayload.code.status.ErrorStatus; +import com.example.umc.mission.apiPayload.exception.handler.MemberHandler; +import com.example.umc.mission.apiPayload.exception.handler.MissionHandler; +import com.example.umc.mission.apiPayload.exception.handler.StoreHandler; +import com.example.umc.mission.domain.Member; +import com.example.umc.mission.domain.Mission; +import com.example.umc.mission.domain.Store; +import com.example.umc.mission.domain.mapping.MembersMission; +import com.example.umc.mission.repository.MemberRepository; +import com.example.umc.mission.repository.MembersMissionRepository; +import com.example.umc.mission.repository.MissionRepository; +import com.example.umc.mission.repository.StoreRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class MissionQueryServiceImpl implements MissionQueryService{ + + private final MissionRepository missionRepository; + + private final StoreRepository storeRepository; + + private final MembersMissionRepository membersMissionRepository; + + private final MemberRepository memberRepository; + + @Override + public Page getMissions(Long StoreId, Integer page){ + Store store = storeRepository.findById(StoreId) + .orElseThrow(()->new StoreHandler(ErrorStatus.STORE_NOT_FOUND)); + return missionRepository.findAllByStore(store, PageRequest.of(page,10)); + } + + + @Override + public boolean checkMembersMission(Long missionId, Long memberId){ + Member member = memberRepository.findById(memberId) + .orElseThrow(()->new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND)); + Mission mission = missionRepository.findById(missionId) + .orElseThrow(()->new MissionHandler(ErrorStatus.MISSION_NOT_FOUND)); + return membersMissionRepository.existsByMissionAndMember(mission, member); + } + + @Override + public MembersMission getMembersMission(Long missionId, Long memberId){ + Member member = memberRepository.findById(memberId) + .orElseThrow(()->new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND)); + Mission mission = missionRepository.findById(missionId) + .orElseThrow(()->new MissionHandler(ErrorStatus.MISSION_NOT_FOUND)); + return membersMissionRepository.findByMissionAndMember(mission, member); + } + +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/ReviewService/ReviewCommandService.java b/umc.mission/src/main/java/com/example/umc/mission/service/ReviewService/ReviewCommandService.java new file mode 100644 index 0000000..1626b66 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/ReviewService/ReviewCommandService.java @@ -0,0 +1,12 @@ +package com.example.umc.mission.service.ReviewService; + +import com.example.umc.mission.domain.Review; +import com.example.umc.mission.web.dto.request.StoreRequestDTO; +import org.springframework.web.multipart.MultipartFile; + +public interface ReviewCommandService { + + public Review saveReview(StoreRequestDTO.postReviewDTO request, MultipartFile reviewPicture); + + public Long deleteReview(Long reviewId); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/ReviewService/ReviewCommandServiceImpl.java b/umc.mission/src/main/java/com/example/umc/mission/service/ReviewService/ReviewCommandServiceImpl.java new file mode 100644 index 0000000..e07a6df --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/ReviewService/ReviewCommandServiceImpl.java @@ -0,0 +1,64 @@ +package com.example.umc.mission.service.ReviewService; + +import com.example.umc.mission.apiPayload.code.status.ErrorStatus; +import com.example.umc.mission.apiPayload.exception.handler.MemberHandler; +import com.example.umc.mission.apiPayload.exception.handler.StoreHandler; +import com.example.umc.mission.aws.s3.AmazonS3Manager; +import com.example.umc.mission.converter.ReviewConverter; +import com.example.umc.mission.domain.Member; +import com.example.umc.mission.domain.Review; +import com.example.umc.mission.domain.Store; +import com.example.umc.mission.domain.Uuid; +import com.example.umc.mission.repository.*; +import com.example.umc.mission.web.dto.request.StoreRequestDTO; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.UUID; + +@Service +@Transactional +@RequiredArgsConstructor +public class ReviewCommandServiceImpl implements ReviewCommandService{ + + private final MemberRepository memberRepository; + + private final ReviewRepository reviewRepository; + + private final StoreRepository storeRepository; + + private final AmazonS3Manager s3Manager; + + private final UuidRepository uuidRepository; + + private final ReviewImageRepository reviewImageRepository; + + public Review saveReview(StoreRequestDTO.postReviewDTO request, MultipartFile reviewPicture){ + + Store store = storeRepository.findById(request.getStoreId()).orElseThrow(()->new StoreHandler(ErrorStatus.STORE_NOT_FOUND)); + Member member =memberRepository.findById(request.getUserId()).orElseThrow(()->new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND)); + Review newReview = ReviewConverter.toReivew(request, store, member); + + String uuid = UUID.randomUUID().toString(); + Uuid saveUuid = uuidRepository.save(Uuid.builder() + .uuid(uuid).build()); + + String pictureUrl = s3Manager.uploadFile(s3Manager.generateReviewKeyName(saveUuid), reviewPicture); + + + reviewImageRepository.save(ReviewConverter.toReviewImage(pictureUrl,newReview)); + return reviewRepository.save(newReview); + } + + public Long deleteReview(Long reviewId){ + + Review review = reviewRepository.findById(reviewId).orElseThrow(()->new StoreHandler(ErrorStatus.REVIEW_NOT_FOUND)); + s3Manager.deleteImage(review.getReviewImage().getPictureUrl()); + + Long storeId = review.getStore().getId(); + reviewRepository.delete(review); + return storeId; + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/StoreService/StoreCommandService.java b/umc.mission/src/main/java/com/example/umc/mission/service/StoreService/StoreCommandService.java new file mode 100644 index 0000000..3d4b591 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/StoreService/StoreCommandService.java @@ -0,0 +1,9 @@ +package com.example.umc.mission.service.StoreService; + +import com.example.umc.mission.domain.Store; +import com.example.umc.mission.web.dto.request.StoreRequestDTO; + +public interface StoreCommandService { + + public Store saveStore(StoreRequestDTO.addStoreDTO request); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/StoreService/StoreCommandServiceImpl.java b/umc.mission/src/main/java/com/example/umc/mission/service/StoreService/StoreCommandServiceImpl.java new file mode 100644 index 0000000..4a7132c --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/StoreService/StoreCommandServiceImpl.java @@ -0,0 +1,30 @@ +package com.example.umc.mission.service.StoreService; + +import com.example.umc.mission.apiPayload.code.status.ErrorStatus; +import com.example.umc.mission.apiPayload.exception.handler.RegionHandler; +import com.example.umc.mission.converter.StoreConverter; +import com.example.umc.mission.domain.Region; +import com.example.umc.mission.domain.Store; +import com.example.umc.mission.repository.RegionRepository; +import com.example.umc.mission.repository.StoreRepository; +import com.example.umc.mission.web.dto.request.StoreRequestDTO; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class StoreCommandServiceImpl implements StoreCommandService{ + + private final StoreRepository storeRepository; + + private final RegionRepository regionRepository; + + public Store saveStore(StoreRequestDTO.addStoreDTO request){ + + Region region = regionRepository.findByName(request.getRegionName()).orElseThrow(() -> new RegionHandler(ErrorStatus.REGION_NOT_FOUND)); + Store newStore = StoreConverter.toStore(request, region); + + return storeRepository.save(newStore); + + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/StoreService/StoreQueryService.java b/umc.mission/src/main/java/com/example/umc/mission/service/StoreService/StoreQueryService.java new file mode 100644 index 0000000..15e9cbc --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/StoreService/StoreQueryService.java @@ -0,0 +1,14 @@ +package com.example.umc.mission.service.StoreService; + +import com.example.umc.mission.domain.Review; +import com.example.umc.mission.domain.Store; +import org.springframework.data.domain.Page; + +import java.util.Optional; + +public interface StoreQueryService { + + Optional findStore(Long id); + + Page getReviewList(Long StoreId, Integer page); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/StoreService/StoreQueryServiceImpl.java b/umc.mission/src/main/java/com/example/umc/mission/service/StoreService/StoreQueryServiceImpl.java new file mode 100644 index 0000000..ff06302 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/StoreService/StoreQueryServiceImpl.java @@ -0,0 +1,36 @@ +package com.example.umc.mission.service.StoreService; + +import com.example.umc.mission.domain.Review; +import com.example.umc.mission.domain.Store; +import com.example.umc.mission.repository.*; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class StoreQueryServiceImpl implements StoreQueryService{ + + private final StoreRepository storeRepository; + + private final ReviewRepository reviewRepository; + + @Override + public Page getReviewList(Long StoreId, Integer page){ + + Store store = storeRepository.findById(StoreId).get(); + + Page StorePage = reviewRepository.findAllByStore(store, PageRequest.of(page, 2)); + return StorePage; + } + + @Override + public Optional findStore(Long id){ + return storeRepository.findById(id); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/TempService/TempCommandService.java b/umc.mission/src/main/java/com/example/umc/mission/service/TempService/TempCommandService.java new file mode 100644 index 0000000..691ff4d --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/TempService/TempCommandService.java @@ -0,0 +1,4 @@ +package com.example.umc.mission.service.TempService; + +public interface TempCommandService { +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/TempService/TempCommandServiceImpl.java b/umc.mission/src/main/java/com/example/umc/mission/service/TempService/TempCommandServiceImpl.java new file mode 100644 index 0000000..009a1c9 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/TempService/TempCommandServiceImpl.java @@ -0,0 +1,9 @@ +package com.example.umc.mission.service.TempService; + +public class TempCommandServiceImpl implements TempQueryService{ + + @Override + public void CheckFlag(Integer flag){ + + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/TempService/TempQueryService.java b/umc.mission/src/main/java/com/example/umc/mission/service/TempService/TempQueryService.java new file mode 100644 index 0000000..2c8936a --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/TempService/TempQueryService.java @@ -0,0 +1,6 @@ +package com.example.umc.mission.service.TempService; + +public interface TempQueryService { + + void CheckFlag(Integer flag); +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/service/TempService/TempQueryServiceImpl.java b/umc.mission/src/main/java/com/example/umc/mission/service/TempService/TempQueryServiceImpl.java new file mode 100644 index 0000000..a42da93 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/service/TempService/TempQueryServiceImpl.java @@ -0,0 +1,18 @@ +package com.example.umc.mission.service.TempService; + +import com.example.umc.mission.apiPayload.code.status.ErrorStatus; +import com.example.umc.mission.apiPayload.exception.handler.TempHandler; +import com.example.umc.mission.service.TempService.TempQueryService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class TempQueryServiceImpl implements TempQueryService { + + @Override + public void CheckFlag(Integer flag){ + if(flag==1) + throw new TempHandler(ErrorStatus.TEMP_EXCEPTION); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/validation/ValidationAspect.java b/umc.mission/src/main/java/com/example/umc/mission/validation/ValidationAspect.java new file mode 100644 index 0000000..cf16c99 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/validation/ValidationAspect.java @@ -0,0 +1,24 @@ +package com.example.umc.mission.validation; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +@Aspect +@Component +public class ValidationAspect { + + //@Around("execution(* com.example.umc.mission.web.controller.MemberRestController.*(..)) && args(..,@com.example.umc.mission.validation.annotation.CheckPage(*)))") + /*public Object around(ProceedingJoinPoint joinPoint) throws Throwable { + //값 변경 로직 구현 + Object[] args = joinPoint.getArgs(); + for (int i = 0; i < args.length; i++) { + if (args[i] instanceof Integer num) { + args[i] = num-1; + } + } + + return joinPoint.proceed(args); + }*/ +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/CheckMissionStatus.java b/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/CheckMissionStatus.java new file mode 100644 index 0000000..1a494a0 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/CheckMissionStatus.java @@ -0,0 +1,18 @@ +package com.example.umc.mission.validation.annotation; + +import com.example.umc.mission.validation.validator.CheckMissionStatusValidator; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.*; + +@Documented +@Constraint(validatedBy = CheckMissionStatusValidator.class) +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface CheckMissionStatus { + + String message() default "해당 미션은 이미 CHALLENGING 상태입니다."; + Class[] groups() default {}; + Class[] payload() default {}; +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/CheckPage.java b/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/CheckPage.java new file mode 100644 index 0000000..665b78e --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/CheckPage.java @@ -0,0 +1,17 @@ +package com.example.umc.mission.validation.annotation; + +import com.example.umc.mission.validation.validator.CheckPageValidator; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; +import java.lang.annotation.*; + +@Documented +@Constraint(validatedBy = CheckPageValidator.class) +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface CheckPage { + + String message() default "페이지의 값이 1보다 작습니다 :: 페이지의 값은 양수가 되어야 합니다."; + Class[] groups() default {}; + Class[] payload() default {}; +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/ExistCategories.java b/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/ExistCategories.java new file mode 100644 index 0000000..3ce0283 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/ExistCategories.java @@ -0,0 +1,18 @@ +package com.example.umc.mission.validation.annotation; + +import com.example.umc.mission.validation.validator.CategoriesExistValidator; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.*; + +@Documented +@Constraint(validatedBy = CategoriesExistValidator.class) +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ExistCategories { + + String message() default "해당하는 카테고리가 존재하지 않습니다."; + Class[] groups() default {}; + Class[] payload() default {}; +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/ExistMember.java b/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/ExistMember.java new file mode 100644 index 0000000..67aac38 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/ExistMember.java @@ -0,0 +1,18 @@ +package com.example.umc.mission.validation.annotation; + +import com.example.umc.mission.validation.validator.MemberExistValidator; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; +//import net.bytebuddy.build.RepeatedAnnotationPlugin; + +import java.lang.annotation.*; + +@Documented +@Constraint(validatedBy = MemberExistValidator.class) +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ExistMember { + String message() default "해당하는 멤버가 존재하지 않습니다. : 리뷰 작성 불가"; + Class[] groups() default {}; + Class[] payload() default {}; +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/ExistMission.java b/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/ExistMission.java new file mode 100644 index 0000000..8449ae8 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/ExistMission.java @@ -0,0 +1,17 @@ +package com.example.umc.mission.validation.annotation; + +import com.example.umc.mission.validation.validator.ExistMissionValidator; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.*; + +@Documented +@Constraint(validatedBy = ExistMissionValidator.class) +@Target({ElementType.PARAMETER, ElementType.FIELD,ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ExistMission { + String message() default "해당미션은 존재하지 않습니다."; + Class[] groups() default {}; + Class[] payload() default {}; +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/ExistStore.java b/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/ExistStore.java new file mode 100644 index 0000000..40485dd --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/validation/annotation/ExistStore.java @@ -0,0 +1,18 @@ +package com.example.umc.mission.validation.annotation; + +import com.example.umc.mission.validation.validator.StoreExistValidator; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.*; + +@Documented +@Constraint(validatedBy = StoreExistValidator.class) +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ExistStore { + + String message() default "해당하는 가게가 존재하지 않습니다. : 리뷰 작성 불가"; + Class[] groups() default {}; + Class[] payload() default {}; +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/validation/validator/CategoriesExistValidator.java b/umc.mission/src/main/java/com/example/umc/mission/validation/validator/CategoriesExistValidator.java new file mode 100644 index 0000000..18b05f8 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/validation/validator/CategoriesExistValidator.java @@ -0,0 +1,36 @@ +package com.example.umc.mission.validation.validator; + +import com.example.umc.mission.apiPayload.code.status.ErrorStatus; +import com.example.umc.mission.repository.FoodCategoryRepository; +import com.example.umc.mission.validation.annotation.ExistCategories; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@RequiredArgsConstructor +public class CategoriesExistValidator implements ConstraintValidator> { + + private final FoodCategoryRepository foodCategoryRepository; + + @Override + public void initialize(ExistCategories constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(List values, ConstraintValidatorContext context) { + boolean isValid = values.stream() + .allMatch(value -> foodCategoryRepository.existsById(value)); + + if (!isValid){ + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate(ErrorStatus.FOOD_CATEGORY_NOT_FOUND.toString()).addConstraintViolation(); + } + + return isValid; + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/validation/validator/CheckMissionStatusValidator.java b/umc.mission/src/main/java/com/example/umc/mission/validation/validator/CheckMissionStatusValidator.java new file mode 100644 index 0000000..ac6828f --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/validation/validator/CheckMissionStatusValidator.java @@ -0,0 +1,48 @@ +package com.example.umc.mission.validation.validator; + +import com.example.umc.mission.apiPayload.code.status.ErrorStatus; +import com.example.umc.mission.domain.enums.MissionStatus; +import com.example.umc.mission.domain.mapping.MembersMission; +import com.example.umc.mission.repository.MembersMissionRepository; +import com.example.umc.mission.service.MissionService.MissionCommandService; +import com.example.umc.mission.service.MissionService.MissionQueryService; +import com.example.umc.mission.service.StoreService.StoreQueryService; +import com.example.umc.mission.validation.annotation.CheckMissionStatus; +import com.example.umc.mission.web.dto.request.StoreRequestDTO; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@RequiredArgsConstructor +public class CheckMissionStatusValidator implements ConstraintValidator { + + private final MissionQueryService missionQueryService; + + @Override + public void initialize(CheckMissionStatus constraintAnnotation){ + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(StoreRequestDTO.postChallengeDTO request, ConstraintValidatorContext context) { + boolean isExist = missionQueryService.checkMembersMission(request.getMissionId(),request.getMemberId()); + + if(isExist){ + MembersMission membersMission = missionQueryService.getMembersMission(request.getMissionId(), request.getMemberId()); + boolean isValid = (membersMission.getStatus() != MissionStatus.CHALLENGING); + + if(!isValid){ + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate(ErrorStatus.MISSION_IS_CHALLENGING.toString()).addConstraintViolation(); + } + + return isValid; + } + + return true; + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/validation/validator/CheckPageValidator.java b/umc.mission/src/main/java/com/example/umc/mission/validation/validator/CheckPageValidator.java new file mode 100644 index 0000000..ba68c0c --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/validation/validator/CheckPageValidator.java @@ -0,0 +1,30 @@ +package com.example.umc.mission.validation.validator; + +import com.example.umc.mission.apiPayload.code.status.ErrorStatus; +import com.example.umc.mission.validation.annotation.CheckPage; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class CheckPageValidator implements ConstraintValidator { + + @Override + public void initialize(CheckPage constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(Integer value, ConstraintValidatorContext context) { + boolean isValid = (value > 0); + + if (!isValid) { + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate(ErrorStatus.PAGE_FORBIDDEN.toString()).addConstraintViolation(); + } + + return isValid; + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/validation/validator/ExistMissionValidator.java b/umc.mission/src/main/java/com/example/umc/mission/validation/validator/ExistMissionValidator.java new file mode 100644 index 0000000..b6a382f --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/validation/validator/ExistMissionValidator.java @@ -0,0 +1,35 @@ +package com.example.umc.mission.validation.validator; + +import com.example.umc.mission.apiPayload.code.status.ErrorStatus; +import com.example.umc.mission.domain.enums.MissionStatus; +import com.example.umc.mission.service.MissionService.MissionCommandService; +import com.example.umc.mission.validation.annotation.ExistMission; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class ExistMissionValidator implements ConstraintValidator { + + private final MissionCommandService missionCommandService; + + @Override + public void initialize(ExistMission constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(Long value, ConstraintValidatorContext context) { + boolean isValid = missionCommandService.existOfMission(value); + + if (!isValid) { + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate(ErrorStatus.MISSION_NOT_FOUND.toString()).addConstraintViolation(); + } + + return isValid; + } + +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/validation/validator/MemberExistValidator.java b/umc.mission/src/main/java/com/example/umc/mission/validation/validator/MemberExistValidator.java new file mode 100644 index 0000000..f219be0 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/validation/validator/MemberExistValidator.java @@ -0,0 +1,33 @@ +package com.example.umc.mission.validation.validator; + +import com.example.umc.mission.apiPayload.code.status.ErrorStatus; +import com.example.umc.mission.repository.MemberRepository; +import com.example.umc.mission.validation.annotation.ExistMember; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class MemberExistValidator implements ConstraintValidator { + + private final MemberRepository memberRepository; + + @Override + public void initialize(ExistMember constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(Long value, ConstraintValidatorContext context) { + boolean isValid = memberRepository.existsById(value); + + if (!isValid) { + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate(ErrorStatus.MEMBER_NOT_FOUND.toString()).addConstraintViolation(); + } + + return isValid; + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/validation/validator/StoreExistValidator.java b/umc.mission/src/main/java/com/example/umc/mission/validation/validator/StoreExistValidator.java new file mode 100644 index 0000000..c361f0f --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/validation/validator/StoreExistValidator.java @@ -0,0 +1,34 @@ +package com.example.umc.mission.validation.validator; + +import com.example.umc.mission.apiPayload.code.status.ErrorStatus; +import com.example.umc.mission.repository.StoreRepository; +import com.example.umc.mission.validation.annotation.ExistStore; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + + +@Component +@RequiredArgsConstructor +public class StoreExistValidator implements ConstraintValidator { + + private final StoreRepository storeRepository; + + @Override + public void initialize(ExistStore constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(Long value, ConstraintValidatorContext context) { + boolean isValid = storeRepository.existsById(value); + + if(!isValid){ + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate(ErrorStatus.STORE_NOT_FOUND.toString()).addConstraintViolation(); + } + + return isValid; + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/web/controller/MemberRestController.java b/umc.mission/src/main/java/com/example/umc/mission/web/controller/MemberRestController.java new file mode 100644 index 0000000..2faff1c --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/web/controller/MemberRestController.java @@ -0,0 +1,76 @@ +package com.example.umc.mission.web.controller; + +import com.example.umc.mission.apiPayload.ApiResponse; +import com.example.umc.mission.converter.MemberConverter; +import com.example.umc.mission.converter.ReviewConverter; +import com.example.umc.mission.domain.Member; +import com.example.umc.mission.domain.Review; +import com.example.umc.mission.domain.mapping.MembersMission; +import com.example.umc.mission.service.MemberService.MemberCommandService; +import com.example.umc.mission.service.MemberService.MemberQueryService; +import com.example.umc.mission.validation.annotation.CheckPage; +import com.example.umc.mission.validation.annotation.ExistMember; +import com.example.umc.mission.web.dto.request.MemberRequestDTO; +import com.example.umc.mission.web.dto.response.MemberResponseDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +@Validated +@RequestMapping("/members") +public class MemberRestController { + + private final MemberCommandService memberCommandService; + + private final MemberQueryService memberQueryService; + + @PostMapping("/") + public ApiResponse join(@RequestBody @Valid MemberRequestDTO.JoinDTO request) { + Member member = memberCommandService.joinMember(request); + return ApiResponse.onSucccess(MemberConverter.toJoinResultDTO(member)); + } + + //리뷰 조회 + @GetMapping("/{memberId}/reviews") + @Operation(summary = "특정 멤버의 리뷰 목록 조회 API", description = "특정 멤버의 리뷰목록을 조회하는 API이며, 페이징을 포함합니다. queryString올 page 번호를 주세요") + @ApiResponses({ + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON200", description = "OK, 성공"), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH003", description = "access 토큰을 주세요!",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH004", description = "acess 토큰 만료",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH006", description = "acess 토큰 모양이 이상함",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + }) + @Parameters({ + @Parameter(name = "memberId", description = "멤버의 아이디, path variable") + }) + public ApiResponse getReviewList(@ExistMember @PathVariable(name = "memberId") Long memberId, @CheckPage @RequestParam(name = "page") Integer page){ + Page reviews = memberQueryService.getReviewList(memberId, page-1); + return ApiResponse.onSucccess(ReviewConverter.toMemberReviewListDTO(reviews)); + } + + //진행 중인 미션 조회 + @GetMapping("/{memberId}/missions/challenge") + @Operation(summary = "특정 멤버의 진행 중인 미션목록 조회 API", description = "특정 멤버의 진행 중인 미션목록을 조회하는 API이며, 페이징을 포함합니다. queryString으로 page 번호를 주세요") + @ApiResponses({ + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON200", description = "OK, 성공"), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH003", description = "access 토큰을 주세요!",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH004", description = "acess 토큰 만료",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH006", description = "acess 토큰 모양이 이상함",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + }) + @Parameters({ + @Parameter(name = "memberId", description = "멤버의 아이디, path variable") + }) + public ApiResponse getChallengingMissionList(@ExistMember @PathVariable(name = "memberId") Long memberId, @CheckPage @RequestParam(name = "page") Integer page){ + Page challengingMissions = memberQueryService.getChallengingMissionList(memberId, page-1); + return ApiResponse.onSucccess(MemberConverter.toMissionPreReviewListDTO(challengingMissions)); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/web/controller/StoreRestController.java b/umc.mission/src/main/java/com/example/umc/mission/web/controller/StoreRestController.java new file mode 100644 index 0000000..38acea6 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/web/controller/StoreRestController.java @@ -0,0 +1,133 @@ +package com.example.umc.mission.web.controller; + +import com.example.umc.mission.apiPayload.ApiResponse; +import com.example.umc.mission.converter.MissionConverter; +import com.example.umc.mission.converter.ReviewConverter; +import com.example.umc.mission.converter.StoreConverter; +import com.example.umc.mission.domain.Mission; +import com.example.umc.mission.domain.Review; +import com.example.umc.mission.domain.Store; +import com.example.umc.mission.domain.mapping.MembersMission; +import com.example.umc.mission.service.MissionService.MissionCommandService; +import com.example.umc.mission.service.MissionService.MissionQueryService; +import com.example.umc.mission.service.ReviewService.ReviewCommandService; +import com.example.umc.mission.service.StoreService.StoreCommandService; +import com.example.umc.mission.service.StoreService.StoreQueryService; +import com.example.umc.mission.validation.annotation.CheckMissionStatus; +import com.example.umc.mission.validation.annotation.CheckPage; +import com.example.umc.mission.validation.annotation.ExistMember; +import com.example.umc.mission.validation.annotation.ExistStore; +import com.example.umc.mission.web.dto.request.MissionRequestDTO; +import com.example.umc.mission.web.dto.request.StoreRequestDTO; +import com.example.umc.mission.web.dto.response.MissionResponseDTO; +import com.example.umc.mission.web.dto.response.StoreResponseDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +@RestController +@RequiredArgsConstructor +@Validated +@RequestMapping("/store") +public class StoreRestController { + + private final StoreCommandService storeCommandService; + + private final ReviewCommandService reviewCommandService; + + private final MissionCommandService missionCommandService; + + private final StoreQueryService storeQueryService; + + private final MissionQueryService missionQueryService; + + //1) 특정 지역에 가게 추가하기 + @PostMapping("/") + public ApiResponse addStore(@RequestBody @Valid StoreRequestDTO.addStoreDTO request){ + Store store = storeCommandService.saveStore(request); + return ApiResponse.onSucccess(StoreConverter.toAddStoreResponseDTO(store)); + } + + //2) 가게에 리뷰 추가하기 + @PostMapping(value = "/review", consumes = "multipart/form-data") + public ApiResponse postReview( + @Valid @RequestPart @Parameter(schema =@Schema(type = "string", format = "binary")) StoreRequestDTO.postReviewDTO request, + @RequestPart MultipartFile reviewPicture){ + Review review = reviewCommandService.saveReview(request, reviewPicture); + return ApiResponse.onSucccess(ReviewConverter.toReviewResponseDTO(review)); + } + + //리뷰 조회 + @GetMapping("/{storeId}/reviews") + @Operation(summary = "특정 가게의 리뷰 목록 조회 API", description = "특정 가게의 리뷰들의 목록을 조회하는 API이며, 페이징을 포함합니다. queryString올 page 번호를 주세요") + @ApiResponses({ + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON200", description = "OK, 성공"), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH003", description = "access 토큰을 주세요!",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH004", description = "acess 토큰 만료",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH006", description = "acess 토큰 모양이 이상함",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + }) + @Parameters({ + @Parameter(name = "storeId", description = "가게의 아이디, path variable") + }) + public ApiResponse getReviewList(@ExistStore @PathVariable(name = "storeId") Long storeId, @RequestParam(name = "page") Integer page){ + Page reviewList = storeQueryService.getReviewList(storeId, page); + return ApiResponse.onSucccess(ReviewConverter.toReviewPreViewListDTO(reviewList)); + //return null; + } + + //리뷰 삭제 + @DeleteMapping("/{reviewId}/delete") + @Operation(summary = "특정 가게의 리뷰 삭제 API", description = "특정 리뷰를 삭제하는 API입니다. queryString 으로 reviewId를 주세요") + @ApiResponses({ + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON200", description = "OK, 성공"), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH003", description = "access 토큰을 주세요!",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH004", description = "acess 토큰 만료",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH006", description = "acess 토큰 모양이 이상함",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + }) + @Parameters({ + @Parameter(name = "reviewId", description = "삭제할 리뷰의 아이디, path variable") + }) + public ApiResponse deleteReview(@PathVariable Long reviewId){ + return ApiResponse.onSucccess(ReviewConverter.toDeleteReviewDTO(reviewCommandService.deleteReview(reviewId))); + } + + //3) 가게에 미션 추가하기 + @PostMapping("/mission") + public ApiResponse postMission(@RequestBody @Valid MissionRequestDTO.addMissionDTO request){ + Mission mission = missionCommandService.saveMission(request); + return ApiResponse.onSucccess(MissionConverter.toAddMissionResponseDTO(mission)); + } + + //미션 조회 + @GetMapping("/{storeId}/missions") + @Operation(summary = "특정 가게의 미션 목록 조회 API", description = "특정 가게의 미션 목록을 조회하는 API이며, 페이징을 포함합니다. queryString으로 page 번호를 주세요") + @ApiResponses({ + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON200", description = "OK, 성공"), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH003", description = "access 토큰을 주세요!",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH004", description = "acess 토큰 만료",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH006", description = "acess 토큰 모양이 이상함",content = @Content(schema = @Schema(implementation = ApiResponse.class))), + }) + @Parameters({ + @Parameter(name = "storeId", description = "가게의 아이디, path variable") + }) + public ApiResponse getMissionList(@ExistStore @PathVariable(name = "storeId") Long storeId,@CheckPage @RequestParam(name = "page") Integer page){ + Page missions = missionQueryService.getMissions(storeId, page-1); + return ApiResponse.onSucccess(MissionConverter.toMissionPreReviewListDTO(missions)); + } + + //4) 가게의 미션을 도전 중인 미션에 추가 + @PostMapping("/challenge") + public ApiResponse challengeMission(@CheckMissionStatus @RequestBody @Valid StoreRequestDTO.postChallengeDTO request){ + MembersMission challenge = missionCommandService.saveChallenge(request); + return ApiResponse.onSucccess(StoreConverter.toChallengeResponseDTO(challenge)); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/web/controller/TempRestController.java b/umc.mission/src/main/java/com/example/umc/mission/web/controller/TempRestController.java new file mode 100644 index 0000000..62386ce --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/web/controller/TempRestController.java @@ -0,0 +1,31 @@ +package com.example.umc.mission.web.controller; + +import com.example.umc.mission.apiPayload.ApiResponse; +import com.example.umc.mission.converter.TempConverter; +import com.example.umc.mission.service.TempService.TempQueryService; +import com.example.umc.mission.web.dto.response.TempResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/temp") +@RequiredArgsConstructor +public class TempRestController { + + private final TempQueryService tempQueryService; + + @GetMapping("/test") + public ApiResponse testApi(){ + + return ApiResponse.onSucccess(TempConverter.toTempTestDTO()); + } + + @GetMapping("/exception") + public ApiResponse exceptionAPI(@RequestParam Integer flag){ + tempQueryService.CheckFlag(flag); + return ApiResponse.onSucccess(TempConverter.toTempExceptionDTO(flag)); + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/web/dto/request/MemberRequestDTO.java b/umc.mission/src/main/java/com/example/umc/mission/web/dto/request/MemberRequestDTO.java new file mode 100644 index 0000000..b84b227 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/web/dto/request/MemberRequestDTO.java @@ -0,0 +1,26 @@ +package com.example.umc.mission.web.dto.request; + +import com.example.umc.mission.validation.annotation.ExistCategories; +import jakarta.validation.constraints.*; +import lombok.Getter; + +import java.util.List; + +public class MemberRequestDTO { + + @Getter + public static class JoinDTO{ + @NotBlank + String name; + @Size(min = 5, max = 20) + String address; + @Min(1) + @Max(2) + Integer gender; + Integer bYear; + Integer bMonth; + Integer bDay; + @ExistCategories + List preferCategory; + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/web/dto/request/MissionRequestDTO.java b/umc.mission/src/main/java/com/example/umc/mission/web/dto/request/MissionRequestDTO.java new file mode 100644 index 0000000..d2912ea --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/web/dto/request/MissionRequestDTO.java @@ -0,0 +1,26 @@ +package com.example.umc.mission.web.dto.request; + +import com.example.umc.mission.validation.annotation.ExistStore; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Getter; + +public class MissionRequestDTO { + + @Getter + public static class addMissionDTO{ + @NotNull + String name; + @NotNull + @Size(max = 50) + String cond; + @NotNull + @Min(0) + @Max(50) + Integer reward; + @ExistStore + Long storeId; + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/web/dto/request/StoreRequestDTO.java b/umc.mission/src/main/java/com/example/umc/mission/web/dto/request/StoreRequestDTO.java new file mode 100644 index 0000000..19d3e65 --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/web/dto/request/StoreRequestDTO.java @@ -0,0 +1,49 @@ +package com.example.umc.mission.web.dto.request; + +import com.example.umc.mission.validation.annotation.CheckMissionStatus; +import com.example.umc.mission.validation.annotation.ExistMember; +import com.example.umc.mission.validation.annotation.ExistMission; +import com.example.umc.mission.validation.annotation.ExistStore; +import jakarta.validation.constraints.*; +import lombok.Getter; +import org.springframework.web.multipart.MultipartFile; + +public class StoreRequestDTO { + + @Getter + public static class addStoreDTO{ + @NotBlank + String name; + @Size(max = 50) + @NotNull + String address; + @Size(max = 15) + @NotNull + String phone; + @NotNull + String regionName; + } + + @Getter + public static class postReviewDTO{ + @NotBlank + String title; + @NotNull + String content; + @Min(0) + @Max(5) + Integer starPoint; + @ExistMember + Long userId; + @ExistStore + Long storeId; + } + + @Getter + public static class postChallengeDTO{ + @ExistMember + Long memberId; + @ExistMission + Long missionId; + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/web/dto/response/MemberResponseDTO.java b/umc.mission/src/main/java/com/example/umc/mission/web/dto/response/MemberResponseDTO.java new file mode 100644 index 0000000..876b36d --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/web/dto/response/MemberResponseDTO.java @@ -0,0 +1,69 @@ +package com.example.umc.mission.web.dto.response; + +import com.example.umc.mission.domain.enums.MissionStatus; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +public class MemberResponseDTO { + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class JoinResultDTO { + Long memberId; + //LocalDateTime createdAt; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class ReviewPreViewListDTO{ + List reviewList; + Integer listSize; + Integer totalPage; + Long totalElements; + Boolean isFirst; + Boolean isLast; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class ReviewPreViewDTO{ + String storeName; + Integer starPoint; + String content; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class MissionPreViewListDTO{ + List missionList; + Integer listSize; + Integer totalPage; + Long totalElements; + Boolean isFirst; + Boolean isLast; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class MissionPreViewDTO{ + String storeName; + String cond; + Integer reward; + MissionStatus status; + } + +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/web/dto/response/MissionResponseDTO.java b/umc.mission/src/main/java/com/example/umc/mission/web/dto/response/MissionResponseDTO.java new file mode 100644 index 0000000..05cd8aa --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/web/dto/response/MissionResponseDTO.java @@ -0,0 +1,20 @@ +package com.example.umc.mission.web.dto.response; + + +import com.example.umc.mission.domain.enums.MissionStatus; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +public class MissionResponseDTO { + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class addMissionResponseDTO { + Long mission_id; + Long store_id; + } +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/web/dto/response/StoreResponseDTO.java b/umc.mission/src/main/java/com/example/umc/mission/web/dto/response/StoreResponseDTO.java new file mode 100644 index 0000000..b95be8c --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/web/dto/response/StoreResponseDTO.java @@ -0,0 +1,97 @@ +package com.example.umc.mission.web.dto.response; + +import com.example.umc.mission.domain.enums.MissionStatus; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +public class StoreResponseDTO { + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class addStoreResponseDTO { + Long store_id; + String store_name; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class reviewResponseDTO{ + Long store_id; + Long member_id; + Long review_id; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class ReviewPreViewListDTO{ + List reviewList; + Integer listSize; + Integer totalPage; + Long totalElements; + Boolean isFirst; + Boolean isLast; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class ReviewPreViewDTO{ + String ownerNickname; + Integer starPoint; + String content; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class MissionPreViewListDTO{ + List missionList; + Integer listSize; + Integer totalPage; + Long totalElements; + Boolean isFirst; + Boolean isLast; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class MissionPreViewDTO{ + String storeName; + String cond; + Integer reward; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class ChallengeResponseDTO{ + Long challengeId; + Long missionId; + Long memberId; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class DeleteReviewDTO{ + Long storeId; + String text; + } + +} diff --git a/umc.mission/src/main/java/com/example/umc/mission/web/dto/response/TempResponse.java b/umc.mission/src/main/java/com/example/umc/mission/web/dto/response/TempResponse.java new file mode 100644 index 0000000..faef6ea --- /dev/null +++ b/umc.mission/src/main/java/com/example/umc/mission/web/dto/response/TempResponse.java @@ -0,0 +1,25 @@ +package com.example.umc.mission.web.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +public class TempResponse { + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class TempTestDTO{ + String testString; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class TempExceptionDTO{ + Integer flag; + } +} diff --git a/umc.mission/src/test/java/com/example/umc/mission/ApplicationTests.java b/umc.mission/src/test/java/com/example/umc/mission/ApplicationTests.java new file mode 100644 index 0000000..8d2c079 --- /dev/null +++ b/umc.mission/src/test/java/com/example/umc/mission/ApplicationTests.java @@ -0,0 +1,13 @@ +package com.example.umc.mission; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ApplicationTests { + + @Test + void contextLoads() { + } + +}