From 3ac2a29e35ad6a58efdfa14a8ab9a2ab2eebdba0 Mon Sep 17 00:00:00 2001 From: SEOB Date: Thu, 29 Aug 2024 23:46:56 +0900 Subject: [PATCH 1/7] =?UTF-8?q?SB-293=20(feat)=20:=20Fault=20Module=20?= =?UTF-8?q?=EA=B5=AC=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SB-293 (feat) : Fault Module 구축 1. Fault 모듈에 필요한 exception, errorCode, inage 패키지 구현 2. controller, business, service 클래스 구현 --- fault/build.gradle | 50 +++++++ .../src/main/java/fault/FaultApplication.java | 13 ++ .../CustomAuthenticationEntryPoint.java | 32 +++++ .../fault/common/config/jpa/JpaConfig.java | 12 ++ .../config/security/SecurityConfig.java | 68 ++++++++++ .../customvalidation/CustomValidator.java | 75 +++++++++++ .../fault/common/error/FaultErrorCode.java | 18 +++ .../fault/common/error/GoodsErrorCode.java | 22 ++++ .../fault/common/error/ImageErrorCode.java | 22 ++++ .../common/error/ReceivingErrorCode.java | 19 +++ .../fault/common/error/TokenErrorCode.java | 24 ++++ .../fault/common/error/UserErrorCode.java | 24 ++++ .../exception/GoodsExceptionHandler.java | 40 ++++++ .../exception/ImageExceptionHandler.java | 33 +++++ .../exception/ReceivingExceptionHandler.java | 32 +++++ .../exception/TokenExceptionHandler.java | 39 ++++++ .../exception/UserExceptionHandler.java | 71 ++++++++++ .../exception/ValidationExceptionHandler.java | 22 ++++ .../goods/GoodsNotFoundException.java | 33 +++++ .../goods/GoodsStrategyException.java | 33 +++++ .../goods/InvalidGoodsStatusException.java | 33 +++++ .../exception/image/ApiExceptionIfs.java | 11 ++ .../image/ImageNotFoundException.java | 38 ++++++ .../image/ImageStorageException.java | 36 ++++++ .../common/exception/jwt/TokenException.java | 35 +++++ .../exception/jwt/TokenExpiredException.java | 35 +++++ .../jwt/TokenSignatureException.java | 35 +++++ .../receiving/NoOwnershipException.java | 35 +++++ .../receiving/NotOwnerException.java | 36 ++++++ .../receiving/ReceivingNotFoundException.java | 36 ++++++ .../user/AddressNotFoundException.java | 33 +++++ .../exception/user/ExistUserException.java | 33 +++++ .../user/FailedToRegisterException.java | 36 ++++++ .../common/exception/user/LogInException.java | 35 +++++ .../user/UserNameNotFoundException.java | 36 ++++++ .../exception/user/UserNotFoundException.java | 33 +++++ .../user/UserUnregisterException.java | 33 +++++ .../java/fault/common/utils/ImageUtils.java | 30 +++++ .../domain/fault/business/FaultBusiness.java | 10 ++ .../fault/controller/FaultApiController.java | 12 ++ .../fault/converter/FaultConverter.java | 10 ++ .../domain/fault/service/FaultService.java | 10 ++ .../controller/model/ImageListRequest.java | 32 +++++ .../controller/model/ImageListResponse.java | 19 +++ .../image/controller/model/ImageRequest.java | 28 ++++ .../image/controller/model/ImageResponse.java | 29 +++++ .../image/converter/ImageConverter.java | 122 ++++++++++++++++++ .../converter/ImageMappingConverter.java | 16 +++ .../image/service/ImageMappingService.java | 37 ++++++ .../domain/image/service/ImageService.java | 33 +++++ .../security/jwt/filter/JwtAuthFilter.java | 61 +++++++++ .../security/jwt/helper/JwtTokenHelper.java | 88 +++++++++++++ .../security/jwt/helper/TokenHelperIfs.java | 12 ++ .../users/security/jwt/model/TokenDto.java | 18 +++ .../security/jwt/service/TokenService.java | 27 ++++ .../service/AuthorizationService.java | 34 +++++ .../users/security/service/UsersService.java | 99 ++++++++++++++ fault/src/main/resources/application.yaml | 25 ++++ settings.gradle | 1 + 59 files changed, 2004 insertions(+) create mode 100644 fault/build.gradle create mode 100644 fault/src/main/java/fault/FaultApplication.java create mode 100644 fault/src/main/java/fault/common/config/entrypoint/CustomAuthenticationEntryPoint.java create mode 100644 fault/src/main/java/fault/common/config/jpa/JpaConfig.java create mode 100644 fault/src/main/java/fault/common/config/security/SecurityConfig.java create mode 100644 fault/src/main/java/fault/common/customvalidation/CustomValidator.java create mode 100644 fault/src/main/java/fault/common/error/FaultErrorCode.java create mode 100644 fault/src/main/java/fault/common/error/GoodsErrorCode.java create mode 100644 fault/src/main/java/fault/common/error/ImageErrorCode.java create mode 100644 fault/src/main/java/fault/common/error/ReceivingErrorCode.java create mode 100644 fault/src/main/java/fault/common/error/TokenErrorCode.java create mode 100644 fault/src/main/java/fault/common/error/UserErrorCode.java create mode 100644 fault/src/main/java/fault/common/exception/GoodsExceptionHandler.java create mode 100644 fault/src/main/java/fault/common/exception/ImageExceptionHandler.java create mode 100644 fault/src/main/java/fault/common/exception/ReceivingExceptionHandler.java create mode 100644 fault/src/main/java/fault/common/exception/TokenExceptionHandler.java create mode 100644 fault/src/main/java/fault/common/exception/UserExceptionHandler.java create mode 100644 fault/src/main/java/fault/common/exception/ValidationExceptionHandler.java create mode 100644 fault/src/main/java/fault/common/exception/goods/GoodsNotFoundException.java create mode 100644 fault/src/main/java/fault/common/exception/goods/GoodsStrategyException.java create mode 100644 fault/src/main/java/fault/common/exception/goods/InvalidGoodsStatusException.java create mode 100644 fault/src/main/java/fault/common/exception/image/ApiExceptionIfs.java create mode 100644 fault/src/main/java/fault/common/exception/image/ImageNotFoundException.java create mode 100644 fault/src/main/java/fault/common/exception/image/ImageStorageException.java create mode 100644 fault/src/main/java/fault/common/exception/jwt/TokenException.java create mode 100644 fault/src/main/java/fault/common/exception/jwt/TokenExpiredException.java create mode 100644 fault/src/main/java/fault/common/exception/jwt/TokenSignatureException.java create mode 100644 fault/src/main/java/fault/common/exception/receiving/NoOwnershipException.java create mode 100644 fault/src/main/java/fault/common/exception/receiving/NotOwnerException.java create mode 100644 fault/src/main/java/fault/common/exception/receiving/ReceivingNotFoundException.java create mode 100644 fault/src/main/java/fault/common/exception/user/AddressNotFoundException.java create mode 100644 fault/src/main/java/fault/common/exception/user/ExistUserException.java create mode 100644 fault/src/main/java/fault/common/exception/user/FailedToRegisterException.java create mode 100644 fault/src/main/java/fault/common/exception/user/LogInException.java create mode 100644 fault/src/main/java/fault/common/exception/user/UserNameNotFoundException.java create mode 100644 fault/src/main/java/fault/common/exception/user/UserNotFoundException.java create mode 100644 fault/src/main/java/fault/common/exception/user/UserUnregisterException.java create mode 100644 fault/src/main/java/fault/common/utils/ImageUtils.java create mode 100644 fault/src/main/java/fault/domain/fault/business/FaultBusiness.java create mode 100644 fault/src/main/java/fault/domain/fault/controller/FaultApiController.java create mode 100644 fault/src/main/java/fault/domain/fault/converter/FaultConverter.java create mode 100644 fault/src/main/java/fault/domain/fault/service/FaultService.java create mode 100644 fault/src/main/java/fault/domain/image/controller/model/ImageListRequest.java create mode 100644 fault/src/main/java/fault/domain/image/controller/model/ImageListResponse.java create mode 100644 fault/src/main/java/fault/domain/image/controller/model/ImageRequest.java create mode 100644 fault/src/main/java/fault/domain/image/controller/model/ImageResponse.java create mode 100644 fault/src/main/java/fault/domain/image/converter/ImageConverter.java create mode 100644 fault/src/main/java/fault/domain/image/converter/ImageMappingConverter.java create mode 100644 fault/src/main/java/fault/domain/image/service/ImageMappingService.java create mode 100644 fault/src/main/java/fault/domain/image/service/ImageService.java create mode 100644 fault/src/main/java/fault/domain/users/security/jwt/filter/JwtAuthFilter.java create mode 100644 fault/src/main/java/fault/domain/users/security/jwt/helper/JwtTokenHelper.java create mode 100644 fault/src/main/java/fault/domain/users/security/jwt/helper/TokenHelperIfs.java create mode 100644 fault/src/main/java/fault/domain/users/security/jwt/model/TokenDto.java create mode 100644 fault/src/main/java/fault/domain/users/security/jwt/service/TokenService.java create mode 100644 fault/src/main/java/fault/domain/users/security/service/AuthorizationService.java create mode 100644 fault/src/main/java/fault/domain/users/security/service/UsersService.java create mode 100644 fault/src/main/resources/application.yaml diff --git a/fault/build.gradle b/fault/build.gradle new file mode 100644 index 00000000..cc789787 --- /dev/null +++ b/fault/build.gradle @@ -0,0 +1,50 @@ +plugins { + id 'java' + id 'org.springframework.boot' + id 'io.spring.dependency-management' +} + +group = 'org.fx' +version = '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform('org.junit:junit-bom:5.10.0') + testImplementation 'org.junit.jupiter:junit-jupiter' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + implementation 'org.springframework.boot:spring-boot-starter-security' + + implementation 'org.springframework.boot:spring-boot-starter-web' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2' + + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' + + implementation 'org.springframework.boot:spring-boot-starter-validation' + + implementation project(":db") + implementation project(":global") +} + +test { + useJUnitPlatform() +} + +bootJar { + enabled = true +} + +jar { + enabled = false +} \ No newline at end of file diff --git a/fault/src/main/java/fault/FaultApplication.java b/fault/src/main/java/fault/FaultApplication.java new file mode 100644 index 00000000..a0d078c9 --- /dev/null +++ b/fault/src/main/java/fault/FaultApplication.java @@ -0,0 +1,13 @@ +package fault; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class FaultApplication { + + public static void main(String[] args) { + SpringApplication.run(FaultApplication.class, args); + } + +} diff --git a/fault/src/main/java/fault/common/config/entrypoint/CustomAuthenticationEntryPoint.java b/fault/src/main/java/fault/common/config/entrypoint/CustomAuthenticationEntryPoint.java new file mode 100644 index 00000000..ae0a3ef1 --- /dev/null +++ b/fault/src/main/java/fault/common/config/entrypoint/CustomAuthenticationEntryPoint.java @@ -0,0 +1,32 @@ +package fault.common.config.entrypoint; + +import com.fasterxml.jackson.databind.ObjectMapper; +import global.api.Api; +import global.errorcode.ErrorCode; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.OutputStream; +import org.springframework.http.MediaType; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +@Component +public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) + throws IOException, ServletException { + + Api body = Api.ERROR(ErrorCode.MISSING_REQUIRED_HEADER); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + OutputStream responseStream = response.getOutputStream(); + ObjectMapper mapper = new ObjectMapper(); + mapper.writeValue(responseStream, body); + responseStream.flush(); + + } +} diff --git a/fault/src/main/java/fault/common/config/jpa/JpaConfig.java b/fault/src/main/java/fault/common/config/jpa/JpaConfig.java new file mode 100644 index 00000000..96f193b1 --- /dev/null +++ b/fault/src/main/java/fault/common/config/jpa/JpaConfig.java @@ -0,0 +1,12 @@ +package fault.common.config.jpa; + +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +@Configuration +@EntityScan(basePackages = {"db"}) +@EnableJpaRepositories(basePackages = {"db"}) +public class JpaConfig { + +} diff --git a/fault/src/main/java/fault/common/config/security/SecurityConfig.java b/fault/src/main/java/fault/common/config/security/SecurityConfig.java new file mode 100644 index 00000000..ecea37b1 --- /dev/null +++ b/fault/src/main/java/fault/common/config/security/SecurityConfig.java @@ -0,0 +1,68 @@ +package fault.common.config.security; + +import fault.domain.users.security.jwt.filter.JwtAuthFilter; +import fault.domain.users.security.jwt.service.TokenService; +import fault.domain.users.security.service.AuthorizationService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.autoconfigure.security.servlet.PathRequest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +@Configuration +@EnableWebSecurity // security 활성화 +@EnableGlobalAuthentication +@RequiredArgsConstructor +public class SecurityConfig { + + private final AuthenticationEntryPoint authEntryPoint; + + private final AuthorizationService authorizationService; + private final TokenService tokenService; + + private final List WHITE_LIST = List.of("/swagger-ui.html", "/swagger-ui/**", + "/v3/api-docs/**", "/open-api/**"); + + @Bean + public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { + + httpSecurity.cors(cors -> cors.disable()) + .addFilterBefore(new JwtAuthFilter(authorizationService, tokenService), + UsernamePasswordAuthenticationFilter.class) + .csrf((csrfConfig) -> csrfConfig.disable()) // 1번 + .sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy( + SessionCreationPolicy.STATELESS)).authorizeHttpRequests(it -> { + it.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() + .requestMatchers(WHITE_LIST.toArray(new String[0])).permitAll().anyRequest() + .authenticated() + ; + }).formLogin(AbstractHttpConfigurer::disable).httpBasic(AbstractHttpConfigurer::disable) + .httpBasic(basic -> basic.authenticationEntryPoint(authEntryPoint)) + .exceptionHandling(Customizer.withDefaults()) + ; + + return httpSecurity.build(); + } + + @Bean + public BCryptPasswordEncoder encoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public WebSecurityCustomizer webSecurityCustomizer() { + return (web) -> web.ignoring().requestMatchers(WHITE_LIST.toArray(new String[0])); + } + +} \ No newline at end of file diff --git a/fault/src/main/java/fault/common/customvalidation/CustomValidator.java b/fault/src/main/java/fault/common/customvalidation/CustomValidator.java new file mode 100644 index 00000000..511830f5 --- /dev/null +++ b/fault/src/main/java/fault/common/customvalidation/CustomValidator.java @@ -0,0 +1,75 @@ +package fault.common.customvalidation; + +import global.api.Api; +import jakarta.validation.ValidationException; +import java.util.Objects; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.springframework.stereotype.Component; +import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.validation.Errors; +import org.springframework.validation.FieldError; +import org.springframework.validation.Validator; +import org.springframework.validation.beanvalidation.SpringValidatorAdapter; + +@Aspect +@Component +@RequiredArgsConstructor +@Slf4j +public class CustomValidator implements Validator { + + private final SpringValidatorAdapter validator; + + @Override + public boolean supports(Class clazz) { + return Api.class.equals(clazz); + } + + @Override + public void validate(Object target, Errors errors) { + if (target instanceof Api) { + Api api = (Api) target; + Object body = api.getBody(); + validator.validate(body, errors); + + //TODO 검토 필요 + if (errors.hasGlobalErrors()) { + throw new ValidationException(errors.getAllErrors().toString()); + } + + if (errors.hasFieldErrors()) { + FieldError fieldError = errors.getFieldError(); + String field = Objects.requireNonNull(fieldError).getField(); + Object rejectedValue = fieldError.getRejectedValue(); + + if (Objects.requireNonNull(rejectedValue).equals("")) { + throw new ValidationException("[ " + field + " ] " + "은(는) 빈 값일수 없습니다."); + } + + throw new ValidationException( + "잘못된 입력입니다. [ " + field + " ] " + "의 입력 규칙 확인 후 재 요청바랍니다. 사용자 입력값 : " + rejectedValue); + } + + } + } + + /** + * 1. * -> 접근제한자 + * 2. * -> 반환 타입 + * 3. (.., @global.annotation.ApiValid (*), ..) -> @ApiValid를 사용하는 메서드의 파라미터 전체 + */ + @Before("execution(* *(.., @global.annotation.ApiValid (*), ..))") + public void apiValidAspect(JoinPoint joinPoint) { + Object[] args = joinPoint.getArgs(); + for(Object arg : args) { + if(arg instanceof Api) { + Errors errors = new BeanPropertyBindingResult(args[0], "api"); // 사실상 dummy errors + this.validate(arg, errors); + break; + } + } + } +} \ No newline at end of file diff --git a/fault/src/main/java/fault/common/error/FaultErrorCode.java b/fault/src/main/java/fault/common/error/FaultErrorCode.java new file mode 100644 index 00000000..e347ff79 --- /dev/null +++ b/fault/src/main/java/fault/common/error/FaultErrorCode.java @@ -0,0 +1,18 @@ +package fault.common.error; + +import global.errorcode.ErrorCodeIfs; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum FaultErrorCode implements ErrorCodeIfs { + + + ; + + private final Integer httpCode; + private final Integer errorCode; + private final String description; + +} \ No newline at end of file diff --git a/fault/src/main/java/fault/common/error/GoodsErrorCode.java b/fault/src/main/java/fault/common/error/GoodsErrorCode.java new file mode 100644 index 00000000..504ce30e --- /dev/null +++ b/fault/src/main/java/fault/common/error/GoodsErrorCode.java @@ -0,0 +1,22 @@ +package fault.common.error; + +import global.errorcode.ErrorCodeIfs; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum GoodsErrorCode implements ErrorCodeIfs { + + GOODS_NOT_FOUND(HttpStatus.NOT_FOUND.value(), 1200, "물품이 존재하지 않습니다."), + INVALID_GOODS_STATUS(HttpStatus.BAD_REQUEST.value(),1201,"잘못된 물품 상태입니다."), + INVALID_GOODS_STRATEGY(HttpStatus.BAD_REQUEST.value(), 1202, "요청서 종류가 잘못되었습니다."), + NOT_OWNER(HttpStatus.NOT_ACCEPTABLE.value(), 1203, "소유자가 아닙니다.") + ; + + private final Integer httpCode; + private final Integer errorCode; + private final String description; + +} diff --git a/fault/src/main/java/fault/common/error/ImageErrorCode.java b/fault/src/main/java/fault/common/error/ImageErrorCode.java new file mode 100644 index 00000000..752fb8fc --- /dev/null +++ b/fault/src/main/java/fault/common/error/ImageErrorCode.java @@ -0,0 +1,22 @@ +package fault.common.error; + +import global.errorcode.ErrorCodeIfs; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum ImageErrorCode implements ErrorCodeIfs { + + IMAGE_STORAGE_ERROR(HttpStatus.INTERNAL_SERVER_ERROR.value(), 1300, "이미지를 저장할 수 없습니다."), + NULL_POINT(HttpStatus.INTERNAL_SERVER_ERROR.value(), 1301, "NULL POINT 입니다."), + IMAGE_NOT_FOUND(HttpStatus.NOT_FOUND.value(), 1302, "요청하신 이미지를 찾을 수 없습니다."), + IMAGE_STORAGE_PATH_ERROR(HttpStatus.INTERNAL_SERVER_ERROR.value(), 1303, "업로드된 파일이 저장될 디렉터리를 생성할 수 없습니다.") + ; + + private final Integer httpCode; + private final Integer errorCode; + private final String description; + +} \ No newline at end of file diff --git a/fault/src/main/java/fault/common/error/ReceivingErrorCode.java b/fault/src/main/java/fault/common/error/ReceivingErrorCode.java new file mode 100644 index 00000000..47615651 --- /dev/null +++ b/fault/src/main/java/fault/common/error/ReceivingErrorCode.java @@ -0,0 +1,19 @@ +package fault.common.error; + +import global.errorcode.ErrorCodeIfs; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum ReceivingErrorCode implements ErrorCodeIfs { + + RECEIVING_REQUEST_NOT_FOUND(HttpStatus.NOT_FOUND.value(), 1250, "입고 요청서가 존재하지 않습니다."), + NO_OWNERSHIP(HttpStatus.BAD_REQUEST.value(), 1251, "사용자의 물품이 아닙니다.") + ; + + private final Integer httpCode; + private final Integer errorCode; + private final String description; +} \ No newline at end of file diff --git a/fault/src/main/java/fault/common/error/TokenErrorCode.java b/fault/src/main/java/fault/common/error/TokenErrorCode.java new file mode 100644 index 00000000..cee7d905 --- /dev/null +++ b/fault/src/main/java/fault/common/error/TokenErrorCode.java @@ -0,0 +1,24 @@ +package fault.common.error; + +import global.errorcode.ErrorCodeIfs; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum TokenErrorCode implements ErrorCodeIfs { + + NOT_AUTHENTICATION_USER(401,1100,"로그인이 필요합니다."), + NOT_AUTHORIZATION_USER(404,1101,"허가된 접근이 아닙니다."), + INVALID_TOKEN(401,1102,"유효하지 않은 토큰입니다."), + EXPIRED_TOKEN(401,1103,"만료된 토큰입니다."), + TOKEN_EXCEPTION(401,1104,"알 수 없는 토큰 에러입니다."), + NON_TOKEN_HEADER(401,1105,"인증 헤더 토큰이 없습니다."), + NO_EXPIRED_TOKEN(400,1106,"만료되지 않은 토큰입니다."), + ; + + private final Integer httpCode; + private final Integer errorCode; + private final String description; + +} \ No newline at end of file diff --git a/fault/src/main/java/fault/common/error/UserErrorCode.java b/fault/src/main/java/fault/common/error/UserErrorCode.java new file mode 100644 index 00000000..f6d2d4af --- /dev/null +++ b/fault/src/main/java/fault/common/error/UserErrorCode.java @@ -0,0 +1,24 @@ +package fault.common.error; + +import global.errorcode.ErrorCodeIfs; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum UserErrorCode implements ErrorCodeIfs { + + FAILED_TO_REGISTER(500, 1150, "회원가입이 실패했습니다."), + USER_NOT_FOUND(404, 1151, "사용자를 찾을 수 없습니다."), + UNREGISTERED_MEMBER(403, 1152, "탈퇴한 회원입니다."), + DORMANT_MEMBER(403, 1153, "휴면 계정입니다."), + EXIST_USER(403, 1154, "이미 존재하는 아이디입니다."), + LOGIN_FAIL(401, 1155, "로그인 정보가 일치하지 않습니다."), + ADDRESS_NOT_FOUND(404, 1156, "사용자의 주소를 찾을 수 없습니다."), + FAILED_TO_UNREGISTER(500, 1157, "회원 탈퇴에 실패했습니다."); + + private final Integer httpCode; + private final Integer errorCode; + private final String description; + +} diff --git a/fault/src/main/java/fault/common/exception/GoodsExceptionHandler.java b/fault/src/main/java/fault/common/exception/GoodsExceptionHandler.java new file mode 100644 index 00000000..bc297bc2 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/GoodsExceptionHandler.java @@ -0,0 +1,40 @@ +package fault.common.exception; + +import fault.common.exception.goods.GoodsNotFoundException; +import fault.common.exception.goods.InvalidGoodsStatusException; +import fault.common.error.GoodsErrorCode; +import fault.common.exception.receiving.NotOwnerException; +import global.api.Api; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@Slf4j +@RestControllerAdvice +@Order(value = Integer.MIN_VALUE) +public class GoodsExceptionHandler { + + @ExceptionHandler(value = GoodsNotFoundException.class) + public ResponseEntity> imageException(GoodsNotFoundException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Api.ERROR(GoodsErrorCode.GOODS_NOT_FOUND)); + } + + @ExceptionHandler(value = InvalidGoodsStatusException.class) + public ResponseEntity> InvalidGoodsStatus(InvalidGoodsStatusException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Api.ERROR(GoodsErrorCode.INVALID_GOODS_STATUS)); + } + + @ExceptionHandler(value = NotOwnerException.class) + public ResponseEntity> notOwnerException(NotOwnerException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Api.ERROR(GoodsErrorCode.NOT_OWNER)); + } +} diff --git a/fault/src/main/java/fault/common/exception/ImageExceptionHandler.java b/fault/src/main/java/fault/common/exception/ImageExceptionHandler.java new file mode 100644 index 00000000..c34b672c --- /dev/null +++ b/fault/src/main/java/fault/common/exception/ImageExceptionHandler.java @@ -0,0 +1,33 @@ +package fault.common.exception; + +import global.api.Api; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import fault.common.error.ImageErrorCode; +import fault.common.exception.image.ImageNotFoundException; +import fault.common.exception.image.ImageStorageException; + +@Slf4j +@RestControllerAdvice +@Order(value = Integer.MIN_VALUE) +public class ImageExceptionHandler { + + @ExceptionHandler(value = ImageStorageException.class) + public ResponseEntity> imageException(ImageStorageException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Api.ERROR(ImageErrorCode.IMAGE_STORAGE_ERROR)); + } + + @ExceptionHandler(value = ImageNotFoundException.class) + public ResponseEntity> imageException(ImageNotFoundException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Api.ERROR(ImageErrorCode.IMAGE_NOT_FOUND)); + } + +} diff --git a/fault/src/main/java/fault/common/exception/ReceivingExceptionHandler.java b/fault/src/main/java/fault/common/exception/ReceivingExceptionHandler.java new file mode 100644 index 00000000..5c28271d --- /dev/null +++ b/fault/src/main/java/fault/common/exception/ReceivingExceptionHandler.java @@ -0,0 +1,32 @@ +package fault.common.exception; + +import fault.common.error.ReceivingErrorCode; +import fault.common.exception.receiving.NoOwnershipException; +import fault.common.exception.receiving.ReceivingNotFoundException; +import global.api.Api; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@Slf4j +@RestControllerAdvice +@Order(value = Integer.MIN_VALUE) +public class ReceivingExceptionHandler { + + @ExceptionHandler(value = ReceivingNotFoundException.class) + public ResponseEntity> imageException(ReceivingNotFoundException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Api.ERROR(ReceivingErrorCode.RECEIVING_REQUEST_NOT_FOUND)); + } + + @ExceptionHandler(value = NoOwnershipException.class) + public ResponseEntity> noOwnershipException(NoOwnershipException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Api.ERROR(ReceivingErrorCode.NO_OWNERSHIP)); + } +} diff --git a/fault/src/main/java/fault/common/exception/TokenExceptionHandler.java b/fault/src/main/java/fault/common/exception/TokenExceptionHandler.java new file mode 100644 index 00000000..4ca55b80 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/TokenExceptionHandler.java @@ -0,0 +1,39 @@ +package fault.common.exception; + +import global.api.Api; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import fault.common.error.TokenErrorCode; +import fault.common.exception.jwt.TokenException; +import fault.common.exception.jwt.TokenExpiredException; +import fault.common.exception.jwt.TokenSignatureException; + +@Slf4j +@RestControllerAdvice +public class TokenExceptionHandler { + + @ExceptionHandler(value = TokenSignatureException.class) + public ResponseEntity> tokenSignatureException(TokenSignatureException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(Api.ERROR(TokenErrorCode.INVALID_TOKEN)); + } + + @ExceptionHandler(value = TokenExpiredException.class) + public ResponseEntity> tokenExpiredException(TokenExpiredException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(Api.ERROR(TokenErrorCode.EXPIRED_TOKEN)); + } + + @ExceptionHandler(value = TokenException.class) + public ResponseEntity> tokenException(TokenException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(Api.ERROR(TokenErrorCode.TOKEN_EXCEPTION)); + } + +} diff --git a/fault/src/main/java/fault/common/exception/UserExceptionHandler.java b/fault/src/main/java/fault/common/exception/UserExceptionHandler.java new file mode 100644 index 00000000..382fa9b1 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/UserExceptionHandler.java @@ -0,0 +1,71 @@ +package fault.common.exception; + +import global.api.Api; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import fault.common.error.UserErrorCode; +import fault.common.exception.user.AddressNotFoundException; +import fault.common.exception.user.ExistUserException; +import fault.common.exception.user.FailedToRegisterException; +import fault.common.exception.user.LogInException; +import fault.common.exception.user.UserNameNotFoundException; +import fault.common.exception.user.UserNotFoundException; +import fault.common.exception.user.UserUnregisterException; + +@Slf4j +@RestControllerAdvice +public class UserExceptionHandler { + + @ExceptionHandler(value = ExistUserException.class) + public ResponseEntity> existUserException(ExistUserException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.FORBIDDEN) + .body(Api.ERROR(UserErrorCode.EXIST_USER)); + } + + @ExceptionHandler(FailedToRegisterException.class) + public ResponseEntity> failedToRegisterException(FailedToRegisterException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Api.ERROR(UserErrorCode.FAILED_TO_REGISTER)); + } + + @ExceptionHandler(value = LogInException.class) + public ResponseEntity> logInException(LogInException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(Api.ERROR(UserErrorCode.LOGIN_FAIL)); + } + + @ExceptionHandler(value = AddressNotFoundException.class) + public ResponseEntity> addressNotFoundException(AddressNotFoundException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Api.ERROR(UserErrorCode.ADDRESS_NOT_FOUND)); + } + + @ExceptionHandler(value = UserUnregisterException.class) + public ResponseEntity> userUnregisterException(UserUnregisterException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Api.ERROR(UserErrorCode.FAILED_TO_UNREGISTER)); + } + + @ExceptionHandler(value = UserNotFoundException.class) + public ResponseEntity> userNotFoundException(UserNotFoundException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Api.ERROR(UserErrorCode.USER_NOT_FOUND)); + } + + @ExceptionHandler(value = UserNameNotFoundException.class) + public ResponseEntity> userNameNotFoundException(UserNameNotFoundException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Api.ERROR(UserErrorCode.USER_NOT_FOUND)); + } + +} diff --git a/fault/src/main/java/fault/common/exception/ValidationExceptionHandler.java b/fault/src/main/java/fault/common/exception/ValidationExceptionHandler.java new file mode 100644 index 00000000..0b843f21 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/ValidationExceptionHandler.java @@ -0,0 +1,22 @@ +package fault.common.exception; + +import global.api.Api; +import global.errorcode.ErrorCode; +import jakarta.validation.ValidationException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@Slf4j +@RestControllerAdvice +public class ValidationExceptionHandler { + + @ExceptionHandler(value = ValidationException.class) + public ResponseEntity> validateException(ValidationException e) { + log.info("", e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Api.ERROR(ErrorCode.INVALID_INPUT_DATA,e.getMessage())); + } +} diff --git a/fault/src/main/java/fault/common/exception/goods/GoodsNotFoundException.java b/fault/src/main/java/fault/common/exception/goods/GoodsNotFoundException.java new file mode 100644 index 00000000..f5f43b8c --- /dev/null +++ b/fault/src/main/java/fault/common/exception/goods/GoodsNotFoundException.java @@ -0,0 +1,33 @@ +package fault.common.exception.goods; + +import global.errorcode.ErrorCodeIfs; + +public class GoodsNotFoundException extends RuntimeException { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public GoodsNotFoundException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public GoodsNotFoundException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public GoodsNotFoundException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public GoodsNotFoundException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } +} diff --git a/fault/src/main/java/fault/common/exception/goods/GoodsStrategyException.java b/fault/src/main/java/fault/common/exception/goods/GoodsStrategyException.java new file mode 100644 index 00000000..b04db825 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/goods/GoodsStrategyException.java @@ -0,0 +1,33 @@ +package fault.common.exception.goods; + +import global.errorcode.ErrorCodeIfs; + +public class GoodsStrategyException extends RuntimeException { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public GoodsStrategyException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public GoodsStrategyException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public GoodsStrategyException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public GoodsStrategyException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } +} diff --git a/fault/src/main/java/fault/common/exception/goods/InvalidGoodsStatusException.java b/fault/src/main/java/fault/common/exception/goods/InvalidGoodsStatusException.java new file mode 100644 index 00000000..9162a2dc --- /dev/null +++ b/fault/src/main/java/fault/common/exception/goods/InvalidGoodsStatusException.java @@ -0,0 +1,33 @@ +package fault.common.exception.goods; + +import global.errorcode.ErrorCodeIfs; + +public class InvalidGoodsStatusException extends RuntimeException { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public InvalidGoodsStatusException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public InvalidGoodsStatusException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public InvalidGoodsStatusException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public InvalidGoodsStatusException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } +} diff --git a/fault/src/main/java/fault/common/exception/image/ApiExceptionIfs.java b/fault/src/main/java/fault/common/exception/image/ApiExceptionIfs.java new file mode 100644 index 00000000..7940b3ec --- /dev/null +++ b/fault/src/main/java/fault/common/exception/image/ApiExceptionIfs.java @@ -0,0 +1,11 @@ +package fault.common.exception.image; + +import global.errorcode.ErrorCodeIfs; + +public interface ApiExceptionIfs { + + ErrorCodeIfs getErrorCodeIfs(); + + String getDescription(); + +} diff --git a/fault/src/main/java/fault/common/exception/image/ImageNotFoundException.java b/fault/src/main/java/fault/common/exception/image/ImageNotFoundException.java new file mode 100644 index 00000000..b849f649 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/image/ImageNotFoundException.java @@ -0,0 +1,38 @@ +package fault.common.exception.image; + +import global.errorcode.ErrorCodeIfs; +import lombok.Getter; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@Getter +@ResponseStatus(HttpStatus.NOT_FOUND) +public class ImageNotFoundException extends RuntimeException implements ApiExceptionIfs { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public ImageNotFoundException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public ImageNotFoundException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public ImageNotFoundException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public ImageNotFoundException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } +} diff --git a/fault/src/main/java/fault/common/exception/image/ImageStorageException.java b/fault/src/main/java/fault/common/exception/image/ImageStorageException.java new file mode 100644 index 00000000..2bf76f24 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/image/ImageStorageException.java @@ -0,0 +1,36 @@ +package fault.common.exception.image; + +import global.errorcode.ErrorCodeIfs; +import lombok.Getter; + +@Getter +public class ImageStorageException extends RuntimeException implements ApiExceptionIfs { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public ImageStorageException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public ImageStorageException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public ImageStorageException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public ImageStorageException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + +} diff --git a/fault/src/main/java/fault/common/exception/jwt/TokenException.java b/fault/src/main/java/fault/common/exception/jwt/TokenException.java new file mode 100644 index 00000000..4cf2ba8d --- /dev/null +++ b/fault/src/main/java/fault/common/exception/jwt/TokenException.java @@ -0,0 +1,35 @@ +package fault.common.exception.jwt; + +import global.errorcode.ErrorCodeIfs; + +public class TokenException extends RuntimeException{ + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public TokenException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public TokenException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public TokenException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public TokenException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + +} diff --git a/fault/src/main/java/fault/common/exception/jwt/TokenExpiredException.java b/fault/src/main/java/fault/common/exception/jwt/TokenExpiredException.java new file mode 100644 index 00000000..33a198c1 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/jwt/TokenExpiredException.java @@ -0,0 +1,35 @@ +package fault.common.exception.jwt; + +import global.errorcode.ErrorCodeIfs; + +public class TokenExpiredException extends RuntimeException{ + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public TokenExpiredException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public TokenExpiredException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public TokenExpiredException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public TokenExpiredException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + +} diff --git a/fault/src/main/java/fault/common/exception/jwt/TokenSignatureException.java b/fault/src/main/java/fault/common/exception/jwt/TokenSignatureException.java new file mode 100644 index 00000000..d98d55e7 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/jwt/TokenSignatureException.java @@ -0,0 +1,35 @@ +package fault.common.exception.jwt; + +import global.errorcode.ErrorCodeIfs; + +public class TokenSignatureException extends RuntimeException{ + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public TokenSignatureException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public TokenSignatureException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public TokenSignatureException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public TokenSignatureException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + +} diff --git a/fault/src/main/java/fault/common/exception/receiving/NoOwnershipException.java b/fault/src/main/java/fault/common/exception/receiving/NoOwnershipException.java new file mode 100644 index 00000000..35b7c92b --- /dev/null +++ b/fault/src/main/java/fault/common/exception/receiving/NoOwnershipException.java @@ -0,0 +1,35 @@ +package fault.common.exception.receiving; + +import global.errorcode.ErrorCodeIfs; +import lombok.Getter; + +@Getter +public class NoOwnershipException extends RuntimeException { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public NoOwnershipException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public NoOwnershipException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public NoOwnershipException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public NoOwnershipException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } +} diff --git a/fault/src/main/java/fault/common/exception/receiving/NotOwnerException.java b/fault/src/main/java/fault/common/exception/receiving/NotOwnerException.java new file mode 100644 index 00000000..f8e0def8 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/receiving/NotOwnerException.java @@ -0,0 +1,36 @@ +package fault.common.exception.receiving; + +import global.errorcode.ErrorCodeIfs; +import lombok.Getter; + +@Getter +public class NotOwnerException extends RuntimeException { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public NotOwnerException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public NotOwnerException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public NotOwnerException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public NotOwnerException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + +} \ No newline at end of file diff --git a/fault/src/main/java/fault/common/exception/receiving/ReceivingNotFoundException.java b/fault/src/main/java/fault/common/exception/receiving/ReceivingNotFoundException.java new file mode 100644 index 00000000..71b6b18b --- /dev/null +++ b/fault/src/main/java/fault/common/exception/receiving/ReceivingNotFoundException.java @@ -0,0 +1,36 @@ +package fault.common.exception.receiving; + +import global.errorcode.ErrorCodeIfs; +import lombok.Getter; + +@Getter +public class ReceivingNotFoundException extends RuntimeException { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public ReceivingNotFoundException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public ReceivingNotFoundException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public ReceivingNotFoundException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public ReceivingNotFoundException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + +} \ No newline at end of file diff --git a/fault/src/main/java/fault/common/exception/user/AddressNotFoundException.java b/fault/src/main/java/fault/common/exception/user/AddressNotFoundException.java new file mode 100644 index 00000000..4e6e54a4 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/user/AddressNotFoundException.java @@ -0,0 +1,33 @@ +package fault.common.exception.user; + +import global.errorcode.ErrorCodeIfs; + +public class AddressNotFoundException extends RuntimeException { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public AddressNotFoundException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public AddressNotFoundException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public AddressNotFoundException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public AddressNotFoundException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } +} diff --git a/fault/src/main/java/fault/common/exception/user/ExistUserException.java b/fault/src/main/java/fault/common/exception/user/ExistUserException.java new file mode 100644 index 00000000..31cb09c3 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/user/ExistUserException.java @@ -0,0 +1,33 @@ +package fault.common.exception.user; + +import global.errorcode.ErrorCodeIfs; + +public class ExistUserException extends RuntimeException { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public ExistUserException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public ExistUserException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public ExistUserException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public ExistUserException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } +} diff --git a/fault/src/main/java/fault/common/exception/user/FailedToRegisterException.java b/fault/src/main/java/fault/common/exception/user/FailedToRegisterException.java new file mode 100644 index 00000000..af95ecf4 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/user/FailedToRegisterException.java @@ -0,0 +1,36 @@ +package fault.common.exception.user; + +import global.errorcode.ErrorCodeIfs; +import lombok.Getter; + +@Getter +public class FailedToRegisterException extends RuntimeException { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public FailedToRegisterException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public FailedToRegisterException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public FailedToRegisterException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public FailedToRegisterException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + +} diff --git a/fault/src/main/java/fault/common/exception/user/LogInException.java b/fault/src/main/java/fault/common/exception/user/LogInException.java new file mode 100644 index 00000000..9bd0e6e9 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/user/LogInException.java @@ -0,0 +1,35 @@ +package fault.common.exception.user; + +import global.errorcode.ErrorCodeIfs; +import lombok.Getter; + +@Getter +public class LogInException extends RuntimeException { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public LogInException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public LogInException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public LogInException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public LogInException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } +} diff --git a/fault/src/main/java/fault/common/exception/user/UserNameNotFoundException.java b/fault/src/main/java/fault/common/exception/user/UserNameNotFoundException.java new file mode 100644 index 00000000..f2457856 --- /dev/null +++ b/fault/src/main/java/fault/common/exception/user/UserNameNotFoundException.java @@ -0,0 +1,36 @@ +package fault.common.exception.user; + +import global.errorcode.ErrorCodeIfs; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +public class UserNameNotFoundException extends UsernameNotFoundException { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public UserNameNotFoundException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public UserNameNotFoundException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public UserNameNotFoundException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable.toString()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public UserNameNotFoundException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable.toString()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + +} diff --git a/fault/src/main/java/fault/common/exception/user/UserNotFoundException.java b/fault/src/main/java/fault/common/exception/user/UserNotFoundException.java new file mode 100644 index 00000000..51ad617e --- /dev/null +++ b/fault/src/main/java/fault/common/exception/user/UserNotFoundException.java @@ -0,0 +1,33 @@ +package fault.common.exception.user; + +import global.errorcode.ErrorCodeIfs; + +public class UserNotFoundException extends RuntimeException { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public UserNotFoundException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public UserNotFoundException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public UserNotFoundException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public UserNotFoundException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } +} diff --git a/fault/src/main/java/fault/common/exception/user/UserUnregisterException.java b/fault/src/main/java/fault/common/exception/user/UserUnregisterException.java new file mode 100644 index 00000000..feb62deb --- /dev/null +++ b/fault/src/main/java/fault/common/exception/user/UserUnregisterException.java @@ -0,0 +1,33 @@ +package fault.common.exception.user; + +import global.errorcode.ErrorCodeIfs; + +public class UserUnregisterException extends RuntimeException { + + private final ErrorCodeIfs errorCodeIfs; + private final String description; + + public UserUnregisterException(ErrorCodeIfs errorCodeIfs) { + super(errorCodeIfs.getDescription()); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public UserUnregisterException(ErrorCodeIfs errorCodeIfs, String errorDescription) { + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } + + public UserUnregisterException(ErrorCodeIfs errorCodeIfs, Throwable throwable) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorCodeIfs.getDescription(); + } + + public UserUnregisterException(ErrorCodeIfs errorCodeIfs, Throwable throwable, + String errorDescription) { + super(throwable); + this.errorCodeIfs = errorCodeIfs; + this.description = errorDescription; + } +} diff --git a/fault/src/main/java/fault/common/utils/ImageUtils.java b/fault/src/main/java/fault/common/utils/ImageUtils.java new file mode 100644 index 00000000..64330acf --- /dev/null +++ b/fault/src/main/java/fault/common/utils/ImageUtils.java @@ -0,0 +1,30 @@ +package fault.common.utils; + +import db.common.BaseEntity; +import db.domain.goods.GoodsEntity; +import fault.common.exception.goods.GoodsNotFoundException; +import global.errorcode.ErrorCode; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +@Component +@RequiredArgsConstructor +public class ImageUtils { + + public static String subStringExtension(String originalName) { + int index = originalName.lastIndexOf("."); + return originalName.substring(index); + } + + public static Long getFirstGoodsId(List goodsEntityList) { + return goodsEntityList.stream().findAny().map(BaseEntity::getId).orElseThrow( + () -> new GoodsNotFoundException(ErrorCode.NULL_POINT)); + } + + public static String getCleanPath(String fileName) { + return StringUtils.cleanPath(fileName); + } + +} diff --git a/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java b/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java new file mode 100644 index 00000000..53006847 --- /dev/null +++ b/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java @@ -0,0 +1,10 @@ +package fault.domain.fault.business; + +import global.annotation.Business; +import lombok.RequiredArgsConstructor; + +@Business +@RequiredArgsConstructor +public class FaultBusiness { + +} diff --git a/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java b/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java new file mode 100644 index 00000000..3a7eaa2f --- /dev/null +++ b/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java @@ -0,0 +1,12 @@ +package fault.domain.fault.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/fault") +public class FaultApiController { + +} diff --git a/fault/src/main/java/fault/domain/fault/converter/FaultConverter.java b/fault/src/main/java/fault/domain/fault/converter/FaultConverter.java new file mode 100644 index 00000000..9f86f1b5 --- /dev/null +++ b/fault/src/main/java/fault/domain/fault/converter/FaultConverter.java @@ -0,0 +1,10 @@ +package fault.domain.fault.converter; + +import global.annotation.Converter; +import lombok.RequiredArgsConstructor; + +@Converter +@RequiredArgsConstructor +public class FaultConverter { + +} diff --git a/fault/src/main/java/fault/domain/fault/service/FaultService.java b/fault/src/main/java/fault/domain/fault/service/FaultService.java new file mode 100644 index 00000000..79a068fb --- /dev/null +++ b/fault/src/main/java/fault/domain/fault/service/FaultService.java @@ -0,0 +1,10 @@ +package fault.domain.fault.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class FaultService { + +} diff --git a/fault/src/main/java/fault/domain/image/controller/model/ImageListRequest.java b/fault/src/main/java/fault/domain/image/controller/model/ImageListRequest.java new file mode 100644 index 00000000..866eb27c --- /dev/null +++ b/fault/src/main/java/fault/domain/image/controller/model/ImageListRequest.java @@ -0,0 +1,32 @@ +package fault.domain.image.controller.model; + +import db.domain.image.enums.ImageKind; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.web.multipart.MultipartFile; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class ImageListRequest { + + @NotEmpty + @Size(min = 1, max = 10) + private List files; + + @NotNull + private ImageKind kind; + + @NotNull + @Size(min = 1, max = 10) + private List<@NotBlank @Size(max = 200) String> captions; + +} diff --git a/fault/src/main/java/fault/domain/image/controller/model/ImageListResponse.java b/fault/src/main/java/fault/domain/image/controller/model/ImageListResponse.java new file mode 100644 index 00000000..111c3600 --- /dev/null +++ b/fault/src/main/java/fault/domain/image/controller/model/ImageListResponse.java @@ -0,0 +1,19 @@ +package fault.domain.image.controller.model; + +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ImageListResponse { + + private List basicImageListResponse; + + private List faultImageListResponse; + +} diff --git a/fault/src/main/java/fault/domain/image/controller/model/ImageRequest.java b/fault/src/main/java/fault/domain/image/controller/model/ImageRequest.java new file mode 100644 index 00000000..586e290b --- /dev/null +++ b/fault/src/main/java/fault/domain/image/controller/model/ImageRequest.java @@ -0,0 +1,28 @@ +package fault.domain.image.controller.model; + +import db.domain.image.enums.ImageKind; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.web.multipart.MultipartFile; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class ImageRequest { + + @NotNull + private MultipartFile file; + + @NotNull + private ImageKind kind; + + @NotBlank @Size(max = 200) + private String caption; + +} diff --git a/fault/src/main/java/fault/domain/image/controller/model/ImageResponse.java b/fault/src/main/java/fault/domain/image/controller/model/ImageResponse.java new file mode 100644 index 00000000..0c0922e3 --- /dev/null +++ b/fault/src/main/java/fault/domain/image/controller/model/ImageResponse.java @@ -0,0 +1,29 @@ +package fault.domain.image.controller.model; + +import db.domain.image.enums.ImageKind; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ImageResponse { + + private Long id; + + private String serverName; + + private String originalName; + + private String imageUrl; + + private String caption; + + private ImageKind kind; + + private Long goodsId; + +} diff --git a/fault/src/main/java/fault/domain/image/converter/ImageConverter.java b/fault/src/main/java/fault/domain/image/converter/ImageConverter.java new file mode 100644 index 00000000..1c4a95e5 --- /dev/null +++ b/fault/src/main/java/fault/domain/image/converter/ImageConverter.java @@ -0,0 +1,122 @@ +package fault.domain.image.converter; + +import db.domain.goods.GoodsEntity; +import db.domain.image.ImageEntity; +import db.domain.image.enums.ImageKind; +import db.domain.imagemapping.ImageMappingEntity; +import global.annotation.Converter; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.StringUtils; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import fault.common.error.ImageErrorCode; +import fault.common.exception.image.ImageStorageException; +import fault.common.utils.ImageUtils; +import fault.domain.image.controller.model.ImageListResponse; +import fault.domain.image.controller.model.ImageRequest; +import fault.domain.image.controller.model.ImageResponse; +import fault.domain.image.service.ImageMappingService; +import fault.domain.image.service.ImageService; + +@Slf4j +@RequiredArgsConstructor +@Converter +public class ImageConverter { + + private final ImageService imageService; + private final ImageMappingService imageMappingService; + + public ImageResponse toResponse(ImageEntity newEntity) { + ImageMappingEntity imageMappingEntity = imageMappingService.getImageMappingBy( + newEntity.getImageMappingId()); + return Optional.ofNullable(newEntity).map( + it -> ImageResponse.builder().id(newEntity.getId()) + .serverName(newEntity.getServerName()) + .originalName(newEntity.getOriginalName()) + .imageUrl(newEntity.getImageUrl()) + .caption(newEntity.getCaption()) + .goodsId(imageMappingEntity.getGoodsId()) + .kind(imageMappingEntity.getKind()) + .build()) + .orElseThrow(() -> new ImageStorageException(ImageErrorCode.IMAGE_STORAGE_ERROR)); + } + + public List toResponseList(List imageEntityList) { + return imageEntityList.stream().map(this::toResponse).collect(Collectors.toList()); + } + + public ImageListResponse toImageListResponse(List basic, List fault) { + + List basicImageListResponse = toResponseList(basic); + List faultImageListResponse = toResponseList(fault); + + return ImageListResponse.builder().basicImageListResponse(basicImageListResponse) + .faultImageListResponse(faultImageListResponse).build(); + } + + public ImageListResponse toImageListResponse(GoodsEntity goodsEntity) { + List imageMappingEntityList = imageMappingService.getImageMappingIdByGoodsId( + goodsEntity.getId()); + + List basicImageMappingIdList = getImageMappingIdByKind(imageMappingEntityList, + ImageKind.BASIC); + List faultImageMappingIdList = getImageMappingIdByKind(imageMappingEntityList, + ImageKind.FAULT); + + List basicImageEntityList = imageService.getImageUrlList( + basicImageMappingIdList); + List faultImageEntityList = imageService.getImageUrlList( + faultImageMappingIdList); + return toImageListResponse(basicImageEntityList, faultImageEntityList); + } + + private List getImageMappingIdByKind(List imageMappingEntityList, + ImageKind kind) { + return imageMappingEntityList.stream() + .filter(imageMappingEntity -> imageMappingEntity.getKind() == kind) + .map(imageMappingEntity -> imageMappingEntity.getId()) + .toList(); + } + + @Slf4j + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + static class ImageInfo { + + private String uploadDir; + + private String originalFileName; + + private String serverName; + + private String extension; + + private String fileName; + + private String imageUrl; + + public ImageInfo(ImageRequest request, String uploadDir) { + this.uploadDir = uploadDir; + this.originalFileName = request.getFile().getOriginalFilename(); + this.serverName = UUID.randomUUID().toString(); + this.extension = ImageUtils.subStringExtension( + Objects.requireNonNull(this.originalFileName)); + this.fileName = StringUtils.cleanPath(this.serverName + this.extension); + this.imageUrl = ServletUriComponentsBuilder.fromCurrentContextPath() + .scheme("https") + .path(uploadDir + fileName) + .toUriString(); + } + } +} diff --git a/fault/src/main/java/fault/domain/image/converter/ImageMappingConverter.java b/fault/src/main/java/fault/domain/image/converter/ImageMappingConverter.java new file mode 100644 index 00000000..385eafed --- /dev/null +++ b/fault/src/main/java/fault/domain/image/converter/ImageMappingConverter.java @@ -0,0 +1,16 @@ +package fault.domain.image.converter; + +import db.domain.imagemapping.ImageMappingEntity; +import global.annotation.Converter; +import fault.domain.image.controller.model.ImageRequest; + +@Converter +public class ImageMappingConverter { + + public ImageMappingEntity toEntity(ImageRequest request) { + return ImageMappingEntity.builder() + .kind(request.getKind()) + .build(); + } + +} diff --git a/fault/src/main/java/fault/domain/image/service/ImageMappingService.java b/fault/src/main/java/fault/domain/image/service/ImageMappingService.java new file mode 100644 index 00000000..0c5c7029 --- /dev/null +++ b/fault/src/main/java/fault/domain/image/service/ImageMappingService.java @@ -0,0 +1,37 @@ +package fault.domain.image.service; + +import db.domain.goods.GoodsEntity; +import db.domain.imagemapping.ImageMappingEntity; +import db.domain.imagemapping.ImageMappingRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import fault.common.error.ImageErrorCode; +import fault.common.exception.image.ImageNotFoundException; + +@Service +@RequiredArgsConstructor +public class ImageMappingService { + + private final ImageMappingRepository imageMappingRepository; + + public List getImageMappingIdByGoodsId(Long goodsId) { + return imageMappingRepository.findAllByGoodsIdOrderByIdDesc(goodsId); + } + + public ImageMappingEntity getImageMappingBy(Long imageMappingId) { + return imageMappingRepository.findById(imageMappingId) + .orElseThrow(() -> new ImageNotFoundException(ImageErrorCode.IMAGE_NOT_FOUND)); + } + + public void receivingRequest(ImageMappingEntity imageMappingEntity, GoodsEntity goodsEntity) { + updateImage(imageMappingEntity, goodsEntity); + } + + private void updateImage(ImageMappingEntity imageMappingEntity, GoodsEntity goodsEntity) { + imageMappingEntity.setUserId(goodsEntity.getUserId()); + imageMappingEntity.setGoodsId(goodsEntity.getId()); + imageMappingRepository.save(imageMappingEntity); + } + +} \ No newline at end of file diff --git a/fault/src/main/java/fault/domain/image/service/ImageService.java b/fault/src/main/java/fault/domain/image/service/ImageService.java new file mode 100644 index 00000000..422443b5 --- /dev/null +++ b/fault/src/main/java/fault/domain/image/service/ImageService.java @@ -0,0 +1,33 @@ +package fault.domain.image.service; + +import db.domain.image.ImageEntity; +import db.domain.image.ImageRepository; +import java.util.List; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import fault.common.error.ImageErrorCode; +import fault.common.exception.image.ImageNotFoundException; + +@Slf4j +@RequiredArgsConstructor +@Service +public class ImageService { + + private final ImageRepository imageRepository; + + public List getImagesByImageIdList(List ids) { + return ids.stream().map(this::getImageByImageId).collect(Collectors.toList()); + } + + public List getImageUrlList(List imageMappingIdList) { + return imageRepository.findAllByImageMappingIdInOrderByIdDesc(imageMappingIdList); + } + + public ImageEntity getImageByImageId(Long imageId) { + return imageRepository.findFirstByIdOrderByIdDesc(imageId) + .orElseThrow(() -> new ImageNotFoundException(ImageErrorCode.IMAGE_NOT_FOUND)); + } + +} \ No newline at end of file diff --git a/fault/src/main/java/fault/domain/users/security/jwt/filter/JwtAuthFilter.java b/fault/src/main/java/fault/domain/users/security/jwt/filter/JwtAuthFilter.java new file mode 100644 index 00000000..28140642 --- /dev/null +++ b/fault/src/main/java/fault/domain/users/security/jwt/filter/JwtAuthFilter.java @@ -0,0 +1,61 @@ +package fault.domain.users.security.jwt.filter; + +import fault.common.error.UserErrorCode; +import fault.common.exception.jwt.TokenException; +import fault.domain.users.security.jwt.service.TokenService; +import fault.domain.users.security.service.AuthorizationService; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.web.filter.OncePerRequestFilter; + +@Slf4j +@RequiredArgsConstructor +public class JwtAuthFilter extends OncePerRequestFilter { // OncePerRequestFilter -> 한 번 실행 보장 + + private final AuthorizationService authorizationService; + private final TokenService tokenService; + + @Override + /** + * JWT 토큰 검증 필터 수행 + */ + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + + String authorizationHeader = request.getHeader("Authorization"); + + //JWT가 헤더에 있는 경우 + if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) { + String token = authorizationHeader.substring(7); + + //JWT 유효성 검증 + Long userId = tokenService.validationToken(token); + + if (userId == null) { + throw new TokenException(UserErrorCode.USER_NOT_FOUND); + } + + //유저와 토큰 일치 시 userDetails 생성 + UserDetails userDetails = authorizationService.loadUserByUsername(Long.toString(userId)); + + if (userDetails != null) { + //UserDetsils, Password, Role -> 접근권한 인증 Token 생성 + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = + new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); + + //현재 Request의 Security Context에 접근권한 설정 + SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); + } + + } + + filterChain.doFilter(request, response); // 다음 필터로 넘기기 + } +} \ No newline at end of file diff --git a/fault/src/main/java/fault/domain/users/security/jwt/helper/JwtTokenHelper.java b/fault/src/main/java/fault/domain/users/security/jwt/helper/JwtTokenHelper.java new file mode 100644 index 00000000..48b8de41 --- /dev/null +++ b/fault/src/main/java/fault/domain/users/security/jwt/helper/JwtTokenHelper.java @@ -0,0 +1,88 @@ +package fault.domain.users.security.jwt.helper; + +import fault.common.error.TokenErrorCode; +import fault.common.exception.jwt.TokenException; +import fault.common.exception.jwt.TokenExpiredException; +import fault.common.exception.jwt.TokenSignatureException; +import fault.domain.users.security.jwt.model.TokenDto; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jws; +import io.jsonwebtoken.JwtParser; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import io.jsonwebtoken.security.SignatureException; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import javax.crypto.SecretKey; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class JwtTokenHelper implements TokenHelperIfs { + + @Value("${jwt.secret.key}") + private String secretKey; + @Value("${jwt.access-token.plus-hour}") + private Long accessTokenPlusHour; + @Value("${jwt.refresh-token.plus-hour}") + private Long refreshTokenPlusHour; + + @Override + public TokenDto issueAccessToken(Map data) { + return getTokenDto(data, accessTokenPlusHour); + } + + @Override + public TokenDto issueRefreshToken(Map data) { + return getTokenDto(data, refreshTokenPlusHour); + } + + @Override + public Map validationTokenWithThrow(String token) { + + SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes()); + + JwtParser parser = Jwts.parserBuilder().setSigningKey(key).build(); + + try{ + Jws result = parser.parseClaimsJws(token); + return new HashMap<>(result.getBody()); + }catch (Exception e){ + if (e instanceof SignatureException){ + // 토큰 유효하지 않음 + throw new TokenSignatureException(TokenErrorCode.INVALID_TOKEN,e); + }else if (e instanceof ExpiredJwtException){ + // 토큰 만료 + throw new TokenExpiredException(TokenErrorCode.EXPIRED_TOKEN,e); + }else { + // 그 외 + throw new TokenException(TokenErrorCode.TOKEN_EXCEPTION,e); + } + } + } + + private TokenDto getTokenDto(Map data, Long refreshTokenPlusHour) { + LocalDateTime expiredLocalDateTime = LocalDateTime.now().plusHours(refreshTokenPlusHour); + Date expiredAt = Date.from(expiredLocalDateTime.atZone(ZoneId.systemDefault()).toInstant()); + + SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes()); + + String jwtToken = Jwts.builder() + .signWith(key, SignatureAlgorithm.HS256) + .setClaims(data) + .setExpiration(expiredAt) + .compact(); + + return TokenDto.builder() + .token(jwtToken) + .expiredAt(expiredLocalDateTime) + .build(); + } +} diff --git a/fault/src/main/java/fault/domain/users/security/jwt/helper/TokenHelperIfs.java b/fault/src/main/java/fault/domain/users/security/jwt/helper/TokenHelperIfs.java new file mode 100644 index 00000000..e7eb2716 --- /dev/null +++ b/fault/src/main/java/fault/domain/users/security/jwt/helper/TokenHelperIfs.java @@ -0,0 +1,12 @@ +package fault.domain.users.security.jwt.helper; + +import fault.domain.users.security.jwt.model.TokenDto; +import java.util.Map; + +public interface TokenHelperIfs { + + TokenDto issueAccessToken(Map data); + TokenDto issueRefreshToken(Map data); + Map validationTokenWithThrow(String token); + +} diff --git a/fault/src/main/java/fault/domain/users/security/jwt/model/TokenDto.java b/fault/src/main/java/fault/domain/users/security/jwt/model/TokenDto.java new file mode 100644 index 00000000..532a3955 --- /dev/null +++ b/fault/src/main/java/fault/domain/users/security/jwt/model/TokenDto.java @@ -0,0 +1,18 @@ +package fault.domain.users.security.jwt.model; + +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class TokenDto { + + private String token; + private LocalDateTime expiredAt; + +} diff --git a/fault/src/main/java/fault/domain/users/security/jwt/service/TokenService.java b/fault/src/main/java/fault/domain/users/security/jwt/service/TokenService.java new file mode 100644 index 00000000..40ed0013 --- /dev/null +++ b/fault/src/main/java/fault/domain/users/security/jwt/service/TokenService.java @@ -0,0 +1,27 @@ +package fault.domain.users.security.jwt.service; + +import fault.common.exception.jwt.TokenException; +import fault.domain.users.security.jwt.helper.TokenHelperIfs; +import global.errorcode.ErrorCode; +import java.util.Map; +import java.util.Objects; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class TokenService { + + private final TokenHelperIfs tokenHelperIfs; + + public Long validationToken(String token){ + + Map map = tokenHelperIfs.validationTokenWithThrow(token); + + Object userId = map.get("userId"); + Objects.requireNonNull(userId,()->{throw new TokenException(ErrorCode.NULL_POINT);}); + + return Long.parseLong(userId.toString()); + } + +} diff --git a/fault/src/main/java/fault/domain/users/security/service/AuthorizationService.java b/fault/src/main/java/fault/domain/users/security/service/AuthorizationService.java new file mode 100644 index 00000000..26a1b351 --- /dev/null +++ b/fault/src/main/java/fault/domain/users/security/service/AuthorizationService.java @@ -0,0 +1,34 @@ +package fault.domain.users.security.service; + +import db.domain.users.UserEntity; +import db.domain.users.UsersRepository; +import db.domain.users.enums.UserStatus; +import fault.common.error.UserErrorCode; +import fault.common.exception.user.UserNameNotFoundException; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class AuthorizationService implements UserDetailsService { + + private final UsersRepository usersRepository; + + @Override + public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException { + + Optional account = usersRepository.findFirstByIdAndStatusOrderByIdDesc( + Long.parseLong(userId), UserStatus.REGISTERED); + + return account.map(it -> User.builder().username(it.getEmail()).password(it.getPassword()) + .roles(it.getRole().toString()).build()) + .orElseThrow(() -> new UserNameNotFoundException(UserErrorCode.USER_NOT_FOUND)); + + } +} + diff --git a/fault/src/main/java/fault/domain/users/security/service/UsersService.java b/fault/src/main/java/fault/domain/users/security/service/UsersService.java new file mode 100644 index 00000000..36b283fa --- /dev/null +++ b/fault/src/main/java/fault/domain/users/security/service/UsersService.java @@ -0,0 +1,99 @@ +package fault.domain.users.security.service; + +import db.domain.users.UserEntity; +import db.domain.users.UsersRepository; +import db.domain.users.enums.UserStatus; +import java.time.LocalDateTime; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.crypto.bcrypt.BCrypt; +import org.springframework.stereotype.Service; +import fault.common.error.UserErrorCode; +import fault.common.exception.jwt.TokenException; +import fault.common.exception.user.ExistUserException; +import fault.common.exception.user.LogInException; +import fault.common.exception.user.UserNotFoundException; +import fault.common.exception.user.UserUnregisterException; + +@Slf4j +@Service +@RequiredArgsConstructor +public class UsersService { + + private final UsersRepository usersRepository; + + public boolean existsByEmail(String email){ + return usersRepository.existsByEmail(email); + } + + public boolean existsByName(String name){ + return usersRepository.existsByName(name); + } + + public void existsByEmailThrowEx(String email) { + + boolean existsByEmail = existsByEmail(email); + + if (existsByEmail){ + throw new ExistUserException(UserErrorCode.EXIST_USER); + } + + } + + + public void notExistsByEmailThrowEx(String email) { + + boolean existsByEmail = existsByEmail(email); + + if (!existsByEmail){ + throw new ExistUserException(UserErrorCode.USER_NOT_FOUND); + } + + } + + public UserEntity save(UserEntity userEntity) { + userEntity.setRegisteredAt(LocalDateTime.now()); + userEntity.setStatus(UserStatus.REGISTERED); + return usersRepository.save(userEntity); + } + + public UserEntity login(String email, String password) { + + UserEntity userEntity = usersRepository.findFirstByEmailAndStatusNotOrderByEmailDesc(email,UserStatus.UNREGISTERED) + .orElseThrow(() -> new LogInException(UserErrorCode.LOGIN_FAIL)); + + if (BCrypt.checkpw(password, userEntity.getPassword())){ + userEntity.setLastLoginAt(LocalDateTime.now()); + usersRepository.save(userEntity); + return userEntity; + } + + throw new LogInException(UserErrorCode.LOGIN_FAIL); + + } + + public UserEntity getUserWithThrow(Long userId) { + log.info("userid : {} in UsersService", userId); + return usersRepository.findFirstByIdAndStatusOrderByIdDesc(userId,UserStatus.REGISTERED).orElseThrow(() -> new TokenException( + UserErrorCode.USER_NOT_FOUND)); + } + + public UserEntity getUserWithThrow(String email) { + log.info("userid : {} in UsersService", email); + return usersRepository.findFirstByEmailAndStatusOrderByIdDesc(email,UserStatus.REGISTERED).orElseThrow(() -> new TokenException( + UserErrorCode.USER_NOT_FOUND)); + } + + public void unregister(String email) { + UserEntity userEntity = usersRepository.findFirstByEmailAndStatusOrderByIdDesc(email, + UserStatus.REGISTERED) + .orElseThrow(() -> new UserNotFoundException(UserErrorCode.USER_NOT_FOUND)); + userEntity.setStatus(UserStatus.UNREGISTERED); + userEntity.setUnRegisteredAt(LocalDateTime.now()); + UserEntity unRegisterdUserEntity = usersRepository.save(userEntity); + if (!unRegisterdUserEntity.getStatus().equals(UserStatus.UNREGISTERED)){ + throw new UserUnregisterException(UserErrorCode.FAILED_TO_UNREGISTER); + } + + } +} \ No newline at end of file diff --git a/fault/src/main/resources/application.yaml b/fault/src/main/resources/application.yaml new file mode 100644 index 00000000..efa2c13b --- /dev/null +++ b/fault/src/main/resources/application.yaml @@ -0,0 +1,25 @@ +spring: + jpa: + show-sql: true + hibernate: + ddl-auto: validate + properties: + hibernate: + format_sql: true + dialect: org.hibernate.dialect.MySQL8Dialect + datasource: + url: jdbc:mysql://localhost:3306/baobab?useSSL=false&useUnicode=true&allowPublicKeyRetrieval=true + driver-class-name: com.mysql.cj.jdbc.Driver + username: root + password: 1234 + +jwt: + secret: + key: shinyangjunglee_baobab_passwordkey + access-token: + plus-hour: 1 + refresh-token: + plus-hour: 12 + +server: + port: 8084 \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 6601cebf..2f2f5210 100644 --- a/settings.gradle +++ b/settings.gradle @@ -6,4 +6,5 @@ include 'delivery' include 'gateway' include 'users' include 'image' +include 'fault' From 6f6b3ca795e208f61caecd16e80086fedb084ff6 Mon Sep 17 00:00:00 2001 From: SEOB Date: Sun, 1 Sep 2024 01:00:02 +0900 Subject: [PATCH 2/7] =?UTF-8?q?SB-294=20(feat)=20:=20FaultRepository=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SB-294 (feat) : FaultRepository 구현 1. FaultEntity 2. FaultRepository 3. GoodsStatus - REJECT status 추가 4. ImageKind - DELIVERY kind 추가 --- .../java/db/domain/fault/FaultEntity.java | 34 +++++++++++++++++++ .../java/db/domain/fault/FaultRepository.java | 7 ++++ .../db/domain/goods/enums/GoodsStatus.java | 3 +- .../java/db/domain/image/enums/ImageKind.java | 3 +- 4 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 db/src/main/java/db/domain/fault/FaultEntity.java create mode 100644 db/src/main/java/db/domain/fault/FaultRepository.java diff --git a/db/src/main/java/db/domain/fault/FaultEntity.java b/db/src/main/java/db/domain/fault/FaultEntity.java new file mode 100644 index 00000000..eaf66274 --- /dev/null +++ b/db/src/main/java/db/domain/fault/FaultEntity.java @@ -0,0 +1,34 @@ +package db.domain.fault; + +import db.common.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +@Entity +@Table(name = "fault") +@SuperBuilder +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@AllArgsConstructor +public class FaultEntity extends BaseEntity { + + private LocalDateTime guaranteeAt; + + @Column(length = 200, nullable = false) + private String description; + + @Column(nullable = false) + private Long receivingId; + + @Column(nullable = false) + private Long userId; + +} diff --git a/db/src/main/java/db/domain/fault/FaultRepository.java b/db/src/main/java/db/domain/fault/FaultRepository.java new file mode 100644 index 00000000..4cf3f5e1 --- /dev/null +++ b/db/src/main/java/db/domain/fault/FaultRepository.java @@ -0,0 +1,7 @@ +package db.domain.fault; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface FaultRepository extends JpaRepository { + +} diff --git a/db/src/main/java/db/domain/goods/enums/GoodsStatus.java b/db/src/main/java/db/domain/goods/enums/GoodsStatus.java index 07f85893..bbdf771a 100644 --- a/db/src/main/java/db/domain/goods/enums/GoodsStatus.java +++ b/db/src/main/java/db/domain/goods/enums/GoodsStatus.java @@ -13,7 +13,8 @@ public enum GoodsStatus { TAKE_BACK(4,"반품", "반품된 상품입니다."), SHIPPING_ING(5,"출고 진행 중", "출고 진행 중 입니다."), SHIPPING(6,"출고", "출고된 상품입니다."), - USED(7,"중고", "중고 전환 된 상품입니다.") + USED(7,"중고", "중고 전환 된 상품입니다."), + REJECT(8, "입고 취소", "입고 거절된 상품입니다.") ; private final int current; diff --git a/db/src/main/java/db/domain/image/enums/ImageKind.java b/db/src/main/java/db/domain/image/enums/ImageKind.java index 60c7665d..93ddccf5 100644 --- a/db/src/main/java/db/domain/image/enums/ImageKind.java +++ b/db/src/main/java/db/domain/image/enums/ImageKind.java @@ -10,7 +10,8 @@ public enum ImageKind { BASIC("기본 사진"), FAULT("결함 사진"), - PROFILE("프로필 사진") + PROFILE("프로필 사진"), + DELIVERY("배송 결함") ; private final String description; From fa617ae17ef64fc4c93485405661c41aaea541e3 Mon Sep 17 00:00:00 2001 From: SEOB Date: Sun, 1 Sep 2024 01:16:25 +0900 Subject: [PATCH 3/7] =?UTF-8?q?SB-296=20(feat)=20:=20=EA=B2=B0=ED=95=A8=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EB=B3=B4=EA=B8=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SB-296 (feat) : 결함 목록 보기 구현 1. url : /api/fault/list/{goodsId} 2. FaultApiController 3. FaultBusiness 4. FaultConverter 5. FaultService 5. 불필요한 코드 및 클래스 제거 --- .../domain/fault/business/FaultBusiness.java | 46 ++++++- .../fault/controller/FaultApiController.java | 28 +++- .../model/response/FaultImageResponse.java | 21 +++ .../model/response/FaultListResponse.java} | 10 +- .../fault/converter/FaultConverter.java | 58 +++++++++ .../domain/fault/service/FaultService.java | 8 ++ .../domain/goods/service/GoodsService.java | 37 ++++++ .../controller/model/ImageListRequest.java | 32 ----- .../image/controller/model/ImageRequest.java | 28 ---- .../image/controller/model/ImageResponse.java | 29 ----- .../image/converter/ImageConverter.java | 122 ------------------ .../converter/ImageMappingConverter.java | 16 --- .../image/service/ImageMappingService.java | 21 +-- .../domain/image/service/ImageService.java | 19 ++- .../receiving/service/ReceivingService.java | 33 +++++ 15 files changed, 254 insertions(+), 254 deletions(-) create mode 100644 fault/src/main/java/fault/domain/fault/controller/model/response/FaultImageResponse.java rename fault/src/main/java/fault/domain/{image/controller/model/ImageListResponse.java => fault/controller/model/response/FaultListResponse.java} (50%) create mode 100644 fault/src/main/java/fault/domain/goods/service/GoodsService.java delete mode 100644 fault/src/main/java/fault/domain/image/controller/model/ImageListRequest.java delete mode 100644 fault/src/main/java/fault/domain/image/controller/model/ImageRequest.java delete mode 100644 fault/src/main/java/fault/domain/image/controller/model/ImageResponse.java delete mode 100644 fault/src/main/java/fault/domain/image/converter/ImageConverter.java delete mode 100644 fault/src/main/java/fault/domain/image/converter/ImageMappingConverter.java create mode 100644 fault/src/main/java/fault/domain/receiving/service/ReceivingService.java diff --git a/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java b/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java index 53006847..d2a7091f 100644 --- a/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java +++ b/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java @@ -1,10 +1,54 @@ package fault.domain.fault.business; +import db.domain.fault.FaultEntity; +import db.domain.goods.enums.GoodsStatus; +import db.domain.image.ImageEntity; +import db.domain.image.enums.ImageKind; +import db.domain.imagemapping.ImageMappingEntity; +import db.domain.receiving.ReceivingEntity; +import db.domain.receiving.enums.ReceivingStatus; +import fault.domain.fault.controller.model.common.MessageResponse; +import fault.domain.fault.controller.model.request.AddFaultRequest; +import fault.domain.fault.controller.model.request.RejectFaultRequest; +import fault.domain.fault.controller.model.response.AddFaultResponse; +import fault.domain.fault.controller.model.response.FaultImageResponse; +import fault.domain.fault.controller.model.response.FaultListResponse; +import fault.domain.fault.controller.model.response.RejectFaultResponse; +import fault.domain.fault.converter.FaultConverter; +import fault.domain.fault.converter.MessageConverter; +import fault.domain.fault.service.FaultService; +import fault.domain.goods.service.GoodsService; +import fault.domain.image.service.ImageMappingService; +import fault.domain.image.service.ImageService; +import fault.domain.receiving.service.ReceivingService; +import fault.domain.users.security.service.UsersService; import global.annotation.Business; +import java.util.List; import lombok.RequiredArgsConstructor; @Business @RequiredArgsConstructor public class FaultBusiness { -} + private final UsersService usersService; + private final ImageService imageService; + private final ImageMappingService imageMappingService; + private final ReceivingService receivingService; + private final GoodsService goodsService; + + private final FaultConverter faultConverter; + private final MessageConverter messageConverter; + private final FaultService faultService; + + public FaultListResponse getFaultList(Long goodsId) { + List faultImageMappingIdList = imageMappingService.getImageMappingIdByGoodsId(goodsId) + .stream() + .filter(imageMappingEntity -> imageMappingEntity.getKind() == ImageKind.FAULT) + .map(imageMappingEntity -> imageMappingEntity.getId()).toList(); + + List faultImageEntityList = imageService.getImageBy(faultImageMappingIdList); + + return faultConverter.toResponse(faultImageEntityList, goodsId); + + } + diff --git a/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java b/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java index 3a7eaa2f..44b1e756 100644 --- a/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java +++ b/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java @@ -1,12 +1,38 @@ package fault.domain.fault.controller; +import fault.domain.fault.business.FaultBusiness; +import fault.domain.fault.controller.model.common.MessageResponse; +import fault.domain.fault.controller.model.request.AddFaultRequest; +import fault.domain.fault.controller.model.request.RejectFaultRequest; +import fault.domain.fault.controller.model.response.FaultImageResponse; +import fault.domain.fault.controller.model.response.FaultListResponse; +import fault.domain.fault.controller.model.response.AddFaultResponse; +import fault.domain.fault.controller.model.response.RejectFaultResponse; +import global.annotation.ApiValid; +import global.api.Api; +import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.userdetails.User; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequiredArgsConstructor @RequestMapping("/api/fault") +@Slf4j public class FaultApiController { -} + private final FaultBusiness faultBusiness; + + @GetMapping("/list/{goodsId}") + @Operation(summary = "[결함 목록 보기]") + public Api getFaultList(@PathVariable Long goodsId) { + FaultListResponse response = faultBusiness.getFaultList(goodsId); + return Api.OK(response); + } diff --git a/fault/src/main/java/fault/domain/fault/controller/model/response/FaultImageResponse.java b/fault/src/main/java/fault/domain/fault/controller/model/response/FaultImageResponse.java new file mode 100644 index 00000000..422ae22b --- /dev/null +++ b/fault/src/main/java/fault/domain/fault/controller/model/response/FaultImageResponse.java @@ -0,0 +1,21 @@ +package fault.domain.fault.controller.model.response; + + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class FaultImageResponse { + + private Long imageId; + + private String imageUrl; + + private String caption; + +} diff --git a/fault/src/main/java/fault/domain/image/controller/model/ImageListResponse.java b/fault/src/main/java/fault/domain/fault/controller/model/response/FaultListResponse.java similarity index 50% rename from fault/src/main/java/fault/domain/image/controller/model/ImageListResponse.java rename to fault/src/main/java/fault/domain/fault/controller/model/response/FaultListResponse.java index 111c3600..18ae4cb4 100644 --- a/fault/src/main/java/fault/domain/image/controller/model/ImageListResponse.java +++ b/fault/src/main/java/fault/domain/fault/controller/model/response/FaultListResponse.java @@ -1,4 +1,4 @@ -package fault.domain.image.controller.model; +package fault.domain.fault.controller.model.response; import java.util.List; import lombok.AllArgsConstructor; @@ -6,14 +6,14 @@ import lombok.Data; import lombok.NoArgsConstructor; -@Builder @Data @NoArgsConstructor @AllArgsConstructor -public class ImageListResponse { +@Builder +public class FaultListResponse { - private List basicImageListResponse; + private Long goodsId; - private List faultImageListResponse; + private List faultList; } diff --git a/fault/src/main/java/fault/domain/fault/converter/FaultConverter.java b/fault/src/main/java/fault/domain/fault/converter/FaultConverter.java index 9f86f1b5..a5d273fc 100644 --- a/fault/src/main/java/fault/domain/fault/converter/FaultConverter.java +++ b/fault/src/main/java/fault/domain/fault/converter/FaultConverter.java @@ -1,10 +1,68 @@ package fault.domain.fault.converter; +import db.domain.fault.FaultEntity; +import db.domain.image.ImageEntity; +import db.domain.imagemapping.ImageMappingEntity; +import fault.domain.fault.controller.model.request.RejectFaultRequest; +import fault.domain.fault.controller.model.response.FaultImageResponse; +import fault.domain.fault.controller.model.response.FaultListResponse; +import fault.domain.fault.controller.model.response.AddFaultResponse; +import fault.domain.fault.controller.model.response.RejectFaultResponse; import global.annotation.Converter; +import java.time.LocalDateTime; +import java.util.List; import lombok.RequiredArgsConstructor; @Converter @RequiredArgsConstructor public class FaultConverter { + public FaultEntity toEntity(RejectFaultRequest rejectFaultRequest, Long userId) { + return FaultEntity.builder() + .guaranteeAt(LocalDateTime.now()) + .description(rejectFaultRequest.getDescription()) + .receivingId(rejectFaultRequest.getReceivingId()) + .userId(userId) + .build(); + } + + public AddFaultResponse toResponse(ImageMappingEntity imageMappingEntity, + ImageEntity imageEntity) { + return AddFaultResponse.builder() + .goodsId(imageMappingEntity.getGoodsId()) + .fault(FaultImageResponse.builder() + .imageId(imageEntity.getId()) + .imageUrl(imageEntity.getImageUrl()) + .caption(imageEntity.getCaption()) + .build()) + .build(); + } + + public FaultListResponse toResponse(List imageEntityList, Long goodsId) { + return FaultListResponse.builder() + .goodsId(goodsId) + .faultList( + imageEntityList.stream() + .map(imageEntity -> toResponse(imageEntity)) + .toList()) + .build(); + } + + public FaultImageResponse toResponse(ImageEntity imageEntity) { + return FaultImageResponse.builder() + .imageId(imageEntity.getId()) + .imageUrl(imageEntity.getImageUrl()) + .caption(imageEntity.getCaption()) + .build(); + } + + public RejectFaultResponse toResponse(FaultEntity faultEntity) { + return RejectFaultResponse.builder() + .faultId(faultEntity.getId()) + .receivingId(faultEntity.getReceivingId()) + .description(faultEntity.getDescription()) + .guaranteeAt(faultEntity.getGuaranteeAt()) + .build(); + } + } diff --git a/fault/src/main/java/fault/domain/fault/service/FaultService.java b/fault/src/main/java/fault/domain/fault/service/FaultService.java index 79a068fb..00516f15 100644 --- a/fault/src/main/java/fault/domain/fault/service/FaultService.java +++ b/fault/src/main/java/fault/domain/fault/service/FaultService.java @@ -1,5 +1,7 @@ package fault.domain.fault.service; +import db.domain.fault.FaultEntity; +import db.domain.fault.FaultRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -7,4 +9,10 @@ @RequiredArgsConstructor public class FaultService { + private final FaultRepository faultRepository; + + + public FaultEntity rejectFault(FaultEntity faultEntity) { + return faultRepository.save(faultEntity); + } } diff --git a/fault/src/main/java/fault/domain/goods/service/GoodsService.java b/fault/src/main/java/fault/domain/goods/service/GoodsService.java new file mode 100644 index 00000000..03bf66d6 --- /dev/null +++ b/fault/src/main/java/fault/domain/goods/service/GoodsService.java @@ -0,0 +1,37 @@ +package fault.domain.goods.service; + +import db.domain.goods.GoodsEntity; +import db.domain.goods.GoodsRepository; +import db.domain.goods.enums.GoodsStatus; +import fault.common.error.GoodsErrorCode; +import fault.common.exception.goods.GoodsNotFoundException; +import java.util.List; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +@Slf4j +public class GoodsService { + + private final GoodsRepository goodsRepository; + + private List findAllBy(Long receivingId) { + return goodsRepository.findAllByReceivingIdOrderByIdDesc(receivingId); + } + + public void setGoodsStatusBy(GoodsEntity goodsEntity, GoodsStatus status) { + goodsEntity.setStatus(status); + goodsRepository.save(goodsEntity); + } + + public List findAllByReceivingIdWithThrow(Long receivingId) { + List goodsEntityList = findAllBy(receivingId); + if (goodsEntityList.isEmpty()) { + throw new GoodsNotFoundException(GoodsErrorCode.GOODS_NOT_FOUND); + } + return goodsEntityList; + } + +} \ No newline at end of file diff --git a/fault/src/main/java/fault/domain/image/controller/model/ImageListRequest.java b/fault/src/main/java/fault/domain/image/controller/model/ImageListRequest.java deleted file mode 100644 index 866eb27c..00000000 --- a/fault/src/main/java/fault/domain/image/controller/model/ImageListRequest.java +++ /dev/null @@ -1,32 +0,0 @@ -package fault.domain.image.controller.model; - -import db.domain.image.enums.ImageKind; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.web.multipart.MultipartFile; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class ImageListRequest { - - @NotEmpty - @Size(min = 1, max = 10) - private List files; - - @NotNull - private ImageKind kind; - - @NotNull - @Size(min = 1, max = 10) - private List<@NotBlank @Size(max = 200) String> captions; - -} diff --git a/fault/src/main/java/fault/domain/image/controller/model/ImageRequest.java b/fault/src/main/java/fault/domain/image/controller/model/ImageRequest.java deleted file mode 100644 index 586e290b..00000000 --- a/fault/src/main/java/fault/domain/image/controller/model/ImageRequest.java +++ /dev/null @@ -1,28 +0,0 @@ -package fault.domain.image.controller.model; - -import db.domain.image.enums.ImageKind; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.web.multipart.MultipartFile; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class ImageRequest { - - @NotNull - private MultipartFile file; - - @NotNull - private ImageKind kind; - - @NotBlank @Size(max = 200) - private String caption; - -} diff --git a/fault/src/main/java/fault/domain/image/controller/model/ImageResponse.java b/fault/src/main/java/fault/domain/image/controller/model/ImageResponse.java deleted file mode 100644 index 0c0922e3..00000000 --- a/fault/src/main/java/fault/domain/image/controller/model/ImageResponse.java +++ /dev/null @@ -1,29 +0,0 @@ -package fault.domain.image.controller.model; - -import db.domain.image.enums.ImageKind; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ImageResponse { - - private Long id; - - private String serverName; - - private String originalName; - - private String imageUrl; - - private String caption; - - private ImageKind kind; - - private Long goodsId; - -} diff --git a/fault/src/main/java/fault/domain/image/converter/ImageConverter.java b/fault/src/main/java/fault/domain/image/converter/ImageConverter.java deleted file mode 100644 index 1c4a95e5..00000000 --- a/fault/src/main/java/fault/domain/image/converter/ImageConverter.java +++ /dev/null @@ -1,122 +0,0 @@ -package fault.domain.image.converter; - -import db.domain.goods.GoodsEntity; -import db.domain.image.ImageEntity; -import db.domain.image.enums.ImageKind; -import db.domain.imagemapping.ImageMappingEntity; -import global.annotation.Converter; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.UUID; -import java.util.stream.Collectors; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import fault.common.error.ImageErrorCode; -import fault.common.exception.image.ImageStorageException; -import fault.common.utils.ImageUtils; -import fault.domain.image.controller.model.ImageListResponse; -import fault.domain.image.controller.model.ImageRequest; -import fault.domain.image.controller.model.ImageResponse; -import fault.domain.image.service.ImageMappingService; -import fault.domain.image.service.ImageService; - -@Slf4j -@RequiredArgsConstructor -@Converter -public class ImageConverter { - - private final ImageService imageService; - private final ImageMappingService imageMappingService; - - public ImageResponse toResponse(ImageEntity newEntity) { - ImageMappingEntity imageMappingEntity = imageMappingService.getImageMappingBy( - newEntity.getImageMappingId()); - return Optional.ofNullable(newEntity).map( - it -> ImageResponse.builder().id(newEntity.getId()) - .serverName(newEntity.getServerName()) - .originalName(newEntity.getOriginalName()) - .imageUrl(newEntity.getImageUrl()) - .caption(newEntity.getCaption()) - .goodsId(imageMappingEntity.getGoodsId()) - .kind(imageMappingEntity.getKind()) - .build()) - .orElseThrow(() -> new ImageStorageException(ImageErrorCode.IMAGE_STORAGE_ERROR)); - } - - public List toResponseList(List imageEntityList) { - return imageEntityList.stream().map(this::toResponse).collect(Collectors.toList()); - } - - public ImageListResponse toImageListResponse(List basic, List fault) { - - List basicImageListResponse = toResponseList(basic); - List faultImageListResponse = toResponseList(fault); - - return ImageListResponse.builder().basicImageListResponse(basicImageListResponse) - .faultImageListResponse(faultImageListResponse).build(); - } - - public ImageListResponse toImageListResponse(GoodsEntity goodsEntity) { - List imageMappingEntityList = imageMappingService.getImageMappingIdByGoodsId( - goodsEntity.getId()); - - List basicImageMappingIdList = getImageMappingIdByKind(imageMappingEntityList, - ImageKind.BASIC); - List faultImageMappingIdList = getImageMappingIdByKind(imageMappingEntityList, - ImageKind.FAULT); - - List basicImageEntityList = imageService.getImageUrlList( - basicImageMappingIdList); - List faultImageEntityList = imageService.getImageUrlList( - faultImageMappingIdList); - return toImageListResponse(basicImageEntityList, faultImageEntityList); - } - - private List getImageMappingIdByKind(List imageMappingEntityList, - ImageKind kind) { - return imageMappingEntityList.stream() - .filter(imageMappingEntity -> imageMappingEntity.getKind() == kind) - .map(imageMappingEntity -> imageMappingEntity.getId()) - .toList(); - } - - @Slf4j - @Data - @NoArgsConstructor - @AllArgsConstructor - @Builder - static class ImageInfo { - - private String uploadDir; - - private String originalFileName; - - private String serverName; - - private String extension; - - private String fileName; - - private String imageUrl; - - public ImageInfo(ImageRequest request, String uploadDir) { - this.uploadDir = uploadDir; - this.originalFileName = request.getFile().getOriginalFilename(); - this.serverName = UUID.randomUUID().toString(); - this.extension = ImageUtils.subStringExtension( - Objects.requireNonNull(this.originalFileName)); - this.fileName = StringUtils.cleanPath(this.serverName + this.extension); - this.imageUrl = ServletUriComponentsBuilder.fromCurrentContextPath() - .scheme("https") - .path(uploadDir + fileName) - .toUriString(); - } - } -} diff --git a/fault/src/main/java/fault/domain/image/converter/ImageMappingConverter.java b/fault/src/main/java/fault/domain/image/converter/ImageMappingConverter.java deleted file mode 100644 index 385eafed..00000000 --- a/fault/src/main/java/fault/domain/image/converter/ImageMappingConverter.java +++ /dev/null @@ -1,16 +0,0 @@ -package fault.domain.image.converter; - -import db.domain.imagemapping.ImageMappingEntity; -import global.annotation.Converter; -import fault.domain.image.controller.model.ImageRequest; - -@Converter -public class ImageMappingConverter { - - public ImageMappingEntity toEntity(ImageRequest request) { - return ImageMappingEntity.builder() - .kind(request.getKind()) - .build(); - } - -} diff --git a/fault/src/main/java/fault/domain/image/service/ImageMappingService.java b/fault/src/main/java/fault/domain/image/service/ImageMappingService.java index 0c5c7029..ef55fe4e 100644 --- a/fault/src/main/java/fault/domain/image/service/ImageMappingService.java +++ b/fault/src/main/java/fault/domain/image/service/ImageMappingService.java @@ -1,13 +1,13 @@ package fault.domain.image.service; -import db.domain.goods.GoodsEntity; import db.domain.imagemapping.ImageMappingEntity; import db.domain.imagemapping.ImageMappingRepository; +import fault.common.error.ImageErrorCode; +import fault.common.exception.image.ImageNotFoundException; +import fault.domain.fault.controller.model.request.AddFaultRequest; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import fault.common.error.ImageErrorCode; -import fault.common.exception.image.ImageNotFoundException; @Service @RequiredArgsConstructor @@ -24,14 +24,15 @@ public ImageMappingEntity getImageMappingBy(Long imageMappingId) { .orElseThrow(() -> new ImageNotFoundException(ImageErrorCode.IMAGE_NOT_FOUND)); } - public void receivingRequest(ImageMappingEntity imageMappingEntity, GoodsEntity goodsEntity) { - updateImage(imageMappingEntity, goodsEntity); + public ImageMappingEntity addFault(ImageMappingEntity imageMappingEntity, + AddFaultRequest addFaultRequest, Long userId) { + return updateImageMapping(imageMappingEntity, addFaultRequest, userId); } - private void updateImage(ImageMappingEntity imageMappingEntity, GoodsEntity goodsEntity) { - imageMappingEntity.setUserId(goodsEntity.getUserId()); - imageMappingEntity.setGoodsId(goodsEntity.getId()); - imageMappingRepository.save(imageMappingEntity); + private ImageMappingEntity updateImageMapping(ImageMappingEntity imageMappingEntity, + AddFaultRequest addFaultRequest, Long userId) { + imageMappingEntity.setGoodsId(addFaultRequest.getGoodsId()); + imageMappingEntity.setUserId(userId); + return imageMappingRepository.save(imageMappingEntity); } - } \ No newline at end of file diff --git a/fault/src/main/java/fault/domain/image/service/ImageService.java b/fault/src/main/java/fault/domain/image/service/ImageService.java index 422443b5..a5b48eef 100644 --- a/fault/src/main/java/fault/domain/image/service/ImageService.java +++ b/fault/src/main/java/fault/domain/image/service/ImageService.java @@ -2,13 +2,13 @@ import db.domain.image.ImageEntity; import db.domain.image.ImageRepository; +import fault.common.error.ImageErrorCode; +import fault.common.exception.image.ImageNotFoundException; import java.util.List; -import java.util.stream.Collectors; +import java.util.Optional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import fault.common.error.ImageErrorCode; -import fault.common.exception.image.ImageNotFoundException; @Slf4j @RequiredArgsConstructor @@ -17,15 +17,14 @@ public class ImageService { private final ImageRepository imageRepository; - public List getImagesByImageIdList(List ids) { - return ids.stream().map(this::getImageByImageId).collect(Collectors.toList()); - } - - public List getImageUrlList(List imageMappingIdList) { - return imageRepository.findAllByImageMappingIdInOrderByIdDesc(imageMappingIdList); + public List getImageBy(List imageMappingIdList) { + return Optional.ofNullable( + imageRepository.findAllByImageMappingIdInOrderByIdDesc(imageMappingIdList)).orElseThrow( + () -> new ImageNotFoundException(ImageErrorCode.IMAGE_NOT_FOUND) + ); } - public ImageEntity getImageByImageId(Long imageId) { + public ImageEntity getImageBy(Long imageId) { return imageRepository.findFirstByIdOrderByIdDesc(imageId) .orElseThrow(() -> new ImageNotFoundException(ImageErrorCode.IMAGE_NOT_FOUND)); } diff --git a/fault/src/main/java/fault/domain/receiving/service/ReceivingService.java b/fault/src/main/java/fault/domain/receiving/service/ReceivingService.java new file mode 100644 index 00000000..0357fd7a --- /dev/null +++ b/fault/src/main/java/fault/domain/receiving/service/ReceivingService.java @@ -0,0 +1,33 @@ +package fault.domain.receiving.service; + +import db.domain.receiving.ReceivingEntity; +import db.domain.receiving.ReceivingRepository; +import db.domain.receiving.enums.ReceivingStatus; +import fault.common.exception.receiving.ReceivingNotFoundException; +import global.errorcode.ErrorCode; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class ReceivingService { + + private final ReceivingRepository receivingRepository; + + public ReceivingEntity getReceivingBy(Long receivingId) { + return receivingRepository.findFirstById(receivingId) + .orElseThrow((() -> new ReceivingNotFoundException(ErrorCode.NULL_POINT))); + } + + public void approveFault(Long receivingId) { + ReceivingEntity receivingEntity = this.getReceivingBy(receivingId); + receivingEntity.setStatus(ReceivingStatus.DELIVERY); + receivingRepository.save(receivingEntity); + } + + public ReceivingEntity rejectFault(ReceivingEntity receivingEntity, ReceivingStatus status) { + receivingEntity.setStatus(status); + return receivingRepository.save(receivingEntity); + } + +} From 3271a07ff5c3be05cb4d410e4c058c9f32961f51 Mon Sep 17 00:00:00 2001 From: SEOB Date: Sun, 1 Sep 2024 01:18:35 +0900 Subject: [PATCH 4/7] =?UTF-8?q?SB-297=20(feat)=20:=20=EA=B2=B0=ED=95=A8=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EB=B3=B4=EA=B8=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SB-297 (feat) : 결함 상세 보기 구현 1. url : /api/fault/{imageId} 2. FaultApiController 3. FaultBusiness --- .../java/fault/domain/fault/business/FaultBusiness.java | 6 ++++++ .../fault/domain/fault/controller/FaultApiController.java | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java b/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java index d2a7091f..c4bcc891 100644 --- a/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java +++ b/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java @@ -52,3 +52,9 @@ public FaultListResponse getFaultList(Long goodsId) { } + public FaultImageResponse getFaultDetail(Long imageId) { + ImageEntity imageEntity = imageService.getImageBy(imageId); + return faultConverter.toResponse(imageEntity); + } + + diff --git a/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java b/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java index 44b1e756..8a7fd2c9 100644 --- a/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java +++ b/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java @@ -36,3 +36,11 @@ public Api getFaultList(@PathVariable Long goodsId) { FaultListResponse response = faultBusiness.getFaultList(goodsId); return Api.OK(response); } + + @GetMapping("/{imageId}") + @Operation(summary = "[결함 상세 보기]") + public Api getFaultDetail(@PathVariable Long imageId) { + FaultImageResponse response = faultBusiness.getFaultDetail(imageId); + return Api.OK(response); + } + From 424bbadedbc235d13e113048a26e1e4b05a515e4 Mon Sep 17 00:00:00 2001 From: SEOB Date: Sun, 1 Sep 2024 01:28:51 +0900 Subject: [PATCH 5/7] =?UTF-8?q?SB-299=20(feat)=20:=20=EA=B2=B0=ED=95=A8=20?= =?UTF-8?q?=EC=8A=B9=EC=9D=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SB-299 (feat) : 결함 승인 구현 1. ReceivingStatus.DELIVERY 로 상태 변경 --- .../domain/fault/business/FaultBusiness.java | 6 ++++++ .../fault/controller/FaultApiController.java | 6 ++++++ .../controller/model/common/MessageResponse.java | 16 ++++++++++++++++ .../domain/fault/converter/MessageConverter.java | 13 +++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 fault/src/main/java/fault/domain/fault/controller/model/common/MessageResponse.java create mode 100644 fault/src/main/java/fault/domain/fault/converter/MessageConverter.java diff --git a/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java b/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java index c4bcc891..50f67f63 100644 --- a/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java +++ b/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java @@ -58,3 +58,9 @@ public FaultImageResponse getFaultDetail(Long imageId) { } + public MessageResponse approveFault(Long receivingId) { + receivingService.approveFault(receivingId); // **입고 상태를 DELIVERY 로 변경합니다.** + return messageConverter.toMassageResponse("결함이 승인되었습니다."); + } + + diff --git a/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java b/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java index 8a7fd2c9..3fd6b893 100644 --- a/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java +++ b/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java @@ -44,3 +44,9 @@ public Api getFaultDetail(@PathVariable Long imageId) { return Api.OK(response); } + @PostMapping("/{receivingId}") + @Operation(summary = "[결함 승인]") + public Api approveFault(@PathVariable Long receivingId) { + MessageResponse response = faultBusiness.approveFault(receivingId); + return Api.OK(response); + } diff --git a/fault/src/main/java/fault/domain/fault/controller/model/common/MessageResponse.java b/fault/src/main/java/fault/domain/fault/controller/model/common/MessageResponse.java new file mode 100644 index 00000000..da2b8356 --- /dev/null +++ b/fault/src/main/java/fault/domain/fault/controller/model/common/MessageResponse.java @@ -0,0 +1,16 @@ +package fault.domain.fault.controller.model.common; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class MessageResponse { + + private String Message; + +} diff --git a/fault/src/main/java/fault/domain/fault/converter/MessageConverter.java b/fault/src/main/java/fault/domain/fault/converter/MessageConverter.java new file mode 100644 index 00000000..7cc61cc2 --- /dev/null +++ b/fault/src/main/java/fault/domain/fault/converter/MessageConverter.java @@ -0,0 +1,13 @@ +package fault.domain.fault.converter; + +import fault.domain.fault.controller.model.common.MessageResponse; +import global.annotation.Converter; + +@Converter +public class MessageConverter { + public MessageResponse toMassageResponse(String message) { + return MessageResponse.builder() + .Message(message) + .build(); + } +} From c6ad3f2891697252525ced9bbbe41a2092d982a9 Mon Sep 17 00:00:00 2001 From: SEOB Date: Sun, 1 Sep 2024 01:31:59 +0900 Subject: [PATCH 6/7] =?UTF-8?q?SB-300=20(feat)=20:=20=EA=B2=B0=ED=95=A8=20?= =?UTF-8?q?=EB=B0=98=EB=A0=A4=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SB-300 (feat) : 결함 반려 로직 구현 1. 반려시 - ReceivingStatus -> CLOSE - GoodsStatus -> REJECT 2. Fault Table 에 관련 정보 저장 - description, userId, .... --- .../domain/fault/business/FaultBusiness.java | 21 ++++++++++++++++++ .../fault/controller/FaultApiController.java | 12 ++++++++++ .../model/request/RejectFaultRequest.java | 22 +++++++++++++++++++ .../model/response/RejectFaultResponse.java | 20 +++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 fault/src/main/java/fault/domain/fault/controller/model/request/RejectFaultRequest.java create mode 100644 fault/src/main/java/fault/domain/fault/controller/model/response/RejectFaultResponse.java diff --git a/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java b/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java index 50f67f63..a3bcf8c0 100644 --- a/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java +++ b/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java @@ -64,3 +64,24 @@ public MessageResponse approveFault(Long receivingId) { } + public RejectFaultResponse rejectFault(RejectFaultRequest rejectFaultRequest, String email) { + + Long userId = usersService.getUserWithThrow(email).getId(); // deliveryManId + + ReceivingEntity receivingEntity = receivingService.getReceivingBy( + rejectFaultRequest.getReceivingId()); + + // 결함 반려 + // **입고요청서 CLOSE, 물품 상태 REJECT** + receivingService.rejectFault(receivingEntity, ReceivingStatus.CLOSE); // + goodsService.findAllByReceivingIdWithThrow(receivingEntity.getId()).stream() + .forEach( + goodsEntity -> goodsService.setGoodsStatusBy(goodsEntity, GoodsStatus.REJECT) + ); + + FaultEntity faultEntity = faultConverter.toEntity(rejectFaultRequest, userId); + FaultEntity savedFaultEntity = faultService.rejectFault(faultEntity); + return faultConverter.toResponse(savedFaultEntity); + } + + diff --git a/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java b/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java index 3fd6b893..72120e54 100644 --- a/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java +++ b/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java @@ -50,3 +50,15 @@ public Api approveFault(@PathVariable Long receivingId) { MessageResponse response = faultBusiness.approveFault(receivingId); return Api.OK(response); } + + @PostMapping("/reject") + @Operation(summary = "[결함 반려]") + public Api rejectFault( + @RequestBody @ApiValid Api rejectFaultRequest, + @AuthenticationPrincipal User user) { + log.info("reject result : {}", rejectFaultRequest.toString()); + RejectFaultResponse response = faultBusiness.rejectFault(rejectFaultRequest.getBody(), + user.getUsername()); + return Api.OK(response); + } + diff --git a/fault/src/main/java/fault/domain/fault/controller/model/request/RejectFaultRequest.java b/fault/src/main/java/fault/domain/fault/controller/model/request/RejectFaultRequest.java new file mode 100644 index 00000000..a8a3d6b1 --- /dev/null +++ b/fault/src/main/java/fault/domain/fault/controller/model/request/RejectFaultRequest.java @@ -0,0 +1,22 @@ +package fault.domain.fault.controller.model.request; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RejectFaultRequest { + + @NotNull + private Long receivingId; + + @NotBlank + @Size(max = 200) + private String description; + +} diff --git a/fault/src/main/java/fault/domain/fault/controller/model/response/RejectFaultResponse.java b/fault/src/main/java/fault/domain/fault/controller/model/response/RejectFaultResponse.java new file mode 100644 index 00000000..8139e841 --- /dev/null +++ b/fault/src/main/java/fault/domain/fault/controller/model/response/RejectFaultResponse.java @@ -0,0 +1,20 @@ +package fault.domain.fault.controller.model.response; + +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class RejectFaultResponse { + + private Long faultId; + private Long receivingId; + private String description; + private LocalDateTime guaranteeAt; + +} From 9c3eb144b86e2083606142d242a3ad5d72ca454e Mon Sep 17 00:00:00 2001 From: SEOB Date: Sun, 1 Sep 2024 01:35:48 +0900 Subject: [PATCH 7/7] =?UTF-8?q?SB-302=20(feat)=20:=20=EA=B2=B0=ED=95=A8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=93=B1=EB=A1=9D=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SB-302 (feat) : 결함 추가 등록 로직 구현 ImageKind -> DELIVERY 로 세팅 1. FaultApiController 2. FaultBusiness 3. AddFaultRequest 4. AddFaultResponse --- .../domain/fault/business/FaultBusiness.java | 21 +++++++++++++++++++ .../fault/controller/FaultApiController.java | 12 +++++++++++ .../model/request/AddFaultRequest.java | 19 +++++++++++++++++ .../model/response/AddFaultResponse.java | 17 +++++++++++++++ .../image/service/ImageMappingService.java | 2 ++ 5 files changed, 71 insertions(+) create mode 100644 fault/src/main/java/fault/domain/fault/controller/model/request/AddFaultRequest.java create mode 100644 fault/src/main/java/fault/domain/fault/controller/model/response/AddFaultResponse.java diff --git a/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java b/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java index a3bcf8c0..692509e0 100644 --- a/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java +++ b/fault/src/main/java/fault/domain/fault/business/FaultBusiness.java @@ -85,3 +85,24 @@ public RejectFaultResponse rejectFault(RejectFaultRequest rejectFaultRequest, St } + public AddFaultResponse addFault(AddFaultRequest addFaultRequest, String email) { + + Long userId = usersService.getUserWithThrow(email).getId(); // deliveryManId + + // 1. imageId 로 imageEntity 불러오기 + ImageEntity imageEntity = imageService.getImageBy(addFaultRequest.getImageId()); + + // 2. imageEntity 의 imageMappingId 로 imageMappingEntity 불러오기 + ImageMappingEntity imageMappingEntity = imageMappingService.getImageMappingBy( + imageEntity.getImageMappingId()); + + // 3. 이미지 매핑 + ImageMappingEntity savedMappingEntity = imageMappingService.addFault( + imageMappingEntity, addFaultRequest, userId); + + // 4. 응답 + return faultConverter.toResponse(savedMappingEntity, imageEntity); + + } + +} \ No newline at end of file diff --git a/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java b/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java index 72120e54..1ecc5812 100644 --- a/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java +++ b/fault/src/main/java/fault/domain/fault/controller/FaultApiController.java @@ -62,3 +62,15 @@ public Api rejectFault( return Api.OK(response); } + @PostMapping() + @Operation(summary = "[결함 추가 등록]") + public Api addFault( + @RequestBody @ApiValid Api addFaultRequest, + @AuthenticationPrincipal User user) { + AddFaultResponse response = faultBusiness.addFault(addFaultRequest.getBody(), + user.getUsername()); + return Api.OK(response); + } + + +} \ No newline at end of file diff --git a/fault/src/main/java/fault/domain/fault/controller/model/request/AddFaultRequest.java b/fault/src/main/java/fault/domain/fault/controller/model/request/AddFaultRequest.java new file mode 100644 index 00000000..f7291b2f --- /dev/null +++ b/fault/src/main/java/fault/domain/fault/controller/model/request/AddFaultRequest.java @@ -0,0 +1,19 @@ +package fault.domain.fault.controller.model.request; + +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class AddFaultRequest { + + @NotNull + private Long imageId; + + @NotNull + private Long goodsId; + +} diff --git a/fault/src/main/java/fault/domain/fault/controller/model/response/AddFaultResponse.java b/fault/src/main/java/fault/domain/fault/controller/model/response/AddFaultResponse.java new file mode 100644 index 00000000..92c4c7e1 --- /dev/null +++ b/fault/src/main/java/fault/domain/fault/controller/model/response/AddFaultResponse.java @@ -0,0 +1,17 @@ +package fault.domain.fault.controller.model.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AddFaultResponse { + + private Long goodsId; + private FaultImageResponse fault; + +} diff --git a/fault/src/main/java/fault/domain/image/service/ImageMappingService.java b/fault/src/main/java/fault/domain/image/service/ImageMappingService.java index ef55fe4e..bd45bd10 100644 --- a/fault/src/main/java/fault/domain/image/service/ImageMappingService.java +++ b/fault/src/main/java/fault/domain/image/service/ImageMappingService.java @@ -1,5 +1,6 @@ package fault.domain.image.service; +import db.domain.image.enums.ImageKind; import db.domain.imagemapping.ImageMappingEntity; import db.domain.imagemapping.ImageMappingRepository; import fault.common.error.ImageErrorCode; @@ -31,6 +32,7 @@ public ImageMappingEntity addFault(ImageMappingEntity imageMappingEntity, private ImageMappingEntity updateImageMapping(ImageMappingEntity imageMappingEntity, AddFaultRequest addFaultRequest, Long userId) { + imageMappingEntity.setKind(ImageKind.DELIVERY); imageMappingEntity.setGoodsId(addFaultRequest.getGoodsId()); imageMappingEntity.setUserId(userId); return imageMappingRepository.save(imageMappingEntity);