From 21829e7d72748773102015f8c92df2dc9d1d3edc Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Thu, 30 Nov 2023 18:30:50 +0900 Subject: [PATCH 01/19] =?UTF-8?q?:recycle:=20:=20regular=20Id=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#205)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matchapi/donation/converter/RegularPaymentConverter.java | 1 + .../java/com/example/matchapi/donation/dto/DonationRes.java | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Match-Api/src/main/java/com/example/matchapi/donation/converter/RegularPaymentConverter.java b/Match-Api/src/main/java/com/example/matchapi/donation/converter/RegularPaymentConverter.java index 3ace1ad3..d2bd1910 100644 --- a/Match-Api/src/main/java/com/example/matchapi/donation/converter/RegularPaymentConverter.java +++ b/Match-Api/src/main/java/com/example/matchapi/donation/converter/RegularPaymentConverter.java @@ -29,6 +29,7 @@ public List convertToMatchList(List regul private DonationRes.MatchList convertToMatchListDetail(RegularPayment result) { return DonationRes.MatchList .builder() + .regularId(result.getId()) .regularDate(timeHelper.matchTimeFormat(result.getCreatedAt())) .projectTitle(result.getProject().getProjectName()) .regularPayStatus(result.getRegularPayStatus()) diff --git a/Match-Api/src/main/java/com/example/matchapi/donation/dto/DonationRes.java b/Match-Api/src/main/java/com/example/matchapi/donation/dto/DonationRes.java index 4ee65b39..03b3fbcc 100644 --- a/Match-Api/src/main/java/com/example/matchapi/donation/dto/DonationRes.java +++ b/Match-Api/src/main/java/com/example/matchapi/donation/dto/DonationRes.java @@ -276,6 +276,8 @@ public static class FlameProjectList { @AllArgsConstructor @NoArgsConstructor public static class MatchList { + private Long regularId; + private String projectTitle; private String regularDate; From 883fd89bdd6dd1f00b38b2e4c3411e027eb58860 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Mon, 4 Dec 2023 11:42:10 +0900 Subject: [PATCH 02/19] =?UTF-8?q?:recycle:=20:=20default=20value=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(#209)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/matchdomain/common/model/BaseEntity.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Match-Domain/src/main/java/com/example/matchdomain/common/model/BaseEntity.java b/Match-Domain/src/main/java/com/example/matchdomain/common/model/BaseEntity.java index 590a7a75..f7984687 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/common/model/BaseEntity.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/common/model/BaseEntity.java @@ -1,6 +1,7 @@ package com.example.matchdomain.common.model; import lombok.Getter; +import org.hibernate.annotations.ColumnDefault; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -21,6 +22,7 @@ public abstract class BaseEntity { private LocalDateTime updatedAt; @Enumerated(EnumType.STRING) + @ColumnDefault(value = "ACTIVE") private Status status = Status.ACTIVE; public void setStatus(Status status) { From e23a3fcd40affd6e4ccb05e9b42c396950ae5cc2 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Mon, 4 Dec 2023 11:42:21 +0900 Subject: [PATCH 03/19] =?UTF-8?q?:recycle:=20:=20folder=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/matchapi/common/model/UploadFolder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Match-Api/src/main/java/com/example/matchapi/common/model/UploadFolder.java b/Match-Api/src/main/java/com/example/matchapi/common/model/UploadFolder.java index 43345457..4bdc6bbd 100644 --- a/Match-Api/src/main/java/com/example/matchapi/common/model/UploadFolder.java +++ b/Match-Api/src/main/java/com/example/matchapi/common/model/UploadFolder.java @@ -6,7 +6,7 @@ @Getter @AllArgsConstructor public enum UploadFolder { - EVENT("event"), NOTICE("notice"); + EVENT("event"), NOTICE("notice"), BANNER("banner"); private final String folder; } From 7b3b3d486d8a556b74f9879e2bfe890698b3b4a3 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Mon, 4 Dec 2023 15:12:33 +0900 Subject: [PATCH 04/19] =?UTF-8?q?:recycle:=20:=20swagger=20=EB=B2=84?= =?UTF-8?q?=EC=A0=84=20=EB=B6=84=EB=A6=AC=20(#209)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matchapi/config/SwaggerConfig.java | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/Match-Api/src/main/java/com/example/matchapi/config/SwaggerConfig.java b/Match-Api/src/main/java/com/example/matchapi/config/SwaggerConfig.java index a330f53a..bae84f60 100644 --- a/Match-Api/src/main/java/com/example/matchapi/config/SwaggerConfig.java +++ b/Match-Api/src/main/java/com/example/matchapi/config/SwaggerConfig.java @@ -20,6 +20,7 @@ import io.swagger.v3.oas.models.security.SecurityScheme; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springdoc.core.GroupedOpenApi; import org.springdoc.core.SpringDocUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContext; @@ -48,16 +49,34 @@ public class SwaggerConfig { private String profile; @Bean - public ModelResolver modelResolver(ObjectMapper objectMapper) { - return new ModelResolver(objectMapper); + public GroupedOpenApi v1ApiDocs() { + String[] paths = { "/**" }; + + return GroupedOpenApi.builder() + .group("API Version 1") + .pathsToMatch(paths) + .build(); } + + @Bean + public GroupedOpenApi v2ApiDocs() { + String[] paths = { "/v2/**" }; + + return GroupedOpenApi.builder() + .group("API Version 2") + .pathsToMatch(paths) + .build(); + } + + @Bean public OpenAPI openAPI() { Info info = new Info() .title(profile + "환경 Match Rest API 문서") // 타이틀 .version("0.0.1") // 문서 버전 - .description("잘못된 부분이나 오류 발생 시 바로 말씀해주세요.") // 문서 설명 + .description("잘못된 부분이나 오류 발생 시 바로 말씀해주세요.\n" + + "우측 상단 Select a definition 클릭시 v1 v2 API 버전 분리") // 문서 설명 .contact(new Contact() // 연락처 .name("임현우") .email("gusdn8926@naver.com")); @@ -80,12 +99,6 @@ public OpenAPI openAPI() { .info(info); } - - - - - - @Bean public OperationCustomizer customize() { return (Operation operation, HandlerMethod handlerMethod) -> { From 3b53afe3698311bba64b7cca3e5f81589a4ca20b Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Mon, 4 Dec 2023 15:17:57 +0900 Subject: [PATCH 05/19] :recycle: : octet-stream add (#209) --- ...MultipartJackson2HttpMessageConverter.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Match-Api/src/main/java/com/example/matchapi/config/MultipartJackson2HttpMessageConverter.java diff --git a/Match-Api/src/main/java/com/example/matchapi/config/MultipartJackson2HttpMessageConverter.java b/Match-Api/src/main/java/com/example/matchapi/config/MultipartJackson2HttpMessageConverter.java new file mode 100644 index 00000000..983d8a4d --- /dev/null +++ b/Match-Api/src/main/java/com/example/matchapi/config/MultipartJackson2HttpMessageConverter.java @@ -0,0 +1,33 @@ +package com.example.matchapi.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Type; + +@Component +public class MultipartJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter { + /** + * Converter for support http request with header Content-Type: multipart/form-data + */ + public MultipartJackson2HttpMessageConverter(ObjectMapper objectMapper) { + super(objectMapper, MediaType.APPLICATION_OCTET_STREAM); + } + + @Override + public boolean canWrite(Class clazz, MediaType mediaType) { + return false; + } + + @Override + public boolean canWrite(Type type, Class clazz, MediaType mediaType) { + return false; + } + + @Override + protected boolean canWrite(MediaType mediaType) { + return false; + } +} From 1b984f02ea0a49a6440d0fc15ba1a926aa877386 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Tue, 5 Dec 2023 10:44:21 +0900 Subject: [PATCH 06/19] =?UTF-8?q?:zap:=20:=20Swagger=20=EC=9D=B8=EC=A6=9D?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0=20(#209)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/controller/AdminAuthController.java | 3 ++- .../user/controller/AuthController.java | 21 ++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/auth/controller/AdminAuthController.java b/Match-Api/src/main/java/com/example/matchapi/admin/auth/controller/AdminAuthController.java index ceb0123f..abb000da 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/auth/controller/AdminAuthController.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/auth/controller/AdminAuthController.java @@ -4,10 +4,10 @@ import com.example.matchapi.user.dto.UserRes; import com.example.matchapi.user.service.AuthService; import com.example.matchcommon.annotation.ApiErrorCodeExample; +import com.example.matchcommon.annotation.DisableSecurity; import com.example.matchcommon.exception.errorcode.RequestErrorCode; import com.example.matchcommon.reponse.CommonResponse; import com.example.matchdomain.user.exception.AdminLoginErrorCode; -import com.example.matchdomain.user.exception.UserLoginErrorCode; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; @@ -27,6 +27,7 @@ public class AdminAuthController { private final AuthService authService; @ApiErrorCodeExample({AdminLoginErrorCode.class, RequestErrorCode.class}) + @DisableSecurity @Operation(summary="ADMIN-00-01🔑 관리자 로그인", description= "회원가입 용 API 입니다.") @PostMapping(value="/logIn") public CommonResponse logIn(@RequestBody @Valid UserReq.LogIn logIn){ diff --git a/Match-Api/src/main/java/com/example/matchapi/user/controller/AuthController.java b/Match-Api/src/main/java/com/example/matchapi/user/controller/AuthController.java index b3560bd8..26149096 100644 --- a/Match-Api/src/main/java/com/example/matchapi/user/controller/AuthController.java +++ b/Match-Api/src/main/java/com/example/matchapi/user/controller/AuthController.java @@ -5,6 +5,7 @@ import com.example.matchapi.user.service.AuthService; import com.example.matchapi.user.helper.SmsHelper; import com.example.matchcommon.annotation.ApiErrorCodeExample; +import com.example.matchcommon.annotation.DisableSecurity; import com.example.matchcommon.exception.errorcode.MailSendErrorCode; import com.example.matchcommon.exception.errorcode.OtherServerErrorCode; import com.example.matchcommon.exception.errorcode.RequestErrorCode; @@ -29,6 +30,7 @@ public class AuthController { private final SmsHelper smsHelper; @Operation(summary = "kakao 코드 발급 후 토큰 생성용 개발용 API 입니다",description = "kakao 코드를 발급 할 수 있음") @GetMapping(value = "/kakao") + @DisableSecurity public String kakaoOauthRedirect(@RequestParam String code) { log.info("카카오 로그인 액세스 토큰 발급"); return "카카오 로그인 액세스 토큰 발급 완료, 액세스 토큰 :" + authService.getOauthToken(code,"").getAccess_token(); @@ -38,6 +40,7 @@ public String kakaoOauthRedirect(@RequestParam String code) { @ApiErrorCodeExample({UserSignUpErrorCode.class, OtherServerErrorCode.class}) @Operation(summary= "01-02🔑 카카오 로그인" , description = "카카오 액세스 토큰 보내주기") @PostMapping(value="/kakao") + @DisableSecurity public CommonResponse kakaoLogIn(@RequestBody @Valid UserReq.SocialLoginToken socialLoginToken){ log.info("01-02 카카오 로그인"); return CommonResponse.onSuccess(authService.kakaoLogIn(socialLoginToken)); @@ -50,6 +53,7 @@ public CommonResponse kakaoLogIn(@RequestBody @Valid UserReq. @ApiErrorCodeExample({UserSignUpErrorCode.class, OtherServerErrorCode.class}) @GetMapping(value="/naver") @Operation(summary = "01-03-01🔑 web version API naver 코드 발급 후 회원가입", description = "naver 코드를 발급 할 수 있음") + @DisableSecurity public CommonResponse naverOauthRedirect(@RequestParam String code){ log.info("01-03-01 웹 버전 naver 로그인,회원가입"); return CommonResponse.onSuccess(authService.getNaverOauthToken(code)); @@ -58,6 +62,7 @@ public CommonResponse naverOauthRedirect(@RequestParam Strin @ApiErrorCodeExample({UserSignUpErrorCode.class, OtherServerErrorCode.class, RequestErrorCode.class}) @Operation(summary= "01-03🔑 네이버 로그인" , description = "네이버 액세스 토큰 보내주기") @PostMapping(value="/naver") + @DisableSecurity public CommonResponse naverLogIn(@RequestBody @Valid UserReq.SocialLoginToken socialLoginToken){ log.info("01-03 네이버 로그인,회원가입 API"); return CommonResponse.onSuccess(authService.naverLogIn(socialLoginToken.getAccessToken())); @@ -82,6 +87,7 @@ CommonResponse getNaverAddress(@RequestBody UserReq.SocialLogin @Operation(summary= "01-04🔑 회원 문자인증 요청", description = "회원 문자인증 용 API 입니다.") @PostMapping(value="/sms") @Deprecated + @DisableSecurity public CommonResponse checkSms(@RequestBody @Valid UserReq.Sms sms){ log.info("01-04 비회원 문자인증 = " +sms.getPhone()); String number = smsHelper.sendSms(sms.getPhone()); @@ -91,6 +97,7 @@ public CommonResponse checkSms(@RequestBody @Valid UserReq.Sms sms) @ApiErrorCodeExample({UserNormalSignUpErrorCode.class, UserSignUpErrorCode.class, RequestErrorCode.class}) @Operation(summary="01-05🔑 유저 회원가입", description= "회원가입 용 API 입니다.") @PostMapping(value="/user") + @DisableSecurity public CommonResponse signUpUser(@RequestBody @Valid UserReq.SignUpUser signUpUser){ log.info("01-05 유저 회원가입 API"); return CommonResponse.onSuccess(authService.signUpUser(signUpUser)); @@ -99,6 +106,7 @@ public CommonResponse signUpUser(@RequestBody @Valid UserReq. @ApiErrorCodeExample(RequestErrorCode.class) @Operation(summary="01-05-01🔑 유저 회원가입 이메일 검증용", description= "회원가입 용 API 입니다.") @PostMapping(value="/email") + @DisableSecurity public CommonResponse checkUserEmail(@RequestBody @Valid UserReq.UserEmail userEmail){ log.info("01-05-01 유저 회원가입 이메일 검증"+userEmail.getEmail()); authService.checkUserEmail(userEmail); @@ -108,6 +116,7 @@ public CommonResponse checkUserEmail(@RequestBody @Valid UserReq.UserEma @ApiErrorCodeExample(RequestErrorCode.class) @Operation(summary="01-05-02🔑 유저 회원가입 전화번호 인증용", description= "회원가입 용 API 입니다.") @PostMapping(value="/phone") + @DisableSecurity public CommonResponse checkUserPhone(@RequestBody @Valid UserReq.UserPhone userPhone){ log.info("01-05-01 유저 회원가입 전화번호 검증"+userPhone.getPhone()); authService.checkUserPhone(userPhone); @@ -117,18 +126,17 @@ public CommonResponse checkUserPhone(@RequestBody @Valid UserReq.UserPho @ApiErrorCodeExample({UserLoginErrorCode.class, RequestErrorCode.class}) @Operation(summary="01-06🔑 유저 로그인", description= "회원가입 용 API 입니다.") @PostMapping(value="/logIn") + @DisableSecurity public CommonResponse logIn(@RequestBody @Valid UserReq.LogIn logIn){ log.info("01-06 유저 로그인 회원가입 API "+logIn.getEmail()); return CommonResponse.onSuccess(authService.logIn(logIn)); } - - - @Operation(summary="01-07🔑 유저 이메일 인증번호 보내기", description= "이메일 인증번호 보내기 API 입니다.") @ApiErrorCodeExample({MailSendErrorCode.class, UserNormalSignUpErrorCode.class}) @GetMapping("/email") + @DisableSecurity public CommonResponse emailAuth(@RequestParam String email){ authService.sendEmailMessage(email); return CommonResponse.onSuccess("메일 전송 성공"); @@ -137,6 +145,7 @@ public CommonResponse emailAuth(@RequestParam String email){ @Operation(summary="01-08🔑 유저 이메일 인증번호 확인 API", description= "이메일 인증번호 확인 API 입니다.") @PostMapping("/check/email") @ApiErrorCodeExample(CodeAuthErrorCode.class) + @DisableSecurity public CommonResponse checkEmailAuth(@RequestBody UserReq.UserEmailAuth email){ authService.checkUserEmailAuth(email); return CommonResponse.onSuccess("메일 인증 성공"); @@ -146,6 +155,7 @@ public CommonResponse checkEmailAuth(@RequestBody UserReq.UserEmailAuth @ApiErrorCodeExample(RequestErrorCode.class) @Operation(summary= "01-09🔑 회원 문자인증 요청", description = "회원 문자인증 용 API 입니다.") @GetMapping(value="/phone") + @DisableSecurity public CommonResponse checkPhone(@RequestParam String phone){ authService.sendPhone(phone); return CommonResponse.onSuccess("문자 전송 성공"); @@ -154,6 +164,7 @@ public CommonResponse checkPhone(@RequestParam String phone){ @Operation(summary="01-10🔑 유저 전화번호 인증번호 확인 API", description= "전화번호 인증번호 확인 API 입니다.") @PostMapping("/check/phone") @ApiErrorCodeExample(CodeAuthErrorCode.class) + @DisableSecurity public CommonResponse checkEmailAuth(@RequestBody UserReq.UserPhoneAuth phone){ authService.checkPhoneAuth(phone); return CommonResponse.onSuccess("핸드폰 인증 성공"); @@ -163,6 +174,7 @@ public CommonResponse checkEmailAuth(@RequestBody UserReq.UserPhoneAuth @Operation(summary="01-11🔑 애플로그인 API", description= "애플로그인 API 입니다. APPLE_SIGN_UP 에러 코드 발생 시 01-11-01 API 로 회원가입 요청") @PostMapping("/apple") @ApiErrorCodeExample({UserSignUpErrorCode.class, OtherServerErrorCode.class, RequestErrorCode.class, AppleLoginErrorCode.class}) + @DisableSecurity public CommonResponse appleLogin(@RequestBody @Valid UserReq.SocialLoginToken socialLoginToken){ return CommonResponse.onSuccess(authService.appleLogin(socialLoginToken)); } @@ -170,6 +182,7 @@ public CommonResponse appleLogin(@RequestBody @Valid UserReq. @Operation(summary = "01-11-01 애플 회원가입🔑",description = "애플유저용 회원가입") @PostMapping("/apple/sign-up") @ApiErrorCodeExample({UserSignUpErrorCode.class, RequestErrorCode.class}) + @DisableSecurity public CommonResponse appleSignUp(@RequestBody @Valid UserReq.AppleSignUp appleSignUp){ return CommonResponse.onSuccess(authService.appleSignUp(appleSignUp)); } @@ -177,6 +190,7 @@ public CommonResponse appleSignUp(@RequestBody @Valid UserReq @Operation(summary = "01-14🔑 비밀번호 찾기용 이메일 전송 이메일 전송 시 01-08 API 로 인증번호 확인 입니다.", description = "만료시간 5분") @PostMapping("/password/email") @ApiErrorCodeExample({UserSignUpErrorCode.class, SendEmailFindPassword.class}) + @DisableSecurity public CommonResponse sendEmailPasswordFind(@RequestParam String email){ authService.sendEmailPasswordFind(email); return CommonResponse.onSuccess("메일 인증 성공"); @@ -186,6 +200,7 @@ public CommonResponse sendEmailPasswordFind(@RequestParam String email){ @Operation(summary = "01-13🔑 비밀번호 찾기", description = "여기서 또 한번 인증 코드를 받는 이유는 이중 인증을 위함 입니다. 변경은 5분안에 마무리 되야합니다.") @PostMapping("/password") @ApiErrorCodeExample({UserSignUpErrorCode.class, RequestErrorCode.class, CodeAuthErrorCode.class}) + @DisableSecurity public CommonResponse modifyPassword(@RequestBody @Valid UserReq.FindPassword findPassword){ authService.modifyPassword(findPassword); return CommonResponse.onSuccess("비밀번호 변경 성공"); From 92d277c8f855cba5e73eb0ad5144ec4c3ad01f7b Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Tue, 5 Dec 2023 10:44:23 +0900 Subject: [PATCH 07/19] =?UTF-8?q?:zap:=20:=20Swagger=20=EC=9D=B8=EC=A6=9D?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0=20(#209)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matchcommon/annotation/DisableSecurity.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 Match-Common/src/main/java/com/example/matchcommon/annotation/DisableSecurity.java diff --git a/Match-Common/src/main/java/com/example/matchcommon/annotation/DisableSecurity.java b/Match-Common/src/main/java/com/example/matchcommon/annotation/DisableSecurity.java new file mode 100644 index 00000000..e1d5a8f3 --- /dev/null +++ b/Match-Common/src/main/java/com/example/matchcommon/annotation/DisableSecurity.java @@ -0,0 +1,11 @@ +package com.example.matchcommon.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface DisableSecurity { +} From c4b8d6601f8e7f9dd718a9d67c28ffe6a30ce0c3 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Tue, 5 Dec 2023 10:44:41 +0900 Subject: [PATCH 08/19] =?UTF-8?q?:zap:=20:=20Swagger=20=EC=9D=B8=EC=A6=9D?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0=20+=20=EA=B7=B8=EB=A3=B9=ED=99=94=20custo?= =?UTF-8?q?mize=20(#209)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matchapi/config/SwaggerConfig.java | 65 ++++++++++--------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/Match-Api/src/main/java/com/example/matchapi/config/SwaggerConfig.java b/Match-Api/src/main/java/com/example/matchapi/config/SwaggerConfig.java index bae84f60..59f566fa 100644 --- a/Match-Api/src/main/java/com/example/matchapi/config/SwaggerConfig.java +++ b/Match-Api/src/main/java/com/example/matchapi/config/SwaggerConfig.java @@ -2,6 +2,7 @@ import com.example.matchcommon.annotation.ApiErrorCodeExample; +import com.example.matchcommon.annotation.DisableSecurity; import com.example.matchcommon.dto.ErrorReason; import com.example.matchcommon.exception.errorcode.BaseErrorCode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -23,7 +24,6 @@ import org.springdoc.core.GroupedOpenApi; import org.springdoc.core.SpringDocUtils; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.annotation.AuthenticationPrincipal; @@ -44,21 +44,20 @@ public class SwaggerConfig { } - private final ApplicationContext applicationContext; @Value("${spring.config.activate.on-profile}") private String profile; - @Bean public GroupedOpenApi v1ApiDocs() { - String[] paths = { "/**" }; - + String[] paths = {"/**"}; + String[] excludesPath = {"/v2/**", "/admin/**"}; return GroupedOpenApi.builder() .group("API Version 1") .pathsToMatch(paths) + .addOperationCustomizer(customize()) + .pathsToExclude(excludesPath) .build(); } - @Bean public GroupedOpenApi v2ApiDocs() { String[] paths = { "/v2/**" }; @@ -66,14 +65,25 @@ public GroupedOpenApi v2ApiDocs() { return GroupedOpenApi.builder() .group("API Version 2") .pathsToMatch(paths) + .addOperationCustomizer(customize()) .build(); } + @Bean + public GroupedOpenApi adminApiDocs(){ + String[] paths = { "/admin/**" }; + + return GroupedOpenApi.builder() + .group("Docs for ADMIN API") + .pathsToMatch(paths) + .addOperationCustomizer(customize()) + .build(); + } @Bean public OpenAPI openAPI() { Info info = new Info() - .title(profile + "환경 Match Rest API 문서") // 타이틀 + .title(profile + " 환경 Match Rest API 문서") // 타이틀 .version("0.0.1") // 문서 버전 .description("잘못된 부분이나 오류 발생 시 바로 말씀해주세요.\n" + "우측 상단 Select a definition 클릭시 v1 v2 API 버전 분리") // 문서 설명 @@ -100,19 +110,8 @@ public OpenAPI openAPI() { } @Bean - public OperationCustomizer customize() { - return (Operation operation, HandlerMethod handlerMethod) -> { - ApiErrorCodeExample apiErrorCodeExample = - handlerMethod.getMethodAnnotation(ApiErrorCodeExample.class); - // ApiErrorCodeExample 어노테이션 단 메소드 적용 - if (apiErrorCodeExample != null) { - Class[] errorCodes = apiErrorCodeExample.value(); - generateErrorCodeResponseExample(operation, errorCodes); - - } - return operation; - }; - + public ModelResolver modelResolver(ObjectMapper objectMapper) { + return new ModelResolver(objectMapper); } private void generateErrorCodeResponseExample( @@ -180,16 +179,24 @@ private void addExamplesToResponses( }); } + @Bean + public OperationCustomizer customize() { + return (Operation operation, HandlerMethod handlerMethod) -> { + ApiErrorCodeExample apiErrorCodeExample = + handlerMethod.getMethodAnnotation(ApiErrorCodeExample.class); + DisableSecurity methodAnnotation = + handlerMethod.getMethodAnnotation(DisableSecurity.class); + if (apiErrorCodeExample != null) { + Class[] errorCodes = apiErrorCodeExample.value(); + generateErrorCodeResponseExample(operation, errorCodes); + } + if(methodAnnotation !=null){ + operation.setSecurity(Collections.emptyList()); + } + return operation; + }; - - - - - - - - - + } } \ No newline at end of file From 87756823706b03f8c9b0fbe159cf986ee443a151 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Tue, 5 Dec 2023 10:44:53 +0900 Subject: [PATCH 09/19] =?UTF-8?q?:zap:=20:=20Swagger=20=EC=9D=B8=EC=A6=9D?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0=20(#209)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/matchapi/portone/controller/PaymentController.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Match-Api/src/main/java/com/example/matchapi/portone/controller/PaymentController.java b/Match-Api/src/main/java/com/example/matchapi/portone/controller/PaymentController.java index 31f15785..8c70314a 100644 --- a/Match-Api/src/main/java/com/example/matchapi/portone/controller/PaymentController.java +++ b/Match-Api/src/main/java/com/example/matchapi/portone/controller/PaymentController.java @@ -9,6 +9,7 @@ import com.example.matchapi.project.service.ProjectService; import com.example.matchapi.user.service.UserService; import com.example.matchcommon.annotation.ApiErrorCodeExample; +import com.example.matchcommon.annotation.DisableSecurity; import com.example.matchcommon.annotation.PaymentIntercept; import com.example.matchcommon.reponse.CommonResponse; import com.example.matchdomain.order.exception.PortOneAuthErrorCode; @@ -43,6 +44,7 @@ public class PaymentController { @Operation(summary = "08-01 Payment 가격 검증💸", description = "결제 검증용 API 해당 API") @PaymentIntercept(key = "#validatePayment.impUid") @ApiErrorCodeExample({UserAuthErrorCode.class, PortOneAuthErrorCode.class}) + @DisableSecurity public CommonResponse validatePayment(@RequestBody PaymentReq.ValidatePayment validatePayment){ log.info("가격 검증"); OrderRequest orderRequest = orderRequestService.findByOrderIdForPayment(validatePayment.getOrderId()); @@ -56,6 +58,7 @@ public CommonResponse validatePayment(@RequestBody Pa @GetMapping("/info") @Operation(summary = "08-02 Payment Web 사용자 정보 불러오기", description = "웹에서 결제를 위한 사용자 정보 불러오기 입니다.") + @DisableSecurity public CommonResponse getPaymentInfo(@RequestParam String orderId){ OrderRequest orderRequest = orderRequestService.findByOrderId(orderId); From d57265362c7aeb9b92130420a84cce178e6e4384 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Tue, 5 Dec 2023 10:44:57 +0900 Subject: [PATCH 10/19] =?UTF-8?q?:zap:=20:=20Swagger=20=EC=9D=B8=EC=A6=9D?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0=20(#209)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/matchapi/user/controller/UserController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Match-Api/src/main/java/com/example/matchapi/user/controller/UserController.java b/Match-Api/src/main/java/com/example/matchapi/user/controller/UserController.java index eeeb6e95..d06caf64 100644 --- a/Match-Api/src/main/java/com/example/matchapi/user/controller/UserController.java +++ b/Match-Api/src/main/java/com/example/matchapi/user/controller/UserController.java @@ -6,6 +6,7 @@ import com.example.matchapi.user.dto.UserReq; import com.example.matchapi.user.service.UserService; import com.example.matchcommon.annotation.ApiErrorCodeExample; +import com.example.matchcommon.annotation.DisableSecurity; import com.example.matchcommon.exception.BadRequestException; import com.example.matchcommon.exception.errorcode.RequestErrorCode; import com.example.matchdomain.redis.entity.RefreshToken; @@ -91,8 +92,8 @@ public CommonResponse logOut(@Parameter(hidden = true) @AuthenticationPr } @Operation(summary = "02-05 토큰 재발급 👤", description = "액세스 토큰 만료시 재발급 요청 하는 API X-REFRESH-TOKEN 을 헤더에 담아서 보내주세요, accessToken 은 보내지 않습니다.") - @ResponseBody @PostMapping("/refresh") + @DisableSecurity public CommonResponse reIssueToken( @Parameter(description = "리프레쉬 토큰", required = true, in = ParameterIn.HEADER, name = "X-REFRESH-TOKEN", schema = @Schema(type = "string")) @RequestHeader("X-REFRESH-TOKEN") String refreshToken ){ From 4cbd77aa55d42a3410f94fe91f5b2e2283c819e6 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Tue, 5 Dec 2023 10:46:01 +0900 Subject: [PATCH 11/19] =?UTF-8?q?:recycle:=20:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#209)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/notice/mapper/AdminNoticeMapperImpl.java | 2 +- .../matchapi/order/mapper/OrderMapperImpl.java | 2 +- .../matchapi/portone/mapper/PaymentMapperImpl.java | 2 +- .../banner/controller/AdminBannerController.java | 11 ++++++++--- .../project/controller/AdminProjectController.java | 4 +--- .../MultipartJackson2HttpMessageConverter.java | 13 +++++++++++-- 6 files changed, 23 insertions(+), 11 deletions(-) diff --git a/Match-Api/src/main/generated/com/example/matchapi/admin/notice/mapper/AdminNoticeMapperImpl.java b/Match-Api/src/main/generated/com/example/matchapi/admin/notice/mapper/AdminNoticeMapperImpl.java index 6f4f3eca..a6f654b8 100644 --- a/Match-Api/src/main/generated/com/example/matchapi/admin/notice/mapper/AdminNoticeMapperImpl.java +++ b/Match-Api/src/main/generated/com/example/matchapi/admin/notice/mapper/AdminNoticeMapperImpl.java @@ -10,7 +10,7 @@ @Generated( value = "org.mapstruct.ap.MappingProcessor", - date = "2023-11-30T13:55:53+0900", + date = "2023-12-05T09:50:48+0900", comments = "version: 1.5.3.Final, compiler: javac, environment: Java 11.0.19 (Oracle Corporation)" ) public class AdminNoticeMapperImpl implements AdminNoticeMapper { diff --git a/Match-Api/src/main/generated/com/example/matchapi/order/mapper/OrderMapperImpl.java b/Match-Api/src/main/generated/com/example/matchapi/order/mapper/OrderMapperImpl.java index 4d1b45fc..5bc23f92 100644 --- a/Match-Api/src/main/generated/com/example/matchapi/order/mapper/OrderMapperImpl.java +++ b/Match-Api/src/main/generated/com/example/matchapi/order/mapper/OrderMapperImpl.java @@ -9,7 +9,7 @@ @Generated( value = "org.mapstruct.ap.MappingProcessor", - date = "2023-11-30T13:55:54+0900", + date = "2023-12-05T09:50:48+0900", comments = "version: 1.5.3.Final, compiler: javac, environment: Java 11.0.19 (Oracle Corporation)" ) public class OrderMapperImpl implements OrderMapper { diff --git a/Match-Api/src/main/generated/com/example/matchapi/portone/mapper/PaymentMapperImpl.java b/Match-Api/src/main/generated/com/example/matchapi/portone/mapper/PaymentMapperImpl.java index b694b345..9330c095 100644 --- a/Match-Api/src/main/generated/com/example/matchapi/portone/mapper/PaymentMapperImpl.java +++ b/Match-Api/src/main/generated/com/example/matchapi/portone/mapper/PaymentMapperImpl.java @@ -13,7 +13,7 @@ @Generated( value = "org.mapstruct.ap.MappingProcessor", - date = "2023-11-30T17:29:40+0900", + date = "2023-12-05T09:50:48+0900", comments = "version: 1.5.3.Final, compiler: javac, environment: Java 11.0.19 (Oracle Corporation)" ) public class PaymentMapperImpl implements PaymentMapper { diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/banner/controller/AdminBannerController.java b/Match-Api/src/main/java/com/example/matchapi/admin/banner/controller/AdminBannerController.java index 1cb03655..485874c6 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/banner/controller/AdminBannerController.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/banner/controller/AdminBannerController.java @@ -6,14 +6,19 @@ import com.example.matchcommon.reponse.CommonResponse; import com.example.matchdomain.banner.enums.BannerType; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.List; + @RestController @RequiredArgsConstructor @Slf4j @@ -21,14 +26,14 @@ @Tag(name = "ADMIN-08-Banner💳 관리자 배너 관리 API") public class AdminBannerController { private final AdminBannerService adminBannerService; - @PostMapping("") + @PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) @Operation(summary = "ADMIN-08-01 배너 업로드") public CommonResponse> uploadBanner( - @RequestParam BannerType bannerType, + //@RequestPart BannerType bannerType, @RequestPart MultipartFile bannerImage, @RequestPart BannerReq.BannerUpload bannerUploadDto ){ System.out.println(bannerUploadDto.getContentsUrl()); - return CommonResponse.onSuccess(adminBannerService.uploadBanner(bannerType, bannerImage, bannerUploadDto)); + return CommonResponse.onSuccess(adminBannerService.uploadBanner(BannerType.EVENT, bannerImage, bannerUploadDto)); } } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/project/controller/AdminProjectController.java b/Match-Api/src/main/java/com/example/matchapi/admin/project/controller/AdminProjectController.java index b89839f3..49d53976 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/project/controller/AdminProjectController.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/project/controller/AdminProjectController.java @@ -36,11 +36,9 @@ public class AdminProjectController { private final ProjectService projectService; @Operation(summary = "ADMIN-03-01💻 프로젝트 리스트 업로드 API.",description = "프로젝트 업로드 API 입니다.") - @PostMapping(value = "", consumes = {"multipart/form-data"}, produces = "application/json") + @PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) @ApiErrorCodeExample({UserAuthErrorCode.class, RequestErrorCode.class, FileUploadException.class}) public CommonResponse postProject( - @Parameter(description = "project 상세 내용입니다. type 은 application/json" - , content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) @Valid @RequestPart("project") ProjectReq.Project project, @RequestPart("presentFile") MultipartFile presentFile, @RequestPart("multipartFiles") List multipartFiles){ diff --git a/Match-Api/src/main/java/com/example/matchapi/config/MultipartJackson2HttpMessageConverter.java b/Match-Api/src/main/java/com/example/matchapi/config/MultipartJackson2HttpMessageConverter.java index 983d8a4d..1550d245 100644 --- a/Match-Api/src/main/java/com/example/matchapi/config/MultipartJackson2HttpMessageConverter.java +++ b/Match-Api/src/main/java/com/example/matchapi/config/MultipartJackson2HttpMessageConverter.java @@ -1,21 +1,30 @@ package com.example.matchapi.config; + import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; import org.springframework.http.MediaType; import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.stereotype.Component; import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.List; @Component +@Slf4j public class MultipartJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter { + /** - * Converter for support http request with header Content-Type: multipart/form-data + * "Content-Type: multipart/form-data" 헤더를 지원하는 HTTP 요청 변환기 */ public MultipartJackson2HttpMessageConverter(ObjectMapper objectMapper) { super(objectMapper, MediaType.APPLICATION_OCTET_STREAM); } + @Override public boolean canWrite(Class clazz, MediaType mediaType) { return false; @@ -30,4 +39,4 @@ public boolean canWrite(Type type, Class clazz, MediaType mediaType) { protected boolean canWrite(MediaType mediaType) { return false; } -} +} \ No newline at end of file From 738902434a16ec37053be11ba8457bdc6819f328 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Tue, 5 Dec 2023 10:46:19 +0900 Subject: [PATCH 12/19] =?UTF-8?q?:memo:=20:=20swagger=20yml=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=20(#205)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Match-Api/src/main/resources/application.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Match-Api/src/main/resources/application.yml b/Match-Api/src/main/resources/application.yml index 54412c78..b15867a5 100644 --- a/Match-Api/src/main/resources/application.yml +++ b/Match-Api/src/main/resources/application.yml @@ -36,12 +36,14 @@ springdoc: tags-sorter: alpha # alpha: 알파벳 순 태그 정렬, method: HTTP Method 순 정렬 operations-sorter: alpha # alpha: 알파벳 순 태그 정렬, method: HTTP Method 순 정렬 doc-expansion: none + display-request-duration: true api-docs: path: /api-docs/json groups: enabled: true cache: disabled: true + show-actuator: true --- From a5226c7fb0b47b7ca5df7892b0541a8b8ae611a3 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Tue, 5 Dec 2023 13:23:13 +0900 Subject: [PATCH 13/19] =?UTF-8?q?:recycle:=20:=20DonationUser=201:1=20?= =?UTF-8?q?=EA=B4=80=EA=B3=84=20=EC=A0=9C=EA=B1=B0=20=20(#211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/matchapi/review/service/ReviewService.java | 6 +++++- .../example/matchdomain/donation/entity/DonationUser.java | 3 --- .../example/matchdomain/review/adaptor/ReviewAdaptor.java | 7 +++++++ .../matchdomain/review/repository/ReviewRepository.java | 4 ++++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Match-Api/src/main/java/com/example/matchapi/review/service/ReviewService.java b/Match-Api/src/main/java/com/example/matchapi/review/service/ReviewService.java index ff87521f..693e0c94 100644 --- a/Match-Api/src/main/java/com/example/matchapi/review/service/ReviewService.java +++ b/Match-Api/src/main/java/com/example/matchapi/review/service/ReviewService.java @@ -6,11 +6,13 @@ import com.example.matchdomain.donation.adaptor.DonationAdaptor; import com.example.matchdomain.donation.entity.DonationUser; import com.example.matchdomain.review.adaptor.ReviewAdaptor; +import com.example.matchdomain.review.entity.Review; import com.example.matchdomain.user.entity.User; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Optional; @Service @@ -27,7 +29,9 @@ public ReviewRes.PopUpInfo checkPopUp(User user) { DonationUser donationUser = donationUsers.get(0); - if(donationUser.getReview()!=null) return null; + Optional review = reviewAdaptor.findByDonationUser(donationUser); + + if(review.isEmpty()) return null; return reviewConverter.convertToPopUp(donationUser, donationUser.getId()); } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/DonationUser.java b/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/DonationUser.java index ea660549..879089b8 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/DonationUser.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/DonationUser.java @@ -88,9 +88,6 @@ public class DonationUser extends BaseEntity { @Comment("집행 금액, DonationStatus SomeExecution 인 경우와 Execution Success 인 경우") private Long executionPrice; - @OneToOne(mappedBy = "donationUser", cascade = CascadeType.ALL, fetch = FetchType.LAZY) - private Review review; - public void updateInherenceNumber(String inherenceNumber, String flameName) { this.inherenceNumber = inherenceNumber; this.inherenceName = flameName; diff --git a/Match-Domain/src/main/java/com/example/matchdomain/review/adaptor/ReviewAdaptor.java b/Match-Domain/src/main/java/com/example/matchdomain/review/adaptor/ReviewAdaptor.java index a80412ed..5f9491ad 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/review/adaptor/ReviewAdaptor.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/review/adaptor/ReviewAdaptor.java @@ -1,10 +1,13 @@ package com.example.matchdomain.review.adaptor; import com.example.matchcommon.annotation.Adaptor; +import com.example.matchdomain.donation.entity.DonationUser; import com.example.matchdomain.review.entity.Review; import com.example.matchdomain.review.repository.ReviewRepository; import lombok.RequiredArgsConstructor; +import java.util.Optional; + @Adaptor @RequiredArgsConstructor public class ReviewAdaptor { @@ -14,4 +17,8 @@ public class ReviewAdaptor { public Review save(Review review) { return reviewRepository.save(review); } + + public Optional findByDonationUser(DonationUser donationUser) { + return reviewRepository.findByDonationUser(donationUser); + } } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/review/repository/ReviewRepository.java b/Match-Domain/src/main/java/com/example/matchdomain/review/repository/ReviewRepository.java index 7ce7565c..38b853eb 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/review/repository/ReviewRepository.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/review/repository/ReviewRepository.java @@ -1,7 +1,11 @@ package com.example.matchdomain.review.repository; +import com.example.matchdomain.donation.entity.DonationUser; import com.example.matchdomain.review.entity.Review; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface ReviewRepository extends JpaRepository, ReviewCustomRepository { + Optional findByDonationUser(DonationUser donationUser); } From 9c129a34dfcfe99224dc1e78a63a2f202c0c7b69 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Tue, 5 Dec 2023 13:23:49 +0900 Subject: [PATCH 14/19] =?UTF-8?q?:zap:=20:=20ADMIN=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20=EA=B8=B0=EB=B6=80=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EA=B5=AC=ED=98=84=20(#211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/AdminUserController.java | 18 ++++++++++++ .../donation/service/DonationService.java | 6 +++- .../user/converter/UserConverter.java | 28 +++++++++++++++++++ .../example/matchapi/user/dto/UserRes.java | 20 +++++++++++++ .../matchapi/user/service/UserService.java | 8 ++++++ .../donation/entity/QDonationUser.java | 3 -- .../donation/adaptor/DonationAdaptor.java | 6 ++++ .../repository/DonationUserRepository.java | 2 ++ .../user/exception/UserAuthErrorCode.java | 6 ++-- 9 files changed, 90 insertions(+), 7 deletions(-) diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/user/controller/AdminUserController.java b/Match-Api/src/main/java/com/example/matchapi/admin/user/controller/AdminUserController.java index 6bf636f8..1f93c6a4 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/user/controller/AdminUserController.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/user/controller/AdminUserController.java @@ -1,17 +1,21 @@ package com.example.matchapi.admin.user.controller; +import com.example.matchapi.donation.service.DonationService; +import com.example.matchapi.user.converter.UserConverter; import com.example.matchapi.user.dto.UserRes; import com.example.matchapi.user.service.UserService; import com.example.matchcommon.annotation.ApiErrorCodeExample; import com.example.matchcommon.reponse.CommonResponse; import com.example.matchcommon.reponse.PageResponse; import com.example.matchdomain.common.model.Status; +import com.example.matchdomain.donation.entity.DonationUser; import com.example.matchdomain.user.entity.User; import com.example.matchdomain.user.exception.UserAuthErrorCode; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.web.bind.annotation.*; import javax.validation.constraints.Min; @@ -23,6 +27,8 @@ @Tag(name = "ADMIN-02 User👤 관리자 유저 관련 API 입니다.", description = "ADMIN 유저 관련 API 입니다.") public class AdminUserController { private final UserService userService; + private final DonationService donationService; + private final UserConverter userConverter; @GetMapping("/info") @ApiErrorCodeExample(UserAuthErrorCode.class) @Operation(summary = "ADMIN-02-01👤 유저저 가입 현황파악 API.",description = "프로젝트 리스트 조회 API 입니다.") @@ -51,4 +57,16 @@ public CommonResponse getUserDetail(@PathVariable Long UserRes.UserAdminDetail userAdminDetail = userService.getUserAdminDetail(userId); return CommonResponse.onSuccess(userAdminDetail); } + + @GetMapping("/flame/{userId}") + @ApiErrorCodeExample(UserAuthErrorCode.class) + @Operation(summary = "ADMIN-02-04 유저 불꽃이 생성기록 조회" ,description = "유저 불꽃이 기록 조회") + public CommonResponse>> getUserFlameList(@PathVariable Long userId, + @Parameter(description = "페이지", example = "0") @RequestParam(required = false, defaultValue = "0") @Min(value = 0) int page, + @Parameter(description = "페이지 사이즈", example = "10") @RequestParam(required = false, defaultValue = "10") int size){ + User user = userService.findByUserId(userId); + Page donationUsers = donationService.findByUserId(user, page, size); + + return CommonResponse.onSuccess(new PageResponse<>(donationUsers.isLast(), donationUsers.getTotalElements(), userConverter.convertToFlameList(donationUsers.getContent()))); + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/donation/service/DonationService.java b/Match-Api/src/main/java/com/example/matchapi/donation/service/DonationService.java index 88a2d23a..1dc67775 100644 --- a/Match-Api/src/main/java/com/example/matchapi/donation/service/DonationService.java +++ b/Match-Api/src/main/java/com/example/matchapi/donation/service/DonationService.java @@ -7,7 +7,6 @@ import com.example.matchapi.donation.helper.DonationHelper; import com.example.matchapi.order.helper.OrderHelper; import com.example.matchapi.project.dto.ProjectRes; -import com.example.matchcommon.annotation.RedissonLock; import com.example.matchcommon.exception.BadRequestException; import com.example.matchcommon.reponse.PageResponse; import com.example.matchdomain.donation.adaptor.DonationAdaptor; @@ -26,6 +25,7 @@ import org.springframework.stereotype.Service; import javax.transaction.Transactional; +import javax.validation.constraints.Min; import java.util.List; import static com.example.matchdomain.common.model.Status.ACTIVE; @@ -168,4 +168,8 @@ public DonationRes.CompleteDonation postTutorialDonation(User user, DonationReq. return donationConverter.convertToCompleteDonation(donationUser, project); } + + public Page findByUserId(User user, int page, int size) { + return donationAdaptor.findByUserForAdminPage(user, page, size); + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/user/converter/UserConverter.java b/Match-Api/src/main/java/com/example/matchapi/user/converter/UserConverter.java index be3331b0..8582cd73 100644 --- a/Match-Api/src/main/java/com/example/matchapi/user/converter/UserConverter.java +++ b/Match-Api/src/main/java/com/example/matchapi/user/converter/UserConverter.java @@ -7,6 +7,8 @@ import com.example.matchapi.user.helper.UserHelper; import com.example.matchcommon.annotation.Converter; import com.example.matchcommon.properties.AligoProperties; +import com.example.matchcommon.reponse.PageResponse; +import com.example.matchdomain.donation.entity.DonationUser; import com.example.matchdomain.redis.entity.RefreshToken; import com.example.matchdomain.user.entity.*; import com.example.matchdomain.user.entity.enums.AddressType; @@ -20,10 +22,12 @@ import com.example.matchinfrastructure.oauth.kakao.dto.KakaoUserInfoDto; import com.example.matchinfrastructure.oauth.naver.dto.NaverUserInfoDto; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.security.crypto.password.PasswordEncoder; import javax.validation.Valid; import java.time.LocalDate; +import java.util.ArrayList; import java.util.List; import static com.example.matchcommon.constants.MatchStatic.BASE_PROFILE; @@ -264,4 +268,28 @@ public UserRes.UserToken convertToToken(Long userId, String accessToken, String .isNew(isNew) .build(); } + + public List convertToFlameList(List donationUsers) { + List userFlameLists = new ArrayList<>(); + + int donationCnt = 1; + + for(DonationUser donationUser : donationUsers) { + userFlameLists.add(convertToFlameDto(donationUser, donationCnt)); + donationCnt ++; + } + return userFlameLists; + } + + private UserRes.UserFlameListDto convertToFlameDto(DonationUser donationUser, int donationCnt) { + return UserRes.UserFlameListDto + .builder() + .donationId(donationUser.getId()) + .inherenceName(donationUser.getInherenceName()) + .inherenceNumber(donationUser.getInherenceNumber()) + .donationCnt(donationCnt) + .donationStatus(donationUser.getDonationStatus()) + .donationStatusName(donationUser.getDonationStatus().getName()) + .build(); + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/user/dto/UserRes.java b/Match-Api/src/main/java/com/example/matchapi/user/dto/UserRes.java index deab8241..9329ea21 100644 --- a/Match-Api/src/main/java/com/example/matchapi/user/dto/UserRes.java +++ b/Match-Api/src/main/java/com/example/matchapi/user/dto/UserRes.java @@ -1,5 +1,6 @@ package com.example.matchapi.user.dto; +import com.example.matchdomain.donation.entity.enums.DonationStatus; import com.example.matchdomain.user.entity.enums.Alarm; import com.example.matchdomain.user.entity.enums.SocialType; import io.swagger.v3.oas.annotations.media.Schema; @@ -214,4 +215,23 @@ public static class AlarmAgreeList { private Alarm eventAlarm; } + + @Getter + @Setter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class UserFlameListDto { + private Long donationId; + + private int donationCnt; + + private String inherenceName; + + private String inherenceNumber; + + private DonationStatus donationStatus; + + private String donationStatusName; + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/user/service/UserService.java b/Match-Api/src/main/java/com/example/matchapi/user/service/UserService.java index 58008057..d84c1cdc 100644 --- a/Match-Api/src/main/java/com/example/matchapi/user/service/UserService.java +++ b/Match-Api/src/main/java/com/example/matchapi/user/service/UserService.java @@ -10,6 +10,8 @@ import com.example.matchapi.user.dto.UserRes; import com.example.matchcommon.annotation.RedissonLock; import com.example.matchcommon.exception.BadRequestException; +import com.example.matchcommon.exception.NotFoundException; +import com.example.matchcommon.exception.UnauthorizedException; import com.example.matchcommon.reponse.PageResponse; import com.example.matchdomain.common.model.Status; import com.example.matchdomain.donation.entity.RegularPayment; @@ -22,6 +24,7 @@ import com.example.matchdomain.user.entity.enums.Alarm; import com.example.matchdomain.user.entity.pk.UserFcmPk; import com.example.matchdomain.user.exception.ModifyEmailCode; +import com.example.matchdomain.user.exception.UserAuthErrorCode; import com.example.matchdomain.user.repository.UserAddressRepository; import com.example.matchdomain.user.repository.UserFcmTokenRepository; import com.example.matchdomain.user.repository.UserRepository; @@ -49,6 +52,7 @@ import static com.example.matchdomain.user.entity.enums.Alarm.INACTIVE; import static com.example.matchdomain.user.exception.ModifyEmailCode.NOT_CORRECT_EMAIL; import static com.example.matchdomain.user.exception.ModifyPhoneErrorCode.NOT_CORRECT_PHONE; +import static com.example.matchdomain.user.exception.UserAuthErrorCode.NOT_EXIST_USER; import static com.example.matchdomain.user.exception.UserNormalSignUpErrorCode.USERS_EXISTS_PHONE; @Service @@ -253,4 +257,8 @@ public void deleteAppleUserInfo(User user, UserReq.AppleCode appleCode) { public User findByUser(String userId) { return userAdaptor.findByUser(userId); } + + public User findByUserId(Long userId) { + return userAdaptor.findByUserId(userId).orElseThrow(() -> new NotFoundException(NOT_EXIST_USER)); + } } diff --git a/Match-Domain/src/main/generated/com/example/matchdomain/donation/entity/QDonationUser.java b/Match-Domain/src/main/generated/com/example/matchdomain/donation/entity/QDonationUser.java index e5991c4a..f3d2462c 100644 --- a/Match-Domain/src/main/generated/com/example/matchdomain/donation/entity/QDonationUser.java +++ b/Match-Domain/src/main/generated/com/example/matchdomain/donation/entity/QDonationUser.java @@ -59,8 +59,6 @@ public class QDonationUser extends EntityPathBase { public final EnumPath regularStatus = createEnum("regularStatus", com.example.matchdomain.donation.entity.enums.RegularStatus.class); - public final com.example.matchdomain.review.entity.QReview review; - //inherited public final EnumPath status = _super.status; @@ -93,7 +91,6 @@ public QDonationUser(Class type, PathMetadata metadata, super(type, metadata, inits); this.project = inits.isInitialized("project") ? new com.example.matchdomain.project.entity.QProject(forProperty("project")) : null; this.regularPayment = inits.isInitialized("regularPayment") ? new QRegularPayment(forProperty("regularPayment"), inits.get("regularPayment")) : null; - this.review = inits.isInitialized("review") ? new com.example.matchdomain.review.entity.QReview(forProperty("review"), inits.get("review")) : null; this.user = inits.isInitialized("user") ? new com.example.matchdomain.user.entity.QUser(forProperty("user")) : null; } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/donation/adaptor/DonationAdaptor.java b/Match-Domain/src/main/java/com/example/matchdomain/donation/adaptor/DonationAdaptor.java index 622b7c62..6393428d 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/donation/adaptor/DonationAdaptor.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/donation/adaptor/DonationAdaptor.java @@ -117,4 +117,10 @@ public List checkPopUp(User user) { public List findByProject(Project project) { return donationUserRepository.findAllDtoByProjectId(project.getId()); } + + public Page findByUserForAdminPage(User user, int page, int size) { + Pageable pageable = PageRequest.of(page, size); + + return donationUserRepository.findByUserOrderByIdAsc(user, pageable); + } } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/donation/repository/DonationUserRepository.java b/Match-Domain/src/main/java/com/example/matchdomain/donation/repository/DonationUserRepository.java index 94cbc6b5..422e4f37 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/donation/repository/DonationUserRepository.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/donation/repository/DonationUserRepository.java @@ -81,6 +81,8 @@ public interface DonationUserRepository extends JpaRepository "FROM DonationUser DU WHERE DU.projectId = :projectId AND DU.donationStatus != 'EXECUTION_REFUND'") List findAllDtoByProjectId(@Param("projectId") Long projectId); + Page findByUserOrderByIdAsc(User user, Pageable pageable); + interface flameList { Long getRegularPayId(); diff --git a/Match-Domain/src/main/java/com/example/matchdomain/user/exception/UserAuthErrorCode.java b/Match-Domain/src/main/java/com/example/matchdomain/user/exception/UserAuthErrorCode.java index 0ae6af40..2dd040d1 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/user/exception/UserAuthErrorCode.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/user/exception/UserAuthErrorCode.java @@ -9,10 +9,10 @@ import java.lang.reflect.Field; import java.util.Objects; -import static org.springframework.http.HttpStatus.BAD_REQUEST; -import static org.springframework.http.HttpStatus.UNAUTHORIZED; import com.example.matchcommon.annotation.ExplainError; +import static org.springframework.http.HttpStatus.*; + @Getter @AllArgsConstructor @@ -41,7 +41,7 @@ public enum UserAuthErrorCode implements BaseErrorCode { NOT_EXISTS_USER_HAVE_TOKEN(UNAUTHORIZED,"AUTH011", "해당 토큰을 가진 유저가 존재하지 않습니다."), NOT_USER_ACTIVE(UNAUTHORIZED,"AUTH012","유저가 비활성 상태입니다 로그인 할 수 없습니다."), @ExplainError("유저가 존재하지 않는 경우") - NOT_EXIST_USER(UNAUTHORIZED,"U009" , "해당 유저가 존재하지 않습니다."), + NOT_EXIST_USER(NOT_FOUND,"U009" , "해당 유저가 존재하지 않습니다."), NOT_ALLOWED_ACCESS(UNAUTHORIZED,"U010","접근 권한이 없습니다."); From 61f1898d18751446d7e02790b540fdcacb4c7b51 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Tue, 5 Dec 2023 14:35:28 +0900 Subject: [PATCH 15/19] =?UTF-8?q?:recycle:=20:=20ADMIN=20=EC=A7=91?= =?UTF-8?q?=ED=96=89=20=EC=88=98=EC=A0=95=20(#211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../converter/AdminDonationConverter.java | 3 +- .../service/AdminDonationService.java | 45 +++++++++++-------- .../matchapi/donation/dto/DonationReq.java | 2 + .../donation/entity/DonationHistory.java | 2 + 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/donation/converter/AdminDonationConverter.java b/Match-Api/src/main/java/com/example/matchapi/admin/donation/converter/AdminDonationConverter.java index b841027a..28537954 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/donation/converter/AdminDonationConverter.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/donation/converter/AdminDonationConverter.java @@ -33,12 +33,13 @@ public DonationRes.DonationDetail getDonationDetail(DonationUser donationUser) { .build(); } - public DonationHistory convertToDonationHistoryComplete(Long projectId, List donationUserLists) { + public DonationHistory convertToDonationHistoryComplete(Long projectId, List donationUserLists, List item) { return DonationHistory .builder() .projectId(projectId) .historyStatus(HistoryStatus.COMPLETE) .completeIdLists(donationUserLists) + .item(item.toString()) .build(); } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/donation/service/AdminDonationService.java b/Match-Api/src/main/java/com/example/matchapi/admin/donation/service/AdminDonationService.java index e653ffda..e887cc26 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/donation/service/AdminDonationService.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/donation/service/AdminDonationService.java @@ -4,6 +4,7 @@ import com.example.matchapi.donation.dto.DonationReq; import com.example.matchapi.donation.dto.DonationRes; import com.example.matchapi.donation.helper.DonationHelper; +import com.example.matchcommon.annotation.RedissonLock; import com.example.matchcommon.reponse.PageResponse; import com.example.matchdomain.donation.adaptor.DonationAdaptor; import com.example.matchdomain.donation.adaptor.DonationHistoryAdaptor; @@ -24,14 +25,13 @@ import java.time.LocalDateTime; import java.time.temporal.TemporalAdjusters; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.stream.Collectors; import static com.example.matchcommon.constants.MatchStatic.FIRST_TIME; import static com.example.matchcommon.constants.MatchStatic.LAST_TIME; import static com.example.matchdomain.donation.entity.enums.DonationStatus.*; -import static com.example.matchdomain.donation.entity.enums.Execution.ALL; -import static com.example.matchdomain.donation.entity.enums.Execution.SOME; @Service @RequiredArgsConstructor @@ -74,18 +74,23 @@ public DonationRes.DonationDetail getDonationDetail(Long donationId) { } + @Transactional public void enforceDonation(List imageLists, DonationReq.EnforceDonation enforceDonation) { List someExecutionIds = getSomeExecutionIds(enforceDonation.getSomeExecutions()); List allDonationUserIds = new ArrayList<>(enforceDonation.getDonationUserLists()); DonationHistory donationHistory = donationHistoryAdaptor.saveDonationHistory( - adminDonationConverter.convertToDonationHistoryComplete(enforceDonation.getProjectId(), allDonationUserIds)); + adminDonationConverter.convertToDonationHistoryComplete(enforceDonation.getProjectId(), allDonationUserIds, enforceDonation.getItem())); saveDonationHistoryImages(imageLists, donationHistory.getId()); - executePartialDonations(enforceDonation.getSomeExecutions()); - executeSuccessfulDonations(excludeSomeExecutionIds(allDonationUserIds, someExecutionIds)); + List donationUsers = new ArrayList<>(); + + donationUsers.addAll(executePartialDonations(enforceDonation.getSomeExecutions())); + donationUsers.addAll(executeSuccessfulDonations(excludeSomeExecutionIds(allDonationUserIds, someExecutionIds))); + + donationAdaptor.saveAll(donationUsers); } private List getSomeExecutionIds(List someExecutions) { @@ -94,16 +99,29 @@ private List getSomeExecutionIds(List someExecu .collect(Collectors.toList()); } - private void executePartialDonations(List someExecutions) { + private List executePartialDonations(List someExecutions) { List someExecutionIds = getSomeExecutionIds(someExecutions); List partialDonationUsers = donationAdaptor.findByListIn(someExecutionIds); for (DonationUser donationUser : partialDonationUsers) { - DonationReq.SomeExecution execution = findSomeExecutionByUserId(someExecutions, donationUser.getId()); - donationUser.updateDonationExecution(PARTIAL_EXECUTION, execution.getAmount()); + if(!donationUser.getDonationStatus().equals(EXECUTION_SUCCESS)) { + DonationReq.SomeExecution execution = findSomeExecutionByUserId(someExecutions, donationUser.getId()); + donationUser.updateDonationExecution(PARTIAL_EXECUTION, execution.getAmount()); + } } - donationAdaptor.saveAll(partialDonationUsers); + return partialDonationUsers; + } + + private List executeSuccessfulDonations(List donationUserIds) { + List successfulDonationUsers = donationAdaptor.findByListIn(donationUserIds); + + for (DonationUser donationUser : successfulDonationUsers) { + if(!donationUser.getDonationStatus().equals(EXECUTION_SUCCESS)) { + donationUser.updateDonationExecution(EXECUTION_SUCCESS, (long) (donationUser.getPrice() * 0.9)); + } + } + return successfulDonationUsers; } private DonationReq.SomeExecution findSomeExecutionByUserId(List someExecutions, Long userId) { @@ -113,15 +131,6 @@ private DonationReq.SomeExecution findSomeExecutionByUserId(List new IllegalArgumentException("Invalid user ID")); } - private void executeSuccessfulDonations(List donationUserIds) { - List successfulDonationUsers = donationAdaptor.findByListIn(donationUserIds); - - for (DonationUser donationUser : successfulDonationUsers) { - donationUser.updateDonationExecution(EXECUTION_SUCCESS, (long) (donationUser.getPrice() * 0.9)); - } - - donationAdaptor.saveAll(successfulDonationUsers); - } private List excludeSomeExecutionIds(List allIds, List excludeIds) { return allIds.stream() diff --git a/Match-Api/src/main/java/com/example/matchapi/donation/dto/DonationReq.java b/Match-Api/src/main/java/com/example/matchapi/donation/dto/DonationReq.java index c4f5a8ed..8f618b17 100644 --- a/Match-Api/src/main/java/com/example/matchapi/donation/dto/DonationReq.java +++ b/Match-Api/src/main/java/com/example/matchapi/donation/dto/DonationReq.java @@ -14,6 +14,8 @@ public class DonationReq { public static class EnforceDonation { private Long projectId; + private List item; + private List donationUserLists; private List someExecutions; diff --git a/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/DonationHistory.java b/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/DonationHistory.java index fbd6380b..bf571737 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/DonationHistory.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/DonationHistory.java @@ -54,6 +54,8 @@ public class DonationHistory extends BaseEntity { @Column(name="projectId") private Long projectId; + private String item; + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "donationHistoryId") private List historyImages = new ArrayList<>(); From 2552f2b3fc9962d290ccdfbc9f87d894f8ca6a3b Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Tue, 5 Dec 2023 17:09:13 +0900 Subject: [PATCH 16/19] =?UTF-8?q?:zap:=20:=20ADMIN=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20=EA=B8=B0=EB=B6=80=20=EC=A7=91=ED=96=89=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=ED=86=A1=20event=20listener=20(#211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/lisetner/ExecutionEvent.java | 34 +++++++++++++ .../lisetner/ExecutionEventListener.java | 51 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 Match-Api/src/main/java/com/example/matchapi/common/lisetner/ExecutionEvent.java create mode 100644 Match-Api/src/main/java/com/example/matchapi/common/lisetner/ExecutionEventListener.java diff --git a/Match-Api/src/main/java/com/example/matchapi/common/lisetner/ExecutionEvent.java b/Match-Api/src/main/java/com/example/matchapi/common/lisetner/ExecutionEvent.java new file mode 100644 index 00000000..1726b5e7 --- /dev/null +++ b/Match-Api/src/main/java/com/example/matchapi/common/lisetner/ExecutionEvent.java @@ -0,0 +1,34 @@ +package com.example.matchapi.common.lisetner; + + +import com.example.matchdomain.donation.entity.DonationUser; +import com.example.matchdomain.project.entity.Project; +import org.springframework.context.ApplicationEvent; + +import java.util.ArrayList; +import java.util.List; + +public class ExecutionEvent extends ApplicationEvent { + private final List donationUsers; + private final Project project; + private final List items; + + public ExecutionEvent(Object source, List donationUsers, Project project, List items) { + super(source); + this.donationUsers = donationUsers; + this.project = project; + this.items = items; + } + + public List getDonationUsers() { + return donationUsers; + } + + public Project getProject() { + return project; + } + + public List getItems(){ + return items; + } +} diff --git a/Match-Api/src/main/java/com/example/matchapi/common/lisetner/ExecutionEventListener.java b/Match-Api/src/main/java/com/example/matchapi/common/lisetner/ExecutionEventListener.java new file mode 100644 index 00000000..48aa95be --- /dev/null +++ b/Match-Api/src/main/java/com/example/matchapi/common/lisetner/ExecutionEventListener.java @@ -0,0 +1,51 @@ +package com.example.matchapi.common.lisetner; + +import com.example.matchapi.user.service.AligoService; +import com.example.matchdomain.donation.entity.DonationUser; +import com.example.matchdomain.project.entity.Project; +import com.example.matchdomain.user.entity.User; +import com.example.matchinfrastructure.aligo.converter.AligoConverter; +import com.example.matchinfrastructure.aligo.dto.AlimType; +import com.example.matchinfrastructure.aligo.service.AligoInfraService; +import com.example.matchinfrastructure.match_aligo.dto.AlimTalkDto; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +@RequiredArgsConstructor +@Slf4j +public class ExecutionEventListener { + private final AligoConverter aligoConverter; + private final AligoService aligoService; + @EventListener + @Async("event-listener") + public void onDonationExecution(ExecutionEvent event){ + log.info("event start"); + List donationUsers = event.getDonationUsers(); + + Project project = event.getProject(); + + List alimTalkDtos = new ArrayList<>(); + + String article = getArticle(event.getItems()); + + for(DonationUser donationUser : donationUsers){ + User user = donationUser.getUser(); + alimTalkDtos.add(aligoConverter.convertToAlimTalkExecution(donationUser.getId(), user.getName(), user.getPhoneNumber(), article, project.getUsages())); + } + + aligoService.sendAlimTalks(AlimType.EXECUTION, alimTalkDtos); + log.info("event finish"); + + } + + private String getArticle(List items) { + return items.get(0) + " 외 " + items.size() + "개"; + } +} From c2c767ddb3b0ed399b422a66735a3eb4b8800ee7 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Tue, 5 Dec 2023 17:14:57 +0900 Subject: [PATCH 17/19] =?UTF-8?q?:zap:=20:=20=EC=A7=91=ED=96=89=20?= =?UTF-8?q?=EC=8B=9C=20=EC=95=8C=EB=A6=BC=ED=86=A1=20=EB=B0=9C=EC=86=A1=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20(#211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aligo/controller/AligoController.java | 9 ++++++++ .../service/AdminDonationService.java | 14 ++++++++++-- .../matchapi/user/service/AligoService.java | 22 +++++++++++++++---- .../matchapi/user/service/AuthService.java | 2 +- .../matchcommon/config/AsyncConfig.java | 11 ++++++++++ .../aligo/converter/AligoConverter.java | 11 ++++++++++ .../aligo/service/AligoInfraService.java | 17 ++++++++++++++ .../client/MatchAligoFeignClient.java | 8 +++++++ .../match_aligo/dto/AlimTalkDto.java | 2 ++ 9 files changed, 89 insertions(+), 7 deletions(-) diff --git a/Match-Aligo/src/main/java/com/example/matchaligo/aligo/controller/AligoController.java b/Match-Aligo/src/main/java/com/example/matchaligo/aligo/controller/AligoController.java index 370f9b98..7c359883 100644 --- a/Match-Aligo/src/main/java/com/example/matchaligo/aligo/controller/AligoController.java +++ b/Match-Aligo/src/main/java/com/example/matchaligo/aligo/controller/AligoController.java @@ -14,6 +14,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; +import java.util.List; + @RestController @RequiredArgsConstructor @Slf4j @@ -37,4 +39,11 @@ public CommonResponse sendAlimTalk(@RequestParam AlimType alimType, @Req return CommonResponse.onSuccess("알림톡 전송 성공"); } + @PostMapping("/alim-talk-execution") + public CommonResponse sendAlimTalks(@RequestParam AlimType alimType, @RequestBody List alimTalks){ + aligoInfraService.sendAlimTalks(alimTalks, alimType); + return CommonResponse.onSuccess("알림톡 전송 성공"); + } + + } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/donation/service/AdminDonationService.java b/Match-Api/src/main/java/com/example/matchapi/admin/donation/service/AdminDonationService.java index e887cc26..1c4f793f 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/donation/service/AdminDonationService.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/donation/service/AdminDonationService.java @@ -1,10 +1,10 @@ package com.example.matchapi.admin.donation.service; import com.example.matchapi.admin.donation.converter.AdminDonationConverter; +import com.example.matchapi.common.lisetner.ExecutionEvent; import com.example.matchapi.donation.dto.DonationReq; import com.example.matchapi.donation.dto.DonationRes; import com.example.matchapi.donation.helper.DonationHelper; -import com.example.matchcommon.annotation.RedissonLock; import com.example.matchcommon.reponse.PageResponse; import com.example.matchdomain.donation.adaptor.DonationAdaptor; import com.example.matchdomain.donation.adaptor.DonationHistoryAdaptor; @@ -16,6 +16,8 @@ import com.example.matchdomain.project.entity.Project; import com.example.matchinfrastructure.config.s3.S3UploadService; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -25,7 +27,6 @@ import java.time.LocalDateTime; import java.time.temporal.TemporalAdjusters; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -43,6 +44,9 @@ public class AdminDonationService { private final S3UploadService s3UploadService; private final ProjectAdaptor projectAdaptor; private final HistoryImageRepository historyImageRepository; + @Autowired + private ApplicationEventPublisher eventPublisher; + @Transactional public DonationRes.DonationInfo getDonationInfo() { @@ -91,6 +95,12 @@ public void enforceDonation(List imageLists, DonationReq.EnforceD donationUsers.addAll(executeSuccessfulDonations(excludeSomeExecutionIds(allDonationUserIds, someExecutionIds))); donationAdaptor.saveAll(donationUsers); + + Project project = projectAdaptor.findById(enforceDonation.getProjectId()); + + ExecutionEvent event = new ExecutionEvent(this, donationUsers, project, enforceDonation.getItem()); + + eventPublisher.publishEvent(event); } private List getSomeExecutionIds(List someExecutions) { diff --git a/Match-Api/src/main/java/com/example/matchapi/user/service/AligoService.java b/Match-Api/src/main/java/com/example/matchapi/user/service/AligoService.java index 14759cde..6ed92a0b 100644 --- a/Match-Api/src/main/java/com/example/matchapi/user/service/AligoService.java +++ b/Match-Api/src/main/java/com/example/matchapi/user/service/AligoService.java @@ -1,5 +1,6 @@ package com.example.matchapi.user.service; +import com.example.matchapi.common.security.JwtService; import com.example.matchcommon.reponse.CommonResponse; import com.example.matchinfrastructure.aligo.dto.AlimType; import com.example.matchinfrastructure.match_aligo.client.MatchAligoFeignClient; @@ -9,20 +10,33 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import java.util.List; + @Service @Slf4j @RequiredArgsConstructor public class AligoService { private final MatchAligoFeignClient matchAligoFeignClient; + private final JwtService jwtService; - public CommonResponse sendSmsAuth(String token, String phone, String code){ - return matchAligoFeignClient.sendSmsAuth(token, phone, code); + public CommonResponse sendSmsAuth(String phone, String code){ + return matchAligoFeignClient.sendSmsAuth(createJwt(), phone, code); } @Async("alim-talk") - public void sendAlimTalk(String token, AlimType alimType, AlimTalkDto alimTalkDto){ - CommonResponse response = matchAligoFeignClient.sendAlimTalk(token, alimType, alimTalkDto); + public void sendAlimTalk(AlimType alimType, AlimTalkDto alimTalkDto){ + CommonResponse response = matchAligoFeignClient.sendAlimTalk(createJwt(), alimType, alimTalkDto); log.info(response.toString()); } + + public void sendAlimTalks(AlimType alimType, List alimTalkDtos){ + CommonResponse response = matchAligoFeignClient.sendAlimTalks(createJwt(), alimType, alimTalkDtos); + log.info(response.toString()); + } + + public String createJwt(){ + return jwtService.createToken(1L); + } + } diff --git a/Match-Api/src/main/java/com/example/matchapi/user/service/AuthService.java b/Match-Api/src/main/java/com/example/matchapi/user/service/AuthService.java index ff80506c..01ca3840 100644 --- a/Match-Api/src/main/java/com/example/matchapi/user/service/AuthService.java +++ b/Match-Api/src/main/java/com/example/matchapi/user/service/AuthService.java @@ -213,7 +213,7 @@ public void sendPhone(String phone) { checkUserPhone(new UserReq.UserPhone(phone)); String code = smsHelper.createRandomNumber(); codeAuthRepository.save(CodeAuth.builder().auth(phone).code(code).ttl(300).build()); - CommonResponse sendRes = aligoService.sendSmsAuth(jwtService.createToken(1L), phone, code); + CommonResponse sendRes = aligoService.sendSmsAuth(phone, code); } public void checkPhoneAuth(UserReq.UserPhoneAuth phone) { diff --git a/Match-Common/src/main/java/com/example/matchcommon/config/AsyncConfig.java b/Match-Common/src/main/java/com/example/matchcommon/config/AsyncConfig.java index 082f5752..d789568b 100644 --- a/Match-Common/src/main/java/com/example/matchcommon/config/AsyncConfig.java +++ b/Match-Common/src/main/java/com/example/matchcommon/config/AsyncConfig.java @@ -75,4 +75,15 @@ public Executor alimTalk() { executor.initialize(); return executor; } + + @Bean(name = "event-listener") + public Executor eventListener() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(5); // 기본적으로 실행 대기 중인 Thread 개수 + executor.setMaxPoolSize(10); // 동시에 동작하는 최대 Thread 개수 + executor.setQueueCapacity(1000); // CorePool이 초과될때 Queue에 저장했다가 꺼내서 실행된다. (500개까지 저장함) + executor.setThreadNamePrefix("event-listener-thread"); // Spring에서 생성하는 Thread 이름의 접두사 + executor.initialize(); + return executor; + } } \ No newline at end of file diff --git a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/aligo/converter/AligoConverter.java b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/aligo/converter/AligoConverter.java index 2418d15c..3cdaad25 100644 --- a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/aligo/converter/AligoConverter.java +++ b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/aligo/converter/AligoConverter.java @@ -84,4 +84,15 @@ public AlimTalkDto convertToAlimTalkPayment(Long donationId, String name, String .build(); } + + public AlimTalkDto convertToAlimTalkExecution(Long donationId, String name, String phoneNumber, String article, String usages){ + return AlimTalkDto + .builder() + .donationId(donationId) + .name(name) + .phone(phoneNumber) + .article(article) + .usages(usages) + .build(); + } } diff --git a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/aligo/service/AligoInfraService.java b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/aligo/service/AligoInfraService.java index 1c16bef6..ea776155 100644 --- a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/aligo/service/AligoInfraService.java +++ b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/aligo/service/AligoInfraService.java @@ -9,6 +9,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.util.List; + @Service @RequiredArgsConstructor public class AligoInfraService { @@ -55,4 +57,19 @@ public void sendAlimTalk(AlimTalkDto alimTalkDto, AlimType alimType) { ); System.out.println(aligoResponse.toString()); } + + public void sendAlimTalks(List alimTalks, AlimType alimType) { + CreateTokenRes token = getAligoToken(); + + for(AlimTalkDto alimTalkDto : alimTalks) { + AlimTalkReq alimTalkReq = aligoConverter.convertToAlimTalk(aligoProperties, token.getToken(), alimType, alimTalkDto); + + System.out.println(alimTalkReq.toString()); + + AligoResponse aligoResponse = + kakaoAligoFeignClient.sendAlimTalk( + alimTalkReq + ); + } + } } diff --git a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/match_aligo/client/MatchAligoFeignClient.java b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/match_aligo/client/MatchAligoFeignClient.java index ba17819c..8b0226bc 100644 --- a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/match_aligo/client/MatchAligoFeignClient.java +++ b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/match_aligo/client/MatchAligoFeignClient.java @@ -7,6 +7,8 @@ import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*; +import java.util.List; + @FeignClient( name = "MatchAligoFeignClient", url = "${match.aligo.url}", @@ -23,4 +25,10 @@ CommonResponse sendAlimTalk(@RequestHeader(name = "X-AUTH-TOKEN") String @RequestParam("alimType")AlimType alimType, @RequestBody AlimTalkDto alimTalkDto); + @PostMapping("/send/alim-talk-execution") + CommonResponse sendAlimTalks( + @RequestHeader(name = "X-AUTH-TOKEN") String token, + @RequestParam("alimType")AlimType alimType, + @RequestBody List alimTalkDtos); + } diff --git a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/match_aligo/dto/AlimTalkDto.java b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/match_aligo/dto/AlimTalkDto.java index f97653b9..baf6e7e8 100644 --- a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/match_aligo/dto/AlimTalkDto.java +++ b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/match_aligo/dto/AlimTalkDto.java @@ -11,6 +11,8 @@ public class AlimTalkDto { private Long donationId; private String name; private String phone; + //사용처 private String usages; + //기부 품목 private String article; } From 12ec71d5756a3d7b5e1ef984ca495b6018a5fb60 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Tue, 5 Dec 2023 17:15:19 +0900 Subject: [PATCH 18/19] =?UTF-8?q?:recycle:=20:=20=EB=B0=B0=EC=B9=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/example/matchbatch/job/UserDeleteJob.java | 4 ++-- .../java/com/example/matchbatch/service/OrderService.java | 1 - .../main/java/com/example/matchbatch/service/UserService.java | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Match-Batch/src/main/java/com/example/matchbatch/job/UserDeleteJob.java b/Match-Batch/src/main/java/com/example/matchbatch/job/UserDeleteJob.java index 1b769c90..43f66d4a 100644 --- a/Match-Batch/src/main/java/com/example/matchbatch/job/UserDeleteJob.java +++ b/Match-Batch/src/main/java/com/example/matchbatch/job/UserDeleteJob.java @@ -25,11 +25,11 @@ public Job deleteUserSchedulingJob() { log.info(JOB_NAME + " JOB START"); return jobBuilderFactory.get(JOB_NAME) - .start(regularPaymentStep()) + .start(deleteUserStep()) .build(); } - private Step regularPaymentStep() { + private Step deleteUserStep() { return stepBuilderFactory.get(JOB_NAME+" STEP") .tasklet((contribution, chunkContext) -> { log.info("Step!"); diff --git a/Match-Batch/src/main/java/com/example/matchbatch/service/OrderService.java b/Match-Batch/src/main/java/com/example/matchbatch/service/OrderService.java index d2747009..51a096e9 100644 --- a/Match-Batch/src/main/java/com/example/matchbatch/service/OrderService.java +++ b/Match-Batch/src/main/java/com/example/matchbatch/service/OrderService.java @@ -179,7 +179,6 @@ public void deleteForOrder(User user) { deleteUserCard(userCard, accessToken); } - userCardAdaptor.deleteByUser(user.getId()); } private void deleteUserCard(UserCard userCard, String accessToken) { diff --git a/Match-Batch/src/main/java/com/example/matchbatch/service/UserService.java b/Match-Batch/src/main/java/com/example/matchbatch/service/UserService.java index 8acfae4a..f9923422 100644 --- a/Match-Batch/src/main/java/com/example/matchbatch/service/UserService.java +++ b/Match-Batch/src/main/java/com/example/matchbatch/service/UserService.java @@ -29,9 +29,8 @@ public void deleteUserInfos() { private void deleteUserInfo(User user) { projectService.deleteForProject(user); - donationService.deleteForDonation(user); - orderService.deleteForOrder(user); notificationService.deleteForNotification(user); + orderService.deleteForOrder(user); } } From 8149cb9a28b3fff57302a54c5d3ddee1c7c0f3b2 Mon Sep 17 00:00:00 2001 From: LimHyunwoo <81962309+imenuuu@users.noreply.github.com> Date: Tue, 5 Dec 2023 17:15:31 +0900 Subject: [PATCH 19/19] =?UTF-8?q?:recycle:=20:=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/matchapi/order/service/OrderService.java | 4 ++-- .../com/example/matchapi/portone/service/PaymentService.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Match-Api/src/main/java/com/example/matchapi/order/service/OrderService.java b/Match-Api/src/main/java/com/example/matchapi/order/service/OrderService.java index 976f90af..56fb866a 100644 --- a/Match-Api/src/main/java/com/example/matchapi/order/service/OrderService.java +++ b/Match-Api/src/main/java/com/example/matchapi/order/service/OrderService.java @@ -123,7 +123,7 @@ public OrderRes.CompleteDonation paymentForOnetime(OrderCommand.OneTimeDonation donationHistoryService.oneTimeDonationHistory(donationUser.getId()); - aligoService.sendAlimTalk(jwtService.createToken(1L), AlimType.PAYMENT, aligoConverter.convertToAlimTalkPayment(donationUser.getId(), user.getName(), user.getPhoneNumber())); + aligoService.sendAlimTalk(AlimType.PAYMENT, aligoConverter.convertToAlimTalkPayment(donationUser.getId(), user.getName(), user.getPhoneNumber())); return orderConverter.convertToCompleteDonation(user.getName(), project, oneTimeDonation.getAmount()); } @@ -149,7 +149,7 @@ public OrderRes.CompleteDonation paymentForRegular(OrderCommand.RegularDonation donationHistoryService.postRegularDonationHistory(regularPayment.getId(), donationUser.getId()); - aligoService.sendAlimTalk(jwtService.createToken(1L), AlimType.PAYMENT, aligoConverter.convertToAlimTalkPayment(donationUser.getId(), user.getName(), user.getPhoneNumber())); + aligoService.sendAlimTalk(AlimType.PAYMENT, aligoConverter.convertToAlimTalkPayment(donationUser.getId(), user.getName(), user.getPhoneNumber())); return orderConverter.convertToCompleteDonation(user.getName(), project, regularDonation.getAmount()); } diff --git a/Match-Api/src/main/java/com/example/matchapi/portone/service/PaymentService.java b/Match-Api/src/main/java/com/example/matchapi/portone/service/PaymentService.java index 7b170093..c43c8cca 100644 --- a/Match-Api/src/main/java/com/example/matchapi/portone/service/PaymentService.java +++ b/Match-Api/src/main/java/com/example/matchapi/portone/service/PaymentService.java @@ -82,7 +82,7 @@ public OrderRes.CompleteDonation checkPayment(PaymentCommand.PaymentValidation p orderAdaptor.deleteById(paymentValidation.getValidatePayment().getOrderId()); - aligoService.sendAlimTalk(jwtService.createToken(1L), AlimType.PAYMENT, aligoConverter.convertToAlimTalkPayment(donationUser.getId(), paymentValidation.getUser().getName(), paymentValidation.getUser().getPhoneNumber())); + aligoService.sendAlimTalk(AlimType.PAYMENT, aligoConverter.convertToAlimTalkPayment(donationUser.getId(), paymentValidation.getUser().getName(), paymentValidation.getUser().getPhoneNumber())); return orderConverter.convertToCompleteDonation(paymentValidation.getUser().getName(), paymentValidation.getProject(), (long) paymentValidation.getValidatePayment().getAmount()); } catch (IamportResponseException | IOException e) {