From f18abe79c7e0a4643535d8008f90146aaa6c7092 Mon Sep 17 00:00:00 2001 From: KYS Date: Sun, 17 Nov 2024 01:29:40 +0900 Subject: [PATCH 01/11] mission: submit week7 mission --- build.gradle | 4 + .../Umc7thMissionApplication.java | 4 +- .../apiPayload/ApiResponse.java | 39 ++++++ .../umc7th_mission/apiPayload/BaseCode.java | 8 ++ .../apiPayload/BaseErrorCode.java | 8 ++ .../apiPayload/ErrorReasonDTO.java | 18 +++ .../umc7th_mission/apiPayload/ReasonDTO.java | 18 +++ .../apiPayload/code/status/ErrorStatus.java | 53 ++++++++ .../apiPayload/code/status/SuccessStatus.java | 45 +++++++ .../apiPayload/exception/ExceptionAdvice.java | 119 ++++++++++++++++++ .../exception/GeneralException.java | 21 ++++ .../exception/handler/TempHandler.java | 10 ++ .../converter/TempConverter.java | 18 +++ .../TempService/TempCommandService.java | 5 + .../TempService/TempCommandServiceImpl.java | 11 ++ .../service/TempService/TempQueryService.java | 6 + .../TempService/TempQueryServiceImpl.java | 17 +++ .../web/controller/TempRestController.java | 31 +++++ .../umc7th_mission/web/dto/TempRequest.java | 4 + .../umc7th_mission/web/dto/TempResponse.java | 25 ++++ src/main/resources/application.properties | 1 - src/main/resources/application.yml | 19 +++ 22 files changed, 482 insertions(+), 2 deletions(-) create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/ApiResponse.java create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/BaseCode.java create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/BaseErrorCode.java create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/ErrorReasonDTO.java create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/ReasonDTO.java create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/code/status/SuccessStatus.java create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/exception/GeneralException.java create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/exception/handler/TempHandler.java create mode 100644 src/main/java/javalab/umc7th_mission/converter/TempConverter.java create mode 100644 src/main/java/javalab/umc7th_mission/service/TempService/TempCommandService.java create mode 100644 src/main/java/javalab/umc7th_mission/service/TempService/TempCommandServiceImpl.java create mode 100644 src/main/java/javalab/umc7th_mission/service/TempService/TempQueryService.java create mode 100644 src/main/java/javalab/umc7th_mission/service/TempService/TempQueryServiceImpl.java create mode 100644 src/main/java/javalab/umc7th_mission/web/controller/TempRestController.java create mode 100644 src/main/java/javalab/umc7th_mission/web/dto/TempRequest.java create mode 100644 src/main/java/javalab/umc7th_mission/web/dto/TempResponse.java delete mode 100644 src/main/resources/application.properties create mode 100644 src/main/resources/application.yml diff --git a/build.gradle b/build.gradle index d312f28..347fc5d 100644 --- a/build.gradle +++ b/build.gradle @@ -33,6 +33,10 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + // 에러관련 의존성 주입 + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'jakarta.validation:jakarta.validation-api:3.0.2' + // QueryDsl implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" diff --git a/src/main/java/javalab/umc7th_mission/Umc7thMissionApplication.java b/src/main/java/javalab/umc7th_mission/Umc7thMissionApplication.java index bd55412..9dead6d 100644 --- a/src/main/java/javalab/umc7th_mission/Umc7thMissionApplication.java +++ b/src/main/java/javalab/umc7th_mission/Umc7thMissionApplication.java @@ -2,10 +2,12 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @SpringBootApplication -@EnableJpaRepositories +// @EnableJpaRepositories -> 보통 springBoot가 알아서 리포지토리 추가시켜줌 +@EnableJpaAuditing //생성일 및 업데이트일 자동 입력 public class Umc7thMissionApplication { public static void main(String[] args) { diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/ApiResponse.java b/src/main/java/javalab/umc7th_mission/apiPayload/ApiResponse.java new file mode 100644 index 0000000..4aa3cfb --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/ApiResponse.java @@ -0,0 +1,39 @@ +package javalab.umc7th_mission.apiPayload; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import javalab.umc7th_mission.apiPayload.code.status.SuccessStatus; +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 onSuccess(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<>(false, code, message, data); + } +} diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/BaseCode.java b/src/main/java/javalab/umc7th_mission/apiPayload/BaseCode.java new file mode 100644 index 0000000..4763af7 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/BaseCode.java @@ -0,0 +1,8 @@ +package javalab.umc7th_mission.apiPayload; + +//해당 인터페이스의 역할 -> 구체화 하는 Status에서 +// 두개의 메소드를 반드시 오버라이드할 것을 강제하는 역할 +public interface BaseCode { + ReasonDTO getReason(); + ReasonDTO getReasonHttpStatus(); +} diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/BaseErrorCode.java b/src/main/java/javalab/umc7th_mission/apiPayload/BaseErrorCode.java new file mode 100644 index 0000000..9e8d9a6 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/BaseErrorCode.java @@ -0,0 +1,8 @@ +package javalab.umc7th_mission.apiPayload; + +public interface BaseErrorCode { + + ErrorReasonDTO getReason(); + + ErrorReasonDTO getReasonHttpStatus(); +} diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/ErrorReasonDTO.java b/src/main/java/javalab/umc7th_mission/apiPayload/ErrorReasonDTO.java new file mode 100644 index 0000000..add3309 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/ErrorReasonDTO.java @@ -0,0 +1,18 @@ +package javalab.umc7th_mission.apiPayload; + +import lombok.Builder; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@Builder +public class ErrorReasonDTO { + + private HttpStatus httpStatus; + + private final boolean isSuccess; + private final String code; + private final String message; + + public boolean getIsSuccess(){return isSuccess;} +} diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/ReasonDTO.java b/src/main/java/javalab/umc7th_mission/apiPayload/ReasonDTO.java new file mode 100644 index 0000000..3400b52 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/ReasonDTO.java @@ -0,0 +1,18 @@ +package javalab.umc7th_mission.apiPayload; + +import lombok.Builder; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@Builder +public class ReasonDTO { + + private HttpStatus httpStatus; + + private final boolean isSuccess; + private final String code; + private final String message; + + public boolean getIsSuccess(){return isSuccess;} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java b/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java new file mode 100644 index 0000000..2ec128d --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java @@ -0,0 +1,53 @@ +package javalab.umc7th_mission.apiPayload.code.status; + +import javalab.umc7th_mission.apiPayload.BaseErrorCode; +import javalab.umc7th_mission.apiPayload.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", "금지된 요청입니다."), + + //임시 + TEMP_EXCEPTION(HttpStatus.BAD_REQUEST, "TEMP4001", "테스트용 에러코드"), + + // 멤버 관련 에러 + MEMBER_NOT_FOUND(HttpStatus.BAD_REQUEST, "MEMBER4001", "사용자가 없습니다."), + NICKNAME_NOT_EXIST(HttpStatus.BAD_REQUEST, "MEMBER4002", "닉네임은 필수 입니다."), + + // 예시,,, + ARTICLE_NOT_FOUND(HttpStatus.NOT_FOUND, "ARTICLE4001", "게시글이 없습니다."); + + + 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() + ; + } +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/code/status/SuccessStatus.java b/src/main/java/javalab/umc7th_mission/apiPayload/code/status/SuccessStatus.java new file mode 100644 index 0000000..ee3531f --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/code/status/SuccessStatus.java @@ -0,0 +1,45 @@ +package javalab.umc7th_mission.apiPayload.code.status; + +import javalab.umc7th_mission.apiPayload.BaseCode; +import javalab.umc7th_mission.apiPayload.ReasonDTO; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum SuccessStatus implements BaseCode { + + // 일반적인 응답 + _OK(HttpStatus.OK, "COMMON200", "성공입니다."); + + //맴버 관련 응답 + + // ~~~ 관련 응답 + + //성공응답 추가시 ENUM 형식으로 계속 밑에 추가하면 된다. + 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/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java new file mode 100644 index 0000000..ceec154 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java @@ -0,0 +1,119 @@ +package javalab.umc7th_mission.apiPayload.exception; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.ConstraintViolationException; +import javalab.umc7th_mission.apiPayload.ApiResponse; +import javalab.umc7th_mission.apiPayload.ErrorReasonDTO; +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +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 { + + + @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); + } + + @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 + ); + } +} diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/GeneralException.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/GeneralException.java new file mode 100644 index 0000000..6c713b9 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/GeneralException.java @@ -0,0 +1,21 @@ +package javalab.umc7th_mission.apiPayload.exception; + +import javalab.umc7th_mission.apiPayload.BaseErrorCode; +import javalab.umc7th_mission.apiPayload.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/src/main/java/javalab/umc7th_mission/apiPayload/exception/handler/TempHandler.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/handler/TempHandler.java new file mode 100644 index 0000000..f65148f --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/handler/TempHandler.java @@ -0,0 +1,10 @@ +package javalab.umc7th_mission.apiPayload.exception.handler; + +import javalab.umc7th_mission.apiPayload.BaseErrorCode; +import javalab.umc7th_mission.apiPayload.exception.GeneralException; + +public class TempHandler extends GeneralException { + public TempHandler(BaseErrorCode errorCode) { + super(errorCode); + } +} diff --git a/src/main/java/javalab/umc7th_mission/converter/TempConverter.java b/src/main/java/javalab/umc7th_mission/converter/TempConverter.java new file mode 100644 index 0000000..a00cfdc --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/converter/TempConverter.java @@ -0,0 +1,18 @@ +package javalab.umc7th_mission.converter; + +import javalab.umc7th_mission.web.dto.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(); + } +} diff --git a/src/main/java/javalab/umc7th_mission/service/TempService/TempCommandService.java b/src/main/java/javalab/umc7th_mission/service/TempService/TempCommandService.java new file mode 100644 index 0000000..871d625 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/TempService/TempCommandService.java @@ -0,0 +1,5 @@ +package javalab.umc7th_mission.service.TempService; + +public interface TempCommandService { + +} diff --git a/src/main/java/javalab/umc7th_mission/service/TempService/TempCommandServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/TempService/TempCommandServiceImpl.java new file mode 100644 index 0000000..2aae4ee --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/TempService/TempCommandServiceImpl.java @@ -0,0 +1,11 @@ +package umc.study.service.TempService; + +import javalab.umc7th_mission.service.TempService.TempCommandService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class TempCommandServiceImpl implements TempCommandService { + +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/TempService/TempQueryService.java b/src/main/java/javalab/umc7th_mission/service/TempService/TempQueryService.java new file mode 100644 index 0000000..03bc4ae --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/TempService/TempQueryService.java @@ -0,0 +1,6 @@ +package javalab.umc7th_mission.service.TempService; + +public interface TempQueryService { + + void CheckFlag(Integer flag); +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/TempService/TempQueryServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/TempService/TempQueryServiceImpl.java new file mode 100644 index 0000000..365ae50 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/TempService/TempQueryServiceImpl.java @@ -0,0 +1,17 @@ +package javalab.umc7th_mission.service.TempService; + +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import javalab.umc7th_mission.apiPayload.exception.handler.TempHandler; +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); + } +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/controller/TempRestController.java b/src/main/java/javalab/umc7th_mission/web/controller/TempRestController.java new file mode 100644 index 0000000..bb533d2 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/controller/TempRestController.java @@ -0,0 +1,31 @@ +package javalab.umc7th_mission.web.controller; + +import javalab.umc7th_mission.apiPayload.ApiResponse; +import javalab.umc7th_mission.converter.TempConverter; +import javalab.umc7th_mission.service.TempService.TempQueryService; +import javalab.umc7th_mission.web.dto.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.onSuccess(TempConverter.toTempTestDTO()); + } + + @GetMapping("/exception") + public ApiResponse exceptionAPI(@RequestParam Integer flag){ + tempQueryService.CheckFlag(flag); + return null; + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/dto/TempRequest.java b/src/main/java/javalab/umc7th_mission/web/dto/TempRequest.java new file mode 100644 index 0000000..f01fd3a --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/dto/TempRequest.java @@ -0,0 +1,4 @@ +package javalab.umc7th_mission.web.dto; + +public class TempRequest { +} diff --git a/src/main/java/javalab/umc7th_mission/web/dto/TempResponse.java b/src/main/java/javalab/umc7th_mission/web/dto/TempResponse.java new file mode 100644 index 0000000..310105d --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/dto/TempResponse.java @@ -0,0 +1,25 @@ +package javalab.umc7th_mission.web.dto; + +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/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index 12f39ad..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name=UMC7th_Mission diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..d7745c5 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,19 @@ +spring: + datasource: + url: jdbc:mysql://localhost:3306/study + username: root + password: 425805 + driver-class-name: com.mysql.cj.jdbc.Driver + sql: + init: + mode: never + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.MySQL8Dialect + show_sql: true + format_sql: true + use_sql_comments: true + hbm2ddl: + auto: update + default_batch_fetch_size: 1000 \ No newline at end of file From 4d88c3954efc62464c2491f7f586ba8dfee8ada3 Mon Sep 17 00:00:00 2001 From: KYS Date: Wed, 20 Nov 2024 18:46:50 +0900 Subject: [PATCH 02/11] =?UTF-8?q?=E2=9C=A8Feat=20Join=20Member?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 + .../apiPayload/code/status/ErrorStatus.java | 5 +- .../apiPayload/exception/ExceptionAdvice.java | 21 +++++ .../FoodCategoryNotFoundException.java | 16 ++++ .../umc7th_mission/config/SwaggerConfig.java | 39 +++++++++ .../converter/MemberConverter.java | 60 ++++++++++++++ .../converter/MemberPreferConverter.java | 21 +++++ .../javalab/umc7th_mission/domain/Member.java | 7 +- .../javalab/umc7th_mission/domain/Store.java | 4 +- .../umc7th_mission/domain/enums/Gender.java | 21 ++++- .../domain/mapping/MemberPrefer.java | 12 +++ .../FoodCategoryRepository.java | 9 ++ .../MemberAddressRepository.java | 9 ++ .../MemberAddressRepositoryCustom.java | 9 ++ .../MemberAddressRepositoryImpl.java | 25 ++++++ .../MemberRepository/MemberRepository.java | 5 +- .../RegionRepository/RegionRepository.java | 13 +++ .../RegionRepositoryCustom.java | 4 + .../RegionRepositoryImpl.java | 4 + .../ReviewRepository/ReviewRepository.java | 3 + .../StoreRepository/StoreRepository.java | 3 + .../MemberService/MemberCommandService.java | 12 +++ .../MemberCommandServiceImpl.java | 68 +++++++++++++++ .../web/controller/MemberRestController.java | 27 ++++++ .../web/dto/MemberRequestDTO.java | 83 +++++++++++++++++++ .../web/dto/MemberResponseDTO.java | 33 ++++++++ 26 files changed, 511 insertions(+), 5 deletions(-) create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/exception/FoodCategoryNotFoundException.java create mode 100644 src/main/java/javalab/umc7th_mission/config/SwaggerConfig.java create mode 100644 src/main/java/javalab/umc7th_mission/converter/MemberConverter.java create mode 100644 src/main/java/javalab/umc7th_mission/converter/MemberPreferConverter.java create mode 100644 src/main/java/javalab/umc7th_mission/repository/FoodCategoryRepository/FoodCategoryRepository.java create mode 100644 src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepository.java create mode 100644 src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryCustom.java create mode 100644 src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryImpl.java create mode 100644 src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepository.java create mode 100644 src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryCustom.java create mode 100644 src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryImpl.java create mode 100644 src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandService.java create mode 100644 src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandServiceImpl.java create mode 100644 src/main/java/javalab/umc7th_mission/web/controller/MemberRestController.java create mode 100644 src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java create mode 100644 src/main/java/javalab/umc7th_mission/web/dto/MemberResponseDTO.java diff --git a/build.gradle b/build.gradle index 347fc5d..bea17fa 100644 --- a/build.gradle +++ b/build.gradle @@ -33,6 +33,9 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + //swagger + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' + // 에러관련 의존성 주입 implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'jakarta.validation:jakarta.validation-api:3.0.2' diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java b/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java index 2ec128d..5298851 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java @@ -24,7 +24,10 @@ public enum ErrorStatus implements BaseErrorCode { NICKNAME_NOT_EXIST(HttpStatus.BAD_REQUEST, "MEMBER4002", "닉네임은 필수 입니다."), // 예시,,, - ARTICLE_NOT_FOUND(HttpStatus.NOT_FOUND, "ARTICLE4001", "게시글이 없습니다."); + ARTICLE_NOT_FOUND(HttpStatus.NOT_FOUND, "ARTICLE4001", "게시글이 없습니다."), + + //음식 카테고리 없음 + FOOD_CATEGORY_NOT_FOUND(HttpStatus.NOT_FOUND, "FOOD4001", "해당 음식 카테고리가 없습니다."); private final HttpStatus httpStatus; diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java index ceec154..77ab641 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java @@ -10,6 +10,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.http.ResponseEntity; +import org.springframework.web.ErrorResponse; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestController; @@ -65,6 +66,26 @@ public ResponseEntity onThrowException(GeneralException generalException, HttpSe return handleExceptionInternal(generalException,errorReasonHttpStatus,null,request); } + //FoodCatoryNotFoundException에 대한 에러 처리 + @ExceptionHandler(FoodCategoryNotFoundException.class) + public ResponseEntity handleFoodCategoryNotFoundException(FoodCategoryNotFoundException e, HttpServletRequest request) { + WebRequest webRequest = new ServletWebRequest(request); + + ApiResponse body = ApiResponse.onFailure( + ErrorStatus.FOOD_CATEGORY_NOT_FOUND.getCode(), + ErrorStatus.FOOD_CATEGORY_NOT_FOUND.getMessage(), + null + ); + + return super.handleExceptionInternal( + e, + body, + new HttpHeaders(), + ErrorStatus.FOOD_CATEGORY_NOT_FOUND.getHttpStatus(), + webRequest + ); + } + private ResponseEntity handleExceptionInternal(Exception e, ErrorReasonDTO reason, HttpHeaders headers, HttpServletRequest request) { diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/FoodCategoryNotFoundException.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/FoodCategoryNotFoundException.java new file mode 100644 index 0000000..9bcd386 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/FoodCategoryNotFoundException.java @@ -0,0 +1,16 @@ +package javalab.umc7th_mission.apiPayload.exception; + +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import org.springframework.http.HttpStatus; + +public class FoodCategoryNotFoundException extends RuntimeException { + private final HttpStatus status = HttpStatus.NOT_FOUND; + + public FoodCategoryNotFoundException(ErrorStatus errorStatus) { + super(errorStatus.getMessage()); + } + + public HttpStatus getStatus() { + return status; + } +} diff --git a/src/main/java/javalab/umc7th_mission/config/SwaggerConfig.java b/src/main/java/javalab/umc7th_mission/config/SwaggerConfig.java new file mode 100644 index 0000000..78162d9 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/config/SwaggerConfig.java @@ -0,0 +1,39 @@ +package javalab.umc7th_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); + } +} diff --git a/src/main/java/javalab/umc7th_mission/converter/MemberConverter.java b/src/main/java/javalab/umc7th_mission/converter/MemberConverter.java new file mode 100644 index 0000000..5c2c94d --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/converter/MemberConverter.java @@ -0,0 +1,60 @@ +package javalab.umc7th_mission.converter; + +import javalab.umc7th_mission.domain.Member; +import javalab.umc7th_mission.domain.Region; +import javalab.umc7th_mission.domain.enums.Gender; +import javalab.umc7th_mission.domain.mapping.MemberAddress; +import javalab.umc7th_mission.repository.RegionRepository.RegionRepository; +import javalab.umc7th_mission.web.dto.MemberRequestDTO; +import javalab.umc7th_mission.web.dto.MemberResponseDTO; +import java.time.LocalDateTime; +import java.util.ArrayList; + +public class MemberConverter { + + //Member객체를 MemberResponseDTO중에 JoinResultDTO에 알맞은 객체로 변환후 반환 + public static MemberResponseDTO.JoinResultDTO toJoinResultDTO(Member member) { + return new MemberResponseDTO.JoinResultDTO( + member.getId(), + member.getCreatedAt() + ); + } + + //DTO객체를 다시 Member객체로 변환시 사용 주로 쓰기 영역에서 많이 사용한다. + public static Member toMember(MemberRequestDTO.JoinDto request) { + Gender gender = null; + switch (request.getGender().getValue()) { + case 1: + gender = Gender.MALE; + break; + case 2: + gender = Gender.FEMALE; + break; + case 3: + gender = Gender.OTHER; + break; + case 4: + gender = Gender.UNKNOWN; + break; + } + //member 생성 (주소는 개별) + return Member.builder() + .gender(gender) + .name(request.getName()) + .nickname(request.getNickname()) + .phoneNumber(request.getPhoneNumber()) + .email(request.getEmail()) + .memberPreferList(new ArrayList<>()) + .point(0) + .build(); + } + + public static MemberAddress toMemberAddress(Member member, Region region, MemberRequestDTO.JoinDto request) { + return MemberAddress.builder() + .member(member) + .region(region) + .detailAddress(request.getDetailedAddress()) + .zipCode(request.getZipcode()) + .build(); + } +} diff --git a/src/main/java/javalab/umc7th_mission/converter/MemberPreferConverter.java b/src/main/java/javalab/umc7th_mission/converter/MemberPreferConverter.java new file mode 100644 index 0000000..aa552f6 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/converter/MemberPreferConverter.java @@ -0,0 +1,21 @@ +package javalab.umc7th_mission.converter; + +import javalab.umc7th_mission.domain.FoodCategory; +import javalab.umc7th_mission.domain.mapping.MemberPrefer; + +import java.util.List; +import java.util.stream.Collectors; + +public class MemberPreferConverter { + + public static List toMemberPreferList(List foodCategoryList){ + + return foodCategoryList.stream() + .map(foodCategory -> + MemberPrefer.builder() + .foodCategory(foodCategory) + .build() + ).collect(Collectors.toList()); + } +} + diff --git a/src/main/java/javalab/umc7th_mission/domain/Member.java b/src/main/java/javalab/umc7th_mission/domain/Member.java index 6974030..b55ecf7 100644 --- a/src/main/java/javalab/umc7th_mission/domain/Member.java +++ b/src/main/java/javalab/umc7th_mission/domain/Member.java @@ -10,6 +10,7 @@ import lombok.*; import org.hibernate.annotations.ColumnDefault; import org.hibernate.annotations.Columns; +import org.springframework.boot.context.properties.bind.DefaultValue; import java.time.LocalDate; import java.util.ArrayList; @@ -17,6 +18,8 @@ @Entity @Getter +//24.11.20 @Setter 추가 +@Setter @Builder @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @@ -48,8 +51,10 @@ public class Member extends BaseEntity { @Column(nullable = false, unique = true, length = 50) private String email; + //24.11.20 point = 0 -> @ColumDefault, api에서 null문제가 꾸준히 발생하여 변경함 @Column(nullable = false) - private Integer point = 0; + @ColumnDefault("0") + private Integer point; @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List addressList = new ArrayList<>(); diff --git a/src/main/java/javalab/umc7th_mission/domain/Store.java b/src/main/java/javalab/umc7th_mission/domain/Store.java index 53d0ed9..deb4856 100644 --- a/src/main/java/javalab/umc7th_mission/domain/Store.java +++ b/src/main/java/javalab/umc7th_mission/domain/Store.java @@ -1,5 +1,6 @@ package javalab.umc7th_mission.domain; import jakarta.persistence.*; +import javalab.umc7th_mission.domain.common.BaseEntity; import javalab.umc7th_mission.domain.mapping.StoreAddress; import javalab.umc7th_mission.domain.mapping.StoreCategory; import lombok.*; @@ -15,7 +16,8 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @Builder -public class Store { +//24.11.20 BaseEntity 놓친거 추가 +public class Store extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/javalab/umc7th_mission/domain/enums/Gender.java b/src/main/java/javalab/umc7th_mission/domain/enums/Gender.java index b04b95b..315b867 100644 --- a/src/main/java/javalab/umc7th_mission/domain/enums/Gender.java +++ b/src/main/java/javalab/umc7th_mission/domain/enums/Gender.java @@ -1,5 +1,24 @@ package javalab.umc7th_mission.domain.enums; +//24.11.19 MemberConverter에서 스위치문을 위해 정수 값 매핑 추가 public enum Gender { - MALE, FEMALE, OTHER, UNKNOWN; + MALE(1), FEMALE(2), OTHER(3), UNKNOWN(4); + + private final int value; + + Gender(int value) { + this.value = value; + } + public int getValue() { + return value; + } + + public static Gender fromValue(int value) { + for (Gender gender : Gender.values()) { + if (gender.getValue() == value) { + return gender; + } + } + throw new IllegalArgumentException("잘못된 Gender의 값: " + value); + } } diff --git a/src/main/java/javalab/umc7th_mission/domain/mapping/MemberPrefer.java b/src/main/java/javalab/umc7th_mission/domain/mapping/MemberPrefer.java index 6dd90a8..812f4f2 100644 --- a/src/main/java/javalab/umc7th_mission/domain/mapping/MemberPrefer.java +++ b/src/main/java/javalab/umc7th_mission/domain/mapping/MemberPrefer.java @@ -25,4 +25,16 @@ public class MemberPrefer extends BaseEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "category_id", referencedColumnName = "id") private FoodCategory foodCategory; + + //24.11.20 setMember & setFoodCategory add + public void setMember(Member member){ + if(this.member != null) + member.getMemberPreferList().remove(this); + this.member = member; + member.getMemberPreferList().add(this); + } + + public void setFoodCategory(FoodCategory foodCategory){ + this.foodCategory = foodCategory; + } } diff --git a/src/main/java/javalab/umc7th_mission/repository/FoodCategoryRepository/FoodCategoryRepository.java b/src/main/java/javalab/umc7th_mission/repository/FoodCategoryRepository/FoodCategoryRepository.java new file mode 100644 index 0000000..adced13 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/repository/FoodCategoryRepository/FoodCategoryRepository.java @@ -0,0 +1,9 @@ +package javalab.umc7th_mission.repository.FoodCategoryRepository; + +import javalab.umc7th_mission.domain.FoodCategory; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface FoodCategoryRepository extends JpaRepository { +} diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepository.java b/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepository.java new file mode 100644 index 0000000..644a62c --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepository.java @@ -0,0 +1,9 @@ +package javalab.umc7th_mission.repository.MemberAddressRepository; + +import javalab.umc7th_mission.domain.mapping.MemberAddress; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface MemberAddressRepository extends JpaRepository { +} diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryCustom.java b/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryCustom.java new file mode 100644 index 0000000..09c03e0 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryCustom.java @@ -0,0 +1,9 @@ +package javalab.umc7th_mission.repository.MemberAddressRepository; + +import javalab.umc7th_mission.domain.mapping.MemberAddress; + +import java.util.List; + +public interface MemberAddressRepositoryCustom { + List findAllAddressByMemberId(Long memberId); +} diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryImpl.java b/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryImpl.java new file mode 100644 index 0000000..8cf69bf --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryImpl.java @@ -0,0 +1,25 @@ +package javalab.umc7th_mission.repository.MemberAddressRepository; + + +import jakarta.persistence.EntityManager; +import jakarta.persistence.TypedQuery; +import javalab.umc7th_mission.domain.mapping.MemberAddress; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +@RequiredArgsConstructor +public class MemberAddressRepositoryImpl implements MemberAddressRepositoryCustom { + private final EntityManager entityManager; + //JPQL을 사용해 MemberAddress 엔티티에서 특정 member의 주소 조회 + @Override + public List findAllAddressByMemberId(Long memberId) { + String jpql = "SELECT ma FROM MemberAddress ma WHERE ma.member.id = :memberId"; + TypedQuery query = entityManager.createQuery(jpql, MemberAddress.class); + query.setParameter("memberId", memberId); + + return query.getResultList(); + } +} diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepository.java b/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepository.java index c98e5af..6d078c4 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepository.java +++ b/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepository.java @@ -2,6 +2,9 @@ import javalab.umc7th_mission.domain.Member; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; -public interface MemberRepository extends JpaRepository { +//24.11.19 -> to , @Repository add +@Repository +public interface MemberRepository extends JpaRepository { } diff --git a/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepository.java b/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepository.java new file mode 100644 index 0000000..e103d52 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepository.java @@ -0,0 +1,13 @@ +package javalab.umc7th_mission.repository.RegionRepository; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import javalab.umc7th_mission.domain.Region; + +import java.util.Optional; + +@Repository +public interface RegionRepository extends JpaRepository { + // 추가로 지역 이름으로 검색할 수 있는 메서드 + Region findByName(String name); +} + diff --git a/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryCustom.java b/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryCustom.java new file mode 100644 index 0000000..2d2301b --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryCustom.java @@ -0,0 +1,4 @@ +package javalab.umc7th_mission.repository.RegionRepository; + +public interface RegionRepositoryCustom { +} diff --git a/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryImpl.java b/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryImpl.java new file mode 100644 index 0000000..82fa17a --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryImpl.java @@ -0,0 +1,4 @@ +package javalab.umc7th_mission.repository.RegionRepository; + +public class RegionRepositoryImpl implements RegionRepositoryCustom { +} diff --git a/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepository.java b/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepository.java index 1936109..66bbf49 100644 --- a/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepository.java +++ b/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepository.java @@ -6,9 +6,12 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; import java.math.BigDecimal; +//24.11.19 @Repository add +@Repository public interface ReviewRepository extends JpaRepository { @Modifying diff --git a/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepository.java b/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepository.java index 6eef78b..df4024a 100644 --- a/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepository.java +++ b/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepository.java @@ -2,6 +2,9 @@ import javalab.umc7th_mission.domain.Store; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +//24.11.19 @Repository add +@Repository public interface StoreRepository extends JpaRepository, StoreRepositoryCustom { } \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandService.java b/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandService.java new file mode 100644 index 0000000..5584ff0 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandService.java @@ -0,0 +1,12 @@ +package javalab.umc7th_mission.service.MemberService; + +import jakarta.validation.Valid; +import javalab.umc7th_mission.apiPayload.ApiResponse; +import javalab.umc7th_mission.domain.Member; +import javalab.umc7th_mission.web.dto.MemberRequestDTO; +import javalab.umc7th_mission.web.dto.MemberResponseDTO; +import org.springframework.web.bind.annotation.RequestBody; + +public interface MemberCommandService { + Member joinMember(MemberRequestDTO.JoinDto request); +} diff --git a/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandServiceImpl.java new file mode 100644 index 0000000..6a9a2f2 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandServiceImpl.java @@ -0,0 +1,68 @@ +package javalab.umc7th_mission.service.MemberService; + +import jakarta.transaction.Transactional; +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import javalab.umc7th_mission.apiPayload.exception.FoodCategoryNotFoundException; +import javalab.umc7th_mission.converter.MemberConverter; +import javalab.umc7th_mission.converter.MemberPreferConverter; +import javalab.umc7th_mission.domain.FoodCategory; +import javalab.umc7th_mission.domain.Member; +import javalab.umc7th_mission.domain.Region; +import javalab.umc7th_mission.domain.enums.Gender; +import javalab.umc7th_mission.domain.mapping.MemberAddress; +import javalab.umc7th_mission.domain.mapping.MemberPrefer; +import javalab.umc7th_mission.repository.FoodCategoryRepository.FoodCategoryRepository; +import javalab.umc7th_mission.repository.MemberAddressRepository.MemberAddressRepository; +import javalab.umc7th_mission.repository.MemberRepository.MemberRepository; +import javalab.umc7th_mission.repository.RegionRepository.RegionRepository; +import javalab.umc7th_mission.web.dto.MemberRequestDTO; +import javalab.umc7th_mission.web.dto.MemberResponseDTO; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class MemberCommandServiceImpl implements MemberCommandService { + private final MemberRepository memberRepository; + private final RegionRepository regionRepository; + private final MemberAddressRepository memberAddressRepository; + private final FoodCategoryRepository foodCategoryRepository; + + @Override + @Transactional //트렌잭션 어노테이션 + public Member joinMember(MemberRequestDTO.JoinDto request) { + //후에 지역을 다 추가하고 해당 지역이 있는지 확인 api필요해보임 + Region region = regionRepository.findByName(request.getRegion()); + + //member 생성 및 저장 + Member newMember = MemberConverter.toMember(request); + + if (newMember.getAddressList() == null) { + newMember.setAddressList(new ArrayList<>()); + } + //foodCategory list 조회 + List foodCategoryList = request.getPreferCategory().stream() + .map(category -> { + return foodCategoryRepository.findById(category).orElseThrow(() -> new FoodCategoryNotFoundException(ErrorStatus.FOOD_CATEGORY_NOT_FOUND)); + }).collect(Collectors.toList()); + + //list 생성 및 Member와 연결 + List memberPreferList = MemberPreferConverter.toMemberPreferList(foodCategoryList); + memberPreferList.forEach(memberPrefer -> {memberPrefer.setMember(newMember);}); + newMember.setMemberPreferList(memberPreferList); + + //memberAddress 생성 및 연결 + MemberAddress memberAddress = MemberConverter.toMemberAddress(newMember, region, request); + memberAddress.setMember(newMember); + newMember.getAddressList().add(memberAddress); + + memberAddressRepository.save(memberAddress); + + return memberRepository.save(newMember); + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/controller/MemberRestController.java b/src/main/java/javalab/umc7th_mission/web/controller/MemberRestController.java new file mode 100644 index 0000000..db1bcea --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/controller/MemberRestController.java @@ -0,0 +1,27 @@ +package javalab.umc7th_mission.web.controller; + +import jakarta.validation.Valid; +import javalab.umc7th_mission.apiPayload.ApiResponse; +import javalab.umc7th_mission.converter.MemberConverter; +import javalab.umc7th_mission.domain.Member; +import javalab.umc7th_mission.service.MemberService.MemberCommandService; +import javalab.umc7th_mission.web.dto.MemberRequestDTO; +import javalab.umc7th_mission.web.dto.MemberResponseDTO; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/members") +public class MemberRestController { + private final MemberCommandService memberCommandService; + + @PostMapping("/") + public ApiResponse join(@RequestBody @Valid MemberRequestDTO.JoinDto request){ + Member member = memberCommandService.joinMember(request); + return ApiResponse.onSuccess(MemberConverter.toJoinResultDTO(member)); + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java new file mode 100644 index 0000000..1552719 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java @@ -0,0 +1,83 @@ +package javalab.umc7th_mission.web.dto; + +import jakarta.validation.constraints.*; +import javalab.umc7th_mission.domain.enums.Gender; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + + +public class MemberRequestDTO { + + //회원 가입 시 사용하는 DTO + //빌더를 안쓰고 생성자 주입방식 이용 + @Getter + public static class JoinDto { + @NotBlank(message = "이름은 필수 항목입니다.") + @Size(max = 20, message = "이름은 최대 20자까지 가능합니다.") + private final String name; + + @NotBlank(message = "닉네임은 필수 항목입니다.") + @Size(max = 20, message = "닉네임은 최대 20자까지 가능합니다.") + private final String nickname; + + @NotBlank(message = "전화번호는 필수 항목입니다.") + //전화번호 형식 검증 정규식 + @Pattern(regexp = "^(02|0\\d{2})-\\d{3,4}-\\d{4}$", message = "전화번호 형식이 올바르지 않습니다.") + private final String phoneNumber; + + @NotNull(message = "성별은 필수 항목입니다.") + private final Gender gender; + + @NotBlank(message = "이메일은 필수 항목입니다.") + @Email(message = "이메일 형식이 올바르지 않습니다.") + @Size(max = 50, message = "이메일은 최대 50자까지 가능합니다.") + private final String email; + + //어노테이션 추가 필요 지역 관련 이슈 + private final String region; + private final String detailedAddress; + private final String zipcode; + List preferCategory; + + public JoinDto( + @NotBlank(message = "이름은 필수 항목입니다.") + @Size(max = 20, message = "이름은 최대 20자까지 가능합니다.") + String name, + + @NotBlank(message = "닉네임은 필수 항목입니다.") + @Size(max = 20, message = "닉네임은 최대 20자까지 가능합니다.") + String nickname, + + @NotBlank(message = "전화번호는 필수 항목입니다.") + //전화번호 형식 검증 정규식 + @Pattern(regexp = "^(02|0\\d{2})-\\d{3,4}-\\d{4}$", message = "전화번호 형식이 올바르지 않습니다.") + String phoneNumber, + + @NotNull(message = "성별은 필수 항목입니다.") + Gender gender, + + @NotBlank(message = "이메일은 필수 항목입니다.") + @Email(message = "이메일 형식이 올바르지 않습니다.") + @Size(max = 50, message = "이메일은 최대 50자까지 가능합니다.") + String email, + + String region, + String detailedAddress, + String zipcode, + List preferCategory + ) { + this.name = name; + this.nickname = nickname; + this.phoneNumber = phoneNumber; + this.gender = gender; + this.email = email; + this.region = region; + this.detailedAddress = detailedAddress; + this.zipcode = zipcode; + this.preferCategory = preferCategory; + } + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MemberResponseDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MemberResponseDTO.java new file mode 100644 index 0000000..3e6541e --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/dto/MemberResponseDTO.java @@ -0,0 +1,33 @@ +package javalab.umc7th_mission.web.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.mapping.Join; + +import java.time.LocalDateTime; + + +// @NoArgsConstructor -> 불변성 유지를 위해 생성자 여러개 제공 방지 +public class MemberResponseDTO { + public static class JoinResultDTO { + private final Long memberId; + private final LocalDateTime createdAt; + + public JoinResultDTO(Long memberId, LocalDateTime createdAt) { + this.memberId = memberId; + this.createdAt = createdAt; + } + + // 명시적 Getter (Jackson 직렬화를 위해 필요) + public Long getMemberId() { + return memberId; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + } +} From 62a62953c7098ab873ecd51b962b23dd71dcf939 Mon Sep 17 00:00:00 2001 From: KYS Date: Thu, 21 Nov 2024 11:13:00 +0900 Subject: [PATCH 03/11] =?UTF-8?q?=F0=9F=90=9B=20[fix]=20Member=20and=20Mem?= =?UTF-8?q?berAddress=20N:M=20relationship=20to=201:1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../javalab/umc7th_mission/domain/Member.java | 6 ++-- .../domain/mapping/MemberAddress.java | 4 +-- .../MemberMissionRepositoryImpl.java | 2 +- .../MemberPreferRepository.java | 9 ++++++ .../MemberCommandServiceImpl.java | 15 ++++----- .../web/dto/MemberRequestDTO.java | 31 +++++++++---------- 6 files changed, 38 insertions(+), 29 deletions(-) create mode 100644 src/main/java/javalab/umc7th_mission/repository/MemberPreferRepository/MemberPreferRepository.java diff --git a/src/main/java/javalab/umc7th_mission/domain/Member.java b/src/main/java/javalab/umc7th_mission/domain/Member.java index b55ecf7..6bcc319 100644 --- a/src/main/java/javalab/umc7th_mission/domain/Member.java +++ b/src/main/java/javalab/umc7th_mission/domain/Member.java @@ -56,8 +56,10 @@ public class Member extends BaseEntity { @ColumnDefault("0") private Integer point; - @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, fetch = FetchType.LAZY) - private List addressList = new ArrayList<>(); + //24.11.21 fix/#7 + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "address_id") + private MemberAddress address; @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List memberAgreeList = new ArrayList<>(); diff --git a/src/main/java/javalab/umc7th_mission/domain/mapping/MemberAddress.java b/src/main/java/javalab/umc7th_mission/domain/mapping/MemberAddress.java index 3fd6336..bc34677 100644 --- a/src/main/java/javalab/umc7th_mission/domain/mapping/MemberAddress.java +++ b/src/main/java/javalab/umc7th_mission/domain/mapping/MemberAddress.java @@ -23,8 +23,8 @@ public class MemberAddress extends BaseEntity { @JoinColumn(name = "region_id", referencedColumnName = "id") private Region region; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id", referencedColumnName = "id") + //24.11.21 fix/#7 + @OneToOne(mappedBy = "address",fetch = FetchType.LAZY, cascade = CascadeType.ALL) private Member member; @Column(nullable = false, length = 100) diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryImpl.java b/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryImpl.java index de0e4d1..96f7be8 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryImpl.java +++ b/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryImpl.java @@ -78,7 +78,7 @@ public Long countCompletedMissionByMember(Long memberId, String regionName) { .from(memberMission) .join(memberMission.mission, mission) .join(mission.store, store) - .join(store.addressList, storeAddress) + .join(storeAddress, storeAddress) .where( memberMission.member.id.eq(memberId), memberMission.status.eq(MissionStatus.COMPLETE), diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberPreferRepository/MemberPreferRepository.java b/src/main/java/javalab/umc7th_mission/repository/MemberPreferRepository/MemberPreferRepository.java new file mode 100644 index 0000000..40415fc --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/repository/MemberPreferRepository/MemberPreferRepository.java @@ -0,0 +1,9 @@ +package javalab.umc7th_mission.repository.MemberPreferRepository; + +import javalab.umc7th_mission.domain.mapping.MemberPrefer; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface MemberPreferRepository extends JpaRepository { +} diff --git a/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandServiceImpl.java index 6a9a2f2..5ecead1 100644 --- a/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandServiceImpl.java +++ b/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandServiceImpl.java @@ -3,12 +3,12 @@ import jakarta.transaction.Transactional; import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; import javalab.umc7th_mission.apiPayload.exception.FoodCategoryNotFoundException; +import javalab.umc7th_mission.apiPayload.exception.RegionNotFoundException; import javalab.umc7th_mission.converter.MemberConverter; import javalab.umc7th_mission.converter.MemberPreferConverter; import javalab.umc7th_mission.domain.FoodCategory; import javalab.umc7th_mission.domain.Member; import javalab.umc7th_mission.domain.Region; -import javalab.umc7th_mission.domain.enums.Gender; import javalab.umc7th_mission.domain.mapping.MemberAddress; import javalab.umc7th_mission.domain.mapping.MemberPrefer; import javalab.umc7th_mission.repository.FoodCategoryRepository.FoodCategoryRepository; @@ -36,15 +36,13 @@ public class MemberCommandServiceImpl implements MemberCommandService { @Override @Transactional //트렌잭션 어노테이션 public Member joinMember(MemberRequestDTO.JoinDto request) { - //후에 지역을 다 추가하고 해당 지역이 있는지 확인 api필요해보임 Region region = regionRepository.findByName(request.getRegion()); + if (region == null) { + throw new RegionNotFoundException(ErrorStatus.REGION_NOT_FOUND); + } //member 생성 및 저장 Member newMember = MemberConverter.toMember(request); - - if (newMember.getAddressList() == null) { - newMember.setAddressList(new ArrayList<>()); - } //foodCategory list 조회 List foodCategoryList = request.getPreferCategory().stream() .map(category -> { @@ -56,10 +54,13 @@ public Member joinMember(MemberRequestDTO.JoinDto request) { memberPreferList.forEach(memberPrefer -> {memberPrefer.setMember(newMember);}); newMember.setMemberPreferList(memberPreferList); + //24.11.21 fix/#7 //memberAddress 생성 및 연결 MemberAddress memberAddress = MemberConverter.toMemberAddress(newMember, region, request); + + memberAddress.setMember(newMember); - newMember.getAddressList().add(memberAddress); + newMember.setAddress(memberAddress); memberAddressRepository.save(memberAddress); diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java index 1552719..53cc789 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java @@ -36,34 +36,31 @@ public static class JoinDto { @Size(max = 50, message = "이메일은 최대 50자까지 가능합니다.") private final String email; - //어노테이션 추가 필요 지역 관련 이슈 + //24.11.21 fix/#7 + @NotBlank(message = "지역명은 필수 항목입니다.") + @Size(max = 50, message = "지역명은 최대 50자까지 가능합니다.") private final String region; + + @NotBlank(message = "세부 주소는 필수 항목입니다.") + @Size(max = 100, message = "세부 주소는 최대 100자까지 가능합니다.") private final String detailedAddress; + + @NotBlank(message = "우편번호는 필수 항목입니다.") + @Size(max = 40, message = "우편번호는 최대 40자까지 가능합니다.") private final String zipcode; + List preferCategory; + /* + 24.11.21 fix/#7 -> remove @ + 유효성 검증은 객체 생성 이후에 처리되도록 설계 -> 생성자에서 어노테이션을 적용할 이유 없음 + */ public JoinDto( - @NotBlank(message = "이름은 필수 항목입니다.") - @Size(max = 20, message = "이름은 최대 20자까지 가능합니다.") String name, - - @NotBlank(message = "닉네임은 필수 항목입니다.") - @Size(max = 20, message = "닉네임은 최대 20자까지 가능합니다.") String nickname, - - @NotBlank(message = "전화번호는 필수 항목입니다.") - //전화번호 형식 검증 정규식 - @Pattern(regexp = "^(02|0\\d{2})-\\d{3,4}-\\d{4}$", message = "전화번호 형식이 올바르지 않습니다.") String phoneNumber, - - @NotNull(message = "성별은 필수 항목입니다.") Gender gender, - - @NotBlank(message = "이메일은 필수 항목입니다.") - @Email(message = "이메일 형식이 올바르지 않습니다.") - @Size(max = 50, message = "이메일은 최대 50자까지 가능합니다.") String email, - String region, String detailedAddress, String zipcode, From c314f8faba37d47530d3317a92066501a110cc1f Mon Sep 17 00:00:00 2001 From: KYS Date: Thu, 21 Nov 2024 11:45:54 +0900 Subject: [PATCH 04/11] =?UTF-8?q?=E2=9C=A8=20[Feat]=20Add=20an=20API=20to?= =?UTF-8?q?=20add=20stores=20to=20a=20specific=20area?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apiPayload/code/status/ErrorStatus.java | 5 +- .../apiPayload/exception/ExceptionAdvice.java | 20 ++++++ .../exception/RegionNotFoundException.java | 16 +++++ .../converter/StoreCategoryConverter.java | 19 +++++ .../converter/StoreConverter.java | 40 +++++++++++ .../javalab/umc7th_mission/domain/Store.java | 6 +- .../domain/mapping/StoreAddress.java | 3 +- .../MemberMissionRepositoryImpl.java | 2 +- .../StoreAddressRepository.java | 9 +++ .../StoreAddressRepositoryCustom.java | 4 ++ .../StoreAddressRepositoryImpl.java | 4 ++ .../StoreService/StoreCommandService.java | 9 +++ .../StoreService/StoreCommandServiceImpl.java | 62 ++++++++++++++++ .../web/controller/StoreRestController.java | 28 ++++++++ .../web/dto/StoreRequestDTO.java | 71 +++++++++++++++++++ .../web/dto/StoreResponseDTO.java | 24 +++++++ 16 files changed, 315 insertions(+), 7 deletions(-) create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/exception/RegionNotFoundException.java create mode 100644 src/main/java/javalab/umc7th_mission/converter/StoreCategoryConverter.java create mode 100644 src/main/java/javalab/umc7th_mission/converter/StoreConverter.java create mode 100644 src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepository.java create mode 100644 src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryCustom.java create mode 100644 src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryImpl.java create mode 100644 src/main/java/javalab/umc7th_mission/service/StoreService/StoreCommandService.java create mode 100644 src/main/java/javalab/umc7th_mission/service/StoreService/StoreCommandServiceImpl.java create mode 100644 src/main/java/javalab/umc7th_mission/web/controller/StoreRestController.java create mode 100644 src/main/java/javalab/umc7th_mission/web/dto/StoreRequestDTO.java create mode 100644 src/main/java/javalab/umc7th_mission/web/dto/StoreResponseDTO.java diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java b/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java index 5298851..5528c83 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java @@ -26,8 +26,9 @@ public enum ErrorStatus implements BaseErrorCode { // 예시,,, ARTICLE_NOT_FOUND(HttpStatus.NOT_FOUND, "ARTICLE4001", "게시글이 없습니다."), - //음식 카테고리 없음 - FOOD_CATEGORY_NOT_FOUND(HttpStatus.NOT_FOUND, "FOOD4001", "해당 음식 카테고리가 없습니다."); + //해당 지역 혹은 카테고리 없음 + FOOD_CATEGORY_NOT_FOUND(HttpStatus.NOT_FOUND, "FOOD4001", "해당 음식 카테고리가 없습니다."), + REGION_NOT_FOUND(HttpStatus.NOT_FOUND, "REGION4001", "해당 지역이 없습니다."); private final HttpStatus httpStatus; diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java index 77ab641..141afac 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java @@ -86,6 +86,26 @@ public ResponseEntity handleFoodCategoryNotFoundException(FoodCategoryNo ); } + //RegionNotFoundException에 대한 에러 처리 + @ExceptionHandler(RegionNotFoundException.class) + public ResponseEntity handleRegionNotFoundException(RegionNotFoundException e, HttpServletRequest request) { + WebRequest webRequest = new ServletWebRequest(request); + + ApiResponse body = ApiResponse.onFailure( + ErrorStatus.REGION_NOT_FOUND.getCode(), + ErrorStatus.REGION_NOT_FOUND.getMessage(), + null + ); + + return super.handleExceptionInternal( + e, + body, + new HttpHeaders(), + ErrorStatus.REGION_NOT_FOUND.getHttpStatus(), + webRequest + ); + } + private ResponseEntity handleExceptionInternal(Exception e, ErrorReasonDTO reason, HttpHeaders headers, HttpServletRequest request) { diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/RegionNotFoundException.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/RegionNotFoundException.java new file mode 100644 index 0000000..36fafae --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/RegionNotFoundException.java @@ -0,0 +1,16 @@ +package javalab.umc7th_mission.apiPayload.exception; + +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import org.springframework.http.HttpStatus; + +public class RegionNotFoundException extends RuntimeException { + private final HttpStatus status = HttpStatus.NOT_FOUND; + + public RegionNotFoundException(ErrorStatus errorStatus) { + super(errorStatus.getMessage()); + } + + public HttpStatus getStatus() { + return status; + } +} diff --git a/src/main/java/javalab/umc7th_mission/converter/StoreCategoryConverter.java b/src/main/java/javalab/umc7th_mission/converter/StoreCategoryConverter.java new file mode 100644 index 0000000..eadcb3b --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/converter/StoreCategoryConverter.java @@ -0,0 +1,19 @@ +package javalab.umc7th_mission.converter; + +import javalab.umc7th_mission.domain.FoodCategory; +import javalab.umc7th_mission.domain.mapping.StoreCategory; + +import java.util.List; +import java.util.stream.Collectors; + +public class StoreCategoryConverter { + public static List toStoreCategoryList(List foodCategoryList){ + + return foodCategoryList.stream() + .map(foodCategory -> + StoreCategory.builder() + .foodCategory(foodCategory) + .build() + ).collect(Collectors.toList()); + } +} diff --git a/src/main/java/javalab/umc7th_mission/converter/StoreConverter.java b/src/main/java/javalab/umc7th_mission/converter/StoreConverter.java new file mode 100644 index 0000000..f3769a5 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/converter/StoreConverter.java @@ -0,0 +1,40 @@ +package javalab.umc7th_mission.converter; + +import javalab.umc7th_mission.domain.Member; +import javalab.umc7th_mission.domain.Region; +import javalab.umc7th_mission.domain.Store; +import javalab.umc7th_mission.domain.mapping.StoreAddress; +import javalab.umc7th_mission.web.dto.MemberRequestDTO; +import javalab.umc7th_mission.web.dto.StoreRequestDTO; +import javalab.umc7th_mission.web.dto.StoreResponseDTO; + +public class StoreConverter { + + public static StoreResponseDTO.AddResultDTO toAddResultDTO(Store store) { + return new StoreResponseDTO.AddResultDTO( + store.getId(), + store.getCreatedAt() + ); + } + + public static Store toStore(StoreRequestDTO.AddDto request) { + return Store.builder() + .name(request.getName()) + .phoneNumber(request.getPhoneNumber()) + .description(request.getDescription()) + .openingHours(request.getOpeningHours()) + .closingHours(request.getClosingHours()) + .build(); + } + + public static StoreAddress toStoreAddress(Store store, Region region, StoreRequestDTO.AddDto request) { + return StoreAddress.builder() + .region(region) + .store(store) + .detailAddress(request.getDetailedAddress()) + .zipCode(request.getZipcode()) + .build(); + } +} + + diff --git a/src/main/java/javalab/umc7th_mission/domain/Store.java b/src/main/java/javalab/umc7th_mission/domain/Store.java index deb4856..beea1ce 100644 --- a/src/main/java/javalab/umc7th_mission/domain/Store.java +++ b/src/main/java/javalab/umc7th_mission/domain/Store.java @@ -38,8 +38,10 @@ public class Store extends BaseEntity { @Column(nullable = false, length = 255) private String closingHours; - @OneToMany(mappedBy = "store", cascade = CascadeType.ALL, fetch = FetchType.LAZY) - private List addressList = new ArrayList<>(); + //24.11.20 StoreAddress와의 관계 재설정!! + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "address_id") + private StoreAddress address; @OneToMany(mappedBy = "store", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List categoryList = new ArrayList<>(); diff --git a/src/main/java/javalab/umc7th_mission/domain/mapping/StoreAddress.java b/src/main/java/javalab/umc7th_mission/domain/mapping/StoreAddress.java index 358179c..4711f20 100644 --- a/src/main/java/javalab/umc7th_mission/domain/mapping/StoreAddress.java +++ b/src/main/java/javalab/umc7th_mission/domain/mapping/StoreAddress.java @@ -23,8 +23,7 @@ public class StoreAddress extends BaseEntity { @JoinColumn(name = "region_id", referencedColumnName = "id") private Region region; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "store_id", referencedColumnName = "id") + @OneToOne(mappedBy = "address",fetch = FetchType.LAZY, cascade = CascadeType.ALL) private Store store; @Column(nullable = false, length = 100) diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryImpl.java b/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryImpl.java index de0e4d1..1d3a6e4 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryImpl.java +++ b/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryImpl.java @@ -78,7 +78,7 @@ public Long countCompletedMissionByMember(Long memberId, String regionName) { .from(memberMission) .join(memberMission.mission, mission) .join(mission.store, store) - .join(store.addressList, storeAddress) + .join(store.address, storeAddress) .where( memberMission.member.id.eq(memberId), memberMission.status.eq(MissionStatus.COMPLETE), diff --git a/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepository.java b/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepository.java new file mode 100644 index 0000000..3a55634 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepository.java @@ -0,0 +1,9 @@ +package javalab.umc7th_mission.repository.StoreAddressRepository; + +import javalab.umc7th_mission.domain.mapping.StoreAddress; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface StoreAddressRepository extends JpaRepository, StoreAddressRepositoryCustom { +} diff --git a/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryCustom.java b/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryCustom.java new file mode 100644 index 0000000..6efaf9a --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryCustom.java @@ -0,0 +1,4 @@ +package javalab.umc7th_mission.repository.StoreAddressRepository; + +public interface StoreAddressRepositoryCustom { +} diff --git a/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryImpl.java b/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryImpl.java new file mode 100644 index 0000000..eb78b78 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryImpl.java @@ -0,0 +1,4 @@ +package javalab.umc7th_mission.repository.StoreAddressRepository; + +public class StoreAddressRepositoryImpl implements StoreAddressRepositoryCustom { +} diff --git a/src/main/java/javalab/umc7th_mission/service/StoreService/StoreCommandService.java b/src/main/java/javalab/umc7th_mission/service/StoreService/StoreCommandService.java new file mode 100644 index 0000000..c3c91d4 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/StoreService/StoreCommandService.java @@ -0,0 +1,9 @@ +package javalab.umc7th_mission.service.StoreService; + +import javalab.umc7th_mission.domain.Store; +import javalab.umc7th_mission.web.dto.StoreRequestDTO; + +public interface StoreCommandService { + // 가게 저장 + Store addStore(StoreRequestDTO.AddDto request); +} diff --git a/src/main/java/javalab/umc7th_mission/service/StoreService/StoreCommandServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/StoreService/StoreCommandServiceImpl.java new file mode 100644 index 0000000..0b29fe3 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/StoreService/StoreCommandServiceImpl.java @@ -0,0 +1,62 @@ +package javalab.umc7th_mission.service.StoreService; + +import jakarta.transaction.Transactional; +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import javalab.umc7th_mission.apiPayload.exception.FoodCategoryNotFoundException; +import javalab.umc7th_mission.apiPayload.exception.RegionNotFoundException; +import javalab.umc7th_mission.converter.StoreCategoryConverter; +import javalab.umc7th_mission.converter.StoreConverter; +import javalab.umc7th_mission.domain.FoodCategory; +import javalab.umc7th_mission.domain.Region; +import javalab.umc7th_mission.domain.Store; +import javalab.umc7th_mission.domain.mapping.StoreAddress; +import javalab.umc7th_mission.domain.mapping.StoreCategory; +import javalab.umc7th_mission.repository.FoodCategoryRepository.FoodCategoryRepository; +import javalab.umc7th_mission.repository.RegionRepository.RegionRepository; +import javalab.umc7th_mission.repository.StoreAddressRepository.StoreAddressRepository; +import javalab.umc7th_mission.repository.StoreRepository.StoreRepository; +import javalab.umc7th_mission.web.dto.StoreRequestDTO; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class StoreCommandServiceImpl implements StoreCommandService { + private final StoreRepository storeRepository; + private final StoreAddressRepository storeAddressRepository; + private final RegionRepository regionRepository; + private final FoodCategoryRepository foodCategoryRepository; + + @Override + @Transactional + public Store addStore(StoreRequestDTO.AddDto request) { + Region region = regionRepository.findByName(request.getRegion()); + if (region == null) { + throw new RegionNotFoundException(ErrorStatus.REGION_NOT_FOUND); + } + + + Store newStore = StoreConverter.toStore(request); + StoreAddress storeAddress = StoreConverter.toStoreAddress(newStore, region, request); + + //StoreCategory 생성필요 + //foodCategory list 조회 + List foodCategoryList = request.getStoreCategory().stream() + .map(category -> { + return foodCategoryRepository.findById(category).orElseThrow(() -> new FoodCategoryNotFoundException(ErrorStatus.FOOD_CATEGORY_NOT_FOUND)); + }).collect(Collectors.toList()); + + List storeCategoryList = StoreCategoryConverter.toStoreCategoryList(foodCategoryList); + storeCategoryList.forEach(memberPrefer -> {memberPrefer.setStore(newStore);}); + + newStore.setCategoryList(storeCategoryList); + storeAddress.setStore(newStore); + newStore.setAddress(storeAddress); + + storeAddressRepository.save(storeAddress); + return storeRepository.save(newStore); + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/controller/StoreRestController.java b/src/main/java/javalab/umc7th_mission/web/controller/StoreRestController.java new file mode 100644 index 0000000..997f319 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/controller/StoreRestController.java @@ -0,0 +1,28 @@ +package javalab.umc7th_mission.web.controller; + +import jakarta.validation.Valid; +import javalab.umc7th_mission.apiPayload.ApiResponse; +import javalab.umc7th_mission.converter.StoreConverter; +import javalab.umc7th_mission.domain.Store; +import javalab.umc7th_mission.service.StoreService.StoreCommandService; +import javalab.umc7th_mission.web.dto.StoreRequestDTO; +import javalab.umc7th_mission.web.dto.StoreResponseDTO; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/stores") +public class StoreRestController { + private final StoreCommandService storeCommandService; + + @PostMapping("/") + public ApiResponse join(@RequestBody @Valid StoreRequestDTO.AddDto request){ + + Store store = storeCommandService.addStore(request); + return ApiResponse.onSuccess(StoreConverter.toAddResultDTO(store)); + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/dto/StoreRequestDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/StoreRequestDTO.java new file mode 100644 index 0000000..42fb0c0 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/dto/StoreRequestDTO.java @@ -0,0 +1,71 @@ +package javalab.umc7th_mission.web.dto; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import lombok.Getter; + +import java.util.List; + +public class StoreRequestDTO { + + @Getter + public static class AddDto { + @NotBlank(message = "가게 이름은 필수 항목입니다.") + @Size(max = 30, message = "최대 30자까지 입력 가능합니다.") + private final String name; + + @NotBlank(message = "전화번호는 필수 항목입니다.") + //전화번호 형식 검증 정규식 + @Pattern(regexp = "^(02|0\\d{2})-\\d{3,4}-\\d{4}$", message = "전화번호 형식이 올바르지 않습니다.") + private final String phoneNumber; + + @NotBlank(message = "가게 설명은 필수 항목입니다.") + @Size(max = 500, message = "최대 500자까지 입력 가능합니다.") + private final String description; + + @NotBlank(message = "오픈 시간은 필수 항목입니다.") + @Size(max = 255, message = "최대 255자까지 입력 가능하니다.") + @Pattern( + regexp = "^([01]?[0-9]|2[0-3]):[0-5][0-9]$", + message = "오픈 시간은 'HH:mm' 형식이어야 합니다. (예: 09:00, 23:59)" + ) + private final String openingHours; + + @NotBlank(message = "마감 시간은 필수 항목입니다.") + @Size(max = 255, message = "최대 255자까지 입력 가능하니다.") + @Pattern( + regexp = "^([01]?[0-9]|2[0-3]):[0-5][0-9]$", + message = "마감 시간은 'HH:mm' 형식이어야 합니다. (예: 09:00, 23:59)" + ) + private final String closingHours; + + private final String region; + private final String detailedAddress; + private final String zipcode; + private final List storeCategory; + + public AddDto( + String name, + String phoneNumber, + String description, + String openingHours, + String closingHours, + + String region, + String detailedAddress, + String zipcode, + List storeCategory + ) { + this.name = name; + this.phoneNumber = phoneNumber; + this.description = description; + this.openingHours = openingHours; + this.closingHours = closingHours; + this.region = region; + this.detailedAddress = detailedAddress; + this.zipcode = zipcode; + this.storeCategory = storeCategory; + } + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/dto/StoreResponseDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/StoreResponseDTO.java new file mode 100644 index 0000000..5e33057 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/dto/StoreResponseDTO.java @@ -0,0 +1,24 @@ +package javalab.umc7th_mission.web.dto; + +import java.time.LocalDateTime; + +public class StoreResponseDTO { + public static class AddResultDTO { + private final Long storeId; + private final LocalDateTime createdAt; + + public AddResultDTO(Long storeId, LocalDateTime createdAt) { + this.storeId = storeId; + this.createdAt = createdAt; + } + + // 명시적 Getter (Jackson 직렬화를 위해 필요) + public Long getMemberId() { + return storeId; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + } +} From 1db61071e2a99b88deed025d3fb41a0a4822c4be Mon Sep 17 00:00:00 2001 From: KYS Date: Thu, 21 Nov 2024 14:07:29 +0900 Subject: [PATCH 05/11] =?UTF-8?q?=E2=9C=A8=20[Feat]=20Add=20API=20to=20add?= =?UTF-8?q?=20review=20to=20store?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apiPayload/code/status/ErrorStatus.java | 1 + .../apiPayload/exception/ExceptionAdvice.java | 38 ++++++++++++++++ .../exception/MemberNotFoundException.java | 16 +++++++ .../exception/StoreNotFoundException.java | 16 +++++++ .../converter/ReviewConverter.java | 27 ++++++++++++ .../umc7th_mission/domain/ReviewImage.java | 2 + .../ReviewCommandService.java | 8 ++++ .../ReviewCommandServiceImpl.java | 38 ++++++++++++++++ .../StoreCommandService.java | 2 +- .../StoreCommandServiceImpl.java | 2 +- .../web/controller/ReviewRestController.java | 27 ++++++++++++ .../web/controller/StoreRestController.java | 2 +- .../web/dto/ReviewRequestDTO.java | 44 +++++++++++++++++++ .../web/dto/ReviewResponseDTO.java | 24 ++++++++++ 14 files changed, 244 insertions(+), 3 deletions(-) create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/exception/MemberNotFoundException.java create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/exception/StoreNotFoundException.java create mode 100644 src/main/java/javalab/umc7th_mission/converter/ReviewConverter.java create mode 100644 src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandService.java create mode 100644 src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandServiceImpl.java rename src/main/java/javalab/umc7th_mission/service/{StoreService => StoreCommandService}/StoreCommandService.java (78%) rename src/main/java/javalab/umc7th_mission/service/{StoreService => StoreCommandService}/StoreCommandServiceImpl.java (97%) create mode 100644 src/main/java/javalab/umc7th_mission/web/controller/ReviewRestController.java create mode 100644 src/main/java/javalab/umc7th_mission/web/dto/ReviewRequestDTO.java create mode 100644 src/main/java/javalab/umc7th_mission/web/dto/ReviewResponseDTO.java diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java b/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java index 5528c83..f851d97 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java @@ -23,6 +23,7 @@ public enum ErrorStatus implements BaseErrorCode { MEMBER_NOT_FOUND(HttpStatus.BAD_REQUEST, "MEMBER4001", "사용자가 없습니다."), NICKNAME_NOT_EXIST(HttpStatus.BAD_REQUEST, "MEMBER4002", "닉네임은 필수 입니다."), + STORE_NOT_FOUND(HttpStatus.BAD_REQUEST, "STORE4001", "상점이 없습니다."), // 예시,,, ARTICLE_NOT_FOUND(HttpStatus.NOT_FOUND, "ARTICLE4001", "게시글이 없습니다."), diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java index 141afac..b219c9f 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java @@ -106,6 +106,44 @@ public ResponseEntity handleRegionNotFoundException(RegionNotFoundExcept ); } + @ExceptionHandler(MemberNotFoundException.class) + public ResponseEntity handleMemberNotFoundException(MemberNotFoundException e, HttpServletRequest request) { + WebRequest webRequest = new ServletWebRequest(request); + + ApiResponse body = ApiResponse.onFailure( + ErrorStatus.MEMBER_NOT_FOUND.getCode(), + ErrorStatus.MEMBER_NOT_FOUND.getMessage(), + null + ); + + return super.handleExceptionInternal( + e, + body, + new HttpHeaders(), + ErrorStatus.MEMBER_NOT_FOUND.getHttpStatus(), + webRequest + ); + } + + @ExceptionHandler(StoreNotFoundException.class) + public ResponseEntity handleStoreNotFoundException(StoreNotFoundException e, HttpServletRequest request) { + WebRequest webRequest = new ServletWebRequest(request); + + ApiResponse body = ApiResponse.onFailure( + ErrorStatus.STORE_NOT_FOUND.getCode(), + ErrorStatus.STORE_NOT_FOUND.getMessage(), + null + ); + + return super.handleExceptionInternal( + e, + body, + new HttpHeaders(), + ErrorStatus.STORE_NOT_FOUND.getHttpStatus(), + webRequest + ); + } + private ResponseEntity handleExceptionInternal(Exception e, ErrorReasonDTO reason, HttpHeaders headers, HttpServletRequest request) { diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/MemberNotFoundException.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/MemberNotFoundException.java new file mode 100644 index 0000000..9e5489e --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/MemberNotFoundException.java @@ -0,0 +1,16 @@ +package javalab.umc7th_mission.apiPayload.exception; + +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import org.springframework.http.HttpStatus; + +public class MemberNotFoundException extends RuntimeException { + private final HttpStatus status = HttpStatus.BAD_REQUEST; + + public MemberNotFoundException(ErrorStatus errorStatus) { + super(errorStatus.getMessage()); + } + + public HttpStatus getStatus() { + return status; + } +} diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/StoreNotFoundException.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/StoreNotFoundException.java new file mode 100644 index 0000000..5f7735b --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/StoreNotFoundException.java @@ -0,0 +1,16 @@ +package javalab.umc7th_mission.apiPayload.exception; + +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import org.springframework.http.HttpStatus; + +public class StoreNotFoundException extends RuntimeException { + private final HttpStatus status = HttpStatus.BAD_REQUEST; + + public StoreNotFoundException(ErrorStatus errorStatus) { + super(errorStatus.getMessage()); + } + + public HttpStatus getStatus() { + return status; + } +} diff --git a/src/main/java/javalab/umc7th_mission/converter/ReviewConverter.java b/src/main/java/javalab/umc7th_mission/converter/ReviewConverter.java new file mode 100644 index 0000000..2d89aaf --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/converter/ReviewConverter.java @@ -0,0 +1,27 @@ +package javalab.umc7th_mission.converter; + +import javalab.umc7th_mission.domain.Member; +import javalab.umc7th_mission.domain.Review; +import javalab.umc7th_mission.domain.Store; +import javalab.umc7th_mission.web.dto.ReviewRequestDTO; +import javalab.umc7th_mission.web.dto.ReviewResponseDTO; + +public class ReviewConverter { + + public static ReviewResponseDTO.AddResultDTO toAddResultDTO(Review review) { + return new ReviewResponseDTO.AddResultDTO( + review.getId(), + review.getCreatedAt() + ); + } + + public static Review toReview(Member member, Store store, ReviewRequestDTO.AddDTO request) { + return Review.builder() + .member(member) + .store(store) + .content(request.getContent()) + .rating(request.getRating()) + .reviewImageList(request.getReviewImageList()) + .build(); + } +} diff --git a/src/main/java/javalab/umc7th_mission/domain/ReviewImage.java b/src/main/java/javalab/umc7th_mission/domain/ReviewImage.java index 1d9c054..7c71480 100644 --- a/src/main/java/javalab/umc7th_mission/domain/ReviewImage.java +++ b/src/main/java/javalab/umc7th_mission/domain/ReviewImage.java @@ -1,5 +1,6 @@ package javalab.umc7th_mission.domain; +import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.*; import javalab.umc7th_mission.domain.common.BaseEntity; import lombok.*; @@ -26,5 +27,6 @@ public class ReviewImage extends BaseEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "review_id") + @JsonIgnore //순환참조 방지 private Review review; } diff --git a/src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandService.java b/src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandService.java new file mode 100644 index 0000000..4346012 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandService.java @@ -0,0 +1,8 @@ +package javalab.umc7th_mission.service.ReviewCommandService; + +import javalab.umc7th_mission.domain.Review; +import javalab.umc7th_mission.web.dto.ReviewRequestDTO; + +public interface ReviewCommandService { + Review addReview(ReviewRequestDTO.AddDTO request); +} diff --git a/src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandServiceImpl.java new file mode 100644 index 0000000..679e953 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandServiceImpl.java @@ -0,0 +1,38 @@ +package javalab.umc7th_mission.service.ReviewCommandService; + +import jakarta.transaction.Transactional; +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import javalab.umc7th_mission.apiPayload.exception.MemberNotFoundException; +import javalab.umc7th_mission.apiPayload.exception.StoreNotFoundException; +import javalab.umc7th_mission.converter.ReviewConverter; +import javalab.umc7th_mission.domain.Member; +import javalab.umc7th_mission.domain.Review; +import javalab.umc7th_mission.domain.Store; +import javalab.umc7th_mission.repository.MemberRepository.MemberRepository; +import javalab.umc7th_mission.repository.ReviewRepository.ReviewRepository; +import javalab.umc7th_mission.repository.StoreRepository.StoreRepository; +import javalab.umc7th_mission.web.dto.ReviewRequestDTO; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class ReviewCommandServiceImpl implements ReviewCommandService { + private final ReviewRepository reviewRepository; + private final MemberRepository memberRepository; + private final StoreRepository storeRepository; + + @Transactional + @Override + public Review addReview(ReviewRequestDTO.AddDTO request) { + Member member = memberRepository.findById(request.getMemberId()) + .orElseThrow(() -> new MemberNotFoundException(ErrorStatus.MEMBER_NOT_FOUND)); + + Store store = storeRepository.findById(request.getStoreId()) + .orElseThrow(() -> new StoreNotFoundException(ErrorStatus.STORE_NOT_FOUND)); + + Review newReview = ReviewConverter.toReview(member, store, request); + + return reviewRepository.save(newReview); + } +} diff --git a/src/main/java/javalab/umc7th_mission/service/StoreService/StoreCommandService.java b/src/main/java/javalab/umc7th_mission/service/StoreCommandService/StoreCommandService.java similarity index 78% rename from src/main/java/javalab/umc7th_mission/service/StoreService/StoreCommandService.java rename to src/main/java/javalab/umc7th_mission/service/StoreCommandService/StoreCommandService.java index c3c91d4..5f87e85 100644 --- a/src/main/java/javalab/umc7th_mission/service/StoreService/StoreCommandService.java +++ b/src/main/java/javalab/umc7th_mission/service/StoreCommandService/StoreCommandService.java @@ -1,4 +1,4 @@ -package javalab.umc7th_mission.service.StoreService; +package javalab.umc7th_mission.service.StoreCommandService; import javalab.umc7th_mission.domain.Store; import javalab.umc7th_mission.web.dto.StoreRequestDTO; diff --git a/src/main/java/javalab/umc7th_mission/service/StoreService/StoreCommandServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/StoreCommandService/StoreCommandServiceImpl.java similarity index 97% rename from src/main/java/javalab/umc7th_mission/service/StoreService/StoreCommandServiceImpl.java rename to src/main/java/javalab/umc7th_mission/service/StoreCommandService/StoreCommandServiceImpl.java index 0b29fe3..4625ec8 100644 --- a/src/main/java/javalab/umc7th_mission/service/StoreService/StoreCommandServiceImpl.java +++ b/src/main/java/javalab/umc7th_mission/service/StoreCommandService/StoreCommandServiceImpl.java @@ -1,4 +1,4 @@ -package javalab.umc7th_mission.service.StoreService; +package javalab.umc7th_mission.service.StoreCommandService; import jakarta.transaction.Transactional; import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; diff --git a/src/main/java/javalab/umc7th_mission/web/controller/ReviewRestController.java b/src/main/java/javalab/umc7th_mission/web/controller/ReviewRestController.java new file mode 100644 index 0000000..769df8c --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/controller/ReviewRestController.java @@ -0,0 +1,27 @@ +package javalab.umc7th_mission.web.controller; + +import jakarta.validation.Valid; +import javalab.umc7th_mission.apiPayload.ApiResponse; +import javalab.umc7th_mission.converter.ReviewConverter; +import javalab.umc7th_mission.domain.Review; +import javalab.umc7th_mission.service.ReviewCommandService.ReviewCommandService; +import javalab.umc7th_mission.web.dto.ReviewRequestDTO; +import javalab.umc7th_mission.web.dto.ReviewResponseDTO; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/reviews") +public class ReviewRestController { + private final ReviewCommandService reviewCommandService; + + @PostMapping("/") + public ApiResponse add(@RequestBody @Valid ReviewRequestDTO.AddDTO request) { + Review review = reviewCommandService.addReview(request); + return ApiResponse.onSuccess(ReviewConverter.toAddResultDTO(review)); + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/controller/StoreRestController.java b/src/main/java/javalab/umc7th_mission/web/controller/StoreRestController.java index 997f319..97a6471 100644 --- a/src/main/java/javalab/umc7th_mission/web/controller/StoreRestController.java +++ b/src/main/java/javalab/umc7th_mission/web/controller/StoreRestController.java @@ -4,7 +4,7 @@ import javalab.umc7th_mission.apiPayload.ApiResponse; import javalab.umc7th_mission.converter.StoreConverter; import javalab.umc7th_mission.domain.Store; -import javalab.umc7th_mission.service.StoreService.StoreCommandService; +import javalab.umc7th_mission.service.StoreCommandService.StoreCommandService; import javalab.umc7th_mission.web.dto.StoreRequestDTO; import javalab.umc7th_mission.web.dto.StoreResponseDTO; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/javalab/umc7th_mission/web/dto/ReviewRequestDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/ReviewRequestDTO.java new file mode 100644 index 0000000..465b7fe --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/dto/ReviewRequestDTO.java @@ -0,0 +1,44 @@ +package javalab.umc7th_mission.web.dto; + +import jakarta.validation.constraints.*; +import javalab.umc7th_mission.domain.ReviewImage; +import lombok.Getter; + +import java.math.BigDecimal; +import java.util.List; + +public class ReviewRequestDTO { + + @Getter + public static class AddDTO { + @NotNull(message = "가게 ID는 필수입니다.") + private final Long storeId; + + @NotNull(message = "회원 ID는 필수입니다.") + private final Long memberId; + + @Size(max = 500, message = "리뷰 내용은 최대 500자까지 작성 가능합니다.") + private final String content; + + @DecimalMin(value = "0.0", inclusive = true, message = "별점은 0.0 이상이어야 합니다.") + @DecimalMax(value = "5.0", inclusive = true, message = "별점은 5.0 이하이어야 합니다.") + private final BigDecimal rating; + + private final List reviewImageList; + + public AddDTO( + Long storeId, + Long memberId, + String content, + BigDecimal rating, + List reviewImageList + ) { + this.storeId = storeId; + this.memberId = memberId; + this.content = content; + this.rating = rating; + this.reviewImageList = reviewImageList; + } + + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/dto/ReviewResponseDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/ReviewResponseDTO.java new file mode 100644 index 0000000..a6ce85c --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/dto/ReviewResponseDTO.java @@ -0,0 +1,24 @@ +package javalab.umc7th_mission.web.dto; + +import java.time.LocalDateTime; + +public class ReviewResponseDTO { + public static class AddResultDTO { + private final Long reviewId; + private final LocalDateTime createdAt; + + public AddResultDTO(Long reviewId, LocalDateTime createdAt) { + this.reviewId = reviewId; + this.createdAt = createdAt; + } + + // 명시적 Getter (Jackson 직렬화를 위해 필요) + public Long getReviewId() { + return reviewId; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + } +} From 6de6b914d3139978251de75d63eb42d81643958e Mon Sep 17 00:00:00 2001 From: KYS Date: Thu, 21 Nov 2024 14:39:06 +0900 Subject: [PATCH 06/11] =?UTF-8?q?=F0=9F=93=9D=20[docs]=20Add=20documentati?= =?UTF-8?q?on=20for=20@ExistCategories=20annotation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FoodCategoryService.java | 7 ++++ .../FoodCategoryServiceImpl.java | 20 +++++++++++ .../annotation/ExistCategories.java | 18 ++++++++++ .../validator/CategoriesExistValidator.java | 35 +++++++++++++++++++ .../web/dto/MemberRequestDTO.java | 2 ++ .../web/dto/StoreRequestDTO.java | 3 ++ 6 files changed, 85 insertions(+) create mode 100644 src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryService.java create mode 100644 src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryServiceImpl.java create mode 100644 src/main/java/javalab/umc7th_mission/validation/annotation/ExistCategories.java create mode 100644 src/main/java/javalab/umc7th_mission/validation/validator/CategoriesExistValidator.java diff --git a/src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryService.java b/src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryService.java new file mode 100644 index 0000000..cc650e6 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryService.java @@ -0,0 +1,7 @@ +package javalab.umc7th_mission.service.FoodCategoryService; + +import java.util.List; + +public interface FoodCategoryService { + boolean allCategoriesExist(List values); +} diff --git a/src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryServiceImpl.java new file mode 100644 index 0000000..6d5813a --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryServiceImpl.java @@ -0,0 +1,20 @@ +package javalab.umc7th_mission.service.FoodCategoryService; + +import javalab.umc7th_mission.repository.FoodCategoryRepository.FoodCategoryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class FoodCategoryServiceImpl implements FoodCategoryService { + + FoodCategoryRepository foodCategoryRepository; + + @Override + public boolean allCategoriesExist(List values) { + return values.stream() + .allMatch(id -> foodCategoryRepository.existsById(id)); + } +} diff --git a/src/main/java/javalab/umc7th_mission/validation/annotation/ExistCategories.java b/src/main/java/javalab/umc7th_mission/validation/annotation/ExistCategories.java new file mode 100644 index 0000000..74168c0 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/validation/annotation/ExistCategories.java @@ -0,0 +1,18 @@ +package javalab.umc7th_mission.validation.annotation; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; +import javalab.umc7th_mission.validation.validator.CategoriesExistValidator; + +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/src/main/java/javalab/umc7th_mission/validation/validator/CategoriesExistValidator.java b/src/main/java/javalab/umc7th_mission/validation/validator/CategoriesExistValidator.java new file mode 100644 index 0000000..f871930 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/validation/validator/CategoriesExistValidator.java @@ -0,0 +1,35 @@ +package javalab.umc7th_mission.validation.validator; + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import javalab.umc7th_mission.service.FoodCategoryService.FoodCategoryService; +import javalab.umc7th_mission.validation.annotation.ExistCategories; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@RequiredArgsConstructor +public class CategoriesExistValidator implements ConstraintValidator> { + private final FoodCategoryService foodCategoryService; + + @Override + public void initialize(ExistCategories constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(List values, ConstraintValidatorContext context) { + //개선점: 리포지토리는 "반드시" 서비스단에서만 접근해야됨 -> 간접 접근으로 변경 + boolean isValid = foodCategoryService.allCategoriesExist(values); + + if (!isValid) { + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate(ErrorStatus.FOOD_CATEGORY_NOT_FOUND.toString()).addConstraintViolation(); + } + + return isValid; + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java index 53cc789..2d266e5 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java @@ -2,6 +2,7 @@ import jakarta.validation.constraints.*; import javalab.umc7th_mission.domain.enums.Gender; +import javalab.umc7th_mission.validation.annotation.ExistCategories; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -49,6 +50,7 @@ public static class JoinDto { @Size(max = 40, message = "우편번호는 최대 40자까지 가능합니다.") private final String zipcode; + @ExistCategories List preferCategory; /* diff --git a/src/main/java/javalab/umc7th_mission/web/dto/StoreRequestDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/StoreRequestDTO.java index 42fb0c0..ce0dcc9 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/StoreRequestDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/StoreRequestDTO.java @@ -3,6 +3,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; +import javalab.umc7th_mission.validation.annotation.ExistCategories; import lombok.Getter; import java.util.List; @@ -43,6 +44,8 @@ public static class AddDto { private final String region; private final String detailedAddress; private final String zipcode; + + @ExistCategories private final List storeCategory; public AddDto( From c31046c86a7083a8999966a680e5a924b8840e79 Mon Sep 17 00:00:00 2001 From: KYS Date: Thu, 21 Nov 2024 15:04:19 +0900 Subject: [PATCH 07/11] =?UTF-8?q?=F0=9F=93=9D=20[docs]=20Add=20documentati?= =?UTF-8?q?on=20for=20@ExistStore=20annotation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StoreValidationService.java | 5 +++ .../StoreValidationServiceImpl.java | 16 +++++++++ .../validation/annotation/ExistStore.java | 18 ++++++++++ .../validator/StoreExistValidator.java | 34 +++++++++++++++++++ .../web/dto/ReviewRequestDTO.java | 3 +- 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationService.java create mode 100644 src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationServiceImpl.java create mode 100644 src/main/java/javalab/umc7th_mission/validation/annotation/ExistStore.java create mode 100644 src/main/java/javalab/umc7th_mission/validation/validator/StoreExistValidator.java diff --git a/src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationService.java b/src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationService.java new file mode 100644 index 0000000..1910afe --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationService.java @@ -0,0 +1,5 @@ +package javalab.umc7th_mission.service.StoreValidationService; + +public interface StoreValidationService { + boolean isStoreExist(Long id); +} diff --git a/src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationServiceImpl.java new file mode 100644 index 0000000..bbeae7f --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationServiceImpl.java @@ -0,0 +1,16 @@ +package javalab.umc7th_mission.service.StoreValidationService; + +import javalab.umc7th_mission.repository.StoreRepository.StoreRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class StoreValidationServiceImpl implements StoreValidationService { + private final StoreRepository storeRepository; + + @Override + public boolean isStoreExist(Long id) { + return storeRepository.existsById(id); + } +} diff --git a/src/main/java/javalab/umc7th_mission/validation/annotation/ExistStore.java b/src/main/java/javalab/umc7th_mission/validation/annotation/ExistStore.java new file mode 100644 index 0000000..bc48147 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/validation/annotation/ExistStore.java @@ -0,0 +1,18 @@ +package javalab.umc7th_mission.validation.annotation; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; +import javalab.umc7th_mission.validation.validator.StoreExistValidator; + +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/src/main/java/javalab/umc7th_mission/validation/validator/StoreExistValidator.java b/src/main/java/javalab/umc7th_mission/validation/validator/StoreExistValidator.java new file mode 100644 index 0000000..827fa4f --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/validation/validator/StoreExistValidator.java @@ -0,0 +1,34 @@ +package javalab.umc7th_mission.validation.validator; + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import javalab.umc7th_mission.service.StoreValidationService.StoreValidationService; +import javalab.umc7th_mission.validation.annotation.ExistCategories; +import javalab.umc7th_mission.validation.annotation.ExistStore; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + + +@Component +@RequiredArgsConstructor +public class StoreExistValidator implements ConstraintValidator { + StoreValidationService storeValidationService; + + @Override + public void initialize(ExistStore constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(Long value, ConstraintValidatorContext context) { + boolean isValid = storeValidationService.isStoreExist(value); + + if (!isValid) { + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate(ErrorStatus.STORE_NOT_FOUND.toString()).addConstraintViolation(); + } + + return isValid; + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/dto/ReviewRequestDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/ReviewRequestDTO.java index 465b7fe..21feaa2 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/ReviewRequestDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/ReviewRequestDTO.java @@ -2,6 +2,7 @@ import jakarta.validation.constraints.*; import javalab.umc7th_mission.domain.ReviewImage; +import javalab.umc7th_mission.validation.annotation.ExistStore; import lombok.Getter; import java.math.BigDecimal; @@ -11,7 +12,7 @@ public class ReviewRequestDTO { @Getter public static class AddDTO { - @NotNull(message = "가게 ID는 필수입니다.") + @ExistStore private final Long storeId; @NotNull(message = "회원 ID는 필수입니다.") From 8585f7b2c3b9962e84237534581108ef0db9e332 Mon Sep 17 00:00:00 2001 From: KYS Date: Thu, 21 Nov 2024 16:26:42 +0900 Subject: [PATCH 08/11] =?UTF-8?q?=E2=9C=A8=20[Feat]=20Add=20API=20to=20add?= =?UTF-8?q?=20missions=20to=20stores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../converter/MissionConverter.java | 27 +++++++++ .../MissionRepository/MissionRepository.java | 9 +++ .../MissionCommandService.java | 8 +++ .../MissionCommandServiceImpl.java | 28 +++++++++ .../validator/StoreExistValidator.java | 10 +++- .../web/controller/MissionRestController.java | 58 +++++++++++++++++++ .../web/dto/MissionRequestDTO.java | 53 +++++++++++++++++ .../web/dto/MissionResponseDTO.java | 24 ++++++++ 8 files changed, 214 insertions(+), 3 deletions(-) create mode 100644 src/main/java/javalab/umc7th_mission/converter/MissionConverter.java create mode 100644 src/main/java/javalab/umc7th_mission/repository/MissionRepository/MissionRepository.java create mode 100644 src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandService.java create mode 100644 src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandServiceImpl.java create mode 100644 src/main/java/javalab/umc7th_mission/web/controller/MissionRestController.java create mode 100644 src/main/java/javalab/umc7th_mission/web/dto/MissionRequestDTO.java create mode 100644 src/main/java/javalab/umc7th_mission/web/dto/MissionResponseDTO.java diff --git a/src/main/java/javalab/umc7th_mission/converter/MissionConverter.java b/src/main/java/javalab/umc7th_mission/converter/MissionConverter.java new file mode 100644 index 0000000..2362abb --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/converter/MissionConverter.java @@ -0,0 +1,27 @@ +package javalab.umc7th_mission.converter; + +import javalab.umc7th_mission.domain.Mission; +import javalab.umc7th_mission.domain.Store; +import javalab.umc7th_mission.web.dto.MissionRequestDTO; +import javalab.umc7th_mission.web.dto.MissionResponseDTO; + +public class MissionConverter { + + public static MissionResponseDTO.AddResultDTO toAddResultDTO(Mission mission) { + return new MissionResponseDTO.AddResultDTO( + mission.getId(), + mission.getCreatedAt() + ); + } + + public static Mission toMission(Store store, MissionRequestDTO.AddDTO request) { + return Mission.builder() + .store(store) + .name(request.getName()) + .description(request.getDescription()) + .startDate(request.getStartDate()) + .endDate(request.getEndDate()) + .reward(request.getReward()) + .build(); + } +} diff --git a/src/main/java/javalab/umc7th_mission/repository/MissionRepository/MissionRepository.java b/src/main/java/javalab/umc7th_mission/repository/MissionRepository/MissionRepository.java new file mode 100644 index 0000000..48d2a48 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/repository/MissionRepository/MissionRepository.java @@ -0,0 +1,9 @@ +package javalab.umc7th_mission.repository.MissionRepository; + +import javalab.umc7th_mission.domain.Mission; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface MissionRepository extends JpaRepository { +} diff --git a/src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandService.java b/src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandService.java new file mode 100644 index 0000000..a490286 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandService.java @@ -0,0 +1,8 @@ +package javalab.umc7th_mission.service.MissionCommandService; + +import javalab.umc7th_mission.domain.Mission; +import javalab.umc7th_mission.web.dto.MissionRequestDTO; + +public interface MissionCommandService { + Mission addMission(MissionRequestDTO.AddDTO request); +} diff --git a/src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandServiceImpl.java new file mode 100644 index 0000000..530b923 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandServiceImpl.java @@ -0,0 +1,28 @@ +package javalab.umc7th_mission.service.MissionCommandService; + +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import javalab.umc7th_mission.apiPayload.exception.StoreNotFoundException; +import javalab.umc7th_mission.converter.MissionConverter; +import javalab.umc7th_mission.domain.Mission; +import javalab.umc7th_mission.domain.Store; +import javalab.umc7th_mission.repository.MissionRepository.MissionRepository; +import javalab.umc7th_mission.repository.StoreRepository.StoreRepository; +import javalab.umc7th_mission.web.dto.MissionRequestDTO; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class MissionCommandServiceImpl implements MissionCommandService { + private final StoreRepository storeRepository; + private final MissionRepository missionRepository; + + @Override + public Mission addMission(MissionRequestDTO.AddDTO request) { + Store store = storeRepository.findById(request.getStoreId()) + .orElseThrow(() -> new StoreNotFoundException(ErrorStatus.STORE_NOT_FOUND)); + + Mission newMission = MissionConverter.toMission(store, request); + return missionRepository.save(newMission); + } +} diff --git a/src/main/java/javalab/umc7th_mission/validation/validator/StoreExistValidator.java b/src/main/java/javalab/umc7th_mission/validation/validator/StoreExistValidator.java index 827fa4f..ff03754 100644 --- a/src/main/java/javalab/umc7th_mission/validation/validator/StoreExistValidator.java +++ b/src/main/java/javalab/umc7th_mission/validation/validator/StoreExistValidator.java @@ -13,7 +13,7 @@ @Component @RequiredArgsConstructor public class StoreExistValidator implements ConstraintValidator { - StoreValidationService storeValidationService; + private final StoreValidationService storeValidationService; @Override public void initialize(ExistStore constraintAnnotation) { @@ -21,8 +21,12 @@ public void initialize(ExistStore constraintAnnotation) { } @Override - public boolean isValid(Long value, ConstraintValidatorContext context) { - boolean isValid = storeValidationService.isStoreExist(value); + public boolean isValid(Long storeId, ConstraintValidatorContext context) { + if (storeId == null) { + return false; + } + + boolean isValid = storeValidationService.isStoreExist(storeId); if (!isValid) { context.disableDefaultConstraintViolation(); diff --git a/src/main/java/javalab/umc7th_mission/web/controller/MissionRestController.java b/src/main/java/javalab/umc7th_mission/web/controller/MissionRestController.java new file mode 100644 index 0000000..0ad1cfb --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/controller/MissionRestController.java @@ -0,0 +1,58 @@ +package javalab.umc7th_mission.web.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import javalab.umc7th_mission.apiPayload.ApiResponse; +import javalab.umc7th_mission.converter.MemberConverter; +import javalab.umc7th_mission.converter.MissionConverter; +import javalab.umc7th_mission.converter.ReviewConverter; +import javalab.umc7th_mission.domain.Member; +import javalab.umc7th_mission.domain.Mission; +import javalab.umc7th_mission.domain.Review; +import javalab.umc7th_mission.domain.Store; +import javalab.umc7th_mission.service.MissionCommandService.MissionCommandService; +import javalab.umc7th_mission.web.dto.*; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/missions") +public class MissionRestController { + private final MissionCommandService missionCommandService; + + @PostMapping("/") + @Operation( + summary = "예시 미션 추가", + description = "새로운 미션을 가게에 추가합니다.", + requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody( + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = MissionRequestDTO.AddDTO.class), + examples = @ExampleObject( + name = "미션 추가 예시", + value = """ + { + "storeId": 1, + "name": "첫 방문 포인트 이벤트", + "description": "가게 방문 시 +500점 추가 혜택", + "startDate": "2024-11-21", + "endDate": "2024-12-30", + "reward": 1000 + } + """ + ) + ) + ) + ) + public ApiResponse add(@RequestBody @Valid MissionRequestDTO.AddDTO request) { + Mission mission = missionCommandService.addMission(request); + return ApiResponse.onSuccess(MissionConverter.toAddResultDTO(mission)); + } +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MissionRequestDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MissionRequestDTO.java new file mode 100644 index 0000000..b572786 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/dto/MissionRequestDTO.java @@ -0,0 +1,53 @@ +package javalab.umc7th_mission.web.dto; + +import jakarta.validation.constraints.*; +import javalab.umc7th_mission.validation.annotation.ExistStore; +import lombok.Getter; + +import java.time.LocalDate; + +public class MissionRequestDTO { + + @Getter + public static class AddDTO { + @ExistStore + private Long storeId; + + @NotBlank(message = "미션 이름은 필수 항목입니다.") + @Size(max = 100, message = "미션 이름은 최대 100자까지 입력 가능합니다.") + private String name; + + + @NotBlank(message = "미션 설명은 필수 항목입니다.") + @Size(max = 500, message = "미션 설명은 최대 500자까지 입력 가능합니다.") + private String description; + + @NotNull(message = "시작 날짜는 필수 항목입니다.") + @FutureOrPresent(message = "시작 날짜는 오늘 이후여야 합니다.") + private LocalDate startDate; + + @NotNull(message = "종료 날짜는 필수 항목입니다.") + @Future(message = "종료 날짜는 오늘 이후여야 합니다.") + private LocalDate endDate; + + @NotNull(message = "보상 포인트는 필수 항목입니다.") + @Min(value = 0, message = "보상 포인트는 0 이상이어야 합니다.") + private Integer reward; + + public AddDTO( + Long storeId, + String name, + String description, + LocalDate startDate, + LocalDate endDate, + Integer reward + ) { + this.storeId = storeId; + this.name = name; + this.description = description; + this.startDate = startDate; + this.endDate = endDate; + this.reward = reward; + } + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MissionResponseDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MissionResponseDTO.java new file mode 100644 index 0000000..d5c1b8d --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/dto/MissionResponseDTO.java @@ -0,0 +1,24 @@ +package javalab.umc7th_mission.web.dto; + +import java.time.LocalDateTime; + +public class MissionResponseDTO { + public static class AddResultDTO { + private final Long missionId; + private final LocalDateTime createdAt; + + public AddResultDTO(Long missionId, LocalDateTime createdAt) { + this.missionId = missionId; + this.createdAt = createdAt; + } + + // 명시적 Getter (Jackson 직렬화를 위해 필요) + public Long getReviewId() { + return missionId; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + } +} From 6d8c1ceabf346df9b4806505320e5d3a7516ba50 Mon Sep 17 00:00:00 2001 From: KYS Date: Thu, 21 Nov 2024 16:47:15 +0900 Subject: [PATCH 09/11] =?UTF-8?q?=F0=9F=9A=91=EF=B8=8F=20[hotfix]=20rename?= =?UTF-8?q?=20GETTER?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/javalab/umc7th_mission/web/dto/MissionResponseDTO.java | 2 +- .../java/javalab/umc7th_mission/web/dto/StoreResponseDTO.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MissionResponseDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MissionResponseDTO.java index d5c1b8d..d1d12bb 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/MissionResponseDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/MissionResponseDTO.java @@ -13,7 +13,7 @@ public AddResultDTO(Long missionId, LocalDateTime createdAt) { } // 명시적 Getter (Jackson 직렬화를 위해 필요) - public Long getReviewId() { + public Long getMissionId() { return missionId; } diff --git a/src/main/java/javalab/umc7th_mission/web/dto/StoreResponseDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/StoreResponseDTO.java index 5e33057..0e8fe30 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/StoreResponseDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/StoreResponseDTO.java @@ -13,7 +13,7 @@ public AddResultDTO(Long storeId, LocalDateTime createdAt) { } // 명시적 Getter (Jackson 직렬화를 위해 필요) - public Long getMemberId() { + public Long getStoreId() { return storeId; } From d51139dcff9bffb012189e10495aa783e75a74c0 Mon Sep 17 00:00:00 2001 From: KYS Date: Thu, 21 Nov 2024 17:45:36 +0900 Subject: [PATCH 10/11] =?UTF-8?q?=E2=9C=A8=20[Feat]=20Challenge=20mission?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apiPayload/code/status/ErrorStatus.java | 4 ++ .../apiPayload/exception/ExceptionAdvice.java | 39 ++++++++++++++++ .../MissionAlreadyInProgressException.java | 16 +++++++ .../exception/MissionNotFoundException.java | 16 +++++++ .../converter/MemberMissionConverter.java | 28 +++++++++++ .../domain/enums/MissionStatus.java | 2 +- .../MemberMissionRepository.java | 4 ++ .../MemberMissionCommandService.java | 10 ++++ .../MemberMissionCommandServiceImpl.java | 46 +++++++++++++++++++ .../annotation/MissionNotInProgress.java | 19 ++++++++ .../MissionNotInProgressValidator.java | 42 +++++++++++++++++ .../MemberMissionRestController.java | 28 +++++++++++ .../web/dto/MemberMissionRequestDTO.java | 42 +++++++++++++++++ .../web/dto/MemberMissionResponseDTO.java | 18 ++++++++ 14 files changed, 313 insertions(+), 1 deletion(-) create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionAlreadyInProgressException.java create mode 100644 src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionNotFoundException.java create mode 100644 src/main/java/javalab/umc7th_mission/converter/MemberMissionConverter.java create mode 100644 src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandService.java create mode 100644 src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandServiceImpl.java create mode 100644 src/main/java/javalab/umc7th_mission/validation/annotation/MissionNotInProgress.java create mode 100644 src/main/java/javalab/umc7th_mission/validation/validator/MissionNotInProgressValidator.java create mode 100644 src/main/java/javalab/umc7th_mission/web/controller/MemberMissionRestController.java create mode 100644 src/main/java/javalab/umc7th_mission/web/dto/MemberMissionRequestDTO.java create mode 100644 src/main/java/javalab/umc7th_mission/web/dto/MemberMissionResponseDTO.java diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java b/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java index f851d97..b28c1de 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java @@ -23,6 +23,10 @@ public enum ErrorStatus implements BaseErrorCode { MEMBER_NOT_FOUND(HttpStatus.BAD_REQUEST, "MEMBER4001", "사용자가 없습니다."), NICKNAME_NOT_EXIST(HttpStatus.BAD_REQUEST, "MEMBER4002", "닉네임은 필수 입니다."), + // 미션 관련 에러 + MISSION_NOT_FOUND(HttpStatus.BAD_REQUEST, "MISSION4001", "미션이 없습니다."), + MISSION_ALREADY_IN_PROGRESS(HttpStatus.CONFLICT, "MISSION4091", "이미 진행중인 미션입니다."), + STORE_NOT_FOUND(HttpStatus.BAD_REQUEST, "STORE4001", "상점이 없습니다."), // 예시,,, ARTICLE_NOT_FOUND(HttpStatus.NOT_FOUND, "ARTICLE4001", "게시글이 없습니다."), diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java index b219c9f..5ee84dc 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java @@ -106,6 +106,45 @@ public ResponseEntity handleRegionNotFoundException(RegionNotFoundExcept ); } + @ExceptionHandler(MissionNotFoundException.class) + public ResponseEntity handleMissionNotFoundException(MissionNotFoundException e, HttpServletRequest request) { + WebRequest webRequest = new ServletWebRequest(request); + + ApiResponse body = ApiResponse.onFailure( + ErrorStatus.MISSION_NOT_FOUND.getCode(), + ErrorStatus.MISSION_NOT_FOUND.getMessage(), + null + ); + + return super.handleExceptionInternal( + e, + body, + new HttpHeaders(), + ErrorStatus.MISSION_NOT_FOUND.getHttpStatus(), + webRequest + ); + } + + + @ExceptionHandler(MissionAlreadyInProgressException.class) + public ResponseEntity handleMissionAlreadyInProgressException(MissionAlreadyInProgressException e, HttpServletRequest request) { + WebRequest webRequest = new ServletWebRequest(request); + + ApiResponse body = ApiResponse.onFailure( + ErrorStatus.MISSION_ALREADY_IN_PROGRESS.getCode(), + ErrorStatus.MISSION_ALREADY_IN_PROGRESS.getMessage(), + null + ); + + return super.handleExceptionInternal( + e, + body, + new HttpHeaders(), + ErrorStatus.MISSION_ALREADY_IN_PROGRESS.getHttpStatus(), + webRequest + ); + } + @ExceptionHandler(MemberNotFoundException.class) public ResponseEntity handleMemberNotFoundException(MemberNotFoundException e, HttpServletRequest request) { WebRequest webRequest = new ServletWebRequest(request); diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionAlreadyInProgressException.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionAlreadyInProgressException.java new file mode 100644 index 0000000..d7cd793 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionAlreadyInProgressException.java @@ -0,0 +1,16 @@ +package javalab.umc7th_mission.apiPayload.exception; + +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import org.springframework.http.HttpStatus; + +public class MissionAlreadyInProgressException extends RuntimeException { + private final HttpStatus status = HttpStatus.CONFLICT; + + public MissionAlreadyInProgressException(ErrorStatus errorStatus) { + super(errorStatus.getMessage()); + } + + public HttpStatus getStatus() { + return status; + } +} diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionNotFoundException.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionNotFoundException.java new file mode 100644 index 0000000..91058f0 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionNotFoundException.java @@ -0,0 +1,16 @@ +package javalab.umc7th_mission.apiPayload.exception; + +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import org.springframework.http.HttpStatus; + +public class MissionNotFoundException extends RuntimeException { + private final HttpStatus status = HttpStatus.BAD_REQUEST; + + public MissionNotFoundException(ErrorStatus errorStatus) { + super(errorStatus.getMessage()); + } + + public HttpStatus getStatus() { + return status; + } +} diff --git a/src/main/java/javalab/umc7th_mission/converter/MemberMissionConverter.java b/src/main/java/javalab/umc7th_mission/converter/MemberMissionConverter.java new file mode 100644 index 0000000..907f9f0 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/converter/MemberMissionConverter.java @@ -0,0 +1,28 @@ +package javalab.umc7th_mission.converter; + +import javalab.umc7th_mission.domain.Member; +import javalab.umc7th_mission.domain.Mission; +import javalab.umc7th_mission.domain.enums.MissionStatus; +import javalab.umc7th_mission.domain.mapping.MemberMission; +import javalab.umc7th_mission.web.dto.MemberMissionRequestDTO; +import javalab.umc7th_mission.web.dto.MemberMissionResponseDTO; +import javalab.umc7th_mission.web.dto.MissionRequestDTO; + +public class MemberMissionConverter { + public static MemberMissionResponseDTO.AddResultDTO toAddResultDTO(MemberMission memberMission) { + return new MemberMissionResponseDTO.AddResultDTO( + memberMission.getId(), + memberMission.getCreatedAt() + ); + } + + public static MemberMission toMemberMission(Member member, Mission mission, MemberMissionRequestDTO.AddDTO request) { + return MemberMission.builder() + .member(member) + .mission(mission) + .startDate(request.getStartDate()) + .endDate(request.getEndDate()) + .status(MissionStatus.CHALLENGING) + .build(); + } +} diff --git a/src/main/java/javalab/umc7th_mission/domain/enums/MissionStatus.java b/src/main/java/javalab/umc7th_mission/domain/enums/MissionStatus.java index ee8669b..4204161 100644 --- a/src/main/java/javalab/umc7th_mission/domain/enums/MissionStatus.java +++ b/src/main/java/javalab/umc7th_mission/domain/enums/MissionStatus.java @@ -1,5 +1,5 @@ package javalab.umc7th_mission.domain.enums; public enum MissionStatus { - PENDING,CHALLENGING, COMPLETE + PENDING, CHALLENGING, COMPLETE } diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepository.java b/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepository.java index ec30e9c..6c4c6ea 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepository.java +++ b/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepository.java @@ -1,8 +1,12 @@ package javalab.umc7th_mission.repository.MemberMissionRepository; +import javalab.umc7th_mission.domain.enums.MissionStatus; import javalab.umc7th_mission.domain.mapping.MemberMission; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +@Repository public interface MemberMissionRepository extends JpaRepository, MemberMissionRepositoryCustom { + boolean existsByMemberIdAndMissionIdAndStatus(Long memberId, Long missionId, MissionStatus status); } diff --git a/src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandService.java b/src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandService.java new file mode 100644 index 0000000..f0e74ca --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandService.java @@ -0,0 +1,10 @@ +package javalab.umc7th_mission.service.MemberMissionCommandService; + +import javalab.umc7th_mission.domain.mapping.MemberMission; +import javalab.umc7th_mission.web.dto.MemberMissionRequestDTO; + +public interface MemberMissionCommandService { + MemberMission addMemberMission(MemberMissionRequestDTO.AddDTO request); + + boolean isMissionInProgress(Long memberId, Long missionId); +} diff --git a/src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandServiceImpl.java new file mode 100644 index 0000000..1a4ff81 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandServiceImpl.java @@ -0,0 +1,46 @@ +package javalab.umc7th_mission.service.MemberMissionCommandService; + +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import javalab.umc7th_mission.apiPayload.exception.MemberNotFoundException; +import javalab.umc7th_mission.apiPayload.exception.MissionNotFoundException; +import javalab.umc7th_mission.converter.MemberMissionConverter; +import javalab.umc7th_mission.domain.Member; +import javalab.umc7th_mission.domain.Mission; +import javalab.umc7th_mission.domain.enums.MissionStatus; +import javalab.umc7th_mission.domain.mapping.MemberMission; +import javalab.umc7th_mission.repository.MemberMissionRepository.MemberMissionRepository; +import javalab.umc7th_mission.repository.MemberRepository.MemberRepository; +import javalab.umc7th_mission.repository.MissionRepository.MissionRepository; +import javalab.umc7th_mission.web.dto.MemberMissionRequestDTO; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class MemberMissionCommandServiceImpl implements MemberMissionCommandService { + private final MemberRepository memberRepository; + private final MissionRepository missionRepository; + private final MemberMissionRepository memberMissionRepository; + + @Override + public MemberMission addMemberMission(MemberMissionRequestDTO.AddDTO request) { + //멤버 파악 + Member member = memberRepository.findById(request.getMemberId()) + .orElseThrow(() -> new MemberNotFoundException(ErrorStatus.MEMBER_NOT_FOUND)); + + // + Mission mission = missionRepository.findById(request.getMissionId()) + .orElseThrow(() -> new MissionNotFoundException(ErrorStatus.MISSION_NOT_FOUND)); + + MemberMission memberMission = MemberMissionConverter.toMemberMission(member, mission, request); + + return memberMissionRepository.save(memberMission); + } + + @Override + public boolean isMissionInProgress(Long memberId, Long missionId) { + return memberMissionRepository.existsByMemberIdAndMissionIdAndStatus(memberId, missionId, MissionStatus.CHALLENGING); + } + + +} diff --git a/src/main/java/javalab/umc7th_mission/validation/annotation/MissionNotInProgress.java b/src/main/java/javalab/umc7th_mission/validation/annotation/MissionNotInProgress.java new file mode 100644 index 0000000..9523c29 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/validation/annotation/MissionNotInProgress.java @@ -0,0 +1,19 @@ +package javalab.umc7th_mission.validation.annotation; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; +import javalab.umc7th_mission.repository.MemberMissionRepository.MemberMissionRepository; +import javalab.umc7th_mission.validation.validator.MissionNotInProgressValidator; + + +import java.lang.annotation.*; + +@Documented +@Constraint(validatedBy = MissionNotInProgressValidator.class) +@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER }) +@Retention(RetentionPolicy.RUNTIME) +public @interface MissionNotInProgress { + String message() default "해당 "; + Class[] groups() default {}; + Class[] payload() default {}; +} diff --git a/src/main/java/javalab/umc7th_mission/validation/validator/MissionNotInProgressValidator.java b/src/main/java/javalab/umc7th_mission/validation/validator/MissionNotInProgressValidator.java new file mode 100644 index 0000000..0d16066 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/validation/validator/MissionNotInProgressValidator.java @@ -0,0 +1,42 @@ +package javalab.umc7th_mission.validation.validator; + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import javalab.umc7th_mission.apiPayload.code.status.ErrorStatus; +import javalab.umc7th_mission.repository.MemberMissionRepository.MemberMissionRepository; +import javalab.umc7th_mission.service.MemberMissionCommandService.MemberMissionCommandService; +import javalab.umc7th_mission.validation.annotation.ExistStore; +import javalab.umc7th_mission.validation.annotation.MissionNotInProgress; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + + +@Component +@RequiredArgsConstructor +public class MissionNotInProgressValidator implements ConstraintValidator { + private final MemberMissionCommandService memberMissionCommandService; + @Override + public void initialize(MissionNotInProgress constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(Long missionId, ConstraintValidatorContext context) { + if (missionId == null) { + return true; // 미션 ID가 없으면 검증을 통과시킴 + } + + //원래 현재 로그인한 사용자의 ID를 가져와야됨 + //현재는 로그인 기능이 없으니 하드코딩 + Long memberId = 1L; + + // 특정 회원이 해당 미션을 진행 중인지 확인 + boolean isInProgress = memberMissionCommandService.isMissionInProgress(memberId, missionId); + if (isInProgress) { + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate(ErrorStatus.MISSION_ALREADY_IN_PROGRESS.toString()) + .addConstraintViolation(); + } + return !isInProgress; + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/controller/MemberMissionRestController.java b/src/main/java/javalab/umc7th_mission/web/controller/MemberMissionRestController.java new file mode 100644 index 0000000..9aec096 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/controller/MemberMissionRestController.java @@ -0,0 +1,28 @@ +package javalab.umc7th_mission.web.controller; + +import jakarta.validation.Valid; +import javalab.umc7th_mission.apiPayload.ApiResponse; +import javalab.umc7th_mission.converter.MemberConverter; +import javalab.umc7th_mission.converter.MemberMissionConverter; +import javalab.umc7th_mission.domain.mapping.MemberMission; +import javalab.umc7th_mission.service.MemberMissionCommandService.MemberMissionCommandService; +import javalab.umc7th_mission.web.dto.MemberMissionRequestDTO; +import javalab.umc7th_mission.web.dto.MemberMissionResponseDTO; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/memberMissions") +public class MemberMissionRestController { + private final MemberMissionCommandService memberMissionCommandService; + + @PostMapping("/") + public ApiResponse join(@RequestBody @Valid MemberMissionRequestDTO.AddDTO resquest) { + MemberMission memberMission = memberMissionCommandService.addMemberMission(resquest); + return ApiResponse.onSuccess(MemberMissionConverter.toAddResultDTO(memberMission)); + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MemberMissionRequestDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MemberMissionRequestDTO.java new file mode 100644 index 0000000..c937fe7 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/dto/MemberMissionRequestDTO.java @@ -0,0 +1,42 @@ +package javalab.umc7th_mission.web.dto; + +import jakarta.validation.constraints.Future; +import jakarta.validation.constraints.FutureOrPresent; +import jakarta.validation.constraints.NotNull; +import javalab.umc7th_mission.validation.annotation.MissionNotInProgress; +import lombok.Getter; + +import java.time.LocalDate; + +public class MemberMissionRequestDTO { + + @Getter + public static class AddDTO { + @NotNull(message = "회원 ID는 필수입니다.") + private final Long memberId; + + @NotNull(message = "미션 ID는 필수입니다.") + @MissionNotInProgress + private final Long missionId; + + @NotNull(message = "시작 날짜는 필수 항목입니다.") + @FutureOrPresent(message = "시작 날짜는 오늘 이후여야 합니다.") + private LocalDate startDate; + + @NotNull(message = "종료 날짜는 필수 항목입니다.") + @Future(message = "종료 날짜는 오늘 이후여야 합니다.") + private LocalDate endDate; + + public AddDTO( + Long memberId, + Long missionId, + LocalDate startDate, + LocalDate endDate + ) { + this.memberId = memberId; + this.missionId = missionId; + this.startDate = startDate; + this.endDate = endDate; + } + } +} diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MemberMissionResponseDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MemberMissionResponseDTO.java new file mode 100644 index 0000000..36322db --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/web/dto/MemberMissionResponseDTO.java @@ -0,0 +1,18 @@ +package javalab.umc7th_mission.web.dto; + +import java.time.LocalDateTime; + +public class MemberMissionResponseDTO { + public static class AddResultDTO{ + private final Long memberMissionId; + private final LocalDateTime createdAt; + + public AddResultDTO(Long memberMissionId, LocalDateTime createdAt) { + this.memberMissionId = memberMissionId; + this.createdAt = createdAt; + } + + public Long getMemberMissionId() { return memberMissionId; } + public LocalDateTime getCreatedAt() { return createdAt; } + } +} From 072485142cd5c1963c5da7a9bed194ecccc8e838 Mon Sep 17 00:00:00 2001 From: KYS Date: Fri, 22 Nov 2024 01:23:30 +0900 Subject: [PATCH 11/11] mission: submit week8 mission --- build.gradle | 3 +-- .../umc7th_mission/apiPayload/code/status/ErrorStatus.java | 2 +- .../umc7th_mission/apiPayload/exception/ExceptionAdvice.java | 2 +- .../apiPayload/exception/FoodCategoryNotFoundException.java | 2 +- .../apiPayload/exception/MemberNotFoundException.java | 2 +- .../exception/MissionAlreadyInProgressException.java | 2 +- .../apiPayload/exception/MissionNotFoundException.java | 2 +- .../apiPayload/exception/RegionNotFoundException.java | 2 +- .../apiPayload/exception/StoreNotFoundException.java | 2 +- .../java/javalab/umc7th_mission/config/SwaggerConfig.java | 2 +- .../javalab/umc7th_mission/converter/MemberConverter.java | 2 +- .../umc7th_mission/converter/MemberMissionConverter.java | 2 +- .../umc7th_mission/converter/MemberPreferConverter.java | 3 +-- .../javalab/umc7th_mission/converter/MissionConverter.java | 2 +- .../javalab/umc7th_mission/converter/ReviewConverter.java | 2 +- .../umc7th_mission/converter/StoreCategoryConverter.java | 2 +- .../java/javalab/umc7th_mission/converter/StoreConverter.java | 4 +--- src/main/java/javalab/umc7th_mission/domain/Member.java | 2 +- src/main/java/javalab/umc7th_mission/domain/ReviewImage.java | 2 +- src/main/java/javalab/umc7th_mission/domain/Store.java | 2 +- .../javalab/umc7th_mission/domain/enums/MissionStatus.java | 2 +- .../javalab/umc7th_mission/domain/mapping/MemberAddress.java | 2 +- .../javalab/umc7th_mission/domain/mapping/MemberPrefer.java | 2 +- .../javalab/umc7th_mission/domain/mapping/StoreAddress.java | 2 +- .../FoodCategoryRepository/FoodCategoryRepository.java | 2 +- .../MemberAddressRepository/MemberAddressRepository.java | 2 +- .../MemberAddressRepositoryCustom.java | 2 +- .../MemberAddressRepository/MemberAddressRepositoryImpl.java | 2 +- .../MemberMissionRepository/MemberMissionRepository.java | 2 +- .../MemberMissionRepositoryCustom.java | 2 +- .../MemberMissionRepository/MemberMissionRepositoryImpl.java | 2 +- .../MemberPreferRepository/MemberPreferRepository.java | 2 +- .../repository/MemberRepository/MemberRepository.java | 2 +- .../repository/MemberRepository/MemberRepositoryCustom.java | 2 +- .../repository/MemberRepository/MemberRepositoryImpl.java | 2 +- .../repository/MissionRepository/MissionRepository.java | 2 +- .../repository/RegionRepository/RegionRepository.java | 3 +-- .../repository/RegionRepository/RegionRepositoryCustom.java | 2 +- .../repository/RegionRepository/RegionRepositoryImpl.java | 2 +- .../repository/ReviewRepository/ReviewRepository.java | 2 +- .../repository/ReviewRepository/ReviewRepositoryCustom.java | 2 +- .../repository/ReviewRepository/ReviewRepositoryImpl.java | 2 +- .../StoreAddressRepository/StoreAddressRepository.java | 2 +- .../StoreAddressRepository/StoreAddressRepositoryCustom.java | 2 +- .../StoreAddressRepository/StoreAddressRepositoryImpl.java | 2 +- .../repository/StoreRepository/StoreRepository.java | 2 +- .../repository/StoreRepository/StoreRepositoryCustom.java | 2 +- .../repository/StoreRepository/StoreRepositoryImpl.java | 2 +- .../service/FoodCategoryService/FoodCategoryService.java | 2 +- .../service/FoodCategoryService/FoodCategoryServiceImpl.java | 2 +- .../MemberMissionCommandService.java | 2 +- .../MemberMissionCommandServiceImpl.java | 1 - .../service/MemberService/MemberCommandService.java | 2 +- .../service/MemberService/MemberCommandServiceImpl.java | 2 +- .../service/MissionCommandService/MissionCommandService.java | 2 +- .../MissionCommandService/MissionCommandServiceImpl.java | 2 +- .../service/ReviewCommandService/ReviewCommandService.java | 2 +- .../ReviewCommandService/ReviewCommandServiceImpl.java | 2 +- .../service/StoreCommandService/StoreCommandService.java | 2 +- .../service/StoreCommandService/StoreCommandServiceImpl.java | 2 +- .../StoreValidationService/StoreValidationService.java | 2 +- .../StoreValidationService/StoreValidationServiceImpl.java | 2 +- .../umc7th_mission/validation/annotation/ExistCategories.java | 2 +- .../umc7th_mission/validation/annotation/ExistStore.java | 2 +- .../validation/annotation/MissionNotInProgress.java | 4 ++-- .../validation/validator/CategoriesExistValidator.java | 2 +- .../validation/validator/MissionNotInProgressValidator.java | 2 +- .../validation/validator/StoreExistValidator.java | 2 +- .../web/controller/MemberMissionRestController.java | 2 +- .../umc7th_mission/web/controller/MemberRestController.java | 2 +- .../umc7th_mission/web/controller/MissionRestController.java | 2 +- .../umc7th_mission/web/controller/ReviewRestController.java | 2 +- .../umc7th_mission/web/controller/StoreRestController.java | 2 +- .../java/javalab/umc7th_mission/web/dto/MemberInfoDto.java | 2 +- .../umc7th_mission/web/dto/MemberMissionRequestDTO.java | 2 +- .../umc7th_mission/web/dto/MemberMissionResponseDTO.java | 2 +- .../java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java | 2 +- .../javalab/umc7th_mission/web/dto/MemberResponseDTO.java | 2 +- .../javalab/umc7th_mission/web/dto/MissionRequestDTO.java | 2 +- .../javalab/umc7th_mission/web/dto/MissionResponseDTO.java | 2 +- .../java/javalab/umc7th_mission/web/dto/ReviewRequestDTO.java | 2 +- .../javalab/umc7th_mission/web/dto/ReviewResponseDTO.java | 2 +- .../java/javalab/umc7th_mission/web/dto/StoreRequestDTO.java | 2 +- .../java/javalab/umc7th_mission/web/dto/StoreResponseDTO.java | 2 +- 84 files changed, 84 insertions(+), 90 deletions(-) diff --git a/build.gradle b/build.gradle index bea17fa..d1f30c7 100644 --- a/build.gradle +++ b/build.gradle @@ -58,5 +58,4 @@ sourceSets { tasks.named('test') { useJUnitPlatform() -} - +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java b/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java index b28c1de..34ffb08 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/code/status/ErrorStatus.java @@ -59,4 +59,4 @@ public ErrorReasonDTO getReasonHttpStatus() { .build() ; } -} \ No newline at end of file +} diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java index 5ee84dc..192fe7e 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/ExceptionAdvice.java @@ -234,4 +234,4 @@ private ResponseEntity handleExceptionInternalConstraint(Exception e, Er request ); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/FoodCategoryNotFoundException.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/FoodCategoryNotFoundException.java index 9bcd386..42f7fe4 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/exception/FoodCategoryNotFoundException.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/FoodCategoryNotFoundException.java @@ -13,4 +13,4 @@ public FoodCategoryNotFoundException(ErrorStatus errorStatus) { public HttpStatus getStatus() { return status; } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/MemberNotFoundException.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/MemberNotFoundException.java index 9e5489e..7b503b3 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/exception/MemberNotFoundException.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/MemberNotFoundException.java @@ -13,4 +13,4 @@ public MemberNotFoundException(ErrorStatus errorStatus) { public HttpStatus getStatus() { return status; } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionAlreadyInProgressException.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionAlreadyInProgressException.java index d7cd793..0b601ac 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionAlreadyInProgressException.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionAlreadyInProgressException.java @@ -13,4 +13,4 @@ public MissionAlreadyInProgressException(ErrorStatus errorStatus) { public HttpStatus getStatus() { return status; } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionNotFoundException.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionNotFoundException.java index 91058f0..7a02771 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionNotFoundException.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/MissionNotFoundException.java @@ -13,4 +13,4 @@ public MissionNotFoundException(ErrorStatus errorStatus) { public HttpStatus getStatus() { return status; } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/RegionNotFoundException.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/RegionNotFoundException.java index 36fafae..9f4abf8 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/exception/RegionNotFoundException.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/RegionNotFoundException.java @@ -13,4 +13,4 @@ public RegionNotFoundException(ErrorStatus errorStatus) { public HttpStatus getStatus() { return status; } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/apiPayload/exception/StoreNotFoundException.java b/src/main/java/javalab/umc7th_mission/apiPayload/exception/StoreNotFoundException.java index 5f7735b..5738eed 100644 --- a/src/main/java/javalab/umc7th_mission/apiPayload/exception/StoreNotFoundException.java +++ b/src/main/java/javalab/umc7th_mission/apiPayload/exception/StoreNotFoundException.java @@ -13,4 +13,4 @@ public StoreNotFoundException(ErrorStatus errorStatus) { public HttpStatus getStatus() { return status; } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/config/SwaggerConfig.java b/src/main/java/javalab/umc7th_mission/config/SwaggerConfig.java index 78162d9..6af2cb5 100644 --- a/src/main/java/javalab/umc7th_mission/config/SwaggerConfig.java +++ b/src/main/java/javalab/umc7th_mission/config/SwaggerConfig.java @@ -36,4 +36,4 @@ public OpenAPI UMCstudyAPI() { .addSecurityItem(securityRequirement) .components(components); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/converter/MemberConverter.java b/src/main/java/javalab/umc7th_mission/converter/MemberConverter.java index 5c2c94d..839fc0c 100644 --- a/src/main/java/javalab/umc7th_mission/converter/MemberConverter.java +++ b/src/main/java/javalab/umc7th_mission/converter/MemberConverter.java @@ -57,4 +57,4 @@ public static MemberAddress toMemberAddress(Member member, Region region, Member .zipCode(request.getZipcode()) .build(); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/converter/MemberMissionConverter.java b/src/main/java/javalab/umc7th_mission/converter/MemberMissionConverter.java index 907f9f0..79749ec 100644 --- a/src/main/java/javalab/umc7th_mission/converter/MemberMissionConverter.java +++ b/src/main/java/javalab/umc7th_mission/converter/MemberMissionConverter.java @@ -25,4 +25,4 @@ public static MemberMission toMemberMission(Member member, Mission mission, Memb .status(MissionStatus.CHALLENGING) .build(); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/converter/MemberPreferConverter.java b/src/main/java/javalab/umc7th_mission/converter/MemberPreferConverter.java index aa552f6..f526260 100644 --- a/src/main/java/javalab/umc7th_mission/converter/MemberPreferConverter.java +++ b/src/main/java/javalab/umc7th_mission/converter/MemberPreferConverter.java @@ -17,5 +17,4 @@ public static List toMemberPreferList(List foodCateg .build() ).collect(Collectors.toList()); } -} - +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/converter/MissionConverter.java b/src/main/java/javalab/umc7th_mission/converter/MissionConverter.java index 2362abb..5935b8d 100644 --- a/src/main/java/javalab/umc7th_mission/converter/MissionConverter.java +++ b/src/main/java/javalab/umc7th_mission/converter/MissionConverter.java @@ -24,4 +24,4 @@ public static Mission toMission(Store store, MissionRequestDTO.AddDTO request) { .reward(request.getReward()) .build(); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/converter/ReviewConverter.java b/src/main/java/javalab/umc7th_mission/converter/ReviewConverter.java index 2d89aaf..7c6fa00 100644 --- a/src/main/java/javalab/umc7th_mission/converter/ReviewConverter.java +++ b/src/main/java/javalab/umc7th_mission/converter/ReviewConverter.java @@ -24,4 +24,4 @@ public static Review toReview(Member member, Store store, ReviewRequestDTO.AddDT .reviewImageList(request.getReviewImageList()) .build(); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/converter/StoreCategoryConverter.java b/src/main/java/javalab/umc7th_mission/converter/StoreCategoryConverter.java index eadcb3b..bca00d7 100644 --- a/src/main/java/javalab/umc7th_mission/converter/StoreCategoryConverter.java +++ b/src/main/java/javalab/umc7th_mission/converter/StoreCategoryConverter.java @@ -16,4 +16,4 @@ public static List toStoreCategoryList(List foodCat .build() ).collect(Collectors.toList()); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/converter/StoreConverter.java b/src/main/java/javalab/umc7th_mission/converter/StoreConverter.java index f3769a5..0a14bc0 100644 --- a/src/main/java/javalab/umc7th_mission/converter/StoreConverter.java +++ b/src/main/java/javalab/umc7th_mission/converter/StoreConverter.java @@ -35,6 +35,4 @@ public static StoreAddress toStoreAddress(Store store, Region region, StoreReque .zipCode(request.getZipcode()) .build(); } -} - - +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/domain/Member.java b/src/main/java/javalab/umc7th_mission/domain/Member.java index 6bcc319..1dcea5a 100644 --- a/src/main/java/javalab/umc7th_mission/domain/Member.java +++ b/src/main/java/javalab/umc7th_mission/domain/Member.java @@ -72,4 +72,4 @@ public class Member extends BaseEntity { @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List memberMissionList = new ArrayList<>(); -} \ No newline at end of file +} diff --git a/src/main/java/javalab/umc7th_mission/domain/ReviewImage.java b/src/main/java/javalab/umc7th_mission/domain/ReviewImage.java index 7c71480..1b857ea 100644 --- a/src/main/java/javalab/umc7th_mission/domain/ReviewImage.java +++ b/src/main/java/javalab/umc7th_mission/domain/ReviewImage.java @@ -29,4 +29,4 @@ public class ReviewImage extends BaseEntity { @JoinColumn(name = "review_id") @JsonIgnore //순환참조 방지 private Review review; -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/domain/Store.java b/src/main/java/javalab/umc7th_mission/domain/Store.java index beea1ce..7dc0201 100644 --- a/src/main/java/javalab/umc7th_mission/domain/Store.java +++ b/src/main/java/javalab/umc7th_mission/domain/Store.java @@ -45,4 +45,4 @@ public class Store extends BaseEntity { @OneToMany(mappedBy = "store", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List categoryList = new ArrayList<>(); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/domain/enums/MissionStatus.java b/src/main/java/javalab/umc7th_mission/domain/enums/MissionStatus.java index 4204161..ac114b2 100644 --- a/src/main/java/javalab/umc7th_mission/domain/enums/MissionStatus.java +++ b/src/main/java/javalab/umc7th_mission/domain/enums/MissionStatus.java @@ -2,4 +2,4 @@ public enum MissionStatus { PENDING, CHALLENGING, COMPLETE -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/domain/mapping/MemberAddress.java b/src/main/java/javalab/umc7th_mission/domain/mapping/MemberAddress.java index bc34677..5ceca6f 100644 --- a/src/main/java/javalab/umc7th_mission/domain/mapping/MemberAddress.java +++ b/src/main/java/javalab/umc7th_mission/domain/mapping/MemberAddress.java @@ -33,4 +33,4 @@ public class MemberAddress extends BaseEntity { @Column(nullable = false, length = 40) private String zipCode; -} \ No newline at end of file +} diff --git a/src/main/java/javalab/umc7th_mission/domain/mapping/MemberPrefer.java b/src/main/java/javalab/umc7th_mission/domain/mapping/MemberPrefer.java index 812f4f2..0a4dacb 100644 --- a/src/main/java/javalab/umc7th_mission/domain/mapping/MemberPrefer.java +++ b/src/main/java/javalab/umc7th_mission/domain/mapping/MemberPrefer.java @@ -37,4 +37,4 @@ public void setMember(Member member){ public void setFoodCategory(FoodCategory foodCategory){ this.foodCategory = foodCategory; } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/domain/mapping/StoreAddress.java b/src/main/java/javalab/umc7th_mission/domain/mapping/StoreAddress.java index 4711f20..8f475c9 100644 --- a/src/main/java/javalab/umc7th_mission/domain/mapping/StoreAddress.java +++ b/src/main/java/javalab/umc7th_mission/domain/mapping/StoreAddress.java @@ -31,4 +31,4 @@ public class StoreAddress extends BaseEntity { @Column(nullable = false, length = 40) private String zipCode; -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/FoodCategoryRepository/FoodCategoryRepository.java b/src/main/java/javalab/umc7th_mission/repository/FoodCategoryRepository/FoodCategoryRepository.java index adced13..90a0447 100644 --- a/src/main/java/javalab/umc7th_mission/repository/FoodCategoryRepository/FoodCategoryRepository.java +++ b/src/main/java/javalab/umc7th_mission/repository/FoodCategoryRepository/FoodCategoryRepository.java @@ -6,4 +6,4 @@ @Repository public interface FoodCategoryRepository extends JpaRepository { -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepository.java b/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepository.java index 644a62c..8cd53b8 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepository.java +++ b/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepository.java @@ -6,4 +6,4 @@ @Repository public interface MemberAddressRepository extends JpaRepository { -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryCustom.java b/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryCustom.java index 09c03e0..8c916b4 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryCustom.java +++ b/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryCustom.java @@ -6,4 +6,4 @@ public interface MemberAddressRepositoryCustom { List findAllAddressByMemberId(Long memberId); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryImpl.java b/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryImpl.java index 8cf69bf..b5d1362 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryImpl.java +++ b/src/main/java/javalab/umc7th_mission/repository/MemberAddressRepository/MemberAddressRepositoryImpl.java @@ -22,4 +22,4 @@ public List findAllAddressByMemberId(Long memberId) { return query.getResultList(); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepository.java b/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepository.java index 6c4c6ea..ead83ae 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepository.java +++ b/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepository.java @@ -9,4 +9,4 @@ public interface MemberMissionRepository extends JpaRepository, MemberMissionRepositoryCustom { boolean existsByMemberIdAndMissionIdAndStatus(Long memberId, Long missionId, MissionStatus status); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryCustom.java b/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryCustom.java index 70952c2..c9ce8a6 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryCustom.java +++ b/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryCustom.java @@ -12,4 +12,4 @@ public interface MemberMissionRepositoryCustom { List findChallengingMissionByMember(Long memberId, Pageable pageable); List findCompletedMissionByMember(Long memberId, Pageable pageable); Long countCompletedMissionByMember(Long memberId, String regionName); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryImpl.java b/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryImpl.java index 1d3a6e4..9d5badf 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryImpl.java +++ b/src/main/java/javalab/umc7th_mission/repository/MemberMissionRepository/MemberMissionRepositoryImpl.java @@ -87,4 +87,4 @@ public Long countCompletedMissionByMember(Long memberId, String regionName) { .fetchOne(); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberPreferRepository/MemberPreferRepository.java b/src/main/java/javalab/umc7th_mission/repository/MemberPreferRepository/MemberPreferRepository.java index 40415fc..34c0a6a 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MemberPreferRepository/MemberPreferRepository.java +++ b/src/main/java/javalab/umc7th_mission/repository/MemberPreferRepository/MemberPreferRepository.java @@ -6,4 +6,4 @@ @Repository public interface MemberPreferRepository extends JpaRepository { -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepository.java b/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepository.java index 6d078c4..9b3d5bb 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepository.java +++ b/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepository.java @@ -7,4 +7,4 @@ //24.11.19 -> to , @Repository add @Repository public interface MemberRepository extends JpaRepository { -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepositoryCustom.java b/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepositoryCustom.java index 0d6472f..c96396d 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepositoryCustom.java +++ b/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepositoryCustom.java @@ -9,4 +9,4 @@ @Repository public interface MemberRepositoryCustom { MemberInfoDto findMemberInfoById(Long memberId); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepositoryImpl.java b/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepositoryImpl.java index b2eb68f..71ad4d6 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepositoryImpl.java +++ b/src/main/java/javalab/umc7th_mission/repository/MemberRepository/MemberRepositoryImpl.java @@ -29,4 +29,4 @@ public MemberInfoDto findMemberInfoById(Long memberId) { .where(member.id.eq(memberId)) .fetchOne(); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/MissionRepository/MissionRepository.java b/src/main/java/javalab/umc7th_mission/repository/MissionRepository/MissionRepository.java index 48d2a48..4af0e67 100644 --- a/src/main/java/javalab/umc7th_mission/repository/MissionRepository/MissionRepository.java +++ b/src/main/java/javalab/umc7th_mission/repository/MissionRepository/MissionRepository.java @@ -6,4 +6,4 @@ @Repository public interface MissionRepository extends JpaRepository { -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepository.java b/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepository.java index e103d52..220bfff 100644 --- a/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepository.java +++ b/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepository.java @@ -9,5 +9,4 @@ public interface RegionRepository extends JpaRepository { // 추가로 지역 이름으로 검색할 수 있는 메서드 Region findByName(String name); -} - +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryCustom.java b/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryCustom.java index 2d2301b..c71f84d 100644 --- a/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryCustom.java +++ b/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryCustom.java @@ -1,4 +1,4 @@ package javalab.umc7th_mission.repository.RegionRepository; public interface RegionRepositoryCustom { -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryImpl.java b/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryImpl.java index 82fa17a..6087a9c 100644 --- a/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryImpl.java +++ b/src/main/java/javalab/umc7th_mission/repository/RegionRepository/RegionRepositoryImpl.java @@ -1,4 +1,4 @@ package javalab.umc7th_mission.repository.RegionRepository; public class RegionRepositoryImpl implements RegionRepositoryCustom { -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepository.java b/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepository.java index 66bbf49..df0d29a 100644 --- a/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepository.java +++ b/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepository.java @@ -22,4 +22,4 @@ void insertReview(@Param("memberId") Long memberId, @Param("content") String content, @Param("rating") BigDecimal rating ); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepositoryCustom.java b/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepositoryCustom.java index 6b2ae58..0caaef4 100644 --- a/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepositoryCustom.java +++ b/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepositoryCustom.java @@ -7,4 +7,4 @@ public interface ReviewRepositoryCustom { public Long save(Member member, Store store, String content, BigDecimal rating); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepositoryImpl.java b/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepositoryImpl.java index 85bb848..960b941 100644 --- a/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepositoryImpl.java +++ b/src/main/java/javalab/umc7th_mission/repository/ReviewRepository/ReviewRepositoryImpl.java @@ -25,4 +25,4 @@ public Long save(Member member, Store store, String content, BigDecimal rating) .values(member, store, content, rating) .execute(); } -} \ No newline at end of file +} diff --git a/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepository.java b/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepository.java index 3a55634..45b32a4 100644 --- a/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepository.java +++ b/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepository.java @@ -6,4 +6,4 @@ @Repository public interface StoreAddressRepository extends JpaRepository, StoreAddressRepositoryCustom { -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryCustom.java b/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryCustom.java index 6efaf9a..3f58bb1 100644 --- a/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryCustom.java +++ b/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryCustom.java @@ -1,4 +1,4 @@ package javalab.umc7th_mission.repository.StoreAddressRepository; public interface StoreAddressRepositoryCustom { -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryImpl.java b/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryImpl.java index eb78b78..45a9181 100644 --- a/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryImpl.java +++ b/src/main/java/javalab/umc7th_mission/repository/StoreAddressRepository/StoreAddressRepositoryImpl.java @@ -1,4 +1,4 @@ package javalab.umc7th_mission.repository.StoreAddressRepository; public class StoreAddressRepositoryImpl implements StoreAddressRepositoryCustom { -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepository.java b/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepository.java index df4024a..bcea3eb 100644 --- a/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepository.java +++ b/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepository.java @@ -7,4 +7,4 @@ //24.11.19 @Repository add @Repository public interface StoreRepository extends JpaRepository, StoreRepositoryCustom { -} \ No newline at end of file +} diff --git a/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepositoryCustom.java b/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepositoryCustom.java index 4b89a08..452f4fc 100644 --- a/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepositoryCustom.java +++ b/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepositoryCustom.java @@ -6,4 +6,4 @@ public interface StoreRepositoryCustom { List dynamicQueryWithBooleanBuilder(String name, Float score); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepositoryImpl.java b/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepositoryImpl.java index 4f93dfb..d1c6061 100644 --- a/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepositoryImpl.java +++ b/src/main/java/javalab/umc7th_mission/repository/StoreRepository/StoreRepositoryImpl.java @@ -29,4 +29,4 @@ public List dynamicQueryWithBooleanBuilder(String name, Float score) { .where(predicate) .fetch(); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryService.java b/src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryService.java index cc650e6..43ec2d8 100644 --- a/src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryService.java +++ b/src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryService.java @@ -4,4 +4,4 @@ public interface FoodCategoryService { boolean allCategoriesExist(List values); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryServiceImpl.java index 6d5813a..478405e 100644 --- a/src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryServiceImpl.java +++ b/src/main/java/javalab/umc7th_mission/service/FoodCategoryService/FoodCategoryServiceImpl.java @@ -17,4 +17,4 @@ public boolean allCategoriesExist(List values) { return values.stream() .allMatch(id -> foodCategoryRepository.existsById(id)); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandService.java b/src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandService.java index f0e74ca..65564a0 100644 --- a/src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandService.java +++ b/src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandService.java @@ -7,4 +7,4 @@ public interface MemberMissionCommandService { MemberMission addMemberMission(MemberMissionRequestDTO.AddDTO request); boolean isMissionInProgress(Long memberId, Long missionId); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandServiceImpl.java index 1a4ff81..19b694a 100644 --- a/src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandServiceImpl.java +++ b/src/main/java/javalab/umc7th_mission/service/MemberMissionCommandService/MemberMissionCommandServiceImpl.java @@ -42,5 +42,4 @@ public boolean isMissionInProgress(Long memberId, Long missionId) { return memberMissionRepository.existsByMemberIdAndMissionIdAndStatus(memberId, missionId, MissionStatus.CHALLENGING); } - } diff --git a/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandService.java b/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandService.java index 5584ff0..54622bb 100644 --- a/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandService.java +++ b/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandService.java @@ -9,4 +9,4 @@ public interface MemberCommandService { Member joinMember(MemberRequestDTO.JoinDto request); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandServiceImpl.java index 5ecead1..021419e 100644 --- a/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandServiceImpl.java +++ b/src/main/java/javalab/umc7th_mission/service/MemberService/MemberCommandServiceImpl.java @@ -66,4 +66,4 @@ public Member joinMember(MemberRequestDTO.JoinDto request) { return memberRepository.save(newMember); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandService.java b/src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandService.java index a490286..273a8f3 100644 --- a/src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandService.java +++ b/src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandService.java @@ -5,4 +5,4 @@ public interface MissionCommandService { Mission addMission(MissionRequestDTO.AddDTO request); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandServiceImpl.java index 530b923..56e0263 100644 --- a/src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandServiceImpl.java +++ b/src/main/java/javalab/umc7th_mission/service/MissionCommandService/MissionCommandServiceImpl.java @@ -25,4 +25,4 @@ public Mission addMission(MissionRequestDTO.AddDTO request) { Mission newMission = MissionConverter.toMission(store, request); return missionRepository.save(newMission); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandService.java b/src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandService.java index 4346012..89150fb 100644 --- a/src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandService.java +++ b/src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandService.java @@ -5,4 +5,4 @@ public interface ReviewCommandService { Review addReview(ReviewRequestDTO.AddDTO request); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandServiceImpl.java index 679e953..ed175d8 100644 --- a/src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandServiceImpl.java +++ b/src/main/java/javalab/umc7th_mission/service/ReviewCommandService/ReviewCommandServiceImpl.java @@ -35,4 +35,4 @@ public Review addReview(ReviewRequestDTO.AddDTO request) { return reviewRepository.save(newReview); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/StoreCommandService/StoreCommandService.java b/src/main/java/javalab/umc7th_mission/service/StoreCommandService/StoreCommandService.java index 5f87e85..8cfd8fc 100644 --- a/src/main/java/javalab/umc7th_mission/service/StoreCommandService/StoreCommandService.java +++ b/src/main/java/javalab/umc7th_mission/service/StoreCommandService/StoreCommandService.java @@ -6,4 +6,4 @@ public interface StoreCommandService { // 가게 저장 Store addStore(StoreRequestDTO.AddDto request); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/StoreCommandService/StoreCommandServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/StoreCommandService/StoreCommandServiceImpl.java index 4625ec8..f2ebb2c 100644 --- a/src/main/java/javalab/umc7th_mission/service/StoreCommandService/StoreCommandServiceImpl.java +++ b/src/main/java/javalab/umc7th_mission/service/StoreCommandService/StoreCommandServiceImpl.java @@ -59,4 +59,4 @@ public Store addStore(StoreRequestDTO.AddDto request) { storeAddressRepository.save(storeAddress); return storeRepository.save(newStore); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationService.java b/src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationService.java index 1910afe..5280b9a 100644 --- a/src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationService.java +++ b/src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationService.java @@ -2,4 +2,4 @@ public interface StoreValidationService { boolean isStoreExist(Long id); -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationServiceImpl.java b/src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationServiceImpl.java index bbeae7f..2cf72ae 100644 --- a/src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationServiceImpl.java +++ b/src/main/java/javalab/umc7th_mission/service/StoreValidationService/StoreValidationServiceImpl.java @@ -13,4 +13,4 @@ public class StoreValidationServiceImpl implements StoreValidationService { public boolean isStoreExist(Long id) { return storeRepository.existsById(id); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/validation/annotation/ExistCategories.java b/src/main/java/javalab/umc7th_mission/validation/annotation/ExistCategories.java index 74168c0..dcaa56d 100644 --- a/src/main/java/javalab/umc7th_mission/validation/annotation/ExistCategories.java +++ b/src/main/java/javalab/umc7th_mission/validation/annotation/ExistCategories.java @@ -15,4 +15,4 @@ String message() default "해당하는 카테고리가 존재하지 않습니다."; Class[] groups() default {}; Class[] payload() default {}; -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/validation/annotation/ExistStore.java b/src/main/java/javalab/umc7th_mission/validation/annotation/ExistStore.java index bc48147..8f7c042 100644 --- a/src/main/java/javalab/umc7th_mission/validation/annotation/ExistStore.java +++ b/src/main/java/javalab/umc7th_mission/validation/annotation/ExistStore.java @@ -15,4 +15,4 @@ String message() default "해당하는 상점이 존재하지 않습니다."; Class[] groups() default {}; Class[] payload() default {}; -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/validation/annotation/MissionNotInProgress.java b/src/main/java/javalab/umc7th_mission/validation/annotation/MissionNotInProgress.java index 9523c29..94297d0 100644 --- a/src/main/java/javalab/umc7th_mission/validation/annotation/MissionNotInProgress.java +++ b/src/main/java/javalab/umc7th_mission/validation/annotation/MissionNotInProgress.java @@ -13,7 +13,7 @@ @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) public @interface MissionNotInProgress { - String message() default "해당 "; + String message() default "해당 하는 미션이 이미 진행중입니다."; Class[] groups() default {}; Class[] payload() default {}; -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/validation/validator/CategoriesExistValidator.java b/src/main/java/javalab/umc7th_mission/validation/validator/CategoriesExistValidator.java index f871930..a295a8d 100644 --- a/src/main/java/javalab/umc7th_mission/validation/validator/CategoriesExistValidator.java +++ b/src/main/java/javalab/umc7th_mission/validation/validator/CategoriesExistValidator.java @@ -32,4 +32,4 @@ public boolean isValid(List values, ConstraintValidatorContext context) { return isValid; } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/validation/validator/MissionNotInProgressValidator.java b/src/main/java/javalab/umc7th_mission/validation/validator/MissionNotInProgressValidator.java index 0d16066..b251902 100644 --- a/src/main/java/javalab/umc7th_mission/validation/validator/MissionNotInProgressValidator.java +++ b/src/main/java/javalab/umc7th_mission/validation/validator/MissionNotInProgressValidator.java @@ -39,4 +39,4 @@ public boolean isValid(Long missionId, ConstraintValidatorContext context) { } return !isInProgress; } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/validation/validator/StoreExistValidator.java b/src/main/java/javalab/umc7th_mission/validation/validator/StoreExistValidator.java index ff03754..2ebc60b 100644 --- a/src/main/java/javalab/umc7th_mission/validation/validator/StoreExistValidator.java +++ b/src/main/java/javalab/umc7th_mission/validation/validator/StoreExistValidator.java @@ -35,4 +35,4 @@ public boolean isValid(Long storeId, ConstraintValidatorContext context) { return isValid; } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/controller/MemberMissionRestController.java b/src/main/java/javalab/umc7th_mission/web/controller/MemberMissionRestController.java index 9aec096..57d6a20 100644 --- a/src/main/java/javalab/umc7th_mission/web/controller/MemberMissionRestController.java +++ b/src/main/java/javalab/umc7th_mission/web/controller/MemberMissionRestController.java @@ -25,4 +25,4 @@ public ApiResponse join(@RequestBody @Val MemberMission memberMission = memberMissionCommandService.addMemberMission(resquest); return ApiResponse.onSuccess(MemberMissionConverter.toAddResultDTO(memberMission)); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/controller/MemberRestController.java b/src/main/java/javalab/umc7th_mission/web/controller/MemberRestController.java index db1bcea..01146e4 100644 --- a/src/main/java/javalab/umc7th_mission/web/controller/MemberRestController.java +++ b/src/main/java/javalab/umc7th_mission/web/controller/MemberRestController.java @@ -24,4 +24,4 @@ public ApiResponse join(@RequestBody @Valid Mem Member member = memberCommandService.joinMember(request); return ApiResponse.onSuccess(MemberConverter.toJoinResultDTO(member)); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/controller/MissionRestController.java b/src/main/java/javalab/umc7th_mission/web/controller/MissionRestController.java index 0ad1cfb..2f95de4 100644 --- a/src/main/java/javalab/umc7th_mission/web/controller/MissionRestController.java +++ b/src/main/java/javalab/umc7th_mission/web/controller/MissionRestController.java @@ -55,4 +55,4 @@ public ApiResponse add(@RequestBody @Valid Miss Mission mission = missionCommandService.addMission(request); return ApiResponse.onSuccess(MissionConverter.toAddResultDTO(mission)); } -} \ No newline at end of file +} diff --git a/src/main/java/javalab/umc7th_mission/web/controller/ReviewRestController.java b/src/main/java/javalab/umc7th_mission/web/controller/ReviewRestController.java index 769df8c..620632d 100644 --- a/src/main/java/javalab/umc7th_mission/web/controller/ReviewRestController.java +++ b/src/main/java/javalab/umc7th_mission/web/controller/ReviewRestController.java @@ -24,4 +24,4 @@ public ApiResponse add(@RequestBody @Valid Revie Review review = reviewCommandService.addReview(request); return ApiResponse.onSuccess(ReviewConverter.toAddResultDTO(review)); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/controller/StoreRestController.java b/src/main/java/javalab/umc7th_mission/web/controller/StoreRestController.java index 97a6471..c7e07f6 100644 --- a/src/main/java/javalab/umc7th_mission/web/controller/StoreRestController.java +++ b/src/main/java/javalab/umc7th_mission/web/controller/StoreRestController.java @@ -25,4 +25,4 @@ public ApiResponse join(@RequestBody @Valid Store Store store = storeCommandService.addStore(request); return ApiResponse.onSuccess(StoreConverter.toAddResultDTO(store)); } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MemberInfoDto.java b/src/main/java/javalab/umc7th_mission/web/dto/MemberInfoDto.java index 447391f..913b888 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/MemberInfoDto.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/MemberInfoDto.java @@ -10,4 +10,4 @@ public class MemberInfoDto { private String email; private Integer points; private String phoneNumber; -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MemberMissionRequestDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MemberMissionRequestDTO.java index c937fe7..ef1c8eb 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/MemberMissionRequestDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/MemberMissionRequestDTO.java @@ -39,4 +39,4 @@ public AddDTO( this.endDate = endDate; } } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MemberMissionResponseDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MemberMissionResponseDTO.java index 36322db..ef190df 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/MemberMissionResponseDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/MemberMissionResponseDTO.java @@ -15,4 +15,4 @@ public AddResultDTO(Long memberMissionId, LocalDateTime createdAt) { public Long getMemberMissionId() { return memberMissionId; } public LocalDateTime getCreatedAt() { return createdAt; } } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java index 2d266e5..cd4a666 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/MemberRequestDTO.java @@ -79,4 +79,4 @@ public JoinDto( this.preferCategory = preferCategory; } } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MemberResponseDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MemberResponseDTO.java index 3e6541e..cb6bf19 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/MemberResponseDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/MemberResponseDTO.java @@ -30,4 +30,4 @@ public LocalDateTime getCreatedAt() { return createdAt; } } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MissionRequestDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MissionRequestDTO.java index b572786..7519774 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/MissionRequestDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/MissionRequestDTO.java @@ -50,4 +50,4 @@ public AddDTO( this.reward = reward; } } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/dto/MissionResponseDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/MissionResponseDTO.java index d1d12bb..9912fd6 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/MissionResponseDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/MissionResponseDTO.java @@ -21,4 +21,4 @@ public LocalDateTime getCreatedAt() { return createdAt; } } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/dto/ReviewRequestDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/ReviewRequestDTO.java index 21feaa2..6c8836c 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/ReviewRequestDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/ReviewRequestDTO.java @@ -42,4 +42,4 @@ public AddDTO( } } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/dto/ReviewResponseDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/ReviewResponseDTO.java index a6ce85c..fb28952 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/ReviewResponseDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/ReviewResponseDTO.java @@ -21,4 +21,4 @@ public LocalDateTime getCreatedAt() { return createdAt; } } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/dto/StoreRequestDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/StoreRequestDTO.java index ce0dcc9..0dff5b1 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/StoreRequestDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/StoreRequestDTO.java @@ -71,4 +71,4 @@ public AddDto( this.storeCategory = storeCategory; } } -} +} \ No newline at end of file diff --git a/src/main/java/javalab/umc7th_mission/web/dto/StoreResponseDTO.java b/src/main/java/javalab/umc7th_mission/web/dto/StoreResponseDTO.java index 0e8fe30..59b1092 100644 --- a/src/main/java/javalab/umc7th_mission/web/dto/StoreResponseDTO.java +++ b/src/main/java/javalab/umc7th_mission/web/dto/StoreResponseDTO.java @@ -21,4 +21,4 @@ public LocalDateTime getCreatedAt() { return createdAt; } } -} +} \ No newline at end of file