From 13abe54c25c0cbe815da637281d14c903a532c8a Mon Sep 17 00:00:00 2001 From: zzo3ozz Date: Tue, 25 Jun 2024 20:19:55 +0900 Subject: [PATCH 01/25] =?UTF-8?q?feat:=20=EC=86=8C=EC=85=9C=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99=20=ED=95=B4=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/UserController.java | 15 +++++ .../user/repository/SocialRepository.java | 3 + .../domain/user/service/UserService.java | 3 + .../domain/user/service/UserServiceImpl.java | 17 +++++ .../global/auth/service/SocialService.java | 64 +++++++++++++++++++ .../com/umc/gusto/global/exception/Code.java | 2 + 6 files changed, 104 insertions(+) diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java b/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java index 830b09b9..9700de01 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java @@ -256,4 +256,19 @@ public ResponseEntity followerList(@AuthenticationPrincipal Auth return ResponseEntity.ok() .body(pagingResponse); } + + /** + * 소셜 연동 해제 + * [DELETE] /users/auth/disconnect-social-account + * @param - + * @return - + */ + @DeleteMapping("/auth/disconnect-social-account") + public ResponseEntity disconnectSocialAccount(@AuthenticationPrincipal AuthUser authUser, + @RequestBody SignInRequest signInRequest) { + + userService.disconnectSocialAccount(authUser.getUser(), signInRequest); + return ResponseEntity.status(HttpStatus.NO_CONTENT) + .build(); + } } diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/repository/SocialRepository.java b/gusto/src/main/java/com/umc/gusto/domain/user/repository/SocialRepository.java index 89487102..51584992 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/repository/SocialRepository.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/repository/SocialRepository.java @@ -1,10 +1,13 @@ package com.umc.gusto.domain.user.repository; import com.umc.gusto.domain.user.entity.Social; +import com.umc.gusto.domain.user.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; public interface SocialRepository extends JpaRepository { Optional findBySocialTypeAndProviderId(Social.SocialType socialType, String providerId); + + Integer countSocialsByUser(User user); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java index 2274eeb2..b51db388 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java @@ -54,4 +54,7 @@ public interface UserService { // 팔로워 목록 PagingResponse getFollwerList(User user, Long followId); + + // 소셜 연동 해제 + void disconnectSocialAccount(User user, SignInRequest signInRequest); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java index 01d92378..e5a3475c 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java @@ -386,4 +386,21 @@ public PagingResponse getFollwerList(User user, Long followId) { .result(result) .build(); } + + @Override + @Transactional + public void disconnectSocialAccount(User user, SignInRequest signInRequest) { + socialService.loadUserInfo(signInRequest.getProvider(), signInRequest.getProviderId(), signInRequest.getAccessToken()); + + Social social = socialRepository.findBySocialTypeAndProviderId(Social.SocialType.valueOf(signInRequest.getProvider()), signInRequest.getProviderId()) + .orElseThrow(() -> new GeneralException(Code.SOCIAL_ACCOUNT_NOT_FOUND)); + + Integer num = socialRepository.countSocialsByUser(user); + if(num == 1) { + throw new GeneralException(Code.NEED_LEAST_ONE_SOCIAL_ACCOUNT); + } + + socialService.disconnectAccount(signInRequest.getProvider(), signInRequest.getAccessToken()); + socialRepository.delete(social); + } } diff --git a/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java b/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java index 1a3f7b39..6b2a885f 100644 --- a/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java +++ b/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java @@ -4,6 +4,7 @@ import com.umc.gusto.global.exception.Code; import com.umc.gusto.global.exception.GeneralException; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatusCode; import org.springframework.stereotype.Service; @@ -15,9 +16,15 @@ @Service @RequiredArgsConstructor +@Slf4j public class SocialService { private final RestClient restClient = RestClient.create(); private static final String AUTH_TYPE = "Bearer "; + @Value("${spring.security.oauth2.client.registration.naver.client-id}") + private static String NAVER_CLIENT_ID; + @Value("${spring.security.oauth2.client.registration.naver.client-secret}") + private static String NAVER_CLIENT_SECRET; + public void loadUserInfo(String provider, String providerId, String accessToken) { // TODO: ACCESS TOKEN 복호화 @@ -73,4 +80,61 @@ public void loadUserInfo(String provider, String providerId, String accessToken) throw new GeneralException(Code.UNMATCHED_AUTH_INFO); } } + + + public void disconnectAccount(String provider, String accessToken) { + // TODO: ACCESS TOKEN 복호화 + + if(provider.equals("NAVER")) { + StringBuilder uri = new StringBuilder("https://nid.naver.com/oauth2.0/token?grant_type=delete&"); + uri.append("client_id=").append(NAVER_CLIENT_ID).append("&") + .append("client_secret=").append(NAVER_CLIENT_SECRET).append("&") + .append("access_token=").append(accessToken); + + Map result = restClient.get() + .uri(uri.toString()) + .retrieve() + .onStatus(HttpStatusCode::is4xxClientError, ((request, response) -> { + throw new GeneralException(Code.OAUTH_FIND_ERROR); + })) + .onStatus(HttpStatusCode::is5xxServerError, ((request, response) -> { + throw new GeneralException(Code.OAUTH_FIND_ERROR); + })) + .body(Map.class); + + String resultCode = String.valueOf(result.get("result")); + + log.info(resultCode); + } else if(provider.equals("GOOGLE")) { + StringBuilder uri = new StringBuilder("https://oauth2.googleapis.com/revoke?"); + uri.append("access_token=").append(accessToken); + + Map result = restClient.get() + .uri(uri.toString()) + .retrieve() + .onStatus(HttpStatusCode::is4xxClientError, ((request, response) -> { + throw new GeneralException(Code.OAUTH_FIND_ERROR); + })) + .onStatus(HttpStatusCode::is5xxServerError, ((request, response) -> { + throw new GeneralException(Code.OAUTH_FIND_ERROR); + })) + .body(Map.class); + + log.info(result.toString()); + } else { + String header = AUTH_TYPE + accessToken; + + String result = restClient.get() + .uri("https://kapi.kakao.com/v1/user/unlink") + .header("Authorization", header) + .retrieve() + .onStatus(HttpStatusCode::is4xxClientError, ((request, response) -> { + throw new GeneralException(Code.OAUTH_FIND_ERROR); + })) + .onStatus(HttpStatusCode::is5xxServerError, ((request, response) -> { + throw new GeneralException(Code.OAUTH_FIND_ERROR); + })) + .body(String.class); + } + } } diff --git a/gusto/src/main/java/com/umc/gusto/global/exception/Code.java b/gusto/src/main/java/com/umc/gusto/global/exception/Code.java index 76367ef8..a529aa3a 100644 --- a/gusto/src/main/java/com/umc/gusto/global/exception/Code.java +++ b/gusto/src/main/java/com/umc/gusto/global/exception/Code.java @@ -75,6 +75,8 @@ public enum Code { // AUTH 관련 에러 +7 UNMATCHED_AUTH_INFO(HttpStatus.FORBIDDEN, 403701, "AccessToken과 providerId가 일치하지 않습니다."), + NEED_LEAST_ONE_SOCIAL_ACCOUNT(HttpStatus.FORBIDDEN, 403702, "최소 1개의 소셜 계정이 연동되어야 합니다."), + SOCIAL_ACCOUNT_NOT_FOUND(HttpStatus.NOT_FOUND, 404701, "해당 소셜 계정이 연결되어 있지 않습니다."), OAUTH_FIND_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 500701, "소셜 인증 서버에서 에러가 발생했습니다."), FOR_TEST_ERROR(HttpStatus.BAD_REQUEST,49999, "테스트용 에러") From d969dbb2d737e6449600244464594da22fe06e8f Mon Sep 17 00:00:00 2001 From: zzo3ozz Date: Wed, 26 Jun 2024 03:30:53 +0900 Subject: [PATCH 02/25] =?UTF-8?q?feat:=20=EC=86=8C=EC=85=9C=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99=20=EC=B6=94=EA=B0=80=20API=20=EC=8B=9C=EA=B7=B8?= =?UTF-8?q?=EB=8B=88=EC=B2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/controller/UserController.java | 15 +++++++++++++++ .../gusto/domain/user/service/UserService.java | 3 +++ .../domain/user/service/UserServiceImpl.java | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java b/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java index 9700de01..21df3f14 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java @@ -271,4 +271,19 @@ public ResponseEntity disconnectSocialAccount(@AuthenticationPrincipal AuthUser return ResponseEntity.status(HttpStatus.NO_CONTENT) .build(); } + + /** + * 소셜 연동 추가 + * [POST] /users/auth/connect-social-account + * @param - + * @return - + */ + @PostMapping("/auth/connect-social-account") + public ResponseEntity connectSocialAccount(@AuthenticationPrincipal AuthUser authUser, + @RequestBody SignInRequest signInRequest) { + userService.connectSocialAccount(authUser.getUser(), signInRequest); + + return ResponseEntity.status(HttpStatus.CREATED) + .build(); + } } diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java index b51db388..498a2b31 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java @@ -57,4 +57,7 @@ public interface UserService { // 소셜 연동 해제 void disconnectSocialAccount(User user, SignInRequest signInRequest); + + // 소셜 연동 추가 + void connectSocialAccount(User user, SignInRequest signInRequest); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java index e5a3475c..615e93aa 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java @@ -403,4 +403,13 @@ public void disconnectSocialAccount(User user, SignInRequest signInRequest) { socialService.disconnectAccount(signInRequest.getProvider(), signInRequest.getAccessToken()); socialRepository.delete(social); } + + @Override + public void connectSocialAccount(User user, SignInRequest signInRequest) { + // TODO: providerId 와 AccessToken 값 비교 + + // TODO: 해당 Provider에 이미 연결된 계정이 있는지 확인 + + // TODO: social 정보 추가 + } } From 4e81318cccdeddb2b9d6fbbb24cb0a06a1188b38 Mon Sep 17 00:00:00 2001 From: zzo3ozz Date: Wed, 26 Jun 2024 03:51:46 +0900 Subject: [PATCH 03/25] =?UTF-8?q?feat:=20=EC=86=8C=EC=85=9C=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99=20=EC=B6=94=EA=B0=80=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/repository/SocialRepository.java | 2 ++ .../gusto/domain/user/service/UserServiceImpl.java | 14 +++++++++++--- .../java/com/umc/gusto/global/exception/Code.java | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/repository/SocialRepository.java b/gusto/src/main/java/com/umc/gusto/domain/user/repository/SocialRepository.java index 51584992..0d88d919 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/repository/SocialRepository.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/repository/SocialRepository.java @@ -10,4 +10,6 @@ public interface SocialRepository extends JpaRepository { Optional findBySocialTypeAndProviderId(Social.SocialType socialType, String providerId); Integer countSocialsByUser(User user); + + Boolean existsByUserAndSocialType(User user, Social.SocialType socialType); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java index 615e93aa..19e9a4bd 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java @@ -406,10 +406,18 @@ public void disconnectSocialAccount(User user, SignInRequest signInRequest) { @Override public void connectSocialAccount(User user, SignInRequest signInRequest) { - // TODO: providerId 와 AccessToken 값 비교 + socialService.loadUserInfo(signInRequest.getProvider(), signInRequest.getProviderId(), signInRequest.getAccessToken()); + + if(socialRepository.existsByUserAndSocialType(user, Social.SocialType.valueOf(signInRequest.getProvider()))) { + throw new GeneralException(Code.ALREADY_EXIST_SOCIAL_CONNECT); + } - // TODO: 해당 Provider에 이미 연결된 계정이 있는지 확인 + Social social = Social.builder() + .user(user) + .socialType(Social.SocialType.valueOf(signInRequest.getProvider())) + .providerId(signInRequest.getProviderId()) + .build(); - // TODO: social 정보 추가 + socialRepository.save(social); } } diff --git a/gusto/src/main/java/com/umc/gusto/global/exception/Code.java b/gusto/src/main/java/com/umc/gusto/global/exception/Code.java index a529aa3a..be008422 100644 --- a/gusto/src/main/java/com/umc/gusto/global/exception/Code.java +++ b/gusto/src/main/java/com/umc/gusto/global/exception/Code.java @@ -76,6 +76,7 @@ public enum Code { // AUTH 관련 에러 +7 UNMATCHED_AUTH_INFO(HttpStatus.FORBIDDEN, 403701, "AccessToken과 providerId가 일치하지 않습니다."), NEED_LEAST_ONE_SOCIAL_ACCOUNT(HttpStatus.FORBIDDEN, 403702, "최소 1개의 소셜 계정이 연동되어야 합니다."), + ALREADY_EXIST_SOCIAL_CONNECT(HttpStatus.CONFLICT, 409703, "해당 소셜 서비스에 연결된 계정이 이미 존재합니다."), SOCIAL_ACCOUNT_NOT_FOUND(HttpStatus.NOT_FOUND, 404701, "해당 소셜 계정이 연결되어 있지 않습니다."), OAUTH_FIND_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 500701, "소셜 인증 서버에서 에러가 발생했습니다."), From b6fa6422f1b7ea966a78a7a3e087f8b064efa1f7 Mon Sep 17 00:00:00 2001 From: zzo3ozz Date: Wed, 26 Jun 2024 03:53:53 +0900 Subject: [PATCH 04/25] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=B2=B4=ED=81=AC=20method=EB=AA=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/gusto/domain/user/service/UserServiceImpl.java | 8 ++++---- .../com/umc/gusto/global/auth/service/SocialService.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java index 19e9a4bd..06d476bd 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java @@ -60,7 +60,7 @@ public class UserServiceImpl implements UserService{ @Override @Transactional public Tokens createUser(MultipartFile multipartFile, SignUpRequest request) { - socialService.loadUserInfo(request.getProvider(), request.getProviderId(), request.getAccessToken()); + socialService.checkUserInfo(request.getProvider(), request.getProviderId(), request.getAccessToken()); // 이미 가입된 계정이 존재함 socialRepository.findBySocialTypeAndProviderId(Social.SocialType.valueOf(request.getProvider()), request.getProviderId()) @@ -155,7 +155,7 @@ public NicknameResponse generateRandomNickname() { @Override public Tokens signIn(SignInRequest signInRequest) { - socialService.loadUserInfo(signInRequest.getProvider(), signInRequest.getProviderId(), signInRequest.getAccessToken()); + socialService.checkUserInfo(signInRequest.getProvider(), signInRequest.getProviderId(), signInRequest.getAccessToken()); // social 정보 확인 Social social = socialRepository.findBySocialTypeAndProviderId(Social.SocialType.valueOf(signInRequest.getProvider()), signInRequest.getProviderId()) @@ -390,7 +390,7 @@ public PagingResponse getFollwerList(User user, Long followId) { @Override @Transactional public void disconnectSocialAccount(User user, SignInRequest signInRequest) { - socialService.loadUserInfo(signInRequest.getProvider(), signInRequest.getProviderId(), signInRequest.getAccessToken()); + socialService.checkUserInfo(signInRequest.getProvider(), signInRequest.getProviderId(), signInRequest.getAccessToken()); Social social = socialRepository.findBySocialTypeAndProviderId(Social.SocialType.valueOf(signInRequest.getProvider()), signInRequest.getProviderId()) .orElseThrow(() -> new GeneralException(Code.SOCIAL_ACCOUNT_NOT_FOUND)); @@ -406,7 +406,7 @@ public void disconnectSocialAccount(User user, SignInRequest signInRequest) { @Override public void connectSocialAccount(User user, SignInRequest signInRequest) { - socialService.loadUserInfo(signInRequest.getProvider(), signInRequest.getProviderId(), signInRequest.getAccessToken()); + socialService.checkUserInfo(signInRequest.getProvider(), signInRequest.getProviderId(), signInRequest.getAccessToken()); if(socialRepository.existsByUserAndSocialType(user, Social.SocialType.valueOf(signInRequest.getProvider()))) { throw new GeneralException(Code.ALREADY_EXIST_SOCIAL_CONNECT); diff --git a/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java b/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java index 6b2a885f..e03705be 100644 --- a/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java +++ b/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java @@ -25,7 +25,7 @@ public class SocialService { @Value("${spring.security.oauth2.client.registration.naver.client-secret}") private static String NAVER_CLIENT_SECRET; - public void loadUserInfo(String provider, String providerId, String accessToken) { + public void checkUserInfo(String provider, String providerId, String accessToken) { // TODO: ACCESS TOKEN 복호화 String header = AUTH_TYPE + accessToken; From 31a662fda914d1b6c5fcf4a9d04890e3a7fe71e3 Mon Sep 17 00:00:00 2001 From: zzo3ozz Date: Wed, 26 Jun 2024 04:40:08 +0900 Subject: [PATCH 05/25] =?UTF-8?q?feat:=20=EC=97=B0=EA=B2=B0=EB=90=9C=20?= =?UTF-8?q?=EC=86=8C=EC=85=9C=20=EC=84=9C=EB=B2=84=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/UserController.java | 16 ++++++++++++ .../user/repository/SocialRepository.java | 3 +++ .../domain/user/service/UserService.java | 5 ++++ .../domain/user/service/UserServiceImpl.java | 26 ++++++++++++++++--- .../com/umc/gusto/global/exception/Code.java | 2 +- 5 files changed, 48 insertions(+), 4 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java b/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java index 21df3f14..0a1269d3 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java @@ -17,6 +17,8 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import java.util.Map; + @RestController @RequiredArgsConstructor @RequestMapping("/users") @@ -286,4 +288,18 @@ public ResponseEntity connectSocialAccount(@AuthenticationPrincipal AuthUser aut return ResponseEntity.status(HttpStatus.CREATED) .build(); } + + /** + * 연결된 소셜 계정 목록 + * [POST] /users/social-accounts + * @param - + * @return - + */ + @GetMapping("/social-accounts") + public ResponseEntity socialAccountList(@AuthenticationPrincipal AuthUser authUser) { + Map accountList = userService.getAccountList(authUser.getUser()); + + return ResponseEntity.ok() + .body(accountList); + } } diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/repository/SocialRepository.java b/gusto/src/main/java/com/umc/gusto/domain/user/repository/SocialRepository.java index 0d88d919..f0a7c4cb 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/repository/SocialRepository.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/repository/SocialRepository.java @@ -4,6 +4,7 @@ import com.umc.gusto.domain.user.entity.User; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; import java.util.Optional; public interface SocialRepository extends JpaRepository { @@ -12,4 +13,6 @@ public interface SocialRepository extends JpaRepository { Integer countSocialsByUser(User user); Boolean existsByUserAndSocialType(User user, Social.SocialType socialType); + + List findByUser(User user); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java index 498a2b31..0ce78e1e 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java @@ -9,6 +9,8 @@ import com.umc.gusto.global.auth.model.Tokens; import org.springframework.web.multipart.MultipartFile; +import java.util.Map; + public interface UserService { // 회원 가입 @@ -60,4 +62,7 @@ public interface UserService { // 소셜 연동 추가 void connectSocialAccount(User user, SignInRequest signInRequest); + + // 연결된 소셜 목록 + Map getAccountList(User user); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java index 06d476bd..d536edc8 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java @@ -31,8 +31,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; -import java.util.List; -import java.util.UUID; +import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; @@ -52,7 +51,7 @@ public class UserServiceImpl implements UserService{ private static final int MAX_NICKNAME_NUMBER = 999; private static final int MIN_NICKNAME_NUMBER = 1; private static final int FOLLOW_LIST_PAGE = 30; - + private static final Social.SocialType[] AUTH_SERVERS = Social.SocialType.values(); @Value("${default.img.url}") private String DEFAULT_PROFILE_IMG; @@ -420,4 +419,25 @@ public void connectSocialAccount(User user, SignInRequest signInRequest) { socialRepository.save(social); } + + @Override + public Map getAccountList(User user) { + List socials = socialRepository.findByUser(user); + + Set servers = socials.stream() + .map(social -> String.valueOf(social.getSocialType())) + .collect(Collectors.toSet()); + + Map result = new HashMap<>(); + + for(int i = 0; i < AUTH_SERVERS.length; i++) { + if(servers.contains(AUTH_SERVERS[i].name())) { + result.put(AUTH_SERVERS[i].name(), true); + } else { + result.put(AUTH_SERVERS[i].name(), false); + } + } + + return result; + } } diff --git a/gusto/src/main/java/com/umc/gusto/global/exception/Code.java b/gusto/src/main/java/com/umc/gusto/global/exception/Code.java index be008422..eea564c9 100644 --- a/gusto/src/main/java/com/umc/gusto/global/exception/Code.java +++ b/gusto/src/main/java/com/umc/gusto/global/exception/Code.java @@ -76,8 +76,8 @@ public enum Code { // AUTH 관련 에러 +7 UNMATCHED_AUTH_INFO(HttpStatus.FORBIDDEN, 403701, "AccessToken과 providerId가 일치하지 않습니다."), NEED_LEAST_ONE_SOCIAL_ACCOUNT(HttpStatus.FORBIDDEN, 403702, "최소 1개의 소셜 계정이 연동되어야 합니다."), - ALREADY_EXIST_SOCIAL_CONNECT(HttpStatus.CONFLICT, 409703, "해당 소셜 서비스에 연결된 계정이 이미 존재합니다."), SOCIAL_ACCOUNT_NOT_FOUND(HttpStatus.NOT_FOUND, 404701, "해당 소셜 계정이 연결되어 있지 않습니다."), + ALREADY_EXIST_SOCIAL_CONNECT(HttpStatus.CONFLICT, 409701, "해당 소셜 서비스에 연결된 계정이 이미 존재합니다."), OAUTH_FIND_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 500701, "소셜 인증 서버에서 에러가 발생했습니다."), FOR_TEST_ERROR(HttpStatus.BAD_REQUEST,49999, "테스트용 에러") From 76256f8c744a033838c1fcbd81a89967abf45807 Mon Sep 17 00:00:00 2001 From: zzo3ozz Date: Wed, 26 Jun 2024 06:17:33 +0900 Subject: [PATCH 06/25] =?UTF-8?q?refactor:=20=EC=86=8C=EC=85=9C=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99=20=EA=B4=80=EB=A0=A8=20API=20=EC=97=94?= =?UTF-8?q?=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/gusto/domain/user/controller/UserController.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java b/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java index 0a1269d3..d6234345 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java @@ -261,11 +261,11 @@ public ResponseEntity followerList(@AuthenticationPrincipal Auth /** * 소셜 연동 해제 - * [DELETE] /users/auth/disconnect-social-account + * [DELETE] /users/auth/social-account * @param - * @return - */ - @DeleteMapping("/auth/disconnect-social-account") + @DeleteMapping("/auth/social-account") public ResponseEntity disconnectSocialAccount(@AuthenticationPrincipal AuthUser authUser, @RequestBody SignInRequest signInRequest) { @@ -276,11 +276,11 @@ public ResponseEntity disconnectSocialAccount(@AuthenticationPrincipal AuthUser /** * 소셜 연동 추가 - * [POST] /users/auth/connect-social-account + * [POST] /users/auth/social-account * @param - * @return - */ - @PostMapping("/auth/connect-social-account") + @PostMapping("/auth/social-account") public ResponseEntity connectSocialAccount(@AuthenticationPrincipal AuthUser authUser, @RequestBody SignInRequest signInRequest) { userService.connectSocialAccount(authUser.getUser(), signInRequest); From 1a3d4890b1f83c482acf7d0fd034ff19bf61add2 Mon Sep 17 00:00:00 2001 From: zzo3ozz Date: Wed, 26 Jun 2024 06:25:50 +0900 Subject: [PATCH 07/25] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=ED=83=88?= =?UTF-8?q?=ED=87=B4=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/controller/UserController.java | 14 ++++++++++++++ .../com/umc/gusto/domain/user/entity/User.java | 4 ++++ .../gusto/domain/user/service/UserService.java | 3 +++ .../domain/user/service/UserServiceImpl.java | 16 ++++++++++++++++ 4 files changed, 37 insertions(+) diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java b/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java index d6234345..39e35a8c 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/controller/UserController.java @@ -302,4 +302,18 @@ public ResponseEntity socialAccountList(@AuthenticationPrincipal AuthUser a return ResponseEntity.ok() .body(accountList); } + + /** + * 회원 탈퇴 + * [DELETE] /users/my + * @param - + * @return - + */ + @DeleteMapping("/my") + public ResponseEntity disconnectSocialAccount(@AuthenticationPrincipal AuthUser authUser) { + userService.withdrawalUser(authUser.getUser()); + + return ResponseEntity.status(HttpStatus.NO_CONTENT) + .build(); + } } diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/entity/User.java b/gusto/src/main/java/com/umc/gusto/domain/user/entity/User.java index 6371a0db..14b9fed6 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/entity/User.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/entity/User.java @@ -128,4 +128,8 @@ public void updateCountReview(boolean plus){ if(plus) this.reviewCnt++; else this.reviewCnt--; } + + public void updateMemberStatus(MemberStatus memberStatus) { + this.memberStatus = memberStatus; + } } diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java index 0ce78e1e..e8fd1a68 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserService.java @@ -65,4 +65,7 @@ public interface UserService { // 연결된 소셜 목록 Map getAccountList(User user); + + // 회원 탈퇴 + void withdrawalUser(User user); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java index d536edc8..72cab1c5 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/service/UserServiceImpl.java @@ -404,6 +404,7 @@ public void disconnectSocialAccount(User user, SignInRequest signInRequest) { } @Override + @Transactional public void connectSocialAccount(User user, SignInRequest signInRequest) { socialService.checkUserInfo(signInRequest.getProvider(), signInRequest.getProviderId(), signInRequest.getAccessToken()); @@ -421,6 +422,7 @@ public void connectSocialAccount(User user, SignInRequest signInRequest) { } @Override + @Transactional(readOnly = true) public Map getAccountList(User user) { List socials = socialRepository.findByUser(user); @@ -440,4 +442,18 @@ public Map getAccountList(User user) { return result; } + + @Override + @Transactional + public void withdrawalUser(User user) { + user.updateMemberStatus(User.MemberStatus.INACTIVE); + + List socials = socialRepository.findByUser(user); + + for(Social social : socials) { + socialRepository.delete(social); + } + + userRepository.save(user); + } } From c94c7ceec3dee0149b0d1840c5913c0ad6229863 Mon Sep 17 00:00:00 2001 From: zzo3ozz Date: Wed, 3 Jul 2024 22:06:38 +0900 Subject: [PATCH 08/25] =?UTF-8?q?refactor:=20logging=EC=9A=A9=20sout=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C,=20log.info=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/gusto/global/auth/service/OAuthService.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/global/auth/service/OAuthService.java b/gusto/src/main/java/com/umc/gusto/global/auth/service/OAuthService.java index e82cdacc..581727c7 100644 --- a/gusto/src/main/java/com/umc/gusto/global/auth/service/OAuthService.java +++ b/gusto/src/main/java/com/umc/gusto/global/auth/service/OAuthService.java @@ -6,17 +6,18 @@ import com.umc.gusto.global.auth.model.CustomOAuth2User; import com.umc.gusto.global.auth.model.OAuthAttributes; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Service; -import org.springframework.web.client.RestClient; import java.util.Optional; @Service +@Slf4j @RequiredArgsConstructor public class OAuthService extends DefaultOAuth2UserService { private final SocialRepository socialRepository; @@ -28,9 +29,9 @@ public class OAuthService extends DefaultOAuth2UserService { @Override public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { OAuth2User oAuth2User = super.loadUser(userRequest); - System.out.println("***********************"); - System.out.println(userRequest.getAccessToken().getTokenValue()); - System.out.println("***********************"); + log.info("***********************"); + log.info(userRequest.getAccessToken().getTokenValue()); + log.info("***********************"); // provider - string to enum으로 변환 Social.SocialType provider = Social.SocialType.valueOf(userRequest.getClientRegistration().getRegistrationId().toUpperCase()); @@ -39,6 +40,8 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic .getUserNameAttributeName(); OAuthAttributes oAuthAttributes = OAuthAttributes.of(provider, userNameAttribute, oAuth2User.getAttributes()); + log.info(oAuthAttributes.getId()); + log.info("***********************"); Optional socialInfo = socialRepository.findBySocialTypeAndProviderId(provider, oAuthAttributes.getId()); From c189fbfb47815edd042e681a99080a2a711ce928 Mon Sep 17 00:00:00 2001 From: zzo3ozz Date: Mon, 8 Jul 2024 21:20:10 +0900 Subject: [PATCH 09/25] =?UTF-8?q?refactor:=20=EC=86=8C=EC=85=9C=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EB=B3=84=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EB=A9=94=EC=84=B8=EC=A7=80=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/gusto/global/auth/service/SocialService.java | 12 ++++++------ .../java/com/umc/gusto/global/exception/Code.java | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java b/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java index e03705be..b614e688 100644 --- a/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java +++ b/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java @@ -37,7 +37,7 @@ public void checkUserInfo(String provider, String providerId, String accessToken .header("Authorization", header) .retrieve() .onStatus(HttpStatusCode::is4xxClientError, ((request, response) -> { - throw new GeneralException(Code.OAUTH_FIND_ERROR); + throw new GeneralException(Code.OAUTH_NOT_FOUND_TOKEN); })) .onStatus(HttpStatusCode::is5xxServerError, ((request, response) -> { throw new GeneralException(Code.OAUTH_FIND_ERROR); @@ -52,7 +52,7 @@ public void checkUserInfo(String provider, String providerId, String accessToken .header("Authorization", header) .retrieve() .onStatus(HttpStatusCode::is4xxClientError, ((request, response) -> { - throw new GeneralException(Code.OAUTH_FIND_ERROR); + throw new GeneralException(Code.OAUTH_NOT_FOUND_TOKEN); })) .onStatus(HttpStatusCode::is5xxServerError, ((request, response) -> { throw new GeneralException(Code.OAUTH_FIND_ERROR); @@ -66,7 +66,7 @@ public void checkUserInfo(String provider, String providerId, String accessToken .header("Authorization", header) .retrieve() .onStatus(HttpStatusCode::is4xxClientError, ((request, response) -> { - throw new GeneralException(Code.OAUTH_FIND_ERROR); + throw new GeneralException(Code.OAUTH_NOT_FOUND_TOKEN); })) .onStatus(HttpStatusCode::is5xxServerError, ((request, response) -> { throw new GeneralException(Code.OAUTH_FIND_ERROR); @@ -95,7 +95,7 @@ public void disconnectAccount(String provider, String accessToken) { .uri(uri.toString()) .retrieve() .onStatus(HttpStatusCode::is4xxClientError, ((request, response) -> { - throw new GeneralException(Code.OAUTH_FIND_ERROR); + throw new GeneralException(Code.OAUTH_NOT_FOUND_TOKEN); })) .onStatus(HttpStatusCode::is5xxServerError, ((request, response) -> { throw new GeneralException(Code.OAUTH_FIND_ERROR); @@ -113,7 +113,7 @@ public void disconnectAccount(String provider, String accessToken) { .uri(uri.toString()) .retrieve() .onStatus(HttpStatusCode::is4xxClientError, ((request, response) -> { - throw new GeneralException(Code.OAUTH_FIND_ERROR); + throw new GeneralException(Code.OAUTH_NOT_FOUND_TOKEN); })) .onStatus(HttpStatusCode::is5xxServerError, ((request, response) -> { throw new GeneralException(Code.OAUTH_FIND_ERROR); @@ -129,7 +129,7 @@ public void disconnectAccount(String provider, String accessToken) { .header("Authorization", header) .retrieve() .onStatus(HttpStatusCode::is4xxClientError, ((request, response) -> { - throw new GeneralException(Code.OAUTH_FIND_ERROR); + throw new GeneralException(Code.OAUTH_NOT_FOUND_TOKEN); })) .onStatus(HttpStatusCode::is5xxServerError, ((request, response) -> { throw new GeneralException(Code.OAUTH_FIND_ERROR); diff --git a/gusto/src/main/java/com/umc/gusto/global/exception/Code.java b/gusto/src/main/java/com/umc/gusto/global/exception/Code.java index eea564c9..3dce79e5 100644 --- a/gusto/src/main/java/com/umc/gusto/global/exception/Code.java +++ b/gusto/src/main/java/com/umc/gusto/global/exception/Code.java @@ -79,6 +79,7 @@ public enum Code { SOCIAL_ACCOUNT_NOT_FOUND(HttpStatus.NOT_FOUND, 404701, "해당 소셜 계정이 연결되어 있지 않습니다."), ALREADY_EXIST_SOCIAL_CONNECT(HttpStatus.CONFLICT, 409701, "해당 소셜 서비스에 연결된 계정이 이미 존재합니다."), OAUTH_FIND_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 500701, "소셜 인증 서버에서 에러가 발생했습니다."), + OAUTH_NOT_FOUND_TOKEN(HttpStatus.NOT_FOUND, 404702, "유효한 소셜 서버 Access Token이 아닙니다."), FOR_TEST_ERROR(HttpStatus.BAD_REQUEST,49999, "테스트용 에러") From cbee7c42254e9ba61dbba7d891d1271c3c6be92e Mon Sep 17 00:00:00 2001 From: yujiyea Date: Sun, 21 Jul 2024 00:51:06 +0900 Subject: [PATCH 10/25] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EA=B3=B5=EA=B0=9C,=20=EB=B9=84=EA=B3=B5=EA=B0=9C=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=ED=95=A8=EC=88=98=EB=93=A4=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 피드 검색 API: 리뷰 공개된 것만 검색 - 랜덤 피드 API: 사용자 공개와 리뷰 공개까지 고려해서 노출 - 리뷰 생성, 수정 API: 공개, 비공개 --- .../review/controller/FeedController.java | 5 ++-- .../gusto/domain/review/entity/Review.java | 20 +++----------- .../model/request/CreateReviewRequest.java | 14 ++-------- .../model/request/UpdateReviewRequest.java | 13 +--------- .../model/response/SearchFeedResponse.java | 9 ++++++- .../review/repository/ReviewRepository.java | 19 +++++++++----- .../domain/review/service/FeedService.java | 2 +- .../review/service/FeedServiceImpl.java | 26 ++++++++++++++----- .../review/service/ReviewServiceImpl.java | 22 +++++----------- .../gusto/global/common/PublishStatus.java | 12 ++++++++- 10 files changed, 68 insertions(+), 74 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/controller/FeedController.java b/gusto/src/main/java/com/umc/gusto/domain/review/controller/FeedController.java index 77616a09..83b62af7 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/controller/FeedController.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/controller/FeedController.java @@ -24,8 +24,9 @@ public ResponseEntity getRandomFeed(@AuthenticationPrincipal AuthUser authUse } @GetMapping("/search") - public ResponseEntity searchFeed(@RequestParam(name = "keyword", required = false) String keyword, @RequestParam(name = "hashTags", required = false) List hashTags){ - return ResponseEntity.status(HttpStatus.OK).body(feedService.searchFeed(keyword, hashTags)); + public ResponseEntity searchFeed(@RequestParam(name = "keyword", required = false) String keyword, @RequestParam(name = "hashTags", required = false) List hashTags, + @RequestParam(name = "cursorId", required = false) Long cursorId){ + return ResponseEntity.status(HttpStatus.OK).body(feedService.searchFeed(keyword, hashTags, cursorId)); } @GetMapping("{reviewId}") diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/entity/Review.java b/gusto/src/main/java/com/umc/gusto/domain/review/entity/Review.java index a12324ba..0c8e7849 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/entity/Review.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/entity/Review.java @@ -99,22 +99,6 @@ public void updateTaste(Integer taste) { this.taste = taste; } - public void updateSpiciness(Integer spiciness) { - this.spiciness = spiciness; - } - - public void updateMood(Integer mood){ - this.mood = mood; - } - - public void updateToilet(Integer toilet){ - this.toilet = toilet; - } - - public void updateParking(Integer parking){ - this.parking = parking; - } - public void updateComment(String comment){ this.comment = comment; } @@ -144,4 +128,8 @@ public void updateLiked(String type){ if(type.equals("like")) this.liked += 1; else if(type.equals("unlike")) this.liked -= 1; } + + public void updatePublishReview(boolean check){ + this.publishReview = PublishStatus.of(check); + } } diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/model/request/CreateReviewRequest.java b/gusto/src/main/java/com/umc/gusto/domain/review/model/request/CreateReviewRequest.java index b84639f9..6b9fc94a 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/model/request/CreateReviewRequest.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/model/request/CreateReviewRequest.java @@ -21,18 +21,8 @@ public class CreateReviewRequest { @DecimalMin(value = "0", message = "점수가 0보다 작을 수 없습니다.") @DecimalMax(value = "5", message = "점수가 5보다 클 수 없습니다.") Integer taste; - @DecimalMin(value = "0", message = "점수가 0보다 작을 수 없습니다.") - @DecimalMax(value = "5", message = "점수가 5보다 클 수 없습니다.") - Integer spiciness; - @DecimalMin(value = "0", message = "점수가 0보다 작을 수 없습니다.") - @DecimalMax(value = "5", message = "점수가 5보다 클 수 없습니다.") - Integer mood; - @DecimalMin(value = "0", message = "점수가 0보다 작을 수 없습니다.") - @DecimalMax(value = "5", message = "점수가 5보다 클 수 없습니다.") - Integer toilet; - @DecimalMin(value = "0", message = "점수가 0보다 작을 수 없습니다.") - @DecimalMax(value = "5", message = "점수가 5보다 클 수 없습니다.") - Integer parking; @Size(max=200, message = "내용은 200자를 초과할 수 없습니다.") String comment; + @NotNull(message = "전체공개, 나만보기 둘 중 하나는 선택해야 합니다.") + boolean publicCheck; } diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/model/request/UpdateReviewRequest.java b/gusto/src/main/java/com/umc/gusto/domain/review/model/request/UpdateReviewRequest.java index 0d146ed9..8bb6c02e 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/model/request/UpdateReviewRequest.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/model/request/UpdateReviewRequest.java @@ -16,18 +16,7 @@ public class UpdateReviewRequest { @DecimalMin(value = "0", message = "점수가 0보다 작을 수 없습니다.") @DecimalMax(value = "5", message = "점수가 5보다 클 수 없습니다.") Integer taste; - @DecimalMin(value = "0", message = "점수가 0보다 작을 수 없습니다.") - @DecimalMax(value = "5", message = "점수가 5보다 클 수 없습니다.") - Integer spiciness; - @DecimalMin(value = "0", message = "점수가 0보다 작을 수 없습니다.") - @DecimalMax(value = "5", message = "점수가 5보다 클 수 없습니다.") - Integer mood; - @DecimalMin(value = "0", message = "점수가 0보다 작을 수 없습니다.") - @DecimalMax(value = "5", message = "점수가 5보다 클 수 없습니다.") - Integer toilet; - @DecimalMin(value = "0", message = "점수가 0보다 작을 수 없습니다.") - @DecimalMax(value = "5", message = "점수가 5보다 클 수 없습니다.") - Integer parking; @Size(max=200, message = "내용은 200자를 초과할 수 없습니다.") String comment; + Boolean publicCheck; //Boolean box화한 기본 자료형을 사용하여 null이 들어올 수 있도록 한다. } diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/model/response/SearchFeedResponse.java b/gusto/src/main/java/com/umc/gusto/domain/review/model/response/SearchFeedResponse.java index 86977960..f85f6f46 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/model/response/SearchFeedResponse.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/model/response/SearchFeedResponse.java @@ -5,14 +5,21 @@ import java.util.List; + + @Builder @Getter public class SearchFeedResponse { List reviews; + boolean hasNext; + Long cursorId; + - public static SearchFeedResponse of(List reviews){ + public static SearchFeedResponse of(List reviews, boolean hasNext, Long cursorId){ return SearchFeedResponse.builder() .reviews(reviews) + .hasNext(hasNext) + .cursorId(cursorId) .build(); } } diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java b/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java index 33d439ed..8eecbf30 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java @@ -38,16 +38,21 @@ public interface ReviewRepository extends JpaRepository { Optional> findAllByUserAndStatusAndReviewIdLessThanAndVisitedAtLessThanEqual(User user, BaseEntity.Status status, Long reviewId, LocalDate visitedAt,PageRequest pageRequest); List findByUserAndStatusAndVisitedAtBetween(User user, BaseEntity.Status status, LocalDate startDate, LocalDate lastDate); - @Query(value = "SELECT * FROM review r WHERE r.user_id <> :user AND r.status = 'ACTIVE' AND r.skip_check=false ORDER BY RAND() limit 33", nativeQuery = true) + @Query(value = "SELECT * FROM review r join user u on r.user_id = u.user_id WHERE r.user_id <> :user AND u.publish_review = 'PUBLIC' AND r.status = 'ACTIVE' AND r.publish_review = 'PUBLIC' AND r.skip_check=false ORDER BY RAND() limit 33", nativeQuery = true) List findRandomFeedByUser(@Param("user") UUID user); //WHERE r.user_id <> :userZ boolean existsByStoreAndUserNickname(Store store, String nickname); //검색 기능 - @Query("SELECT r FROM Review r WHERE r.status = 'ACTIVE' AND r.skipCheck = false AND r.store.storeName like concat('%', :keyword, '%') OR r.comment like concat('%', :keyword, '%')") - List searchByStoreContains(String keyword, PageRequest pageRequest); //TODO: 후에 페이징 처리 하기 - @Query("SELECT t.review FROM Tagging t WHERE t.review.status = 'ACTIVE' AND t.review.skipCheck=false AND t.review.store.storeName like concat('%', :keyword, '%') AND t.hashTag.hasTagId = :hashTagId") - List searchByStoreAndHashTagContains(String keyword, Long hashTagId, PageRequest pageRequest); - @Query("SELECT t.review FROM Tagging t WHERE t.review.status = 'ACTIVE' AND t.review.skipCheck=false AND t.hashTag.hasTagId = :hashTagId") - List searchByHashTagContains(Long hashTagId, PageRequest pageRequest); + @Query("SELECT r FROM Review r WHERE r.status = 'ACTIVE' AND r.publishReview = 'PUBLIC' AND r.skipCheck = false " + + "AND r.reviewId < :cursorId AND r.store.storeName like concat('%', :keyword, '%') OR r.comment like concat('%', :keyword, '%')" + + "ORDER BY r.reviewId desc") + Page searchByStoreContains(String keyword, Long cursorId, PageRequest pageRequest); //TODO: 후에 페이징 처리 하기 + @Query("SELECT t.review FROM Tagging t WHERE t.review.status = 'ACTIVE' AND t.review.publishReview = 'PUBLIC' AND t.review.skipCheck=false " + + "AND t.review.reviewId < :cursorId AND t.review.store.storeName like concat('%', :keyword, '%') AND t.hashTag.hasTagId = :hashTagId" + + " ORDER BY t.review.reviewId desc") + Page searchByStoreAndHashTagContains(String keyword, Long hashTagId, Long cursorId, PageRequest pageRequest); + @Query("SELECT t.review FROM Tagging t WHERE t.review.status = 'ACTIVE' AND t.review.publishReview = 'PUBLIC' AND t.review.skipCheck=false " + + "AND t.review.reviewId < :cursorId AND t.hashTag.hasTagId = :hashTagId ORDER BY t.review.reviewId desc") + Page searchByHashTagContains(Long hashTagId, Long cursorId, PageRequest pageRequest); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/service/FeedService.java b/gusto/src/main/java/com/umc/gusto/domain/review/service/FeedService.java index 757d0b87..a0797e0b 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/service/FeedService.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/service/FeedService.java @@ -9,6 +9,6 @@ public interface FeedService { List getRandomFeed(User user); - SearchFeedResponse searchFeed(String keyword, List hashTags); + SearchFeedResponse searchFeed(String keyword, List hashTags, Long cursorId); FeedDetailResponse getFeedDetail(User user, Long reviewId); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/service/FeedServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/review/service/FeedServiceImpl.java index d65ec47e..dd815106 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/service/FeedServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/service/FeedServiceImpl.java @@ -11,6 +11,7 @@ import com.umc.gusto.global.exception.customException.NotFoundException; import com.umc.gusto.global.exception.customException.PrivateItemException; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; @@ -31,26 +32,39 @@ public List getRandomFeed(User user) { } @Override - public SearchFeedResponse searchFeed(String keyword, List hashTags) { - List searchResult = new ArrayList<>(); + public SearchFeedResponse searchFeed(String keyword, List hashTags, Long cursor) { //TODO: 검색 결과가 랜덤으로 다시 정렬되야 할듯 + Page searchResult = null; PageRequest pageRequest = PageRequest.of(0,33); + + if(cursor == null){ + cursor = Long.MAX_VALUE; + } + //맛집과 해시태그를 함께 검색하는 경우 if(keyword!=null && hashTags!=null){ for(Long hashTagId: hashTags){ - searchResult.addAll(reviewRepository.searchByStoreAndHashTagContains(keyword, hashTagId, pageRequest)); +// searchResult.addAll(reviewRepository.searchByStoreAndHashTagContains(keyword, hashTagId, pageRequest)); + searchResult = reviewRepository.searchByStoreAndHashTagContains(keyword, hashTagId, cursor, pageRequest); } } else if(keyword!=null){ //맛집을 검색하는 경우 - searchResult = reviewRepository.searchByStoreContains(keyword, pageRequest); + searchResult = reviewRepository.searchByStoreContains(keyword, cursor, pageRequest); } else if(hashTags!=null){ for(Long hashTagId: hashTags){ - searchResult.addAll(reviewRepository.searchByHashTagContains(hashTagId, pageRequest)); + searchResult = reviewRepository.searchByHashTagContains(hashTagId, cursor, pageRequest); } } + if(searchResult == null){ + return SearchFeedResponse.builder().build(); + } + + boolean checkNext = searchResult.hasNext(); List basicViewResponse = searchResult.stream().map(BasicViewResponse::of).toList(); - return SearchFeedResponse.of(basicViewResponse); + Long cursorId = basicViewResponse.isEmpty() ? null : basicViewResponse.get(basicViewResponse.size()-1).getReviewId(); + return SearchFeedResponse.of(basicViewResponse, checkNext, cursorId); } + //TODO: 해당 함수도 이미 피드에서 보인 리뷰임. 그래서 디테일이 안보이면 안됨 사용자 공개 체크를 할 필요가 없음 @Override public FeedDetailResponse getFeedDetail(User user, Long reviewId) { //TOOD: reviewServiceImpl와 중복되는 코드 분리하기 diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewServiceImpl.java index be947273..492defc5 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewServiceImpl.java @@ -65,11 +65,8 @@ public void createReview(User user, List images, CreateReviewRequ .visitedAt(visitedAt) .menuName(createReviewRequest.getMenuName()) .taste(createReviewRequest.getTaste()) - .spiciness(createReviewRequest.getSpiciness()) - .mood(createReviewRequest.getMood()) - .toilet(createReviewRequest.getToilet()) - .parking(createReviewRequest.getParking()) .comment(createReviewRequest.getComment()) + .publishReview(PublishStatus.of(createReviewRequest.isPublicCheck())) .build(); //TODO: review 엔티티에서 이미지를 분리하거나 monogoDB를 쓰는게 나을 듯, 나머지 기능 개발 후 바꿀 예정 @@ -117,18 +114,6 @@ public void updateReview(Long reviewId, List images, UpdateReview if(updateReviewRequest.getTaste()!=null){ review.updateTaste(updateReviewRequest.getTaste()); } - if(updateReviewRequest.getSpiciness()!=null){ - review.updateSpiciness(updateReviewRequest.getSpiciness()); - } - if(updateReviewRequest.getMood()!=null){ - review.updateMood(updateReviewRequest.getMood()); - } - if(updateReviewRequest.getToilet()!=null){ - review.updateToilet(updateReviewRequest.getToilet()); - } - if(updateReviewRequest.getParking()!=null){ - review.updateParking(updateReviewRequest.getParking()); - } if(updateReviewRequest.getComment()!=null){ review.updateComment(updateReviewRequest.getComment()); } @@ -137,6 +122,10 @@ public void updateReview(Long reviewId, List images, UpdateReview updateImages(images, review); } + if(updateReviewRequest.getPublicCheck() != null){ + review.updatePublishReview(updateReviewRequest.getPublicCheck()); + } + reviewRepository.save(review); } @@ -153,6 +142,7 @@ public void deleteReview(User user, Long reviewId) { public ReviewDetailResponse getReview(Long reviewId) { Review review = reviewRepository.findByReviewIdAndStatus(reviewId, BaseEntity.Status.ACTIVE).orElseThrow(()->new NotFoundException(Code.REVIEW_NOT_FOUND)); //TODO: 후에 각 리뷰마다의 공개, 비공개를 확인해서 주는거로 수정하기 + //TODO: 해당 함수는 사용자의 공개를 체크하면 안 될 것 같은데?? 리뷰 하나를 조회하는 것으로 분명 앞에서 리뷰가 보였으니까 해당 함수를 사용할 것임 if(!review.getUser().getPublishReview().equals(PublishStatus.PUBLIC)){ throw new PrivateItemException(Code.NO_PUBLIC_REVIEW); } diff --git a/gusto/src/main/java/com/umc/gusto/global/common/PublishStatus.java b/gusto/src/main/java/com/umc/gusto/global/common/PublishStatus.java index 6a4cf8e6..fed88a43 100644 --- a/gusto/src/main/java/com/umc/gusto/global/common/PublishStatus.java +++ b/gusto/src/main/java/com/umc/gusto/global/common/PublishStatus.java @@ -1,5 +1,15 @@ package com.umc.gusto.global.common; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor public enum PublishStatus { - PUBLIC, PRIVATE + PUBLIC(true), + PRIVATE(false); + + private final boolean check; + + public static PublishStatus of(boolean check){ + return check ? PUBLIC : PRIVATE; + } } From 509e5362b6dc80e1eaa78b771912b0d9b349d3fa Mon Sep 17 00:00:00 2001 From: yujiyea Date: Sun, 21 Jul 2024 00:57:55 +0900 Subject: [PATCH 11/25] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=8B=9C=20=EB=A6=AC=EB=B7=B0=20=EA=B3=B5?= =?UTF-8?q?=EA=B0=9C,=20=EB=B9=84=EA=B3=B5=EA=B0=9C=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/response/ReviewDetailResponse.java | 14 +---- .../review/model/response/ReviewResponse.java | 55 ------------------- .../gusto/global/common/PublishStatus.java | 4 ++ 3 files changed, 6 insertions(+), 67 deletions(-) delete mode 100644 gusto/src/main/java/com/umc/gusto/domain/review/model/response/ReviewResponse.java diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/model/response/ReviewDetailResponse.java b/gusto/src/main/java/com/umc/gusto/domain/review/model/response/ReviewDetailResponse.java index dceb6f26..5eafd86e 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/model/response/ReviewDetailResponse.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/model/response/ReviewDetailResponse.java @@ -21,16 +21,9 @@ public class ReviewDetailResponse { List hashTags; Integer taste; @JsonInclude(JsonInclude.Include.NON_NULL) - Integer spiciness; - @JsonInclude(JsonInclude.Include.NON_NULL) - Integer mood; - @JsonInclude(JsonInclude.Include.NON_NULL) - Integer toilet; - @JsonInclude(JsonInclude.Include.NON_NULL) - Integer parking; - @JsonInclude(JsonInclude.Include.NON_NULL) String comment; Integer likeCnt; + boolean publicCheck; public static ReviewDetailResponse of(Review review, List hashTags){ return ReviewDetailResponse.builder() @@ -41,12 +34,9 @@ public static ReviewDetailResponse of(Review review, List hashTags){ .menuName(review.getMenuName()) .hashTags(hashTags) .taste(review.getTaste()) - .spiciness(review.getSpiciness()) - .mood(review.getMood()) - .toilet(review.getToilet()) - .parking(review.getParking()) .comment(review.getComment()) .likeCnt(review.getLiked()) + .publicCheck(review.getPublishReview().isCheck()) .build(); } } diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/model/response/ReviewResponse.java b/gusto/src/main/java/com/umc/gusto/domain/review/model/response/ReviewResponse.java deleted file mode 100644 index 290daa67..00000000 --- a/gusto/src/main/java/com/umc/gusto/domain/review/model/response/ReviewResponse.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.umc.gusto.domain.review.model.response; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.umc.gusto.domain.review.entity.Review; -import lombok.Builder; -import lombok.Getter; - -import java.time.LocalDate; - -public class ReviewResponse { - @Builder - @Getter - public static class ReviewDetailDTO{ - Long storeId; - String storeName; - String nickName; - LocalDate visitedAt; - //TODO: img고려 - @JsonInclude(JsonInclude.Include.NON_NULL) - String menuName; - @JsonInclude(JsonInclude.Include.NON_NULL) - String hashTags; - Integer taste; - @JsonInclude(JsonInclude.Include.NON_NULL) - Integer spiciness; - @JsonInclude(JsonInclude.Include.NON_NULL) - Integer mood; - @JsonInclude(JsonInclude.Include.NON_NULL) - Integer toilet; - @JsonInclude(JsonInclude.Include.NON_NULL) - Integer parking; - @JsonInclude(JsonInclude.Include.NON_NULL) - String comment; - Integer likeCnt; - - public static ReviewDetailDTO of(Review review, String hashTags){ - return ReviewDetailDTO.builder() - .storeId(review.getStore().getStoreId()) - .storeName(review.getStore().getStoreName()) - .nickName(review.getUser().getNickname()) - .visitedAt(review.getVisitedAt()) -// .img() TODO: img 처리하기 - .menuName(review.getMenuName()) - .hashTags(hashTags) - .taste(review.getTaste()) - .spiciness(review.getSpiciness()) - .mood(review.getMood()) - .toilet(review.getToilet()) - .parking(review.getParking()) - .comment(review.getComment()) - .likeCnt(review.getLiked()) - .build(); - } - } -} diff --git a/gusto/src/main/java/com/umc/gusto/global/common/PublishStatus.java b/gusto/src/main/java/com/umc/gusto/global/common/PublishStatus.java index fed88a43..e99bedab 100644 --- a/gusto/src/main/java/com/umc/gusto/global/common/PublishStatus.java +++ b/gusto/src/main/java/com/umc/gusto/global/common/PublishStatus.java @@ -9,6 +9,10 @@ public enum PublishStatus { private final boolean check; + public boolean isCheck() { + return check; + } + public static PublishStatus of(boolean check){ return check ? PUBLIC : PRIVATE; } From f7c7e356d4dd99368de88311e14539198963cad4 Mon Sep 17 00:00:00 2001 From: yujiyea Date: Sun, 21 Jul 2024 23:54:26 +0900 Subject: [PATCH 12/25] =?UTF-8?q?fix:=20=EB=A6=AC=EB=B7=B0=20=EB=AA=A8?= =?UTF-8?q?=EC=95=84=EB=B3=B4=EA=B8=B0=20=ED=8E=98=EC=9D=B4=EC=A7=95=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0=20&=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EA=B3=B5=EA=B0=9C=20=EC=B2=B4=ED=81=AC=ED=95=B4?= =?UTF-8?q?=EC=84=9C=20=ED=8E=98=EC=9D=B4=EC=A7=95=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 인스타 뷰 API: 내 리뷰 보기용일때는 각 리뷰의 공개 체크가 필요없음, 타인 리뷰 보기 용일 때는 타인의 프로필 공개 여부와 각 리뷰 공개 체크 해야 함 - 페이징 처리: 이전에 sort방식이 잘못됨, reviewId로 정렬을 한번 해야 하는데 createAt만 생각했음 --- .idea/compiler.xml | 2 +- .../review/controller/ReviewController.java | 8 +++- .../review/repository/ReviewRepository.java | 18 +++++++- .../review/service/CollectReviewService.java | 1 + .../service/CollectReviewServiceImpl.java | 41 +++++++++++++++++-- .../review/service/FeedServiceImpl.java | 3 +- 6 files changed, 65 insertions(+), 8 deletions(-) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index dcf922e5..ff2e3754 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -9,7 +9,7 @@ - + diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/controller/ReviewController.java b/gusto/src/main/java/com/umc/gusto/domain/review/controller/ReviewController.java index 3c4e4ec3..c66a4bbb 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/controller/ReviewController.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/controller/ReviewController.java @@ -67,8 +67,14 @@ public ResponseEntity getReview(@PathVariable Long reviewId){ * 리뷰 모아보기 - 인스타 뷰 */ @GetMapping("/instaView") - public ResponseEntity getReviewOfInstaView(@AuthenticationPrincipal AuthUser authUser, @RequestParam(name = "reviewId", required = false) Long reviewId, @RequestParam(name = "size") int size){ + public ResponseEntity getReviewOfInstaView(@AuthenticationPrincipal AuthUser authUser, @RequestParam(name = "mineCheck") boolean mineCheck,@RequestParam(name = "reviewId", required = false) Long reviewId, @RequestParam(name = "size") int size){ User user = authUser.getUser(); + + //내 인스타 뷰라면 + if(mineCheck){ + return ResponseEntity.ok().body(collectReviewService.getMyReviewOfInstaView(user, reviewId, size)); + } + return ResponseEntity.ok().body(collectReviewService.getReviewOfInstaView(user, reviewId, size)); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java b/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java index 8eecbf30..0edc4196 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java @@ -35,7 +35,6 @@ public interface ReviewRepository extends JpaRepository { Optional findByReviewIdAndStatus(Long reviewId, BaseEntity.Status status); Optional> findAllByUserAndStatus(User user, BaseEntity.Status status, PageRequest pageRequest); - Optional> findAllByUserAndStatusAndReviewIdLessThanAndVisitedAtLessThanEqual(User user, BaseEntity.Status status, Long reviewId, LocalDate visitedAt,PageRequest pageRequest); List findByUserAndStatusAndVisitedAtBetween(User user, BaseEntity.Status status, LocalDate startDate, LocalDate lastDate); @Query(value = "SELECT * FROM review r join user u on r.user_id = u.user_id WHERE r.user_id <> :user AND u.publish_review = 'PUBLIC' AND r.status = 'ACTIVE' AND r.publish_review = 'PUBLIC' AND r.skip_check=false ORDER BY RAND() limit 33", nativeQuery = true) @@ -43,7 +42,9 @@ public interface ReviewRepository extends JpaRepository { boolean existsByStoreAndUserNickname(Store store, String nickname); - //검색 기능 + /* + 검색 관련 + */ @Query("SELECT r FROM Review r WHERE r.status = 'ACTIVE' AND r.publishReview = 'PUBLIC' AND r.skipCheck = false " + "AND r.reviewId < :cursorId AND r.store.storeName like concat('%', :keyword, '%') OR r.comment like concat('%', :keyword, '%')" + "ORDER BY r.reviewId desc") @@ -55,4 +56,17 @@ public interface ReviewRepository extends JpaRepository { @Query("SELECT t.review FROM Tagging t WHERE t.review.status = 'ACTIVE' AND t.review.publishReview = 'PUBLIC' AND t.review.skipCheck=false " + "AND t.review.reviewId < :cursorId AND t.hashTag.hasTagId = :hashTagId ORDER BY t.review.reviewId desc") Page searchByHashTagContains(Long hashTagId, Long cursorId, PageRequest pageRequest); + + /* + 리뷰 모아보기 페이징 처리 + */ + @Query("select r from Review r where r.user = :user and r.status = 'ACTIVE' and r.publishReview = 'PUBLIC'") + Page pagingInstaViewNoCursor(User user, PageRequest pageRequest); + @Query("select r from Review r where r.user = :user and r.status = 'ACTIVE' and r.publishReview = 'PUBLIC' " + + "and r.visitedAt < :visitedAt or (r.visitedAt = :visitedAt and r.reviewId < :reviewId)") + Page pagingInstaView(User user, Long reviewId, LocalDate visitedAt,PageRequest pageRequest); + + @Query("select r from Review r where r.user = :user and r.status = 'ACTIVE'" + + "and r.visitedAt < :visitedAt or (r.visitedAt = :visitedAt and r.reviewId < :reviewId)") + Page pagingMyReview(User user, Long reviewId, LocalDate visitedAt,PageRequest pageRequest); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewService.java b/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewService.java index e047061b..3e4001ef 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewService.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewService.java @@ -8,6 +8,7 @@ public interface CollectReviewService { // CollectReviewsOfInstaResponse getReviewOfInstaView(User user, ReviewViewRequest reviewViewRequest); + CollectReviewsResponse getMyReviewOfInstaView(User user, Long reviewId, int size); CollectReviewsResponse getReviewOfInstaView(User user, Long reviewId, int size); CollectReviewsOfCalResponse getReviewOfCalView(User user, Long reviewId, int size, LocalDate date); CollectReviewsResponse getReviewOfTimeView(User user, Long reviewId, int size); diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewServiceImpl.java index 8ce58951..2cbbcf4d 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewServiceImpl.java @@ -27,7 +27,7 @@ public class CollectReviewServiceImpl implements CollectReviewService{ private final UserRepository userRepository; @Override - public CollectReviewsResponse getReviewOfInstaView(User user, Long reviewId, int size) { + public CollectReviewsResponse getMyReviewOfInstaView(User user, Long reviewId, int size) { //페이징해서 가져오기 Page reviews = pagingReview(user, reviewId, size); @@ -42,6 +42,39 @@ public CollectReviewsResponse getReviewOfInstaView(User user, Long reviewId, int return CollectReviewsResponse.of(basicViewResponse, cursorId,checkNext); } + /* + 다른 사용자의 프로필을 볼 때 사용하는 인스타 뷰이기 때문에 사용자의 publish_review 체크와 각 리뷰의 publish_reivew 체크가 필요 + */ + @Override + public CollectReviewsResponse getReviewOfInstaView(User user, Long reviewId, int size) { + Page reviews; + + //사용자가 리뷰 프로필에 표기를 했는지 체크 + if(!user.getPublishReview().isCheck()){ // 표기 X + return CollectReviewsResponse.builder().build(); + } + + //사용자의 리뷰들 중 public인 것만 추출 + Sort sort = Sort.by("visitedAt").descending().and(Sort.by("reviewId").descending()); + PageRequest pageRequest = PageRequest.of(0, size, sort); + + if(reviewId == null){ + reviews = reviewRepository.pagingInstaViewNoCursor(user, pageRequest); + }else { + Review review = reviewRepository.findById(reviewId).orElseThrow(()->new NotFoundException(Code.REVIEW_NOT_FOUND)); + reviews = reviewRepository.pagingInstaView(user, reviewId, review.getVisitedAt(), pageRequest); + } + + //다음 조회 되는 리뷰가 있는지 확인 + boolean checkNext = reviews.hasNext(); + + //response 형태로 변환 + List basicViewResponse = reviews.map(BasicViewResponse::of).toList(); + Long cursorId = basicViewResponse.isEmpty() ? null : basicViewResponse.get(basicViewResponse.size()-1).getReviewId(); + + return CollectReviewsResponse.of(basicViewResponse, cursorId,checkNext); + } + @Override public CollectReviewsOfCalResponse getReviewOfCalView(User user, Long reviewId, int size, LocalDate date) { //해당 달의 첫 날짜, 마지막 날짜 구하기 @@ -95,7 +128,8 @@ public CollectReviewsResponse getOthersReview(String nickName, Long reviewId, in private Page pagingReview(User user, Long cursorId, int size){ //최신순 날짜로 정렬 - Sort sort = Sort.by("visitedAt").descending().and(Sort.by("createdAt").descending()); +// Sort sort = Sort.by("visitedAt").descending().and(Sort.by("createdAt").descending()); + Sort sort = Sort.by("visitedAt").descending().and(Sort.by("reviewId").descending()); PageRequest pageRequest = PageRequest.of(0, size, sort); Page reviews; @@ -105,7 +139,8 @@ private Page pagingReview(User user, Long cursorId, int size){ }else{ //최초가 아닌 경우 //커서 id를 기반으로 그보다 낮은 ID의 리뷰를 가져온다 => 최신 날짜가 이전의 데이터가 나타난다. Review review = reviewRepository.findById(cursorId).orElseThrow(()->new NotFoundException(Code.REVIEW_NOT_FOUND)); - reviews = reviewRepository.findAllByUserAndStatusAndReviewIdLessThanAndVisitedAtLessThanEqual(user, BaseEntity.Status.ACTIVE, cursorId, review.getVisitedAt(),pageRequest).orElseThrow(()-> new NotFoundException(Code.REVIEW_NOT_FOUND)); +// reviews = reviewRepository.findAllByUserAndStatusAndReviewIdLessThanAndVisitedAtLessThanEqual(user, BaseEntity.Status.ACTIVE, cursorId, review.getVisitedAt(),pageRequest).orElseThrow(()-> new NotFoundException(Code.REVIEW_NOT_FOUND)); + reviews = reviewRepository.pagingMyReview(user, cursorId, review.getVisitedAt(),pageRequest); } if(reviews.isEmpty()){ diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/service/FeedServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/review/service/FeedServiceImpl.java index dd815106..41540f48 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/service/FeedServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/service/FeedServiceImpl.java @@ -32,7 +32,7 @@ public List getRandomFeed(User user) { } @Override - public SearchFeedResponse searchFeed(String keyword, List hashTags, Long cursor) { //TODO: 검색 결과가 랜덤으로 다시 정렬되야 할듯 + public SearchFeedResponse searchFeed(String keyword, List hashTags, Long cursor) { //TODO: 검색 결과가 랜덤으로 다시 정렬되야 할듯 & 자기 리뷰가 아니여야함 Page searchResult = null; PageRequest pageRequest = PageRequest.of(0,33); @@ -61,6 +61,7 @@ public SearchFeedResponse searchFeed(String keyword, List hashTags, Long c boolean checkNext = searchResult.hasNext(); List basicViewResponse = searchResult.stream().map(BasicViewResponse::of).toList(); Long cursorId = basicViewResponse.isEmpty() ? null : basicViewResponse.get(basicViewResponse.size()-1).getReviewId(); + return SearchFeedResponse.of(basicViewResponse, checkNext, cursorId); } From 11aaa4e21cf074d0cbc63d3c3bf4ea7c6d922833 Mon Sep 17 00:00:00 2001 From: hyesoo kim Date: Mon, 22 Jul 2024 22:09:07 +0900 Subject: [PATCH 13/25] =?UTF-8?q?[refactor]=20=EB=82=B4=20=EB=A3=A8?= =?UTF-8?q?=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=ED=95=A0=20=EB=95=8C=EB=82=98=20?= =?UTF-8?q?=EB=A3=A8=ED=8A=B8=20=EC=83=81=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=8B=9C=20=EA=B3=B5=EA=B0=9C/=EB=B9=84=EA=B3=B5=EA=B0=9C=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=ED=8F=AC=ED=95=A8=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/route/model/response/RouteRouteListResponse.java | 3 +++ .../umc/gusto/domain/route/service/RouteListServiceImpl.java | 1 + .../com/umc/gusto/domain/route/service/RouteServiceImpl.java | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/route/model/response/RouteRouteListResponse.java b/gusto/src/main/java/com/umc/gusto/domain/route/model/response/RouteRouteListResponse.java index 21266a9f..3acd282b 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/route/model/response/RouteRouteListResponse.java +++ b/gusto/src/main/java/com/umc/gusto/domain/route/model/response/RouteRouteListResponse.java @@ -1,5 +1,6 @@ package com.umc.gusto.domain.route.model.response; +import com.fasterxml.jackson.annotation.JsonInclude; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -14,5 +15,7 @@ public class RouteRouteListResponse { private Long routeId; private String routeName; + @JsonInclude(JsonInclude.Include.NON_NULL) + private boolean publishRoute; private List routes; } diff --git a/gusto/src/main/java/com/umc/gusto/domain/route/service/RouteListServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/route/service/RouteListServiceImpl.java index 3f55fc1c..baec17dd 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/route/service/RouteListServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/route/service/RouteListServiceImpl.java @@ -163,6 +163,7 @@ public RouteRouteListResponse getRouteListDetail(Long routeId, User user, Long g return RouteRouteListResponse.builder() .routeId(route.getRouteId()) .routeName(route.getRouteName()) + .publishRoute(route.getPublishRoute() == PublishStatus.PUBLIC ? true : false) .routes(routeLists) .build(); diff --git a/gusto/src/main/java/com/umc/gusto/domain/route/service/RouteServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/route/service/RouteServiceImpl.java index a35359d4..fce6624c 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/route/service/RouteServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/route/service/RouteServiceImpl.java @@ -142,7 +142,7 @@ public RoutePagingResponse getRoute(User user, Long routeId) { .map(route -> RouteResponse.builder() .routeId(route.getRouteId()) .routeName(route.getRouteName()) - .publishRoute(route.getPublishRoute() == PublishStatus.PUBLIC) + .publishRoute(route.getPublishRoute() == PublishStatus.PUBLIC ? true : false) .numStore(routeListRepository.countRouteListByRoute(route)) .build()) .collect(Collectors.toList()); From 12c1516fa240c86604fc1c97ed43d190030de70e Mon Sep 17 00:00:00 2001 From: zzo3ozz Date: Mon, 22 Jul 2024 23:57:42 +0900 Subject: [PATCH 14/25] =?UTF-8?q?fix:=20publishingInfo=20Request=20body?= =?UTF-8?q?=EC=97=90=EC=84=9C=20publishCategory=20=EB=A7=A4=ED=95=91?= =?UTF-8?q?=EC=9D=84=20=EB=AA=BB=ED=95=98=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit API 문서에 작성한 request body 내역과 서버에서 명시한 body 내역이 일치하지 않아 발생한 문제로, 이를 일치하도록 수정함 --- .../domain/user/model/request/PublishingInfoRequest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/model/request/PublishingInfoRequest.java b/gusto/src/main/java/com/umc/gusto/domain/user/model/request/PublishingInfoRequest.java index c407c34a..f3522738 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/model/request/PublishingInfoRequest.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/model/request/PublishingInfoRequest.java @@ -1,7 +1,14 @@ package com.umc.gusto.domain.user.model.request; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor public class PublishingInfoRequest { private boolean publishReview; + @JsonProperty("publishCategory") private boolean publishPin; private boolean publishRoute; From ced1e4df3adac96a8c54fd18413e0110d66a6029 Mon Sep 17 00:00:00 2001 From: kchaeeun Date: Mon, 22 Jul 2024 23:59:53 +0900 Subject: [PATCH 15/25] =?UTF-8?q?refactor=20:=20=ED=83=80=EC=9D=B8=20?= =?UTF-8?q?=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=8B=9C=20=ED=86=A0=ED=81=B0=20=EC=B2=98=EB=A6=AC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MyCategoryController.java | 21 ++++++++++++++----- .../service/MyCategoryServiceImpl.java | 4 ---- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/controller/MyCategoryController.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/controller/MyCategoryController.java index 0a5b33e9..a3dc1cc2 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/controller/MyCategoryController.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/controller/MyCategoryController.java @@ -33,8 +33,14 @@ public ResponseEntity allMyCategory( @RequestParam(name = "nickname", required = false) String nickname, @RequestParam(name = "townName", required = false) String townName, @RequestParam(name = "myCategoryId", required = false) Long myCategoryId) { // paging 처리를 위해 마지막 리턴 myCategoryId 사용 - User user = authUser.getUser(); - PagingResponse pagingResponse = myCategoryService.getAllMyCategory(user, nickname, townName, myCategoryId); + + PagingResponse pagingResponse; + if (nickname == null) { + User user = authUser.getUser(); + pagingResponse = myCategoryService.getAllMyCategory(user, null, townName, myCategoryId); + } else { + pagingResponse = myCategoryService.getAllMyCategory(null, nickname, townName, myCategoryId); + } return ResponseEntity.status(HttpStatus.OK).body(pagingResponse); } @@ -51,10 +57,15 @@ public ResponseEntity allPinByMyCategory( @RequestParam(name = "townName", required = false) String townName, @RequestParam(name = "pinId", required = false) Long pinId, @RequestParam(name = "storeName", required = false) String storeName, - @RequestParam(name = "sort", required = false) String sort// paging 처리를 위해 마지막 리턴 pinId 사용 + @RequestParam(name = "sort", required = false) String sort // paging 처리를 위해 마지막 리턴 pinId 사용 ) { - User user = authUser.getUser(); - PagingResponse pagingResponse = myCategoryService.getAllPinByMyCategory(user, nickname, myCategoryId, townName, pinId, storeName, sort); + PagingResponse pagingResponse; + if (nickname == null) { + User user = authUser.getUser(); + pagingResponse = myCategoryService.getAllPinByMyCategory(user, null, myCategoryId, townName, pinId, storeName, sort); + } else { + pagingResponse = myCategoryService.getAllPinByMyCategory(null, nickname, myCategoryId, townName, pinId, storeName, sort); + } return ResponseEntity.status(HttpStatus.OK).body(pagingResponse); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java index 875a25c0..c33fcfbe 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java @@ -44,10 +44,6 @@ public class MyCategoryServiceImpl implements MyCategoryService { public PagingResponse getAllMyCategory(User user, String nickname, String townName, Long myCategoryId) { Page myCategoryList; if (nickname != null) { - if (nickname.equals(user.getNickname())) { - throw new GeneralException(Code.USER_NOT_FOUND_SELF); - } - user = userRepository.findByNickname(nickname) // 타 닉네임 조회 .orElseThrow(() -> new GeneralException(Code.USER_NOT_FOUND)); if (myCategoryId != null) { From f5162f9d1a5438d509f7e8859d34c929b4a40940 Mon Sep 17 00:00:00 2001 From: kchaeeun Date: Tue, 23 Jul 2024 00:15:12 +0900 Subject: [PATCH 16/25] =?UTF-8?q?refactor=20:=20=EA=B0=80=EA=B2=8C=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20=EB=A6=AC=EB=B7=B0=EC=9D=98=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=ED=86=A0=ED=81=B0=20=EB=B0=9B=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../group/service/GroupServiceImpl.java | 2 +- .../service/MyCategoryServiceImpl.java | 2 +- .../review/repository/ReviewRepository.java | 20 +++++++++---------- .../store/controller/StoreController.java | 4 ++-- .../domain/store/service/StoreService.java | 2 +- .../store/service/StoreServiceImpl.java | 16 +++++++-------- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/group/service/GroupServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/group/service/GroupServiceImpl.java index ee41a8d1..7585f247 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/group/service/GroupServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/group/service/GroupServiceImpl.java @@ -360,7 +360,7 @@ public PagingResponse getAllGroupList(Long groupId, Long groupListId,User user) // 그룹 리스트에 해당하는 각 상점 정보 조회 List list = groupLists.stream().map(gl -> { - Optional topReviewOptional = reviewRepository.findFirstByStoreOrderByLikedDesc(user,gl.getStore()); // 가장 좋아요가 많은 review + Optional topReviewOptional = reviewRepository.findFirstByStoreOrderByLikedDesc(gl.getStore()); // 가장 좋아요가 많은 review String reviewImg = topReviewOptional.map(Review::getImg1).orElse(""); return GroupListResponse.builder() .groupListId(gl.getGroupListId()) diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java index c33fcfbe..27766060 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java @@ -161,7 +161,7 @@ public PagingResponse getAllPinByMyCategory(User user, String nickname, Long myC List result = pinList.stream() // townName을 기준으로 보일 수 있는 store가 포함된 pin만 보이기 .map(pin -> { Store store = pin.getStore(); - List topReviews = reviewRepository.findFirst4ByStoreOrderByLikedDesc(store, finalUser); // 가장 좋아요가 많은 review // 가장 좋아요가 많은 review 이미지(TO DO: 3개 출력으로 변경) + List topReviews = reviewRepository.findFirst4ByStoreOrderByLikedDesc(store); // 가장 좋아요가 많은 review // 가장 좋아요가 많은 review 이미지(TO DO: 3개 출력으로 변경) Integer reviewCnt = reviewRepository.countByStoreAndUserNickname(store, finalUser.getNickname()); // 내가 작성한 리뷰의 개수 == 방문 횟수 String img1 = !topReviews.isEmpty() ? topReviews.get(0).getImg1() : ""; diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java b/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java index 33d439ed..9ad0eb36 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java @@ -17,16 +17,16 @@ import java.util.UUID; public interface ReviewRepository extends JpaRepository { - @Query("SELECT r FROM Review r WHERE r.user.memberStatus = 'ACTIVE' AND r.status = 'ACTIVE' AND (r.user.publishReview = 'PUBLIC' AND r.publishReview = 'PUBLIC' OR r.user = :user) AND r.store = :store ORDER BY r.liked DESC LIMIT 1") - Optional findFirstByStoreOrderByLikedDesc(@Param("user") User user, @Param("store") Store store); - @Query("SELECT r FROM Review r WHERE r.user.memberStatus = 'ACTIVE' AND r.status = 'ACTIVE' AND (r.user.publishReview = 'PUBLIC' AND r.publishReview = 'PUBLIC' OR r.user = :user) AND r.store = :store ORDER BY r.liked DESC, r.reviewId DESC LIMIT 3") // - List findFirst3ByStoreOrderByLikedDesc(@Param("user") User user, @Param("store") Store store); - @Query("SELECT r FROM Review r WHERE r.user.memberStatus = 'ACTIVE' AND r.status = 'ACTIVE' AND (r.user.publishReview = 'PUBLIC' AND r.publishReview = 'PUBLIC' OR r.user = :user) AND r.store = :store ORDER BY r.liked DESC, r.reviewId DESC LIMIT 4") // - List findFirst4ByStoreOrderByLikedDesc(@Param("store") Store store , @Param("user") User user); - @Query("SELECT r FROM Review r WHERE r.user.memberStatus = 'ACTIVE' AND r.status = 'ACTIVE' AND (r.user.publishReview = 'PUBLIC' AND r.publishReview = 'PUBLIC' OR r.user = :user) AND r.store = :store ORDER BY r.visitedAt DESC, r.reviewId DESC") - Page findFirstReviewsByStore(@Param("user") User user, @Param("store") Store store, Pageable pageable); - @Query("SELECT r FROM Review r WHERE r.user.memberStatus = 'ACTIVE' AND r.status = 'ACTIVE' AND (r.user.publishReview = 'PUBLIC' AND r.publishReview = 'PUBLIC' OR r.user = :user) AND r.store = :store AND r.visitedAt <= :visitedAt AND r.reviewId < :reviewId ORDER BY r.visitedAt DESC, r.reviewId DESC") - Page findReviewsAfterIdByStore(@Param("user") User user, @Param("store") Store store, @Param("visitedAt") LocalDate visitedAt, @Param("reviewId") Long reviewId, Pageable pageable); + @Query("SELECT r FROM Review r WHERE r.user.memberStatus = 'ACTIVE' AND r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.publishReview = 'PUBLIC' AND r.store = :store ORDER BY r.liked DESC LIMIT 1") + Optional findFirstByStoreOrderByLikedDesc(@Param("store") Store store); + @Query("SELECT r FROM Review r WHERE r.user.memberStatus = 'ACTIVE' AND r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.publishReview = 'PUBLIC' AND r.store = :store ORDER BY r.liked DESC, r.reviewId DESC LIMIT 3") // + List findFirst3ByStoreOrderByLikedDesc(@Param("store") Store store); + @Query("SELECT r FROM Review r WHERE r.user.memberStatus = 'ACTIVE' AND r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.publishReview = 'PUBLIC' AND r.store = :store ORDER BY r.liked DESC, r.reviewId DESC LIMIT 4") // + List findFirst4ByStoreOrderByLikedDesc(@Param("store") Store store); + @Query("SELECT r FROM Review r WHERE r.user.memberStatus = 'ACTIVE' AND r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.publishReview = 'PUBLIC' AND r.store = :store ORDER BY r.visitedAt DESC, r.reviewId DESC") + Page findFirstReviewsByStore(@Param("store") Store store, Pageable pageable); + @Query("SELECT r FROM Review r WHERE r.user.memberStatus = 'ACTIVE' AND r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.publishReview = 'PUBLIC'AND r.store = :store AND r.visitedAt <= :visitedAt AND r.reviewId < :reviewId ORDER BY r.visitedAt DESC, r.reviewId DESC") + Page findReviewsAfterIdByStore(@Param("store") Store store, @Param("visitedAt") LocalDate visitedAt, @Param("reviewId") Long reviewId, Pageable pageable); boolean existsByReviewIdAndUser(Long reviewId, User user); @Query("SELECT count(r.reviewId) FROM Review r WHERE r.user.memberStatus = 'ACTIVE' AND r.status = 'ACTIVE' AND r.store = :store AND r.user.nickname = :nickname") Integer countByStoreAndUserNickname(Store store, String nickname); // 방문횟수는 리뷰 공개여부과 상관 X diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/controller/StoreController.java b/gusto/src/main/java/com/umc/gusto/domain/store/controller/StoreController.java index 4152617f..d51e5295 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/controller/StoreController.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/controller/StoreController.java @@ -117,7 +117,7 @@ public ResponseEntity> getUnvisitedPinStoresByCategoryAndLoc * 맛집 검색 엔진 */ @GetMapping("/search") - public ResponseEntity> searchStore(@AuthenticationPrincipal AuthUser authUser,@RequestParam(name = "keyword") String keyword){ - return ResponseEntity.status(HttpStatus.OK).body(storeService.searchStore(authUser.getUser(),keyword)); + public ResponseEntity> searchStore(@RequestParam(name = "keyword") String keyword){ + return ResponseEntity.status(HttpStatus.OK).body(storeService.searchStore(keyword)); } } diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreService.java b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreService.java index 9ffa1cc2..18230f93 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreService.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreService.java @@ -16,5 +16,5 @@ public interface StoreService { List getPinStoresByCategoryAndLocation(User user, Long myCategoryId, String townName); Map getVisitedPinStores(User user, Long myCategoryId, String townName, Long lastStoreId, int size); Map getUnvisitedPinStores(User user, Long myCategoryId, String townName, Long lastStoreId, int size); - List searchStore(User user,String keyword); + List searchStore(String keyword); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java index 408be3dd..559ba4aa 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java @@ -50,7 +50,7 @@ public List getStores(User user, List storeIds) { businessDays.put(openingHours.getBusinessDay(), timing); } - List top3Reviews = reviewRepository.findFirst3ByStoreOrderByLikedDesc(user,store); + List top3Reviews = reviewRepository.findFirst3ByStoreOrderByLikedDesc(store); List reviewImg = top3Reviews.stream() .map(review -> Optional.ofNullable(review.getImg1()).orElse("")) @@ -84,7 +84,7 @@ public GetStoreDetailResponse getStoreDetail(User user, Long storeId, LocalDate // .orElseThrow(() -> new GeneralException(Code.CATEGORY_NOT_FOUND)); Long pinId = pinRepository.findByUserAndStoreStoreId(user, storeId); - List top4Reviews = reviewRepository.findFirst4ByStoreOrderByLikedDesc(store,user); + List top4Reviews = reviewRepository.findFirst4ByStoreOrderByLikedDesc(store); List reviewImg = top4Reviews.stream() .map(review -> Optional.ofNullable(review.getImg1()).orElse("")) @@ -96,10 +96,10 @@ public GetStoreDetailResponse getStoreDetail(User user, Long storeId, LocalDate if (reviewId != null && visitedAt != null) { pageSize = PAGE_SIZE; - reviews = reviewRepository.findReviewsAfterIdByStore(user,store, visitedAt, reviewId, Pageable.ofSize(pageSize)); + reviews = reviewRepository.findReviewsAfterIdByStore(store, visitedAt, reviewId, Pageable.ofSize(pageSize)); } else { pageSize = PAGE_SIZE_FIRST; - reviews = reviewRepository.findFirstReviewsByStore(user,store, Pageable.ofSize(pageSize)); + reviews = reviewRepository.findFirstReviewsByStore(store, Pageable.ofSize(pageSize)); } List getReviews = reviews.stream() @@ -194,7 +194,7 @@ public List getPinStoresByCategoryAndLocation(User user, Lo for (Pin pin : pins){ Store store = pin.getStore(); - Optional topReviewOptional = reviewRepository.findFirstByStoreOrderByLikedDesc(user,store); + Optional topReviewOptional = reviewRepository.findFirstByStoreOrderByLikedDesc(store); String reviewImg = topReviewOptional.map(Review::getImg1).orElse(""); boolean hasVisited = reviewRepository.existsByStoreAndUserNickname(store, user.getNickname()); @@ -253,7 +253,7 @@ public Map getPinStoresInfo(User user, Long myCategoryId, String boolean hasVisited = reviewRepository.existsByStoreAndUserNickname(store, user.getNickname()); if (hasVisited == visited) { - List top3Reviews = reviewRepository.findFirst3ByStoreOrderByLikedDesc(user,store); + List top3Reviews = reviewRepository.findFirst3ByStoreOrderByLikedDesc(store); List reviewImg = top3Reviews.stream() .map(review -> Optional.ofNullable(review.getImg1()).orElse("")) .collect(Collectors.toList()); @@ -289,12 +289,12 @@ public Map getUnvisitedPinStores(User user, Long myCategoryId, S } @Override - public List searchStore(User user,String keyword) { + public List searchStore(String keyword) { List searchResult = storeRepository.findTop5ByStoreNameContains(keyword); return searchResult.stream() .map(result -> { - Optional review = reviewRepository.findFirstByStoreOrderByLikedDesc(user,result); + Optional review = reviewRepository.findFirstByStoreOrderByLikedDesc(result); String reviewImg = review.map(Review::getImg1).orElse(""); return GetStoreInfoResponse.builder() .storeId(result.getStoreId()) From 70ad7f543dc94e28f41b0651be37b76b7ea4def1 Mon Sep 17 00:00:00 2001 From: zzo3ozz Date: Tue, 23 Jul 2024 00:41:28 +0900 Subject: [PATCH 17/25] =?UTF-8?q?Revert=20"fix:=20publishingInfo=20Request?= =?UTF-8?q?=20body=EC=97=90=EC=84=9C=20publishCategory=20=EB=A7=A4?= =?UTF-8?q?=ED=95=91=EC=9D=84=20=EB=AA=BB=ED=95=98=EB=8A=94=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=88=98=EC=A0=95"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 12c1516fa240c86604fc1c97ed43d190030de70e. --- .../domain/user/model/request/PublishingInfoRequest.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/model/request/PublishingInfoRequest.java b/gusto/src/main/java/com/umc/gusto/domain/user/model/request/PublishingInfoRequest.java index f3522738..c407c34a 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/model/request/PublishingInfoRequest.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/model/request/PublishingInfoRequest.java @@ -1,14 +1,7 @@ package com.umc.gusto.domain.user.model.request; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor public class PublishingInfoRequest { private boolean publishReview; - @JsonProperty("publishCategory") private boolean publishPin; private boolean publishRoute; From 995bec482b908ef4d99ee324ceddc7ad572809bb Mon Sep 17 00:00:00 2001 From: kchaeeun Date: Tue, 23 Jul 2024 00:58:44 +0900 Subject: [PATCH 18/25] =?UTF-8?q?refactor=20:=20=EA=B0=80=EA=B2=8C=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20=ED=86=A0=ED=81=B0=EC=9D=B4=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20=EC=B0=9C=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=20=EB=B0=98=ED=99=98,=20=EC=97=86=EB=8A=94=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EC=B0=9C=20=EC=97=AC=EB=B6=80=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=20x?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MyCategoryController.java | 24 ++++--------------- .../store/controller/StoreController.java | 4 ++-- .../store/service/StoreServiceImpl.java | 11 +++++++-- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/controller/MyCategoryController.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/controller/MyCategoryController.java index a3dc1cc2..cd96986b 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/controller/MyCategoryController.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/controller/MyCategoryController.java @@ -34,13 +34,8 @@ public ResponseEntity allMyCategory( @RequestParam(name = "townName", required = false) String townName, @RequestParam(name = "myCategoryId", required = false) Long myCategoryId) { // paging 처리를 위해 마지막 리턴 myCategoryId 사용 - PagingResponse pagingResponse; - if (nickname == null) { - User user = authUser.getUser(); - pagingResponse = myCategoryService.getAllMyCategory(user, null, townName, myCategoryId); - } else { - pagingResponse = myCategoryService.getAllMyCategory(null, nickname, townName, myCategoryId); - } + User user = (nickname == null) ? authUser.getUser() : null; + PagingResponse pagingResponse = myCategoryService.getAllMyCategory(user, nickname, townName, myCategoryId); return ResponseEntity.status(HttpStatus.OK).body(pagingResponse); } @@ -59,22 +54,13 @@ public ResponseEntity allPinByMyCategory( @RequestParam(name = "storeName", required = false) String storeName, @RequestParam(name = "sort", required = false) String sort // paging 처리를 위해 마지막 리턴 pinId 사용 ) { - PagingResponse pagingResponse; - if (nickname == null) { - User user = authUser.getUser(); - pagingResponse = myCategoryService.getAllPinByMyCategory(user, null, myCategoryId, townName, pinId, storeName, sort); - } else { - pagingResponse = myCategoryService.getAllPinByMyCategory(null, nickname, myCategoryId, townName, pinId, storeName, sort); - } + + User user = (nickname == null) ? authUser.getUser() : null; + PagingResponse pagingResponse = myCategoryService.getAllPinByMyCategory(user, nickname, myCategoryId, townName, pinId, storeName, sort); return ResponseEntity.status(HttpStatus.OK).body(pagingResponse); } - /** - * 내 카테고리 공개 상태 업데이트 - * [ - */ - /** * 내 카테고리 생성 * [POST] /myCategories diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/controller/StoreController.java b/gusto/src/main/java/com/umc/gusto/domain/store/controller/StoreController.java index d51e5295..6b31de93 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/controller/StoreController.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/controller/StoreController.java @@ -29,7 +29,7 @@ public class StoreController { public ResponseEntity> getStores( @AuthenticationPrincipal AuthUser authUser, @RequestParam(name = "storeId") List storeIds) { - User user = authUser.getUser(); + User user = authUser != null ? authUser.getUser() : null; List getStores = storeService.getStores(user, storeIds); return ResponseEntity.status(HttpStatus.OK).body(getStores); } @@ -44,7 +44,7 @@ public ResponseEntity getStoreDetail( @PathVariable Long storeId, @RequestParam(name = "visitedAt", required = false) LocalDate visitedAt, @RequestParam(name = "reviewId", required = false) Long reviewId){ - User user = authUser.getUser(); + User user = authUser != null ? authUser.getUser() : null; // 상점 세부 정보 가져오기 GetStoreDetailResponse getStoreDetail = storeService.getStoreDetail(user, storeId, visitedAt, reviewId); return ResponseEntity.status(HttpStatus.OK).body(getStoreDetail); diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java index 559ba4aa..f651480a 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java @@ -38,7 +38,15 @@ public List getStores(User user, List storeIds) { for (Long storeId : storeIds) { Store store = storeRepository.findById(storeId) .orElseThrow(() -> new GeneralException(Code.STORE_NOT_FOUND)); - Long pinId = pinRepository.findByUserAndStoreStoreId(user, storeId); + + Long pinId = null; + boolean isPinned = false; + if (user != null) { + pinId = pinRepository.findByUserAndStoreStoreId(user, storeId); + isPinned = pinRepository.existsByUserAndStoreStoreId(user, storeId); + } + + List openingHoursList = openingHoursRepository.findByStoreStoreId(storeId); Map businessDays = new LinkedHashMap<>(); @@ -55,7 +63,6 @@ public List getStores(User user, List storeIds) { List reviewImg = top3Reviews.stream() .map(review -> Optional.ofNullable(review.getImg1()).orElse("")) .collect(Collectors.toList()); - boolean isPinned = pinRepository.existsByUserAndStoreStoreId(user, storeId); responses.add(GetStoreResponse.builder() From 1c9696f1b197d1584abe75a88b9c2839f08cc9bf Mon Sep 17 00:00:00 2001 From: zzo3ozz Date: Tue, 23 Jul 2024 01:08:42 +0900 Subject: [PATCH 19/25] =?UTF-8?q?fix:=20publishingInfo=20Request=20body?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=A7=A4=ED=95=91=ED=95=98=EC=A7=80=20?= =?UTF-8?q?=EB=AA=BB=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Getter가 누락되어 올바르게 mapping이 진행되지 않았음 (순서가 변경되면 값을 매핑하지 못함) --- .../gusto/domain/user/model/request/PublishingInfoRequest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gusto/src/main/java/com/umc/gusto/domain/user/model/request/PublishingInfoRequest.java b/gusto/src/main/java/com/umc/gusto/domain/user/model/request/PublishingInfoRequest.java index c407c34a..de4d0629 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/user/model/request/PublishingInfoRequest.java +++ b/gusto/src/main/java/com/umc/gusto/domain/user/model/request/PublishingInfoRequest.java @@ -1,5 +1,8 @@ package com.umc.gusto.domain.user.model.request; +import lombok.Getter; + +@Getter public class PublishingInfoRequest { private boolean publishReview; private boolean publishPin; From 28d0bef1b83399673531f19fa9b3708a60f37ef2 Mon Sep 17 00:00:00 2001 From: kchaeeun Date: Tue, 23 Jul 2024 21:05:00 +0900 Subject: [PATCH 20/25] =?UTF-8?q?refactor=20:=20=EA=B0=80=EA=B2=8C=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=20=EC=97=AC=EB=B6=80=EC=97=90=20=EB=94=B0=EB=9D=BC=20?= =?UTF-8?q?=EC=B0=9C=20=EC=97=AC=EB=B6=80=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gusto/.idea/inspectionProfiles/Project_Default.xml | 10 ++++++++++ .../umc/gusto/domain/myCategory/entity/MyCategory.java | 3 --- .../gusto/domain/store/service/StoreServiceImpl.java | 10 +++++++--- 3 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 gusto/.idea/inspectionProfiles/Project_Default.xml diff --git a/gusto/.idea/inspectionProfiles/Project_Default.xml b/gusto/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..6f67cf72 --- /dev/null +++ b/gusto/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/entity/MyCategory.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/entity/MyCategory.java index 813e2844..226073e2 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/entity/MyCategory.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/entity/MyCategory.java @@ -45,9 +45,6 @@ public class MyCategory extends BaseEntity{ @JoinColumn(name = "userId") private User user; - @OneToMany(mappedBy = "myCategory", cascade = CascadeType.ALL) - private final List pinList = new ArrayList<>(); - public void updateMyCategoryName(String myCategoryName) { this.myCategoryName = myCategoryName; } diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java index f651480a..18e04d14 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java @@ -89,7 +89,13 @@ public GetStoreDetailResponse getStoreDetail(User user, Long storeId, LocalDate // 가게별 기본 카테고리 값 // Category category = storeRepository.findCategoryByStoreId(storeId) // .orElseThrow(() -> new GeneralException(Code.CATEGORY_NOT_FOUND)); - Long pinId = pinRepository.findByUserAndStoreStoreId(user, storeId); + + Long pinId = null; + boolean isPinned = false; + if (user != null) { + pinId = pinRepository.findByUserAndStoreStoreId(user, storeId); + isPinned = pinRepository.existsByUserAndStoreStoreId(user, storeId); + } List top4Reviews = reviewRepository.findFirst4ByStoreOrderByLikedDesc(store); @@ -127,8 +133,6 @@ public GetStoreDetailResponse getStoreDetail(User user, Long storeId, LocalDate }) .toList(); - boolean isPinned = pinRepository.existsByUserAndStoreStoreId(user, storeId); - return GetStoreDetailResponse.builder() .pinId(pinId) .storeId(storeId) From 0491bd8a5e1ce23ca5bb6b6bdacc89fb63ab12b6 Mon Sep 17 00:00:00 2001 From: kchaeeun Date: Tue, 23 Jul 2024 21:25:08 +0900 Subject: [PATCH 21/25] =?UTF-8?q?fix=20:=20hard=20delete=EC=99=80=EC=9D=98?= =?UTF-8?q?=20=EC=B6=A9=EB=8F=8C=20=EB=B0=A9=EC=A7=80=EB=A5=BC=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20=EC=88=98=EC=A0=95=ED=95=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EC=9D=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/umc/gusto/domain/myCategory/entity/MyCategory.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/entity/MyCategory.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/entity/MyCategory.java index 226073e2..813e2844 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/entity/MyCategory.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/entity/MyCategory.java @@ -45,6 +45,9 @@ public class MyCategory extends BaseEntity{ @JoinColumn(name = "userId") private User user; + @OneToMany(mappedBy = "myCategory", cascade = CascadeType.ALL) + private final List pinList = new ArrayList<>(); + public void updateMyCategoryName(String myCategoryName) { this.myCategoryName = myCategoryName; } From 173044128bab0a6e8bfec69724c8465d6faa8bfe Mon Sep 17 00:00:00 2001 From: kchaeeun Date: Tue, 23 Jul 2024 21:48:25 +0900 Subject: [PATCH 22/25] =?UTF-8?q?refactor=20:=20=EC=B9=B4=ED=85=8C?= =?UTF-8?q?=EA=B3=A0=EB=A6=AC=20=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20PublishCa?= =?UTF-8?q?tegory=20=EA=B0=92=EC=9D=B4=20bool=20=EA=B0=92=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=B6=9C=EB=A0=A5=EB=90=98=EA=B2=8C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../myCategory/model/response/MyCategoryResponse.java | 7 ++++--- .../domain/myCategory/service/MyCategoryServiceImpl.java | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/MyCategoryResponse.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/MyCategoryResponse.java index 567dd51f..380cd874 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/MyCategoryResponse.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/MyCategoryResponse.java @@ -1,6 +1,6 @@ package com.umc.gusto.domain.myCategory.model.response; -import com.umc.gusto.global.common.PublishStatus; +import com.fasterxml.jackson.annotation.JsonInclude; import lombok.*; @Builder @@ -12,8 +12,9 @@ public class MyCategoryResponse{ String myCategoryName; String myCategoryScript; Integer myCategoryIcon; - PublishStatus publishCategory; - PublishStatus userPublishCategory; + @JsonInclude(JsonInclude.Include.NON_NULL) + Boolean publishCategory; + Boolean userPublishCategory; Integer pinCnt; } diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java index 27766060..ff30da97 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java @@ -74,8 +74,8 @@ public PagingResponse getAllMyCategory(User user, String nickname, String townNa .myCategoryName(myCategory.getMyCategoryName()) .myCategoryScript(myCategory.getMyCategoryScript()) .myCategoryIcon(myCategory.getMyCategoryIcon()) - .publishCategory(myCategory.getPublishCategory()) - .userPublishCategory(finalUser.getPublishCategory()) + .publishCategory(myCategory.getPublishCategory() == PublishStatus.PUBLIC) // PublishCategory가 PUBLIC이면 true 반환 + .userPublishCategory(finalUser.getPublishCategory() == PublishStatus.PUBLIC) .pinCnt(pinList.size()) .build(); }) From da101baa7a359e30084d3d11558181f3f2437e4f Mon Sep 17 00:00:00 2001 From: kchaeeun Date: Tue, 23 Jul 2024 22:05:02 +0900 Subject: [PATCH 23/25] =?UTF-8?q?refactor=20:=20=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20reponse=20=EA=B0=92=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gusto/domain/myCategory/model/response/PagingResponse.java | 2 -- .../gusto/domain/myCategory/service/MyCategoryServiceImpl.java | 2 -- 2 files changed, 4 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/PagingResponse.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/PagingResponse.java index b49bb9f7..a886a000 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/PagingResponse.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/PagingResponse.java @@ -12,7 +12,5 @@ @Builder public class PagingResponse { private boolean hasNext; - private PublishStatus userPublishCategory; - private PublishStatus publishCategory; private List result; } diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java index ff30da97..d2fa25d6 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java @@ -184,8 +184,6 @@ public PagingResponse getAllPinByMyCategory(User user, String nickname, Long myC return PagingResponse.builder() .hasNext(pinList.hasNext()) - .userPublishCategory(user.getPublishCategory()) - .publishCategory(myCategory.get().getPublishCategory()) .result(result) .build(); } From 92ecddc1affecb72b3fb0d9ed7128e5fd705462c Mon Sep 17 00:00:00 2001 From: yujiyea Date: Wed, 24 Jul 2024 17:19:12 +0900 Subject: [PATCH 24/25] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EB=AA=A8=EC=95=84=EB=B3=B4=EA=B8=B0=20-=20=EC=9D=B8=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EB=B7=B0=20API=EA=B0=80=20=ED=83=80=EC=9D=B8,=20?= =?UTF-8?q?=EB=82=98=EB=A5=BC=20=EA=B5=AC=EB=B6=84=ED=95=A0=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=EC=97=86=EC=9D=8C,=20=ED=83=80=EC=9D=B8=20API?= =?UTF-8?q?=EA=B0=80=20=EB=94=B0=EB=A1=9C=20=EC=9E=88=EA=B8=B0=20=EB=95=8C?= =?UTF-8?q?=EB=AC=B8=EC=97=90=20=ED=83=80=EC=9D=B8=20=EB=AA=A8=EC=95=84?= =?UTF-8?q?=EB=B3=B4=EA=B8=B0=20API=EC=97=90=EC=84=9C=20=EA=B3=B5=EA=B0=9C?= =?UTF-8?q?=20=EC=97=AC=EB=B6=80=20=EC=B2=B4=ED=81=AC=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 8 +-- .../review/service/CollectReviewService.java | 1 - .../service/CollectReviewServiceImpl.java | 69 +++++++------------ 3 files changed, 24 insertions(+), 54 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/controller/ReviewController.java b/gusto/src/main/java/com/umc/gusto/domain/review/controller/ReviewController.java index c66a4bbb..3c4e4ec3 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/controller/ReviewController.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/controller/ReviewController.java @@ -67,14 +67,8 @@ public ResponseEntity getReview(@PathVariable Long reviewId){ * 리뷰 모아보기 - 인스타 뷰 */ @GetMapping("/instaView") - public ResponseEntity getReviewOfInstaView(@AuthenticationPrincipal AuthUser authUser, @RequestParam(name = "mineCheck") boolean mineCheck,@RequestParam(name = "reviewId", required = false) Long reviewId, @RequestParam(name = "size") int size){ + public ResponseEntity getReviewOfInstaView(@AuthenticationPrincipal AuthUser authUser, @RequestParam(name = "reviewId", required = false) Long reviewId, @RequestParam(name = "size") int size){ User user = authUser.getUser(); - - //내 인스타 뷰라면 - if(mineCheck){ - return ResponseEntity.ok().body(collectReviewService.getMyReviewOfInstaView(user, reviewId, size)); - } - return ResponseEntity.ok().body(collectReviewService.getReviewOfInstaView(user, reviewId, size)); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewService.java b/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewService.java index 3e4001ef..e047061b 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewService.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewService.java @@ -8,7 +8,6 @@ public interface CollectReviewService { // CollectReviewsOfInstaResponse getReviewOfInstaView(User user, ReviewViewRequest reviewViewRequest); - CollectReviewsResponse getMyReviewOfInstaView(User user, Long reviewId, int size); CollectReviewsResponse getReviewOfInstaView(User user, Long reviewId, int size); CollectReviewsOfCalResponse getReviewOfCalView(User user, Long reviewId, int size, LocalDate date); CollectReviewsResponse getReviewOfTimeView(User user, Long reviewId, int size); diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewServiceImpl.java index 2cbbcf4d..7d97255f 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/service/CollectReviewServiceImpl.java @@ -6,10 +6,8 @@ import com.umc.gusto.domain.user.entity.User; import com.umc.gusto.domain.user.repository.UserRepository; import com.umc.gusto.global.common.BaseEntity; -import com.umc.gusto.global.common.PublishStatus; import com.umc.gusto.global.exception.Code; import com.umc.gusto.global.exception.customException.NotFoundException; -import com.umc.gusto.global.exception.customException.PrivateItemException; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -27,14 +25,14 @@ public class CollectReviewServiceImpl implements CollectReviewService{ private final UserRepository userRepository; @Override - public CollectReviewsResponse getMyReviewOfInstaView(User user, Long reviewId, int size) { + public CollectReviewsResponse getReviewOfInstaView(User user, Long reviewId, int size) { //페이징해서 가져오기 Page reviews = pagingReview(user, reviewId, size); //다음에 조회될 리뷰가 있는지 확인하기 boolean checkNext = reviews.hasNext(); List basicViewResponse = reviews.map(BasicViewResponse::of).toList(); -// Long cursorId = basicViewResponse.get(basicViewResponse.size()-1).getReviewId(); + Long cursorId = null; if(!basicViewResponse.isEmpty()){ cursorId = basicViewResponse.get(basicViewResponse.size()-1).getReviewId(); @@ -42,38 +40,6 @@ public CollectReviewsResponse getMyReviewOfInstaView(User user, Long reviewId, i return CollectReviewsResponse.of(basicViewResponse, cursorId,checkNext); } - /* - 다른 사용자의 프로필을 볼 때 사용하는 인스타 뷰이기 때문에 사용자의 publish_review 체크와 각 리뷰의 publish_reivew 체크가 필요 - */ - @Override - public CollectReviewsResponse getReviewOfInstaView(User user, Long reviewId, int size) { - Page reviews; - - //사용자가 리뷰 프로필에 표기를 했는지 체크 - if(!user.getPublishReview().isCheck()){ // 표기 X - return CollectReviewsResponse.builder().build(); - } - - //사용자의 리뷰들 중 public인 것만 추출 - Sort sort = Sort.by("visitedAt").descending().and(Sort.by("reviewId").descending()); - PageRequest pageRequest = PageRequest.of(0, size, sort); - - if(reviewId == null){ - reviews = reviewRepository.pagingInstaViewNoCursor(user, pageRequest); - }else { - Review review = reviewRepository.findById(reviewId).orElseThrow(()->new NotFoundException(Code.REVIEW_NOT_FOUND)); - reviews = reviewRepository.pagingInstaView(user, reviewId, review.getVisitedAt(), pageRequest); - } - - //다음 조회 되는 리뷰가 있는지 확인 - boolean checkNext = reviews.hasNext(); - - //response 형태로 변환 - List basicViewResponse = reviews.map(BasicViewResponse::of).toList(); - Long cursorId = basicViewResponse.isEmpty() ? null : basicViewResponse.get(basicViewResponse.size()-1).getReviewId(); - - return CollectReviewsResponse.of(basicViewResponse, cursorId,checkNext); - } @Override public CollectReviewsOfCalResponse getReviewOfCalView(User user, Long reviewId, int size, LocalDate date) { @@ -110,25 +76,37 @@ public CollectReviewsResponse getReviewOfTimeView(User user, Long reviewId, int @Override public CollectReviewsResponse getOthersReview(String nickName, Long reviewId, int size) { + Page reviews; User other = userRepository.findByNicknameAndMemberStatusIs(nickName, User.MemberStatus.ACTIVE).orElseThrow(()-> new NotFoundException(Code.USER_NOT_FOUND)); - //다른 유저의 공개 여부 확인 - if(!other.getPublishReview().equals(PublishStatus.PUBLIC)){ - throw new PrivateItemException(Code.NO_PUBLIC_REVIEW); + + //사용자가 리뷰 프로필에 표기를 했는지 체크 + if(!other.getPublishReview().isCheck()){ // 표기 X + return CollectReviewsResponse.builder().build(); } - //페이징해서 가져오기 - Page reviews = pagingReview(other, reviewId, size); + //사용자의 리뷰들 중 public인 것만 추출 + Sort sort = Sort.by("visitedAt").descending().and(Sort.by("reviewId").descending()); + PageRequest pageRequest = PageRequest.of(0, size, sort); - //다음에 조회될 리뷰가 있는지 확인하기 + if(reviewId == null){ + reviews = reviewRepository.pagingInstaViewNoCursor(other, pageRequest); + }else { + Review review = reviewRepository.findById(reviewId).orElseThrow(()->new NotFoundException(Code.REVIEW_NOT_FOUND)); + reviews = reviewRepository.pagingInstaView(other, reviewId, review.getVisitedAt(), pageRequest); + } + + //다음 조회 되는 리뷰가 있는지 확인 boolean checkNext = reviews.hasNext(); + + //response 형태로 변환 List basicViewResponse = reviews.map(BasicViewResponse::of).toList(); - Long cursorId = basicViewResponse.get(basicViewResponse.size()-1).getReviewId(); - return CollectReviewsResponse.of(basicViewResponse, cursorId, checkNext); + Long cursorId = basicViewResponse.isEmpty() ? null : basicViewResponse.get(basicViewResponse.size()-1).getReviewId(); + + return CollectReviewsResponse.of(basicViewResponse, cursorId,checkNext); } private Page pagingReview(User user, Long cursorId, int size){ //최신순 날짜로 정렬 -// Sort sort = Sort.by("visitedAt").descending().and(Sort.by("createdAt").descending()); Sort sort = Sort.by("visitedAt").descending().and(Sort.by("reviewId").descending()); PageRequest pageRequest = PageRequest.of(0, size, sort); @@ -139,7 +117,6 @@ private Page pagingReview(User user, Long cursorId, int size){ }else{ //최초가 아닌 경우 //커서 id를 기반으로 그보다 낮은 ID의 리뷰를 가져온다 => 최신 날짜가 이전의 데이터가 나타난다. Review review = reviewRepository.findById(cursorId).orElseThrow(()->new NotFoundException(Code.REVIEW_NOT_FOUND)); -// reviews = reviewRepository.findAllByUserAndStatusAndReviewIdLessThanAndVisitedAtLessThanEqual(user, BaseEntity.Status.ACTIVE, cursorId, review.getVisitedAt(),pageRequest).orElseThrow(()-> new NotFoundException(Code.REVIEW_NOT_FOUND)); reviews = reviewRepository.pagingMyReview(user, cursorId, review.getVisitedAt(),pageRequest); } From c4f2ec2a007ad9eecfe327dc7b0fefba8b9bdc74 Mon Sep 17 00:00:00 2001 From: zzo3ozz Date: Thu, 25 Jul 2024 22:56:23 +0900 Subject: [PATCH 25/25] =?UTF-8?q?fix:=20=EC=A4=91=EB=B3=B5=EB=90=9C=20?= =?UTF-8?q?=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/umc/gusto/global/auth/service/SocialService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java b/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java index e5d54243..fdf799eb 100644 --- a/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java +++ b/gusto/src/main/java/com/umc/gusto/global/auth/service/SocialService.java @@ -17,7 +17,6 @@ @Service @Slf4j @RequiredArgsConstructor -@Slf4j public class SocialService { private final RestClient restClient = RestClient.create(); private static final String AUTH_TYPE = "Bearer ";